--- sys/vfs/ext2fs/ext2_vfsops.c +++ sys/vfs/ext2fs/ext2_vfsops.c @@ -822,6 +822,21 @@ brelse(bp); return (error); } + + /* + * DF-3216: a new superblock has been adopted and validated. + * Re-derive the mount constants that ext2_mountfs() only sets at + * initial mount time (ext2_vfsops.c), plus the statfs block size + * used to size indirect-block buffers in ext2_bmap.c:readindir(). + * Otherwise ext2_getlbns()/ext2_bmaparray()/ext2_balloc() walk the + * new geometry with the old um_nindir/um_bptrtodb and index (and + * ext2_balloc writes) past the indirect-block buffers. + */ + VFSTOEXT2(mp)->um_nindir = EXT2_ADDR_PER_BLOCK(fs); + VFSTOEXT2(mp)->um_bptrtodb = + le32toh(fs->e2fs->e2fs_log_bsize) + 1; + VFSTOEXT2(mp)->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs); + mp->mnt_stat.f_iosize = fs->e2fs_bsize; #ifdef UNKLAR if (fs->fs_sbsize < SBSIZE) bp->b_flags |= B_INVAL;