===================PATCH FOR CURRENT===================== diff -ur src-ORIG/include/sys/dir.h src/include/sys/dir.h --- src-ORIG/include/sys/dir.h 2007-02-16 14:25:33.000000000 +0100 +++ src/include/sys/dir.h 2007-02-16 14:25:33.000000000 +0100 @@ -16,4 +16,8 @@ char d_name[DIRSIZ]; }; +struct direct1 { /* for backwards compatibility */ + unsigned short d_ino; + char d_name[14]; +}; #endif /* _DIR_H */ diff -ur src-ORIG/servers/mfs/const.h src/servers/mfs/const.h --- src-ORIG/servers/mfs/const.h 2007-02-16 14:25:33.000000000 +0100 +++ src/servers/mfs/const.h 2007-02-16 14:25:33.000000000 +0100 @@ -80,7 +80,9 @@ #define START_BLOCK 2 /* first block of FS (not counting SB) */ #define DIR_ENTRY_SIZE usizeof (struct direct) /* # bytes/dir entry */ +#define V1_DIR_ENTRY_SIZE usizeof (struct direct1) #define NR_DIR_ENTRIES(b) ((b)/DIR_ENTRY_SIZE) /* # dir entries/blk */ +#define V1_NR_DIR_ENTRIES(b) ((b)/V1_DIR_ENTRY_SIZE) #define SUPER_SIZE usizeof (struct super_block) /* super_block size */ #define PIPE_SIZE(b) (V1_NR_DZONES*(b)) /* pipe size in bytes */ diff -ur src-ORIG/servers/mfs/super.h src/servers/mfs/super.h --- src-ORIG/servers/mfs/super.h 2007-02-16 14:25:33.000000000 +0100 +++ src/servers/mfs/super.h 2007-02-16 14:25:33.000000000 +0100 @@ -54,6 +54,19 @@ bit_t s_zsearch; /* all zones below this bit number are in use*/ } super_block[NR_SUPERS]; +EXTERN struct super_block_v1 { /* for backwards compatibility */ + unsigned short s_ninodes; + zone1_t s_nzones; + short s_imap_blocks; + short s_zmap_blocks; + zone1_t s_firstdatazone; + short s_log_zone_size; + off_t s_max_size; + short s_magic; + short s_state; + zone_t s_zones; +}; + #define NIL_SUPER (struct super_block *) 0 #define IMAP 0 /* operating on the inode bit map */ #define ZMAP 1 /* operating on the zone bit map */ diff -ur src-ORIG/commands/simple/mkfs.c src/commands/simple/mkfs.c --- src-ORIG/commands/simple/mkfs.c 2007-02-16 14:25:33.000000000 +0100 +++ src/commands/simple/mkfs.c 2007-02-16 14:25:33.000000000 +0100 @@ -1,9 +1,11 @@ /* mkfs - make the MINIX filesystem Authors: Tanenbaum et al. */ /* Authors: Andy Tanenbaum, Paul Ogilvie, Frans Meulenbroeks, Bruce Evans + * Backwards compatibility fixed by Daniel Aragones * - * This program can make both version 1 and version 2 file systems, as follows: - * mkfs /dev/fd0 1200 # Version 2 (default) + * This program can make file systems versions 3, 2 and 1, as follows: + * mkfs /dev/fd0 # Version 3 (default) + * mkfs -2 /dev/fd0 1200 # Version 2 * mkfs -1 /dev/fd0 360 # Version 1 * */ @@ -178,6 +180,7 @@ break; case '2': fs_version = 2; + max_nrblocks = (1024L * 1024); break; case 'b': blocks = strtoul(optarg, (char **) NULL, 0); @@ -286,19 +289,29 @@ if (i == 0) { int kb; kb = blocks * (max(block_size,1024) / 1024); - /* The default for inodes is 2 blocks per kb, rounded up + /* The default for inodes is 2 blocks per kb in version 3 + * and 3 blocks per inode in versions 1 and 2. Rounded up * to fill an inode block. Above 20M, the average files are * sure to be larger because it is hard to fill up 20M with * tiny files, so reduce the default number of inodes. This * default can always be overridden by using the '-i option. */ - i = kb / 2; - if (kb >= 20000) i = kb / 3; - if (kb >= 40000) i = kb / 4; - if (kb >= 60000) i = kb / 5; - if (kb >= 80000) i = kb / 6; - if (kb >= 100000) i = kb / 7; + if (fs_version == 3) { + i = kb / 2; + if (kb >= 20000) i = kb / 3; + if (kb >= 40000) i = kb / 4; + if (kb >= 60000) i = kb / 5; + if (kb >= 80000) i = kb / 6; + if (kb >= 100000) i = kb / 7; + } else { + i = blocks / 3; + if (blocks >= 20000) i = blocks / 4; + if (blocks >= 40000) i = blocks / 5; + if (blocks >= 60000) i = blocks / 6; + if (blocks >= 80000) i = blocks / 7; + if (blocks >= 100000) i = blocks / 8; + } /* round up to fill inode block */ i += inodes_per_block - 1; i = i / inodes_per_block * inodes_per_block; @@ -452,58 +465,88 @@ int inodeblks; int initblks; - zone_t initzones, nrzones, v1sq, v2sq; - zone_t zo; + zone_t initzones, nrzones, v1sq, v2sq, zo, s_zones; + ino_t s_ninodes; + off_t s_max_size; + zone1_t s_nzones, s_firstdatazone; + short s_imap_blocks, s_zmap_blocks, s_log_zone_size, s_magic, s_state; + unsigned short s_block_size; struct super_block *sup; - char *buf, *cp; + struct super_block_v1 *sup_v1; + char *buf, *cp, s_disk_version; buf = alloc_block(); for (cp = buf; cp < &buf[block_size]; cp++) *cp = 0; - sup = (struct super_block *) buf; /* lint - might use a union */ - sup->s_ninodes = inodes; + s_ninodes = inodes; if (fs_version == 1) { - sup->s_nzones = zones; + s_nzones = (zone1_t) zones; } else { - sup->s_nzones = 0; /* not used in V2 - 0 forces errors early */ - sup->s_zones = zones; + s_nzones = 0; /* not used in V2 - 0 forces errors early */ + s_zones = zones; } - sup->s_imap_blocks = bitmapsize((bit_t) (1 + inodes), block_size); - sup->s_zmap_blocks = bitmapsize((bit_t) zones, block_size); - inode_offset = sup->s_imap_blocks + sup->s_zmap_blocks + 2; + s_imap_blocks = bitmapsize((bit_t) (1 + inodes), block_size); + s_zmap_blocks = bitmapsize((bit_t) zones, block_size); + inode_offset = s_imap_blocks + s_zmap_blocks + 2; inodeblks = (inodes + inodes_per_block - 1) / inodes_per_block; initblks = inode_offset + inodeblks; initzones = (initblks + (1 << zone_shift) - 1) >> zone_shift; nrzones = nrblocks >> zone_shift; - sup->s_firstdatazone = (initblks + (1 << zone_shift) - 1) >> zone_shift; - zoff = sup->s_firstdatazone - 1; - sup->s_log_zone_size = zone_shift; + s_firstdatazone = (initblks + (1 << zone_shift) - 1) >> zone_shift; + zoff = s_firstdatazone - 1; + s_log_zone_size = zone_shift; if (fs_version == 1) { - sup->s_magic = SUPER_MAGIC; /* identify super blocks */ + s_magic = SUPER_MAGIC; /* identify super blocks */ v1sq = (zone_t) V1_INDIRECTS * V1_INDIRECTS; zo = V1_NR_DZONES + (long) V1_INDIRECTS + v1sq; - sup->s_max_size = zo * block_size; + s_max_size = zo * block_size; } else { v2sq = (zone_t) V2_INDIRECTS(block_size) * V2_INDIRECTS(block_size); zo = V2_NR_DZONES + (zone_t) V2_INDIRECTS(block_size) + v2sq; if(fs_version == 2) { - sup->s_magic = SUPER_V2;/* identify super blocks */ - sup->s_max_size = zo * block_size; + s_magic = SUPER_V2; + s_max_size = zo * block_size; } else { - sup->s_magic = SUPER_V3; - sup->s_block_size = block_size; - sup->s_disk_version = 0; + s_magic = SUPER_V3; + s_block_size = block_size; + s_disk_version = 0; #define MAX_MAX_SIZE ((unsigned long) LONG_MAX) if(MAX_MAX_SIZE/block_size < zo) { - sup->s_max_size = MAX_MAX_SIZE; + s_max_size = MAX_MAX_SIZE; } else { - sup->s_max_size = zo * block_size; + s_max_size = zo * block_size; } } } + if (fs_version == 3) { + sup = (struct super_block *) buf; + sup->s_ninodes = s_ninodes; + sup->s_nzones = s_nzones; + sup->s_imap_blocks = s_imap_blocks; + sup->s_zmap_blocks = s_zmap_blocks; + sup->s_firstdatazone = s_firstdatazone; + sup->s_log_zone_size = s_log_zone_size; + sup->s_max_size = s_max_size; + sup->s_zones = s_zones; + sup->s_magic = s_magic; + sup->s_block_size = s_block_size; + sup->s_disk_version = s_disk_version; + } else { + sup_v1 = (struct super_block_v1 *) buf; + sup_v1->s_ninodes = (unsigned short) s_ninodes; + sup_v1->s_nzones = s_nzones; + sup_v1->s_imap_blocks = s_imap_blocks; + sup_v1->s_zmap_blocks = s_zmap_blocks; + sup_v1->s_firstdatazone = s_firstdatazone; + sup_v1->s_log_zone_size = s_log_zone_size; + sup_v1->s_max_size = s_max_size; + sup_v1->s_magic = s_magic; + sup_v1->s_state = 1; /* mark as a clean filesystem */ + sup_v1->s_zones = s_zones; + } zone_size = 1 << zone_shift; /* nr of blocks per zone */ if (lseek(fd, (off_t) _STATIC_BLOCK_SIZE, SEEK_SET) == (off_t) -1) { @@ -516,10 +559,10 @@ /* Clear maps and inodes. */ for (i = 2; i < initblks; i++) put_block((block_t) i, zero); - next_zone = sup->s_firstdatazone; + next_zone = s_firstdatazone; next_inode = 1; - zone_map = INODE_MAP + sup->s_imap_blocks; + zone_map = INODE_MAP + s_imap_blocks; insert_bit(zone_map, 0); /* bit zero must always be allocated */ insert_bit((block_t) INODE_MAP, 0); /* inode zero not used but @@ -538,7 +581,11 @@ zone_t z; z = alloc_zone(); - add_zone(inode, z, 2 * sizeof(struct direct), current_time); + if (fs_version == 3) { + add_zone(inode, z, 2 * sizeof(struct direct), current_time); + } else { + add_zone(inode, z, 2 * sizeof(struct direct1), current_time); + } enter_dir(inode, ".", inode); enter_dir(inode, "..", inode); incr_link(inode); @@ -573,14 +620,22 @@ /* Enter name in directory and update directory's size. */ enter_dir(parent, token[0], n); - incr_size(parent, sizeof(struct direct)); + if (fs_version == 3 ) { + incr_size(parent, sizeof(struct direct)); + } else { + incr_size(parent, sizeof(struct direct1)); + } /* Check to see if file is directory or special. */ incr_link(n); if (*p == 'd') { /* This is a directory. */ z = alloc_zone(); /* zone for new directory */ - add_zone(n, z, 2 * sizeof(struct direct), current_time); + if (fs_version == 3) { + add_zone(n, z, 2 * sizeof(struct direct), current_time); + } else { + add_zone(n, z, 2 * sizeof(struct direct1), current_time); + } enter_dir(n, ".", n); enter_dir(n, "..", parent); incr_link(parent); @@ -652,6 +707,7 @@ zone_t z; char *p1, *p2; struct direct *dir_entry; + struct direct1 *dir_entry1; d1_inode ino1[V1_INODES_PER_BLOCK]; d2_inode *ino2; int nr_dzones; @@ -659,8 +715,13 @@ b = ((parent - 1) / inodes_per_block) + inode_offset; off = (parent - 1) % inodes_per_block; + if (fs_version == 3) { if(!(dir_entry = malloc(NR_DIR_ENTRIES(block_size) * sizeof(*dir_entry)))) pexit("couldn't allocate directory entry"); + } else { + if(!(dir_entry1 = malloc(V1_NR_DIR_ENTRIES(block_size) * sizeof(*dir_entry1)))) + pexit("couldn't allocate directory entry"); + } if(!(ino2 = malloc(V2_INODES_PER_BLOCK(block_size) * sizeof(*ino2)))) pexit("couldn't allocate block of inodes entry"); @@ -668,24 +729,71 @@ if (fs_version == 1) { get_block(b, (char *) ino1); nr_dzones = V1_NR_DZONES; + for (k = 0; k < nr_dzones; k++) { + z = ino1[off].d1_zone[k]; + if (z == 0) { + z = alloc_zone(); + ino1[off].d1_zone[k] = z; + } + for (l = 0; l < zone_size; l++) { + get_block((z << zone_shift) + l, (char *) dir_entry1); + for (i = 0; i < V1_NR_DIR_ENTRIES(block_size); i++) { + if (dir_entry1[i].d_ino == 0) { + dir_entry1[i].d_ino = child; + p1 = name; + p2 = dir_entry1[i].d_name; + j = sizeof(dir_entry1[i].d_name); + while (j--) { + *p2++ = *p1; + if (*p1 != 0) p1++; + } + put_block((z << zone_shift) + l, (char *) dir_entry1); + put_block(b, (char *) ino1); + free(dir_entry1); + free(ino2); + return; + } + } + } + } } else { get_block(b, (char *) ino2); nr_dzones = V2_NR_DZONES; - } + if (fs_version == 2) { for (k = 0; k < nr_dzones; k++) { - if (fs_version == 1) { - z = ino1[off].d1_zone[k]; - if (z == 0) { - z = alloc_zone(); - ino1[off].d1_zone[k] = z; - } - } else { - z = ino2[off].d2_zone[k]; - if (z == 0) { - z = alloc_zone(); - ino2[off].d2_zone[k] = z; + z = ino2[off].d2_zone[k]; + if (z == 0) { + z = alloc_zone(); + ino2[off].d2_zone[k] = z; + } + for (l = 0; l < zone_size; l++) { + get_block((z << zone_shift) + l, (char *) dir_entry1); + for (i = 0; i < V1_NR_DIR_ENTRIES(block_size); i++) { + if (dir_entry1[i].d_ino == 0) { + dir_entry1[i].d_ino = child; + p1 = name; + p2 = dir_entry1[i].d_name; + j = sizeof(dir_entry1[i].d_name); + while (j--) { + *p2++ = *p1; + if (*p1 != 0) p1++; + } + put_block((z << zone_shift) + l, (char *) dir_entry1); + put_block(b, (char *) ino2); + free(dir_entry1); + free(ino2); + return; + } } } + } + } else { + for (k = 0; k < nr_dzones; k++) { + z = ino2[off].d2_zone[k]; + if (z == 0) { + z = alloc_zone(); + ino2[off].d2_zone[k] = z; + } for (l = 0; l < zone_size; l++) { get_block((z << zone_shift) + l, (char *) dir_entry); for (i = 0; i < NR_DIR_ENTRIES(block_size); i++) { @@ -699,11 +807,7 @@ if (*p1 != 0) p1++; } put_block((z << zone_shift) + l, (char *) dir_entry); - if (fs_version == 1) { - put_block(b, (char *) ino1); - } else { - put_block(b, (char *) ino2); - } + put_block(b, (char *) ino2); free(dir_entry); free(ino2); return; @@ -712,6 +816,8 @@ } } + } + } printf("Directory-inode %d beyond direct blocks. Could not enter %s\n", parent, name); pexit("Halt"); @@ -847,6 +953,14 @@ inode1[off].d1_nlinks++; put_block(b, (char *) inode1); } else { + if (fs_version == 2) { + d2_inode inode2[V2_INODES_PER_BLOCK(_STATIC_BLOCK_SIZE)]; + + get_block(b, (char *) inode2); + inode2[off].d2_nlinks++; + put_block(b, (char *) inode2); + } else { + static d2_inode *inode2 = NULL; int n; @@ -858,6 +972,7 @@ inode2[off].d2_nlinks++; put_block(b, (char *) inode2); } + } enter = 0; } @@ -1145,12 +1260,18 @@ unsigned short *usbuf; block_t b, inode_limit; struct direct *dir; + struct direct1 *dir1; if(!(inode2 = malloc(V2_INODES_PER_BLOCK(block_size) * sizeof(*inode2)))) pexit("couldn't allocate a block of inodes"); - if(!(dir = malloc(NR_DIR_ENTRIES(block_size)*sizeof(*dir)))) - pexit("malloc of directory entry failed"); + if (fs_version == 3) { + if(!(dir = malloc(NR_DIR_ENTRIES(block_size)*sizeof(*dir)))) + pexit("malloc of directory entry failed"); + } else { + if(!(dir1 = malloc(V1_NR_DIR_ENTRIES(block_size)*sizeof(*dir1)))) + pexit("malloc of directory entry failed"); + } usbuf = (unsigned short *) alloc_block(); @@ -1190,11 +1311,11 @@ } if ((inode1[i].d1_mode & I_TYPE) == I_DIRECTORY) { /* This is a directory */ - get_block(inode1[i].d1_zone[0], (char *) dir); - for (j = 0; j < NR_DIR_ENTRIES(block_size); j++) - if (dir[j].d_ino) - printf("\tInode %2d: %s\n", dir[j].d_ino, dir[j].d_name); - } + get_block(inode1[i].d1_zone[0], (char *) dir1); + for (j = 0; j < V1_NR_DIR_ENTRIES(block_size); j++) + if (dir1[j].d_ino) + printf("\tInode %2d: %s\n", dir1[j].d_ino, dir1[j].d_name); + } } else { if (inode2[i].d2_mode != 0) { printf("Inode %2d: mode=", k); @@ -1206,17 +1327,29 @@ } if ((inode2[i].d2_mode & I_TYPE) == I_DIRECTORY) { /* This is a directory */ + if (fs_version == 2 ) { + get_block(inode2[i].d2_zone[0], (char *) dir1); + for (j = 0; j < V1_NR_DIR_ENTRIES(block_size); j++) + if (dir1[j].d_ino) + printf("\tInode %2d: %s\n",dir1[j].d_ino,dir1[j].d_name); + } else { get_block(inode2[i].d2_zone[0], (char *) dir); - for (j = 0; j < NR_DIR_ENTRIES(block_size); j++) - if (dir[j].d_ino) - printf("\tInode %2d: %s\n", dir[j].d_ino, dir[j].d_name); + for (j = 0; j < NR_DIR_ENTRIES(block_size); j++) + if (dir[j].d_ino) + printf("\tInode %2d: %s\n", dir[j].d_ino, dir[j].d_name); } + } } } } printf("%d inodes used. %d zones used.\n", next_inode - 1, next_zone); - free(dir); + + if (fs_version == 3 ) { + free(dir); + } else { + free(dir1); + } free(inode2); } ==========================END OF PATCH===========================