diff --git a/tools/mkfs.c b/tools/mkfs.c index 78eb260..eee942c 100644 --- a/tools/mkfs.c +++ b/tools/mkfs.c @@ -8,8 +8,8 @@ * ensure that swap is not used on RF disk images. * deal with errors instead of exiting :-) * - * $Revision: 1.18 $ - * $Date: 2008/05/04 09:07:54 $ + * $Revision: 1.17 $ + * $Date: 2008/05/04 14:20:12 $ */ int debug=1; @@ -55,7 +55,7 @@ struct v1inode { /* Format of 1st edition i-node */ /* * We build directories with certain limitations: first, they are all - * directories under /; second, most of them occupy 4 contiguous disk blocks, + * directories under /; second, they all occupy 4 contiguous disk blocks, * giving us up to 64 directory entries. */ #define DIRBLOCKS 4 @@ -68,8 +68,10 @@ struct v1dirent { /* Format of 1st edition dir entry */ struct directory { /* Internal structure for each dir */ uint16_t block; /* Starting block */ + uint16_t inum; /* I-node number used by this dir */ int numentries; /* Number of entries in entry[] */ - struct v1dirent *entry; /* calloc'd later to be an array */ + int nextfree; /* Next free entry */ + struct v1dirent *entry; }; unsigned char buf[BLKSIZE]; /* A block buffer */ @@ -107,7 +109,7 @@ void write_superblock(void) if (debug) printf("Writing %d inodes, each size %d, total %d\n", icount, sizeof(struct v1inode), icount * sizeof(struct v1inode)); - fwrite(inodelist, sizeof(struct v1inode), icount, diskfh); + fwrite(&inodelist[1], sizeof(struct v1inode), icount-1, diskfh); if (debug) { long posn= ftell(diskfh); long block= posn/BLKSIZE; @@ -178,8 +180,6 @@ int alloc_blocks(int n) /* Add a filename and i-number to the given directory */ void add_direntry(struct directory *d, uint16_t inum, char *name) { - int i; - if (d == NULL) { printf("I need a struct directory * please\n"); exit(1); } @@ -194,23 +194,18 @@ void add_direntry(struct directory *d, uint16_t inum, char *name) } /* Find an entry in the directory which is empty */ - for (i = 0; i < d->numentries; i++) { - if (d->entry[i].inode == 0) { - d->entry[i].inode = inum; - strncpy(d->entry[i].name, name, 8); - return; - } + if (d->nextfree >= d->numentries) { + printf("Unable to add directory entry\n"); exit(1); } - - printf("Unable to add directory entry\n"); exit(1); + d->entry[d->nextfree].inode = inum; + strncpy(d->entry[d->nextfree].name, name, 8); + d->nextfree++; } /* * Create a directory with the given name. Allocate an i-node for it, and a * set of blocks. Attach it to /. Return the struct allocated. If name is - * "/", we are making the root directory itself. numblocks is the number of - * disk blocks the dir will occupy, normally this is DIRBLOCKS, but / and - * /dev only need 1 block each. + * "/", we are making the root directory itself. */ struct directory *create_dir(char *name, int numblocks) { @@ -228,26 +223,23 @@ struct directory *create_dir(char *name, int numblocks) d = (struct directory *)calloc(1, sizeof(struct directory)); d->numentries= numblocks * DIRENTPERBLOCK; + d->nextfree= 0; d->entry= (struct v1dirent *)calloc(d->numentries, sizeof(struct v1dirent)); /* Allocate an i-node and some blocks for the directory */ - /* / always gets ROOTDIR_INUM; other dirs get allocated an inode number */ if (strcmp(name, "/")) inum = alloc_inode(); else inum = ROOTDIR_INUM; d->block = alloc_blocks(numblocks); - if (debug) printf("In create_dir, got back block %d, %d config blks\n", - d->block, numblocks); + d->inum= inum; + if (debug) printf("In create_dir, got back inum %d blk %d, %d config blks\n", + inum, d->block, numblocks); - /* Mark the i-node as a directory. Set the number of links to default 2 */ - /* (. and the root entry), set the directory size, and write the number */ - /* of blocks occupied into the directory's i-node. */ - inodelist[inum].flags |= I_DIR | I_UREAD | I_UWRITE | I_OREAD | I_OWRITE; - inodelist[inum].nlinks= 2; - inodelist[inum].size= numblocks * BLKSIZE; + /* Mark the i-node as a directory */ + inodelist[inum].flags |= I_DIR | I_UREAD | I_UWRITE | I_OREAD; + inodelist[inum].nlinks= 2; /* Size is determined at write-time */ for (i=0, blk=d->block; i < numblocks; i++, blk++) inodelist[inum].block[i]= blk; - /* If the directory is not /, attach it to rootdir */ if (strcmp(name, "/")) { add_direntry(rootdir, inum, name); @@ -272,10 +264,13 @@ void write_dir(struct directory *d, char *name) } if (debug) - printf("Writing dir %s of %d blocks from block %d (offset 0x%x) on\n", - name, d->numentries / DIRENTPERBLOCK, d->block, + printf("Writing dir %s, size %d, %d blks from block %d (offset 0x%x) on\n", + name, d->numentries * sizeof(struct v1dirent), + d->numentries / DIRENTPERBLOCK, d->block, d->block * BLKSIZE); + /* Directory size is the # of bytes of the in-use directory entries */ + inodelist[d->inum].size= d->nextfree * sizeof(struct v1dirent); fseek(diskfh, d->block * BLKSIZE, SEEK_SET); fwrite(d->entry, d->numentries * sizeof(struct v1dirent), 1, diskfh); } @@ -364,7 +359,7 @@ void add_files(char *basedir, char *dir) printf("Cannot opendir %s\n", fullname); exit(1); } - /* Create the image directory with a default number of blocks */ + /* Create the image directory */ d = create_dir(dir, DIRBLOCKS); /* Walk the directory */ @@ -586,12 +581,12 @@ int main(int argc, char *argv[]) /* Walk the top directory argument, dealing with the subdirs */ process_topdir(argv[1]); - /* Write out the superblock and i-nodes */ - write_superblock(); - /* Write out the root directory */ write_dir(rootdir, "/"); + /* Write out the superblock and i-nodes */ + write_superblock(); + fclose(diskfh); exit(0); }