svn commit: r367034 - in head: sbin/fsck_ffs sys/ufs/ffs

Kirk McKusick mckusick at FreeBSD.org
Sun Oct 25 00:43:50 UTC 2020


Author: mckusick
Date: Sun Oct 25 00:43:48 2020
New Revision: 367034
URL: https://svnweb.freebsd.org/changeset/base/367034

Log:
  Various new check-hash checks have been added to the UFS filesystem
  over various major releases. Superblock check hashes were added for
  the 12 release and cylinder-group and inode check hashes will appear
  in the 13 release.
  
  When a disk with a UFS filesystem is writably mounted, the kernel
  clears the feature flags for anything that it does not support. For
  example, if a UFS disk from a 12-stable kernel is mounted on an
  11-stable system, the 11-stable kernel will clear the flag in the
  filesystem superblock that indicates that superblock check-hashs
  are being maintained. Thus if the disk is later moved back to a
  12-stable system, the 12-stable system will know to ignore its
  incorrect check-hash.
  
  If the only filesystem modification done on the earlier kernel is
  to run a utility such as growfs(8) that modifies the superblock but
  neither updates the check-hash nor clears the feature flag indicating
  that it does not support the check-hash, the disk will fail to mount
  if it is moved back to its original newer kernel.
  
  This patch moves the code that clears the filesystem feature flags
  from the mount code (ffs_mountfs()) to the code that reads the
  superblock (ffs_sbget()). As ffs_sbget() is used by the kernel mount
  code and is imported into libufs(3), all the filesystem utilities
  will now also clear these flags when they make modifications to the
  filesystem.
  
  As suggested by John Baldwin, fsck_ffs(8) has been changed to accept
  and repair bad superblock check-hashes rather than refusing to run.
  This change allows fsck to recover filesystems that have been impacted
  by utilities older than those created after this change and is a
  sensible thing to do in any event.
  
  Reported by:  John Baldwin (jhb@)
  MFC after:    2 weeks
  Sponsored by: Netflix

Modified:
  head/sbin/fsck_ffs/setup.c
  head/sys/ufs/ffs/ffs_subr.c
  head/sys/ufs/ffs/ffs_vfsops.c
  head/sys/ufs/ffs/fs.h

Modified: head/sbin/fsck_ffs/setup.c
==============================================================================
--- head/sbin/fsck_ffs/setup.c	Sat Oct 24 23:21:51 2020	(r367033)
+++ head/sbin/fsck_ffs/setup.c	Sun Oct 25 00:43:48 2020	(r367034)
@@ -330,7 +330,7 @@ readsb(int listerr)
 	int bad, ret;
 	struct fs *fs;
 
-	super = bflag ? bflag * dev_bsize : STDSB;
+	super = bflag ? bflag * dev_bsize : STDSB_NOHASHFAIL;
 	readcnt[sblk.b_type]++;
 	if ((ret = sbget(fsreadfd, &fs, super)) != 0) {
 		switch (ret) {

Modified: head/sys/ufs/ffs/ffs_subr.c
==============================================================================
--- head/sys/ufs/ffs/ffs_subr.c	Sat Oct 24 23:21:51 2020	(r367033)
+++ head/sys/ufs/ffs/ffs_subr.c	Sun Oct 25 00:43:48 2020	(r367034)
@@ -165,15 +165,15 @@ ffs_sbget(void *devfd, struct fs **fsp, off_t altsbloc
 
 	fs = NULL;
 	*fsp = NULL;
-	chkhash = 1;
 	if (altsblock >= 0) {
-		if ((error = readsuper(devfd, &fs, altsblock, 1, chkhash,
+		if ((error = readsuper(devfd, &fs, altsblock, 1, 0,
 		     readfunc)) != 0) {
 			if (fs != NULL)
 				UFS_FREE(fs, filltype);
 			return (error);
 		}
 	} else {
+		chkhash = 1;
 		if (altsblock == STDSB_NOHASHFAIL)
 			chkhash = 0;
 		for (i = 0; sblock_try[i] != -1; i++) {
@@ -277,6 +277,12 @@ readsuper(void *devfd, struct fs **fsp, off_t sblocklo
 		 */
 		if ((fs->fs_flags & FS_METACKHASH) == 0)
 			fs->fs_metackhash = 0;
+		/*
+		 * Clear any check-hashes that are not maintained
+		 * by this kernel. Also clear any unsupported flags.
+		 */
+		fs->fs_metackhash &= CK_SUPPORTED;
+		fs->fs_flags &= FS_SUPPORTED;
 		if (fs->fs_ckhash != (ckhash = ffs_calc_sbhash(fs))) {
 #ifdef _KERNEL
 			res = uprintf("Superblock check-hash failed: recorded "

Modified: head/sys/ufs/ffs/ffs_vfsops.c
==============================================================================
--- head/sys/ufs/ffs/ffs_vfsops.c	Sat Oct 24 23:21:51 2020	(r367033)
+++ head/sys/ufs/ffs/ffs_vfsops.c	Sun Oct 25 00:43:48 2020	(r367034)
@@ -1070,10 +1070,6 @@ ffs_mountfs(odevvp, mp, td)
 		loc = STDSB_NOHASHFAIL;
 	if ((error = ffs_sbget(devvp, &fs, loc, M_UFSMNT, ffs_use_bread)) != 0)
 		goto out;
-	/* none of these types of check-hashes are maintained by this kernel */
-	fs->fs_metackhash &= ~(CK_INDIR | CK_DIR);
-	/* no support for any undefined flags */
-	fs->fs_flags &= FS_SUPPORTED;
 	fs->fs_flags &= ~FS_UNCLEAN;
 	if (fs->fs_clean == 0) {
 		fs->fs_flags |= FS_UNCLEAN;

Modified: head/sys/ufs/ffs/fs.h
==============================================================================
--- head/sys/ufs/ffs/fs.h	Sat Oct 24 23:21:51 2020	(r367033)
+++ head/sys/ufs/ffs/fs.h	Sun Oct 25 00:43:48 2020	(r367034)
@@ -501,6 +501,7 @@ CTASSERT(sizeof(struct fs) == 1376);
 #define	CK_INODE	0x0004	/* inodes */
 #define	CK_INDIR	0x0008	/* indirect blocks */
 #define	CK_DIR		0x0010	/* directory contents */
+#define	CK_SUPPORTED	0x0007	/* supported flags, others cleared at mount */
 /*
  * The BX_FSPRIV buffer b_xflags are used to track types of data in buffers.
  */


More information about the svn-src-head mailing list