static int dir_extend( ufs2_daddr_t blk, ufs2_daddr_t nblk, off_t size, ino_t ino ) { char block[MAXBSIZE]; if ( bread( &disk, fsbtodb( &sblock, blk ), block, roundup( size, sblock.fs_fsize ) ) <= 0 ) { warn( "Failed to read dir block" ); return ( -1 ); } dir_clear_block( block, size ); if ( bwrite( &disk, fsbtodb( &sblock, nblk ), block, sblock.fs_bsize ) <= 0 ) { warn( "Failed to write dir block" ); return ( -1 ); } return ( dir_insert( nblk, size, ino ) ); }
/** * @brief Reads a folder listing, prints all items and adds all subdirectories to the global queue * @param offset where the first directory entry of the folder structure begins */ void listDirectory(unsigned int offset) { // do not read into next cluster long maxOffset = offset + (bootsector->BPB.sectorspercluster * bootsector->BPB.sectorsize); long newOffset = offset; lseek(handle, newOffset, SEEK_SET); // the reference point in the list where we want to add the subdirectories // by default, we want to add subdirectories to the top so that we get depth-first search DIRENTRY* referencePoint = firstDirItem->directoryEntry; // this is where we read into DIRENTRY* directoryEntry; // in case we have to handle VFAT / LFN entries, prepare the buffer char LFN[260]; while((newOffset < maxOffset) && (directoryEntry = readDirectoryEntry())) { // we need to preserve the offset in case any operations move the file pointer //newOffset = tell(handle); newOffset = lseek(handle, 0, SEEK_CUR); if(memcmp(directoryEntry->name, dot, 8) == 0) { char buf2[1024]; absoluteDirectoryPath(directoryEntry, buf2); printf("Directory of %s\n", buf2); } if(directoryEntry->attr == DIRENTRY_ATTR_VFAT) { printf("this is a VFAT entry!\n"); handleLFN(directoryEntry, LFN); }else{ printDirectoryEntry(directoryEntry); } if(isDirectory(directoryEntry)) { // add subdirectories to the queue // please ignore the current directory entry ('.') and parent ('..') if((memcmp(directoryEntry->name, dot, 8) != 0) && (memcmp(directoryEntry->name, dotdot, 8) != 0)) { dir_insert(referencePoint, directoryEntry); referencePoint = directoryEntry; //dir_push_back(directoryEntry); } } lseek(handle, newOffset, SEEK_SET); } }
/* * Insert the journal file into the ROOTINO directory. We always extend the * last frag */ static int journal_insertfile(ino_t ino) { struct ufs1_dinode *dp1; struct ufs2_dinode *dp2; void *ip; ufs2_daddr_t nblk; ufs2_daddr_t blk; ufs_lbn_t lbn; int size; int mode; int off; if (getino(&disk, &ip, ROOTINO, &mode) != 0) { warn("Failed to get root inode"); sbdirty(); return (-1); } dp2 = ip; dp1 = ip; blk = 0; size = 0; nblk = journal_balloc(); if (nblk <= 0) return (-1); /* * For simplicity sake we aways extend the ROOTINO into a new * directory block rather than searching for space and inserting * into an existing block. However, if the rootino has frags * have to free them and extend the block. */ if (sblock.fs_magic == FS_UFS1_MAGIC) { lbn = lblkno(&sblock, dp1->di_size); off = blkoff(&sblock, dp1->di_size); blk = dp1->di_db[lbn]; size = sblksize(&sblock, (off_t)dp1->di_size, lbn); } else { lbn = lblkno(&sblock, dp2->di_size); off = blkoff(&sblock, dp2->di_size); blk = dp2->di_db[lbn]; size = sblksize(&sblock, (off_t)dp2->di_size, lbn); } if (off != 0) { if (dir_extend(blk, nblk, off, ino) == -1) return (-1); } else { blk = 0; if (dir_insert(nblk, 0, ino) == -1) return (-1); } if (sblock.fs_magic == FS_UFS1_MAGIC) { dp1->di_blocks += (sblock.fs_bsize - size) / DEV_BSIZE; dp1->di_db[lbn] = nblk; dp1->di_size = lblktosize(&sblock, lbn+1); } else { dp2->di_blocks += (sblock.fs_bsize - size) / DEV_BSIZE; dp2->di_db[lbn] = nblk; dp2->di_size = lblktosize(&sblock, lbn+1); } if (putino(&disk) < 0) { warn("Failed to write root inode"); return (-1); } if (cgwrite(&disk) < 0) { warn("Failed to write updated cg"); sbdirty(); return (-1); } if (blk) { if (cgbfree(&disk, blk, size) < 0) { warn("Failed to write cg"); return (-1); } } return (0); }
static int journal_insertfile( ino_t ino ) { struct ufs1_dinode *dp1; struct ufs2_dinode *dp2; void *ip; ufs2_daddr_t nblk; ufs2_daddr_t blk; ufs_lbn_t lbn; int size; int mode; int off; if ( getino( &disk, &ip, ROOTINO, &mode ) != 0 ) { warn( "Failed to get root inode" ); sbdirty(); return ( -1 ); } dp2 = ip; dp1 = ip; blk = 0; size = 0; nblk = journal_balloc(); if ( nblk <= 0 ) return ( -1 ); if ( sblock.fs_magic == FS_UFS1_MAGIC ) { lbn = lblkno( &sblock, dp1->di_size ); off = blkoff( &sblock, dp1->di_size ); blk = dp1->di_db[lbn]; size = sblksize( &sblock, (off_t) dp1->di_size, lbn ); } else { lbn = lblkno( &sblock, dp2->di_size ); off = blkoff( &sblock, dp2->di_size ); blk = dp2->di_db[lbn]; size = sblksize( &sblock, (off_t) dp2->di_size, lbn ); } if ( off != 0 ) { if ( dir_extend( blk, nblk, off, ino ) == -1 ) return ( -1 ); } else { blk = 0; if ( dir_insert( nblk, 0, ino ) == -1 ) return ( -1 ); } if ( sblock.fs_magic == FS_UFS1_MAGIC ) { dp1->di_blocks += ( sblock.fs_bsize - size ) / DEV_BSIZE; dp1->di_db[lbn] = nblk; dp1->di_size = lblktosize( &sblock, lbn + 1 ); } else { dp2->di_blocks += ( sblock.fs_bsize - size ) / DEV_BSIZE; dp2->di_db[lbn] = nblk; dp2->di_size = lblktosize( &sblock, lbn + 1 ); } if ( putino( &disk ) < 0 ) { warn( "Failed to write root inode" ); return ( -1 ); } if ( cgwrite( &disk ) < 0 ) { warn( "Failed to write updated cg" ); sbdirty(); return ( -1 ); } if ( blk ) { if ( cgbfree( &disk, blk, size ) < 0 ) { warn( "Failed to write cg" ); return ( -1 ); } } return ( 0 ); }