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