--- util-linux-2.4/disk-utils/fsck.minix.c~ Sun Mar 12 02:38:42 1995 +++ util-linux-2.4/disk-utils/fsck.minix.c Thu Jun 22 16:19:11 1995 @@ -38,4 +38,8 @@ * program name and version number when program * is executed. + * + * 30.10.94 - added support for v2 filesystem + * (Andreas Schwab, schwab@issan.informatik.uni-dortmund.de) + * * * 10.12.94 - added test to prevent checking of mounted fs adapted @@ -87,5 +91,7 @@ #define UPPER(size,n) ((size+((n)-1))/(n)) #define INODE_SIZE (sizeof(struct minix_inode)) -#define INODE_BLOCKS UPPER(INODES,MINIX_INODES_PER_BLOCK) +#define INODE_SIZE2 (sizeof(struct new_minix_inode)) +#define INODE_BLOCKS UPPER(INODES, (version2 ? MINIX_INODES_PER_BLOCK2 \ + : MINIX_INODES_PER_BLOCK)) #define INODE_BUFFER_SIZE (INODE_BLOCKS * BLOCK_SIZE) @@ -105,4 +111,5 @@ static int dirsize = 16; static int namelen = 14; +static int version2 = 0; /* File-name data */ @@ -113,8 +120,9 @@ static char * inode_buffer = NULL; #define Inode (((struct minix_inode *) inode_buffer)-1) +#define Inode2 (((struct new_minix_inode *) inode_buffer)-1) static char super_block_buffer[BLOCK_SIZE]; #define Super (*(struct minix_super_block *)super_block_buffer) #define INODES ((unsigned long)Super.s_ninodes) -#define ZONES ((unsigned long)Super.s_nzones) +#define ZONES ((unsigned long)(version2 ? Super.s_zones : Super.s_nzones)) #define IMAPS ((unsigned long)Super.s_imap_blocks) #define ZMAPS ((unsigned long)Super.s_zmap_blocks) @@ -132,4 +140,7 @@ void recursive_check(unsigned int ino); +void recursive_check2 (unsigned int ino); + +#ifdef __i386__ #define bitop(name,op) \ @@ -147,4 +158,24 @@ bitop(clrbit,"r") +#elif defined (__mc68000__) + +#define bitop(name,op) \ +static inline int name (char *addr, unsigned int nr) \ +{ \ + char __res; \ + __asm__ __volatile__("bf" op " %2@{%1:#1}; sne %0" \ + : "=d" (__res) \ + : "d" (nr ^ 15), "a" (addr)); \ + return __res != 0; \ +} + +bitop (bit, "tst") +bitop (setbit, "set") +bitop (clrbit, "clr") + +#else +#error "Architecture not supported" +#endif + #define inode_in_use(x) (bit(inode_map,(x))) #define zone_in_use(x) (bit(zone_map,(x)-FIRSTZONE+1)) @@ -180,4 +211,6 @@ while (i= ZONES) + printf ("Zone nr >= ZONES in file `"); + else + return *nr; + print_current_name (); + printf ("'."); + if (ask ("Remove block", 1)) { + *nr = 0; + *corrected = 1; + } + return 0; +} + /* * read-block reads block nr into the buffer at addr. @@ -379,4 +432,63 @@ } +int +map_block2 (struct new_minix_inode *inode, unsigned int blknr) +{ + unsigned long ind[BLOCK_SIZE >> 2]; + unsigned long dind[BLOCK_SIZE >> 2]; + unsigned long tind[BLOCK_SIZE >> 2]; + int blk_chg, block, result; + int ind_nr; + + if (blknr < 7) + return check_zone_nr2 (inode->i_zone + blknr, &changed); + blknr -= 7; + if (blknr < 256) { + block = check_zone_nr2 (inode->i_zone + 7, &changed); + read_block (block, (char *) ind); + blk_chg = 0; + result = check_zone_nr2 (blknr + ind, &blk_chg); + if (blk_chg) + write_block (block, (char *) ind); + return result; + } + blknr -= 256; + if (blknr >= 256 * 256) { + block = check_zone_nr2 (inode->i_zone + 8, &changed); + read_block (block, (char *) dind); + blk_chg = 0; + result = check_zone_nr2 (dind + blknr / 256, &blk_chg); + if (blk_chg) + write_block (block, (char *) dind); + block = result; + read_block (block, (char *) ind); + blk_chg = 0; + result = check_zone_nr2 (ind + blknr % 256, &blk_chg); + if (blk_chg) + write_block (block, (char *) ind); + return result; + } + blknr -= 256 * 256; + block = check_zone_nr2 (inode->i_zone + 9, &changed); + read_block (block, (char *) tind); + blk_chg = 0; + result = check_zone_nr2 (tind + blknr / (256 * 256), &blk_chg); + if (blk_chg) + write_block (block, (char *) tind); + block = result; + read_block (block, (char *) dind); + blk_chg = 0; + result = check_zone_nr2 (dind + (blknr / 256) % 256, &blk_chg); + if (blk_chg) + write_block (block, (char *) dind); + block = result; + read_block (block, (char *) ind); + blk_chg = 0; + result = check_zone_nr2 (ind + blknr % 256, &blk_chg); + if (blk_chg) + write_block (block, (char *) ind); + return result; +} + void write_super_block(void) { @@ -412,4 +524,26 @@ } +void +get_dirsize (void) +{ + int block; + char blk[BLOCK_SIZE]; + int size; + + if (version2) + block = Inode2[ROOT_INO].i_zone[0]; + else + block = Inode[ROOT_INO].i_zone[0]; + read_block (block, blk); + for (size = 16; size < BLOCK_SIZE; size <<= 1) { + if (strcmp (blk + size + 2, "..") == 0) { + dirsize = size; + namelen = size - 2; + return; + } + } + /* use defaults */ +} + void read_tables(void) { @@ -423,7 +557,13 @@ namelen = 14; dirsize = 16; + version2 = 0; } else if (MAGIC == MINIX_SUPER_MAGIC2) { namelen = 30; dirsize = 32; + version2 = 0; + } else if (MAGIC == NEW_MINIX_SUPER_MAGIC) { + namelen = 14; + dirsize = 16; + version2 = 1; } else die("bad magic number in super-block"); @@ -453,4 +593,5 @@ errors_uncorrected = 1; } + get_dirsize (); if (show) { printf("%d inodes\n",INODES); @@ -513,4 +654,51 @@ } +struct new_minix_inode * +get_inode2 (unsigned int nr) +{ + struct new_minix_inode *inode; + + if (!nr || nr >= INODES) + return NULL; + total++; + inode = Inode2 + nr; + if (!inode_count[nr]) { + if (!inode_in_use (nr)) { + printf ("Inode %d marked not used, but used for file '", nr); + print_current_name (); + printf ("'\n"); + if (repair) { + if (ask ("Mark in use", 1)) + mark_inode (nr); + else + errors_uncorrected = 1; + } + } + if (S_ISDIR (inode->i_mode)) + directory++; + else if (S_ISREG (inode->i_mode)) + regular++; + else if (S_ISCHR (inode->i_mode)) + chardev++; + else if (S_ISBLK (inode->i_mode)) + blockdev++; + else if (S_ISLNK (inode->i_mode)) + symlinks++; + else if (S_ISSOCK (inode->i_mode)); + else if (S_ISFIFO (inode->i_mode)); + else { + print_current_name (); + printf (" has mode %05o\n", inode->i_mode); + } + } else + links++; + if (!++inode_count[nr]) { + printf ("Warning: inode count too big.\n"); + inode_count[nr]--; + errors_uncorrected = 1; + } + return inode; +} + void check_root(void) { @@ -521,4 +709,13 @@ } +void +check_root2 (void) +{ + struct new_minix_inode *inode = Inode2 + ROOT_INO; + + if (!inode || !S_ISDIR (inode->i_mode)) + die ("root inode isn't a directory"); +} + static int add_zone(unsigned short * znr, int * corrected) { @@ -554,4 +751,38 @@ } +static int +add_zone2 (unsigned long *znr, int *corrected) +{ + int result; + int block; + + result = 0; + block = check_zone_nr2 (znr, corrected); + if (!block) + return 0; + if (zone_count[block]) { + printf ("Block has been used before. Now in file `"); + print_current_name (); + printf ("'."); + if (ask ("Clear", 1)) { + *znr = 0; + block = 0; + *corrected = 1; + } + } + if (!block) + return 0; + if (!zone_in_use (block)) { + printf ("Block %d in file `", block); + print_current_name (); + printf ("' is marked not in use."); + if (ask ("Correct", 1)) + mark_zone (block); + } + if (!++zone_count[block]) + zone_count[block]--; + return block; +} + static void add_zone_ind(unsigned short * znr, int * corrected) { @@ -570,4 +801,21 @@ } +static void +add_zone_ind2 (unsigned long *znr, int *corrected) +{ + static char blk[BLOCK_SIZE]; + int i, chg_blk = 0; + int block; + + block = add_zone2 (znr, corrected); + if (!block) + return; + read_block (block, blk); + for (i = 0; i < BLOCK_SIZE >> 2; i++) + add_zone2 (i + (unsigned long *) blk, &chg_blk); + if (chg_blk) + write_block (block, blk); +} + static void add_zone_dind(unsigned short * znr, int * corrected) { @@ -586,4 +834,38 @@ } +static void +add_zone_dind2 (unsigned long *znr, int *corrected) +{ + static char blk[BLOCK_SIZE]; + int i, blk_chg = 0; + int block; + + block = add_zone2 (znr, corrected); + if (!block) + return; + read_block (block, blk); + for (i = 0; i < BLOCK_SIZE >> 2; i++) + add_zone_ind2 (i + (unsigned long *) blk, &blk_chg); + if (blk_chg) + write_block (block, blk); +} + +static void +add_zone_tind2 (unsigned long *znr, int *corrected) +{ + static char blk[BLOCK_SIZE]; + int i, blk_chg = 0; + int block; + + block = add_zone2 (znr, corrected); + if (!block) + return; + read_block (block, blk); + for (i = 0; i < BLOCK_SIZE >> 2; i++) + add_zone_dind2 (i + (unsigned long *) blk, &blk_chg); + if (blk_chg) + write_block (block, blk); +} + void check_zones(unsigned int i) { @@ -604,4 +886,24 @@ } +void +check_zones2 (unsigned int i) +{ + struct new_minix_inode *inode; + + if (!i || i >= INODES) + return; + if (inode_count[i] > 1) /* have we counted this file already? */ + return; + inode = Inode2 + i; + if (!S_ISDIR (inode->i_mode) && !S_ISREG (inode->i_mode) + && !S_ISLNK (inode->i_mode)) + return; + for (i = 0; i < 7; i++) + add_zone2 (i + inode->i_zone, &changed); + add_zone_ind2 (7 + inode->i_zone, &changed); + add_zone_dind2 (8 + inode->i_zone, &changed); + add_zone_tind2 (9 + inode->i_zone, &changed); +} + void check_file(struct minix_inode * dir, unsigned int offset) { @@ -626,5 +928,9 @@ ino = 0; } + if (name_depth < MAX_DEPTH) + strncpy (name_list[name_depth], name, namelen); + name_depth++; inode = get_inode(ino); + name_depth--; if (!offset) if (!inode || strcmp(".",name)) { @@ -660,4 +966,67 @@ } +void +check_file2 (struct new_minix_inode *dir, unsigned int offset) +{ + static char blk[BLOCK_SIZE]; + struct new_minix_inode *inode; + int ino; + char *name; + int block; + + block = map_block2 (dir, offset / BLOCK_SIZE); + read_block (block, blk); + name = blk + (offset % BLOCK_SIZE) + 2; + ino = *(unsigned short *) (name - 2); + if (ino >= INODES) { + print_current_name (); + printf (" contains a bad inode number for file '"); + printf ("%.*s'.", namelen, name); + if (ask (" Remove", 1)) { + *(unsigned short *) (name - 2) = 0; + write_block (block, blk); + } + ino = 0; + } + if (name_depth < MAX_DEPTH) + strncpy (name_list[name_depth], name, namelen); + name_depth++; + inode = get_inode2 (ino); + name_depth--; + if (!offset) { + if (!inode || strcmp (".", name)) { + print_current_name (); + printf (": bad directory: '.' isn't first\n"); + errors_uncorrected = 1; + } else + return; + } + if (offset == dirsize) { + if (!inode || strcmp ("..", name)) { + print_current_name (); + printf (": bad directory: '..' isn't second\n"); + errors_uncorrected = 1; + } else + return; + } + if (!inode) + return; + name_depth++; + if (list) { + if (verbose) + printf ("%6d %07o %3d ", ino, inode->i_mode, inode->i_nlinks); + print_current_name (); + if (S_ISDIR (inode->i_mode)) + printf (":\n"); + else + printf ("\n"); + } + check_zones2 (ino); + if (inode && S_ISDIR (inode->i_mode)) + recursive_check2 (ino); + name_depth--; + return; +} + void recursive_check(unsigned int ino) { @@ -668,5 +1037,5 @@ if (!S_ISDIR(dir->i_mode)) die("internal error"); - if (dir->i_size < 32) { + if (dir->i_size < 2 * dirsize) { print_current_name(); printf(": bad directory: size<32"); @@ -677,4 +1046,22 @@ } +void +recursive_check2 (unsigned int ino) +{ + struct new_minix_inode *dir; + unsigned int offset; + + dir = Inode2 + ino; + if (!S_ISDIR (dir->i_mode)) + die ("internal error"); + if (dir->i_size < 2 * dirsize) { + print_current_name (); + printf (": bad directory: size < 32"); + errors_uncorrected = 1; + } + for (offset = 0; offset < dir->i_size; offset += dirsize) + check_file2 (dir, offset); +} + int bad_zone(int i) { @@ -737,4 +1124,55 @@ } +void +check_counts2 (void) +{ + int i; + + for (i = 1; i < INODES; i++) { + if (!inode_in_use (i) && Inode2[i].i_mode && warn_mode) { + printf ("Inode %d mode not cleared.", i); + if (ask ("Clear", 1)) { + Inode2[i].i_mode = 0; + changed = 1; + } + } + if (!inode_count[i]) { + if (!inode_in_use (i)) + continue; + printf ("Inode %d not used, marked used in the bitmap.", i); + if (ask ("Clear", 1)) + unmark_inode (i); + continue; + } + if (!inode_in_use (i)) { + printf ("Inode %d used, marked unused in the bitmap.", i); + if (ask ("Set", 1)) + mark_inode (i); + } + if (Inode2[i].i_nlinks != inode_count[i]) { + printf ("Inode %d (mode = %07o), i_nlinks=%d, counted=%d.", + i, Inode2[i].i_mode, Inode2[i].i_nlinks, inode_count[i]); + if (ask ("Set i_nlinks to count", 1)) { + Inode2[i].i_nlinks = inode_count[i]; + changed = 1; + } + } + } + for (i = FIRSTZONE; i < ZONES; i++) { + if (zone_in_use (i) == zone_count[i]) + continue; + if (!zone_count[i]) { + if (bad_zone (i)) + continue; + printf ("Zone %d: marked in use, no file uses it.", i); + if (ask ("Unmark", 1)) + unmark_zone (i); + continue; + } + printf ("Zone %d: %sin use, counted=%d\n", + i, zone_in_use (i) ? "" : "not ", zone_count[i]); + } +} + void check(void) { @@ -746,4 +1184,14 @@ } +void +check2 (void) +{ + memset (inode_count, 0, INODES * sizeof (*inode_count)); + memset (zone_count, 0, ZONES * sizeof (*zone_count)); + check_zones2 (ROOT_INO); + recursive_check2 (ROOT_INO); + check_counts2 (); +} + int main(int argc, char ** argv) { @@ -756,4 +1204,6 @@ if (INODE_SIZE * MINIX_INODES_PER_BLOCK != BLOCK_SIZE) die("bad inode size"); + if (INODE_SIZE2 * MINIX_INODES_PER_BLOCK2 != BLOCK_SIZE) + die("bad v2 inode size"); while (argc-- > 1) { argv++; @@ -787,6 +1237,9 @@ } IN = open(device_name,repair?O_RDWR:O_RDONLY); - if (IN < 0) + if (IN < 0) { + if (repair && !automatic) + tcsetattr(0,TCSANOW,&termios); die("unable to open '%s'"); + } for (count=0 ; count<3 ; count++) sync(); @@ -815,6 +1268,11 @@ device_name); - check_root(); - check(); + if (version2) { + check_root2 (); + check2 (); + } else { + check_root(); + check(); + } if (verbose) { int i, free; --- util-linux-2.4/disk-utils/mkfs.minix.c~ Sun Jun 4 03:46:23 1995 +++ util-linux-2.4/disk-utils/mkfs.minix.c Fri Jun 30 20:47:27 1995 @@ -32,4 +32,7 @@ * 03.01.94 - Added support for file system valid flag. * (Dr. Wettstein, greg%wind.uucp@plains.nodak.edu) + * + * 30.10.94 - added support for v2 filesystem + * (Andreas Schwab, schwab@issan.informatik.uni-dortmund.de) * * 09.11.94 - Added test to prevent overwrite of mounted fs adapted @@ -48,4 +51,5 @@ * -n for namelength (currently the kernel only uses 14 or 30) * -i for number of inodes + * -v for v2 filesystem * * The device may be a block device or a image of one, but this isn't @@ -84,5 +88,7 @@ #define UPPER(size,n) ((size+((n)-1))/(n)) #define INODE_SIZE (sizeof(struct minix_inode)) -#define INODE_BLOCKS UPPER(INODES,MINIX_INODES_PER_BLOCK) +#define INODE_SIZE2 (sizeof(struct new_minix_inode)) +#define INODE_BLOCKS UPPER(INODES, (version2 ? MINIX_INODES_PER_BLOCK2 \ + : MINIX_INODES_PER_BLOCK)) #define INODE_BUFFER_SIZE (INODE_BLOCKS * BLOCK_SIZE) @@ -97,6 +103,7 @@ static int namelen = 30; /* default (changed to 30, per Linus's suggestion, Sun Nov 21 08:05:07 1993) */ -static int dirsize = 16; -static int magic = MINIX_SUPER_MAGIC; +static int dirsize = 32; +static int magic = MINIX_SUPER_MAGIC2; +static int version2 = 0; static char root_block[BLOCK_SIZE] = "\0"; @@ -104,9 +111,10 @@ static char * inode_buffer = NULL; #define Inode (((struct minix_inode *) inode_buffer)-1) +#define Inode2 (((struct new_minix_inode *) inode_buffer)-1) static char super_block_buffer[BLOCK_SIZE]; static char boot_block_buffer[512]; #define Super (*(struct minix_super_block *)super_block_buffer) #define INODES ((unsigned long)Super.s_ninodes) -#define ZONES ((unsigned long)Super.s_nzones) +#define ZONES ((unsigned long)(version2 ? Super.s_zones : Super.s_nzones)) #define IMAPS ((unsigned long)Super.s_imap_blocks) #define ZMAPS ((unsigned long)Super.s_zmap_blocks) @@ -124,4 +132,6 @@ static unsigned long req_nr_inodes = 0; +#ifdef __i386__ + #define bitop(name,op) \ static inline int name(char * addr,unsigned int nr) \ @@ -138,4 +148,24 @@ bitop(clrbit,"r") +#elif defined (__mc68000__) + +#define bitop(name,op) \ +static inline int name (char *addr, unsigned int nr) \ +{ \ + char __res; \ + __asm__ __volatile__("bf" op " %2@{%1:#1}; sne %0" \ + : "=d" (__res) \ + : "d" (nr ^ 15), "a" (addr)); \ + return __res != 0; \ +} + +bitop (bit, "tst") +bitop (setbit, "set") +bitop (clrbit, "clr") + +#else +#error "Architecture not supported" +#endif + #define inode_in_use(x) (bit(inode_map,(x))) #define zone_in_use(x) (bit(zone_map,(x)-FIRSTZONE+1)) @@ -183,4 +213,55 @@ } +static long valid_offset (int fd, int offset) +{ + char ch; + + if (lseek (fd, offset, 0) < 0) + return 0; + if (read (fd, &ch, 1) < 1) + return 0; + return 1; +} + +static int count_blocks (int fd) +{ + int high, low; + + low = 0; + for (high = 1; valid_offset (fd, high); high *= 2) + low = high; + while (low < high - 1) + { + const int mid = (low + high) / 2; + + if (valid_offset (fd, mid)) + low = mid; + else + high = mid; + } + valid_offset (fd, 0); + return (low + 1); +} + +static int get_size(const char *file) +{ + int fd; + int size; + + fd = open(file, O_RDWR); + if (fd < 0) { + perror(file); + exit(1); + } + if (ioctl(fd, BLKGETSIZE, &size) >= 0) { + close(fd); + return (size * 512); + } + + size = count_blocks(fd); + close(fd); + return size; +} + void write_tables(void) { @@ -189,8 +270,10 @@ Super.s_state &= ~MINIX_ERROR_FS; +#if 0 if (lseek(DEV, 0, SEEK_SET)) die("seek to boot block failed in write_tables"); if (512 != write(DEV, boot_block_buffer, 512)) die("unable to clear boot sector"); +#endif if (BLOCK_SIZE != lseek(DEV, BLOCK_SIZE, SEEK_SET)) die("seek failed in write_tables"); @@ -301,4 +384,54 @@ } +void +make_bad_inode2 (void) +{ + struct new_minix_inode *inode = &Inode2[MINIX_BAD_INO]; + int i, j, zone; + int ind = 0, dind = 0; + unsigned long ind_block[BLOCK_SIZE >> 2]; + unsigned long dind_block[BLOCK_SIZE >> 2]; + + if (!badblocks) + return; + mark_inode (MINIX_BAD_INO); + inode->i_nlinks = 1; + inode->i_atime = inode->i_mtime = inode->i_ctime = time (NULL); + inode->i_mode = S_IFREG + 0000; + inode->i_size = badblocks * BLOCK_SIZE; + zone = next (0); + for (i = 0; i < 7; i++) { + inode->i_zone[i] = zone; + if (!NEXT_BAD) + goto end_bad; + } + inode->i_zone[7] = ind = get_free_block (); + memset (ind_block, 0, BLOCK_SIZE); + for (i = 0; i < 256; i++) { + ind_block[i] = zone; + if (!NEXT_BAD) + goto end_bad; + } + inode->i_zone[8] = dind = get_free_block (); + memset (dind_block, 0, BLOCK_SIZE); + for (i = 0; i < 256; i++) { + write_block (ind, (char *) ind_block); + dind_block[i] = ind = get_free_block (); + memset (ind_block, 0, BLOCK_SIZE); + for (j = 0; j < 256; j++) { + ind_block[j] = zone; + if (!NEXT_BAD) + goto end_bad; + } + } + /* Could make triple indirect block here */ + die ("too many bad blocks"); + end_bad: + if (ind) + write_block (ind, (char *) ind_block); + if (dind) + write_block (dind, (char *) dind_block); +} + void make_root_inode(void) { @@ -320,7 +453,28 @@ } +void +make_root_inode2 (void) +{ + struct new_minix_inode *inode = &Inode2[MINIX_ROOT_INO]; + + mark_inode (MINIX_ROOT_INO); + inode->i_zone[0] = get_free_block (); + inode->i_nlinks = 2; + inode->i_atime = inode->i_mtime = inode->i_ctime = time (NULL); + if (badblocks) + inode->i_size = 3 * dirsize; + else { + root_block[2 * dirsize] = '\0'; + root_block[2 * dirsize + 1] = '\0'; + inode->i_size = 2 * dirsize; + } + inode->i_mode = S_IFDIR + 0755; + write_block (inode->i_zone[0], root_block); +} + void setup_tables(void) { int i; + unsigned long inodes; memset(inode_map,0xff,sizeof(inode_map)); @@ -330,11 +484,14 @@ MAGIC = magic; ZONESIZE = 0; - MAXSIZE = (7+512+512*512)*1024; + MAXSIZE = version2 ? 0x7fffffff : (7+512+512*512)*1024; ZONES = BLOCKS; /* some magic nrs: 1 inode / 3 blocks */ if ( req_nr_inodes == 0 ) - INODES = BLOCKS/3; + inodes = BLOCKS/3; else - INODES = req_nr_inodes; + inodes = req_nr_inodes; + if (inodes > 65535) + inodes = 65535; + INODES = inodes; /* I don't want some off-by-one errors, so this hack... */ if ((INODES & 8191) > 8188) @@ -346,4 +503,6 @@ while (ZMAPS != UPPER(BLOCKS - NORM_FIRSTZONE,BITS_PER_BLOCK)) ZMAPS = UPPER(BLOCKS - NORM_FIRSTZONE,BITS_PER_BLOCK); + if (ZMAPS > 64) + die ("Filesystem too big for Linux to handle"); FIRSTZONE = NORM_FIRSTZONE; for (i = FIRSTZONE ; i 1) { argv++; @@ -503,4 +664,7 @@ dirsize = i+2; break; + case 'v': + version2 = 1; + break; default: usage(); } @@ -509,19 +673,22 @@ } } - if (!device_name || BLOCKS<10 || BLOCKS > 65536) { + if (device_name && !BLOCKS) + BLOCKS = get_size (device_name) / 1024; + if (!device_name || BLOCKS<10) { usage(); } + if (version2) + magic = NEW_MINIX_SUPER_MAGIC; + else if (BLOCKS > 65535) + BLOCKS = 65535; check_mount(); /* is it already mounted? */ tmp = root_block; - tmp[0] = 1; - tmp[1] = 0; + *(short *)tmp = 1; strcpy(tmp+2,"."); tmp += dirsize; - tmp[0] = 1; - tmp[1] = 0; + *(short *)tmp = 1; strcpy(tmp+2,".."); tmp += dirsize; - tmp[0] = 2; - tmp[1] = 0; + *(short *)tmp = 2; strcpy(tmp+2,".badblocks"); DEV = open(device_name,O_RDWR ); @@ -539,6 +706,11 @@ else if (listfile) get_list_blocks(listfile); - make_root_inode(); - make_bad_inode(); + if (version2) { + make_root_inode2 (); + make_bad_inode2 (); + } else { + make_root_inode(); + make_bad_inode(); + } mark_good_blocks(); write_tables();