]> Zhao Yanbai Git Server - minix.git/commitdiff
MFS: do not crash when reading superblock fails 16/3316/1
authorDavid van Moolenbroek <david@minix3.org>
Fri, 17 Jun 2016 19:48:20 +0000 (19:48 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Fri, 17 Jun 2016 19:48:20 +0000 (19:48 +0000)
While MFS failing to do I/O on a block is generally fatal, reading
the superblock at mount time is an exception: this case may occur
when the given partition is too small to contain the superblock.
Therefore, MFS should not crash or even report anything in this
case, but rather refuse to mount cleanly.

This fixes #121.

Change-Id: I11326b48922a0e0ebefecbb8eec7c428f985f2b3

minix/fs/mfs/super.c
minix/lib/libminixfs/cache.c

index 32d30fdad30a74323e70f8e92d8498e27d5c738f..92fca4bd8e2cc7d0e21286ab8a32e08e295f1c93 100644 (file)
@@ -176,6 +176,7 @@ static int rw_super(struct super_block *sp, int writing)
   dev_t save_dev = sp->s_dev;
   struct buf *bp;
   char *sbbuf;
+  int r;
 
 /* To keep the 1kb on disk clean, only read/write up to and including
  * this field.
@@ -202,8 +203,18 @@ static int rw_super(struct super_block *sp, int writing)
   assert(lmfs_fs_block_size() >= sizeof(struct super_block) + SUPER_BLOCK_BYTES);
   assert(SUPER_BLOCK_BYTES >= sizeof(struct super_block));
   assert(SUPER_BLOCK_BYTES >= ondisk_bytes);
-  if(!(bp = get_block(sp->s_dev, 0, NORMAL)))
-       panic("get_block of superblock failed");
+
+  /* Unlike accessing any other block, failure to read the superblock is a
+   * somewhat legitimate use case: it may happen when trying to mount a
+   * zero-sized partition.  In that case, we'd rather faily cleanly than
+   * crash the MFS service.
+   */
+  if ((r = lmfs_get_block(&bp, sp->s_dev, 0, NORMAL)) != OK) {
+       if (writing)
+               panic("get_block of superblock failed: %d", r);
+       else
+               return r;
+  }
 
   /* sbbuf points to the disk block at the superblock offset */
   sbbuf = (char *) b_data(bp) + SUPER_BLOCK_BYTES;
index f562f56bb5c8885160b726e217b3019a683cdeec..d022709c7adfd95c67843c2387f2c1f4c43d3ba9 100644 (file)
@@ -758,8 +758,13 @@ static int read_block(struct buf *bp, size_t block_size)
        r = bdev_read(dev, pos, bp->data, block_size, BDEV_NOFLAGS);
   }
   if (r != (ssize_t)block_size) {
-       printf("fs cache: I/O error on device %d/%d, block %"PRIu64" (%zd)\n",
-           major(dev), minor(dev), bp->lmfs_blocknr, r);
+       /* Aesthetics: do not report EOF errors on superblock reads, because
+        * this is a fairly common occurrence, e.g. during system installation.
+        */
+       if (bp->lmfs_blocknr != 0 /*first block*/ || r != 0 /*EOF*/)
+               printf("fs cache: I/O error on device %d/%d, block %"PRIu64
+                   " (%zd)\n", major(dev), minor(dev), bp->lmfs_blocknr, r);
+
        if (r >= 0)
                r = EIO; /* TODO: retry retrieving (just) the remaining part */