Subject: Re: ffs compat problem since ffs2
To: Manuel Bouyer <bouyer@antioche.eu.org>
From: Luke Mewburn <lukem@NetBSD.org>
List: tech-kern
Date: 09/26/2003 08:35:30
On Sat, Sep 06, 2003 at 12:30:26AM +0200, Manuel Bouyer wrote:
| since ffsv2 was introduced, we have a problem where an old NetBSD
| kernel fails to use filesystems which have been mounted R/W by a new
| kernel (PR 21283) I tracked this down to the new kernel setting the
| FS_FLAGS_UPDATED flag in the superblock, which unfortunably happens
| to be the old FS_SWAPPED flag. And old kernel will keep this flag
| after mount, and swap the filesystem when it shouldn't.
|
| I agree that the (old) kernel should have filtered this flag at
| mount time, but unfortunably it doesn't and it's too late to fix it.
Yes. However, your fix doesn't work correctly either...
Recently I experienced some lossage with a new kernel on an older
-current system (looked like FS corruption), and upon further
investigation, determined that a -current GENERIC kernel works
but my custom cut-down kernel with FFS_EI did not.
I also noticed that dumpfs was printing the wrong results.
See below for more info...
| FS_FLAGS_UPDATED is used to tell the kernel that the superblock has been
| updated to the new world. It's used in 3 places:
Actually, it's used in more than just the kernel.
Further investigation reveals that FS_SWAPPED and FS_FLAGS_UPDATED
are used in more than just src/sys/ufs ...
FS_FLAGS_UPDATED
sys/ufs/ffs/ffs_vfsops.c
set in fs_old_flags
tested in fs_old_flags
fs_flags gets all fs_old_flags except FS_FLAGS_UPDATED
sys/ufs/ffs/fs.h
defined
sbin/fsck_ffs/utilities.c
tested in fs_old_flags
sbin/newfs/mkfs.c
set in fs_old_flags
usr.sbin/dumpfs/dumpfs.c
tested in fs_old_flags
usr.sbin/makefs/ffs/mkfs.c
set in fs_old_flags
FS_SWAPPED
sys/ufs/ffs/ffs_vfsops.c
set in fs_flags
cleared in fs_flags
sys/ufs/ffs/fs.h
defined
sys/ufs/ufs/ufs_bswap.h
tested as part of UFS_FSNEEDSWAP()
usr.sbin/makefs/ffs/mkfs.c
set in fs_flags (for ffs_write_superblock() ?)
| One obvious way of doing it would be to change FS_FLAGS_UPDATED to 0x40,
| but this will likely cause compat problems with the others BSDs.
|
| [...]
|
| I think we could remove checks of FS_FLAGS_UPDATED in our kernel, and
| not set FS_FLAGS_UPDATED if we're not using any of the new features
| (basically, if fs->fs_flags contains only FS_UNCLEAN and FS_DOSOFTDEP)
|
| [...]
|
| So it looks like we don't need to set FS_FLAGS_UPDATED for v1
| filesystem on NetBSD. But unfortunably, not doing this may cause
| compatibility problems with others BSD.
Given that fsck_ffs & dumpfs currently test FS_FLAGS_UPDATED,
we need to do one of:
a) Renumber FS_FLAGS_UPDATED to 0x40 and reinstate FS_FLAGS_UPDATED
setting in fs_old_flags in the kernel.
This should retain backwards compat with NetBSD 1.6.x prior
to your recent ``fs_flags &= ~FS_SWAPPED'' fix & pullup.
This isn't compatible with the "other BSDs", but neither
is our current situation anyway...
We can ask the "other BSDs" (i.e, Kirk :) to reserve 0x40 in
their fs_flags and not use it going forward.
b) Implement a new macro, something like:
#define FS_UPDATED_UFS1(fs) \
(((fs)->fs_magic == FS_UFS1_MAGIC)
&& ((fs)->fs_maxbsize == (fs)->fs_bsize))
Use that instead of "(foo.fs_old_flags & FS_FLAGS_UPDATED) == 0"
Deprecate FS_FLAGS_UPDATED except as a place-holder (maybe
rename it in fs.h ?)
c) Revert the recent changes and set FS_FLAGS_UPDATED in the
kernel, with FS_FLAGS_UPDATED being 0x80.
Leave the FS_SWAPPED fixes in -current and the head of the
-1-6 branch.
I'm leaning towards `a)' at this point.