From: David van Moolenbroek Date: Mon, 26 Oct 2009 13:35:39 +0000 (+0000) Subject: Ground work for larger file systems, and miscellaneous fixes: X-Git-Tag: v3.1.5~5 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zpipe.c?a=commitdiff_plain;h=bd30f2a98815f3b478445673c16a9335975fff56;p=minix.git Ground work for larger file systems, and miscellaneous fixes: - MFS and mkfs(1) now perform extra sanity checks - fsck(1) can now deal with inode tables extending beyond the file system's first 4GB - badblocks(8) no longer writes out the superblock for no reason - mkfs(1) no longer crashes when given no parameters - more(1) no longer crashes when standard output is redirected --- diff --git a/commands/simple/badblocks.c b/commands/simple/badblocks.c index 1ff680200..5acbdbc27 100755 --- a/commands/simple/badblocks.c +++ b/commands/simple/badblocks.c @@ -40,9 +40,7 @@ #include "../../servers/mfs/super.h" _PROTOTYPE(int main, (int argc, char **argv)); -_PROTOTYPE(void rw_super, (int flag)); _PROTOTYPE(void get_super, (void)); -_PROTOTYPE(void put_super, (void)); _PROTOTYPE(void rw_inode, (struct stat * stat_ptr, int rw_mode)); _PROTOTYPE(void get_inode, (struct stat * stat_ptr)); _PROTOTYPE(void put_inode, (struct stat * stat_ptr)); @@ -99,20 +97,6 @@ _PROTOTYPE(void done, (int nr)); #define V_SMALLER V1_NR_DZONES #endif -#if 0 -struct super_block { - ino_t s_ninodes; /* # usable inodes on the minor device */ - zone1_t s_nzones; /* total device size, including bit maps etc */ - short s_imap_blocks; /* # of blocks used by inode bit map */ - short s_zmap_blocks; /* # of blocks used by zone bit map */ - zone1_t s_firstdatazone; /* number of first data zone */ - short s_log_zone_size; /* log2 of blocks/zone */ - off_t s_max_size; /* maximum file size on this device */ - short s_magic; /* magic number to recognize super-blocks */ - short s_pad; /* try to avoid compiler-dependent padding */ - zone_t s_zones; /* number of zones (replaces s_nzones in V2) */ -} super_block; -#endif /* ====== globals ======= */ @@ -142,30 +126,19 @@ d2_inode *ip2; /* ====== super block routines ======= */ -void rw_super(flag) -int flag; -{ /* read or write a superblock */ - int rwd; +void get_super() + /* Get super_block. global pointer sp is used */ +{ + int rd; - lseek(fd, 0L, SEEK_SET); /* rewind */ lseek(fd, (long) BLOCK_SIZE, SEEK_SET); /* seek */ - if (flag == READ) - rwd = read(fd, (char *) sp, SUPER_SIZE); - else - rwd = write(fd, (char *) sp, SUPER_SIZE); - if (rwd != SUPER_SIZE) { /* ok ? */ - printf("Bad %s in get_super() (should be %u is %d)\n", - flag == READ ? "read" : "write", - (unsigned) SUPER_SIZE, rwd); + rd = read(fd, (char *) sp, SUPER_SIZE); + if (rd != SUPER_SIZE) { /* ok ? */ + printf("Bad read in get_super() (should be %u is %d)\n", + (unsigned) SUPER_SIZE, rd); done(DIR_CREATED); } -} - -void get_super() - /* Get super_block. global pointer sp is used */ -{ - rw_super(READ); if (sp->s_magic == SUPER_MAGIC) { /* This is a V1 file system. */ @@ -184,11 +157,6 @@ void get_super() } -void put_super() -{ - rw_super(WRITE); -} - /* ========== inode routines =========== */ void rw_inode(stat_ptr, rw_mode) @@ -209,7 +177,6 @@ int rw_mode; offset = (block_t) ((i_num - 1) % inodes_per_block); offset *= (block_t) (inode_size); /* and this offset */ - lseek(fd, (off_t) 0, SEEK_SET); /* rewind */ lseek(fd, (off_t) (blk + offset), SEEK_SET); /* seek */ /* Pointer is at the inode */ @@ -449,7 +416,6 @@ int nr_blocks; } put_inode(&stat_buf); /* save the inode on disk */ - put_super(); /* bit_maps too */ } @@ -520,7 +486,6 @@ block_t num; blk_offset += (block_t) (words * SIZE_OF_INT); /* offset */ - lseek(fd, (off_t) 0, SEEK_SET); /* rewind */ lseek(fd, (off_t) blk_offset, SEEK_SET); /* set pointer at word */ rd = read(fd, (char *) &tst_word, SIZE_OF_INT); @@ -560,7 +525,6 @@ zone_t num; blk_offset += (long) (words * SIZE_OF_INT); - lseek(fd, (off_t) 0, SEEK_SET); /* rewind */ lseek(fd, (off_t) blk_offset, SEEK_SET); rwd = read(fd, (char *) &tst_word, SIZE_OF_INT); @@ -570,7 +534,6 @@ zone_t num; } bit = offset % INT_BITS; if (((tst_word >> bit) & 01) == 0) { /* free */ - lseek(fd, 0L, SEEK_SET);/* rewind */ lseek(fd, (off_t) blk_offset, SEEK_SET); tst_word |= (1 << bit); /* not free anymore */ rwd = write(fd, (char *) &tst_word, SIZE_OF_INT); diff --git a/commands/simple/fsck.c b/commands/simple/fsck.c index a2c81fcaf..7e63abf04 100755 --- a/commands/simple/fsck.c +++ b/commands/simple/fsck.c @@ -116,9 +116,7 @@ static struct super_block sb; #define ZONE_SIZE ((int) ztob(block_size)) #define NLEVEL (NR_ZONE_NUMS - NR_DZONE_NUM + 1) -/* Byte address of a zone/of an inode */ -#define cinoblock(i) (((i - 1)*INODE_SIZE) / block_size + BLK_ILIST) -#define cinooff(i) (((i - 1)*INODE_SIZE) % block_size) +/* Byte address of a zone */ #define INDCHUNK ((int) (CINDIR * ZONE_NUM_SIZE)) #define DIRCHUNK ((int) (CDIRECT * DIR_ENTRY_SIZE)) @@ -629,16 +627,12 @@ void chksuper() int inoblock(int inn) { - int a; - a = cinoblock(inn); - return a; + return div64u(mul64u(inn - 1, INODE_SIZE), block_size) + BLK_ILIST; } int inooff(int inn) { - int a; - a = cinooff(inn); - return a; + return rem64u(mul64u(inn - 1, INODE_SIZE), block_size); } /* Make a listing of the inodes given by `clist'. If `repair' is set, ask diff --git a/commands/simple/mkfs.c b/commands/simple/mkfs.c index 7fb72f5aa..236293af8 100755 --- a/commands/simple/mkfs.c +++ b/commands/simple/mkfs.c @@ -2,10 +2,12 @@ /* Authors: Andy Tanenbaum, Paul Ogilvie, Frans Meulenbroeks, Bruce Evans * - * 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 version 1, 2 and 3 file systems, as follows: + * mkfs /dev/fd0 1200 # Version 3 (default) * mkfs -1 /dev/fd0 360 # Version 1 * + * Note that the version 1 and 2 file systems produced by this program are not + * compatible with the original version 1 and 2 file system layout. */ #include @@ -185,6 +187,8 @@ char *argv[]; default: usage(); } + if (argc == optind) usage(); + if(fs_version == 3) { if(!block_size) block_size = _MAX_BLOCK_SIZE; /* V3 default block size */ if(block_size%SECTOR_SIZE || block_size < _MIN_BLOCK_SIZE) { @@ -428,8 +432,7 @@ ino_t inodes; int inodeblks; int initblks; u32_t nb; - - zone_t initzones, nrzones, v1sq, v2sq; + zone_t v1sq, v2sq; zone_t zo; struct super_block *sup; char *buf, *cp; @@ -442,6 +445,7 @@ ino_t inodes; sup->s_ninodes = inodes; if (fs_version == 1) { sup->s_nzones = zones; + if (sup->s_nzones != zones) pexit("too many zones"); } else { sup->s_nzones = 0; /* not used in V2 - 0 forces errors early */ sup->s_zones = zones; @@ -461,9 +465,8 @@ ino_t inodes; inode_offset = sup->s_imap_blocks + sup->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 = nb = (initblks + (1 << zone_shift) - 1) >> zone_shift; + if(nb >= zones) pexit("bit maps too large"); if(nb != sup->s_firstdatazone) { fprintf(stderr, "mkfs: too much bitmap and inode data.\n" BIGGERBLOCKS); exit(1); diff --git a/commands/yap/main.c b/commands/yap/main.c index 52d4e7cff..a095092b4 100755 --- a/commands/yap/main.c +++ b/commands/yap/main.c @@ -37,6 +37,7 @@ int main(argc,argv) register char ** argv; { register char ** av; + char *empty_envp[] = { (char *) 0 }; if (! isatty(1)) { no_tty = 1; @@ -58,7 +59,7 @@ main(argc,argv) register char ** argv; { } if (no_tty) { *--av = "cat"; - execve("/bin/cat", av, (char *) 0); + execve("/bin/cat", av, &empty_envp); } else processfiles(argc-(av-argv), av); (VOID) quit(); diff --git a/servers/mfs/super.c b/servers/mfs/super.c index f511bb36d..3133101da 100644 --- a/servers/mfs/super.c +++ b/servers/mfs/super.c @@ -311,10 +311,12 @@ register struct super_block *sp; /* pointer to a superblock */ /* Make a few basic checks to see if super block looks reasonable. */ if (sp->s_imap_blocks < 1 || sp->s_zmap_blocks < 1 || sp->s_ninodes < 1 || sp->s_zones < 1 + || sp->s_firstdatazone <= 4 + || sp->s_firstdatazone >= sp->s_zones || (unsigned) sp->s_log_zone_size > 4) { printf("not enough imap or zone map blocks, \n"); - printf("or not enough inodes, or not enough zones, " - "or zone size too large\n"); + printf("or not enough inodes, or not enough zones, \n" + "or invalid first data zone, or zone size too large\n"); return(EINVAL); } sp->s_dev = dev; /* restore device number */