From ee0384891a6852ef528af0dbea9f2969f3a01b86 Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Fri, 17 Jun 2016 19:48:20 +0000 Subject: [PATCH] MFS: do not crash when reading superblock fails 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 | 15 +++++++++++++-- minix/lib/libminixfs/cache.c | 9 +++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/minix/fs/mfs/super.c b/minix/fs/mfs/super.c index 32d30fdad..92fca4bd8 100644 --- a/minix/fs/mfs/super.c +++ b/minix/fs/mfs/super.c @@ -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; diff --git a/minix/lib/libminixfs/cache.c b/minix/lib/libminixfs/cache.c index f562f56bb..d022709c7 100644 --- a/minix/lib/libminixfs/cache.c +++ b/minix/lib/libminixfs/cache.c @@ -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 */ -- 2.44.0