]> Zhao Yanbai Git Server - minix.git/commitdiff
Ground work for larger file systems, and miscellaneous fixes:
authorDavid van Moolenbroek <david@minix3.org>
Mon, 26 Oct 2009 13:35:39 +0000 (13:35 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Mon, 26 Oct 2009 13:35:39 +0000 (13:35 +0000)
- 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

commands/simple/badblocks.c
commands/simple/fsck.c
commands/simple/mkfs.c
commands/yap/main.c
servers/mfs/super.c

index 1ff6802009d5d6a3a750352336e976d4b142aba6..5acbdbc27bae591dab09f10655cc885c6385df34 100755 (executable)
@@ -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);
index a2c81fcaff8015232281bfd57ee9eee9505d057d..7e63abf04a7f9823b40a25d32b885b1d545b419f 100755 (executable)
@@ -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
index 7fb72f5aa0403300ad88731d8226c67787d2ffae..236293af852407aece06d840f132ad7df90b66e6 100755 (executable)
@@ -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 <sys/types.h>
@@ -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);
index 52d4e7cff77de88eecbf7e0367c18879a2bf558a..a095092b4eaf7fe4a3c8fb76cb0abf12330c457a 100755 (executable)
@@ -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();
index f511bb36d9aa2b5c3697f0c2172b6c250005faeb..3133101dabb1b97f288ff9f93e7d6545b5c3e430 100644 (file)
@@ -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 */