Page MenuHomeFreeBSD

Fix backward compatibility with UFS1 filesystems created before June 2002
AcceptedPublic

Authored by mckusick on Wed, Jan 15, 9:53 PM.
Tags
None
Referenced Files
F107592434: D48472.diff
Thu, Jan 16, 8:44 AM
F107589567: D48472.id149310.diff
Thu, Jan 16, 7:47 AM
F107589409: D48472.diff
Thu, Jan 16, 7:47 AM
Subscribers

Details

Reviewers
kib
phk
Summary
Poul-Henning Kamp writes:
Subject: Re: Did we lose UFS1 compat ?

Here's what happens for me when I try to fsck an old UFS1 filesystem:

	root@fbsd:~ # gunzip fbsd4_6_2_root.dd.gz
	root@fbsd:~ # mdconfig -a -t vnode -f fbsd4_6_2_root.dd 
	md0
	root@fbsd:~ # fsck -n /dev/md0
	UFS1 superblock failed: fs->fs_size (0) < 8 * fs->fs_frag (64)
	UFS1 superblock failed: fs->fs_size (0) <= ((int64_t)fs->fs_ncg - 1) * fs->fs_fpg (0)
	UFS1 superblock failed: fs->fs_csaddr + howmany(fs->fs_cssize, fs->fs_fsize) (1) > fs->fs_size (0)
	UFS1 superblock failed: fs->fs_csaddr (0) < cgdmin(fs, dtog(fs, fs->fs_csaddr)) (1040)
	Attempted recovery for standard superblock: failed
	Attempt extraction of recovery data from standard superblock.
	Try cg 0 at sblock loc 32
	UFS1 superblock failed: fs->fs_size (0) < 8 * fs->fs_frag (64)
	UFS1 superblock failed: fs->fs_size (0) <= ((int64_t)fs->fs_ncg - 1) * fs->fs_fpg (0)
	UFS1 superblock failed: fs->fs_csaddr + howmany(fs->fs_cssize, fs->fs_fsize) (1) > fs->fs_size (0)
	UFS1 superblock failed: fs->fs_csaddr (0) < cgdmin(fs, dtog(fs, fs->fs_csaddr)) (1040)
	Finding an alternate superblock failed.
	Check for only non-critical errors in standard superblock
	UFS1 superblock failed: fs->fs_size (0) < 8 * fs->fs_frag (64)
	UFS1 superblock failed: fs->fs_size (0) <= ((int64_t)fs->fs_ncg - 1) * fs->fs_fpg (0)
	UFS1 superblock failed: fs->fs_csaddr + howmany(fs->fs_cssize, fs->fs_fsize) (1) > fs->fs_size (0)
	UFS1 superblock failed: fs->fs_csaddr (0) < cgdmin(fs, dtog(fs, fs->fs_csaddr)) (1040)
	Failed, superblock has critical errors
	SEARCH FOR ALTERNATE SUPER-BLOCK FAILED. YOU MUST USE THE -b OPTION TO FSCK TO SPECIFY THE LOCATION OF AN ALTERNATE
        SUPER-BLOCK TO SUPPLY NEEDED INFORMATION; SEE fsck_ffs(8).

The code to handle old filesystems still exists and does the right things. The problem is that it was being run after the new integrity checks rather than before them. This bugs was introduced 2.5 years ago when I added the integrity checks.

The reason that it has taken so long to show up is because it only affected filesystems created before UFS2 got added in June 2002 and that had never been mounted read-write (as their superblocks would be updated by the compatibility code if they could be written).  Hence you had to come along with a pre-2002 virgin UFS1 filesystem image. It was actually good that the integrity checks were there as it otherwise would have silently failed to work.

Most of the diffs are moving the compability routines from ffs_vfsops.c to ffs_subr.c so that they are available to libufs The key salient change is the one-line addition of ffs_oldfscompat_read() before calling validate_sblock().

--- a/sys/ufs/ffs/ffs_subr.c
+++ b/sys/ufs/ffs/ffs_subr.c
@@ -268,6 +269,7 @@ readsuper(void *devfd, struct fs **fsp, off_t sblockloc, int flags,
 	if (fs->fs_magic == FS_UFS1_MAGIC && (flags & UFS_ALTSBLK) == 0 &&
 	    fs->fs_bsize == SBLOCK_UFS2 && sblockloc == SBLOCK_UFS2)
 		return (ENOENT);
+	ffs_oldfscompat_read(fs, sblockloc);
 	if ((error = validate_sblock(fs, flags)) > 0)
 		return (error);
 	/*
Test Plan

Have Peter Holm run his full battery of filesystem tests.

Diff Detail

Lint
Lint Skipped
Unit
Tests Skipped