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.
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;
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 */