NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/60855: FFSv2ea superblok mismatch
The following reply was made to PR kern/60855; it has been noted by GNATS.
From: Showta Ishizaki <zakinko%snowrabbit.org@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: zakinko%snowrabbit.org@localhost
Subject: Re: kern/60855: FFSv2ea superblok mismatch
Date: Thu, 29 Oct 2026 09:01:27 +0900 (JST)
I ran into the same thing while testing UFS2ea images in CI: a file
system made with newfs -O 2ea fails fsck_ffs -n -f with "ALTERNATE
SUPERBLK(S) ARE INCORRECT" straight after newfs. As far as I can tell
there are two causes, one in newfs and one in fsck_ffs.
In newfs, mkfs() puts FS_UFS2EA_MAGIC only into the superblock itself.
The alternates are written by initcg() from a copy in iobuf that was
made earlier, so they still have FS_UFS2_MAGIC, and pass5 of fsck_ffs
rejects an alternate whose magic does not match. The magic is also
stored after ffs_sb_swap(), in host byte order, so with -B be on amd64
the superblock cannot be read at all; fsck_ffs reports "BAD SUPER
BLOCK: SIZE PREPOSTEROUSLY LARGE".
In fsck_ffs -c ea, setup() fills sblk from the in-memory sblock (whose
magic is always FS_UFS2_MAGIC) to write the last alternate, and pass5
later copies that buffer to every cylinder group. That code repeats
what sbdirty() does but leaves out cvt_magic(), so the alternates keep
the old magic, and only the superblock itself is converted when
ckfini() calls sbdirty().
The patch below fixes both. I tested it on NetBSD 11.0/amd64 with
trunk as of 2026-10-28, using file images (newfs -F -s 64m) and
checking the magic of each superblock copy. Without the patch, newfs
-O 2ea and newfs -O 2 followed by fsck_ffs -y -c ea both leave the
four alternates with the plain UFS2 magic, with or without -B; newfs
-O 2ea -B be gives the unreadable superblock described above. With
the patch, all five copies have the UFS2ea magic in the right byte
order and fsck_ffs -n -f exits 0. newfs -O 2 and fsck_ffs -c no-ea
behave as before.
Index: sbin/newfs/mkfs.c
--- sbin/newfs/mkfs.c
+++ sbin/newfs/mkfs.c
@@ -662,6 +662,9 @@
memcpy(iobuf, &sblock, sizeof sblock);
if (needswap)
ffs_sb_swap(&sblock, (struct fs *)iobuf);
+ if (eaflag)
+ ((struct fs *)iobuf)->fs_magic = needswap ?
+ FS_UFS2EA_MAGIC_SWAPPED : FS_UFS2EA_MAGIC;
if ((sblock.fs_old_flags & FS_FLAGS_UPDATED) == 0)
memset(iobuf + offsetof(struct fs, fs_old_postbl_start),
0xff, 256);
@@ -748,7 +751,8 @@
if (needswap)
ffs_sb_swap(&sblock, (struct fs *)iobuf);
if (eaflag)
- ((struct fs *)iobuf)->fs_magic = FS_UFS2EA_MAGIC;
+ ((struct fs *)iobuf)->fs_magic = needswap ?
+ FS_UFS2EA_MAGIC_SWAPPED : FS_UFS2EA_MAGIC;
if ((sblock.fs_old_flags & FS_FLAGS_UPDATED) == 0)
memset(iobuf + offsetof(struct fs, fs_old_postbl_start),
0xff, 256);
Index: sbin/fsck_ffs/setup.c
--- sbin/fsck_ffs/setup.c
+++ sbin/fsck_ffs/setup.c
@@ -453,6 +453,7 @@
sb_oldfscompat_write(sblk.b_un.b_fs, sblocksave);
if (needswap)
ffs_sb_swap(sblk.b_un.b_fs, sblk.b_un.b_fs);
+ cvt_magic(sblk.b_un.b_fs);
memmove(asblk.b_un.b_fs, sblk.b_un.b_fs, (size_t)sblock->fs_sbsize);
flush(fswritefd, &asblk);
}
File systems that already have the wrong alternates can be repaired
with fsck_ffs -y -f, even without the patch, since pass5 rewrites the
alternates from the superblock.
Home |
Main Index |
Thread Index |
Old Index