Skip to content

Commit 1b118d9

Browse files
ufs: Allow read-only mounting of NetBSD FFSv2 WAPBL filesystems
Skip UFS2 fs_metaspace upper-bound validation that rejects NetBSD FFSv2 WAPBL filesystems due to differing superblock layouts. Detect the condition during mount instead and permit read-only mounts while rejecting read-write mounts with EROFS. This follows NetBSD's recommendation for systems without WAPBL support and avoids modifying unsupported journal metadata. PR: 296022 Signed-off-by: Ricardo Branco <rbranco@suse.de>
1 parent d949721 commit 1b118d9

2 files changed

Lines changed: 40 additions & 1 deletion

File tree

sys/ufs/ffs/ffs_subr.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,19 @@ validate_sblock(struct fs *fs, int flags)
717717
howmany(fs->fs_cssize, fs->fs_fsize), %jd);
718718
#endif
719719
WCHK(fs->fs_metaspace, <, 0, %jd);
720-
WCHK(fs->fs_metaspace, >, fs->fs_fpg / 2, %jd);
720+
/*
721+
* FreeBSD and NetBSD FFSv2 layouts diverge in the superblock region
722+
* following fs_maxbsize. NetBSD's WAPBL journal metadata occupies
723+
* the same bytes as FreeBSD's fs_metaspace and other fields.
724+
* fs_flags cannot serve as a discriminator: ffs_oldfscompat_read()
725+
* may overwrite it from the 8-bit fs_old_flags before this check runs.
726+
* Skip the upper-bound check for UFS2; ffs_mountfs() detects the
727+
* condition and enforces read-only access without modifying the
728+
* on-disk superblock. The check is preserved for UFS1 where no such
729+
* layout divergence exists.
730+
*/
731+
if (fs->fs_magic != FS_UFS2_MAGIC)
732+
WCHK(fs->fs_metaspace, >, fs->fs_fpg / 2, %jd);
721733
WCHK(fs->fs_minfree, >, 99, %jd%%);
722734
maxfilesize = fs->fs_bsize * UFS_NDADDR - 1;
723735
for (sizepb = fs->fs_bsize, i = 0; i < UFS_NIADDR; i++) {

sys/ufs/ffs/ffs_vfsops.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,16 @@ ffs_mount(struct mount *mp)
604604
if (error) {
605605
return (error);
606606
}
607+
/*
608+
* Refuse upgrade of NetBSD WAPBL filesystem to
609+
* read-write; see validate_sblock() for details.
610+
*/
611+
if (fs->fs_magic == FS_UFS2_MAGIC &&
612+
fs->fs_metaspace > fs->fs_fpg / 2) {
613+
vfs_mount_error(mp, "NetBSD WAPBL filesystem "
614+
"must be mounted read-only");
615+
return (EROFS);
616+
}
607617
fs->fs_flags &= ~FS_UNCLEAN;
608618
if (fs->fs_clean == 0) {
609619
fs->fs_flags |= FS_UNCLEAN;
@@ -926,6 +936,23 @@ ffs_mountfs(struct vnode *odevvp, struct mount *mp, struct thread *td)
926936
ffs_use_bread);
927937
if (error != 0)
928938
goto out;
939+
/*
940+
* Per NetBSD's wapbl(4), systems without WAPBL support should mount it
941+
* read-only; see validate_sblock() for details.
942+
*/
943+
if (fs->fs_magic == FS_UFS2_MAGIC &&
944+
fs->fs_metaspace > fs->fs_fpg / 2) {
945+
if ((mp->mnt_flag & MNT_RDONLY) == 0) {
946+
vfs_mount_error(mp, "NetBSD WAPBL filesystem must be "
947+
"mounted read-only");
948+
error = EROFS;
949+
goto out;
950+
}
951+
printf("WARNING: %s: NetBSD WAPBL filesystem mounted "
952+
"read-only (fs_metaspace %jd, fs_fpg/2 %jd)\n",
953+
mp->mnt_stat.f_mntonname, (intmax_t)fs->fs_metaspace,
954+
(intmax_t)fs->fs_fpg / 2);
955+
}
929956
fs->fs_flags &= ~FS_UNCLEAN;
930957
if (fs->fs_clean == 0) {
931958
fs->fs_flags |= FS_UNCLEAN;

0 commit comments

Comments
 (0)