⬢ DragonFlyBSD Kernel Audit
DF-3216 / fix.diff
← back to finding ↓ download raw
--- 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;