Subject: Re: ffs compat problem since ffs2
To: Luke Mewburn <lukem@NetBSD.org>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: tech-kern
Date: 09/26/2003 08:26:46
On Fri, Sep 26, 2003 at 09:45:36AM +1000, Luke Mewburn wrote:
> On Fri, Sep 26, 2003 at 01:06:25AM +0200, Manuel Bouyer wrote:
>   | On Fri, Sep 26, 2003 at 08:35:30AM +1000, Luke Mewburn wrote:
>   | > Recently I experienced some lossage with a new kernel on an older
>   | > -current system (looked like FS corruption), and upon further
>   | 
>   | Was it current before or after ufs2 integration ?
> 
> Before.  (Kernel was dated March 19; AFAICT, UFS2 went in early April).
> 
> 
>   | What kind of fs corruption ? At kernel or fsck level ?
> 
> First boot; kernel couldn't find /sbin/init or /dev/console
> (errno = 20, ENOTDIR)
> 
> Second boot; kernel accessed /, but accessing /tmp (an mfs
> created with a March 19 mount_mfs) caused a panic.

It's strange to have different behaviors between boot.

Can you add printfs to the kernel to check old_ufs1, fs->fs_time and
fs_old_time in ffs_oldfscompat_read() ?

> 
> 
>   | >    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
>   | 
>   | This shouldn't matter; it'll always get the old values, but current
>   | make sure the old and new fields will match.
>   | 
>   | > 	usr.sbin/dumpfs/dumpfs.c
>   | > 		tested in fs_old_flags
>   | 
>   | Same comment as for fsck
> 
> Well, dumpfs returns the incorrect values for my file systems, saying
> that they're 4.2/4.3BSD because "printold" is true due to the missing
> FS_FLAGS_UPDATED...

I think this code is broken. It will always fail on a pre-ufs2 filesystem.
The  !printold in
	if (!printold && afs.fs_old_postblformat != FS_42POSTBLFMT) {
should not be there. 

I don't understand how fsck can fail though, exept that it *may* corrupt
the filesystem on write (FS_FLAGS_UPDATED is only used on write).
I need to look at this more.

> 
> Note that even if we tweak the tests in fsck_ffs & dumpfs to ignore
> FS_FLAGS_UPDATED and use another method of testing that, it's possible
> that dumpfs will still return incorrect results for a file system
> created on an old system that has not yet had its superblock updated
> by a new kernel...

It should not, but I think dumpfs is brocken currently - see above

> 
> 
>   | > Given that fsck_ffs & dumpfs currently test FS_FLAGS_UPDATED,
>   | 
>   | They do but shouldn't.
>   | At the current state, it should't matter if FS_FLAGS_UPDATED is set or not,
>   | current will make sure the old and new field matches.
>   | 
>   | I'm not sure why you ran into this problem; but I don't think the lack of
>   | FS_FLAGS_UPDATED on disk could cause it. It would be good to be able to
>   | investigate further.
> 
> Look at how FS_FLAGS_UPDATED is used by these tools.  It should be
> apparent why dumpfs gets confused.

I don't think it uses it the right way.
For fsck, I don't know what's happening yet (FS_FLAGS_UPDATED is used only when
writting back the SB).

> 
> 
>   | >     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 ?)
>   | 
>   | We need to do that anyway.
>   | FS_FLAGS_UPDATED will still be set, in case new flags are used, so we can't
>   | deprecate it.
> 
> FS_FLAGS_UPDATED will NOT be set in fs_old_flags that's written back
> to the superblock, and that's what fsck_ffs and dumpfs are checking.

Not *always*, it will if some of the new flags are used.

> 
> FS_FLAGS_UPDATED is also not copied from fs_old_flags to fs_flags,
> so we can't check fs_flags in those tools for the bit being set either.
> 
> So, basically, FS_FLAGS_UPDATED is a flag that is "useless" to
> userland at this point.  Useless in that there's no point setting it
> in makefs / newfs, an useless in testing it since the kernel doesn't
> let userland "see" it in fs_old_flags (because of the FS_SWAPPED bit
> clash) or in fs_flags (for unknown reasons).

It's never set in fs_flags because nothing tests it, and more important
fs_flags may contain trash before the update.

> 
> 
> 
> Luke.
> 
> 
> <side rant>
> 
> BTW: I suggest that next time you check where these type of flags are 
> used throughout the tree (and not just under src/sys) before making
> these type of kernel changes...  If this comes across too "harsh",
> I apologise, but I'm annoyed at this apparent lack of due diligence
> (by checking the entire source tree for how this flag was used).

Yes, I should have. Sorry

-- 
Manuel Bouyer <bouyer@antioche.eu.org>
     NetBSD: 23 ans d'experience feront toujours la difference
--