Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Dec 2018 06:31:50 +0000 (UTC)
From:      Kirk McKusick <mckusick@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r341510 - head/sbin/fsck_ffs
Message-ID:  <201812050631.wB56VoiL055810@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mckusick
Date: Wed Dec  5 06:31:50 2018
New Revision: 341510
URL: https://svnweb.freebsd.org/changeset/base/341510

Log:
  Ensure that cylinder-group check-hashes are properly updated when first
  creating them and when correcting them when they are found to be corrupted.
  
  Reported by:  Don Lewis (truckman@)
  Sponsored by: Netflix

Modified:
  head/sbin/fsck_ffs/fsck.h
  head/sbin/fsck_ffs/fsutil.c
  head/sbin/fsck_ffs/inode.c
  head/sbin/fsck_ffs/pass1.c
  head/sbin/fsck_ffs/pass5.c
  head/sbin/fsck_ffs/setup.c

Modified: head/sbin/fsck_ffs/fsck.h
==============================================================================
--- head/sbin/fsck_ffs/fsck.h	Wed Dec  5 00:46:09 2018	(r341509)
+++ head/sbin/fsck_ffs/fsck.h	Wed Dec  5 06:31:50 2018	(r341510)
@@ -417,6 +417,7 @@ void		blzero(int fd, ufs2_daddr_t blk, long size);
 void		cacheino(union dinode *dp, ino_t inumber);
 void		catch(int);
 void		catchquit(int);
+void		cgdirty(struct bufarea *);
 int		changeino(ino_t dir, const char *name, ino_t newnum);
 int		check_cgmagic(int cg, struct bufarea *cgbp);
 int		chkrange(ufs2_daddr_t blk, int cnt);

Modified: head/sbin/fsck_ffs/fsutil.c
==============================================================================
--- head/sbin/fsck_ffs/fsutil.c	Wed Dec  5 00:46:09 2018	(r341509)
+++ head/sbin/fsck_ffs/fsutil.c	Wed Dec  5 06:31:50 2018	(r341510)
@@ -249,6 +249,24 @@ cglookup(int cg)
 }
 
 /*
+ * Mark a cylinder group buffer as dirty.
+ * Update its check-hash if they are enabled.
+ */
+void
+cgdirty(struct bufarea *cgbp)
+{
+	struct cg *cg;
+
+	cg = cgbp->b_un.b_cg;
+	if ((sblock.fs_metackhash & CK_CYLGRP) != 0) {
+		cg->cg_ckhash = 0;
+		cg->cg_ckhash =
+		    calculate_crc32c(~0L, (void *)cg, sblock.fs_cgsize);
+	}
+	dirty(cgbp);
+}
+
+/*
  * Attempt to flush a cylinder group cache entry.
  * Return whether the flush was successful.
  */
@@ -348,11 +366,11 @@ flush(int fd, struct bufarea *bp)
 		if (bp != &sblk)
 			pfatal("BUFFER %p DOES NOT MATCH SBLK %p\n",
 			    bp, &sblk);
-		if (sbput(fd, (struct fs *)bp->b_un.b_buf, 0) == 0)
+		if (sbput(fd, bp->b_un.b_fs, 0) == 0)
 			fsmodified = 1;
 		break;
 	case BT_CYLGRP:
-		if (cgput(&disk, (struct cg *)bp->b_un.b_buf) == 0)
+		if (cgput(&disk, bp->b_un.b_cg) == 0)
 			fsmodified = 1;
 		break;
 	default:
@@ -740,7 +758,7 @@ check_cgmagic(int cg, struct bufarea *cgbp)
 		cgp->cg_nextfreeoff = cgp->cg_clusteroff +
 		    howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT);
 	}
-	dirty(cgbp);
+	cgdirty(cgbp);
 	return (0);
 }
 
@@ -782,7 +800,7 @@ allocblk(long frags)
 				cgp->cg_cs.cs_nbfree--;
 			else
 				cgp->cg_cs.cs_nffree -= frags;
-			dirty(cgbp);
+			cgdirty(cgbp);
 			return (i + j);
 		}
 	}

Modified: head/sbin/fsck_ffs/inode.c
==============================================================================
--- head/sbin/fsck_ffs/inode.c	Wed Dec  5 00:46:09 2018	(r341509)
+++ head/sbin/fsck_ffs/inode.c	Wed Dec  5 06:31:50 2018	(r341510)
@@ -692,7 +692,7 @@ allocino(ino_t request, int type)
 	default:
 		return (0);
 	}
-	dirty(cgbp);
+	cgdirty(cgbp);
 	dp = ginode(ino);
 	DIP_SET(dp, di_db[0], allocblk((long)1));
 	if (DIP(dp, di_db[0]) == 0) {

Modified: head/sbin/fsck_ffs/pass1.c
==============================================================================
--- head/sbin/fsck_ffs/pass1.c	Wed Dec  5 00:46:09 2018	(r341509)
+++ head/sbin/fsck_ffs/pass1.c	Wed Dec  5 06:31:50 2018	(r341510)
@@ -200,7 +200,7 @@ pass1(void)
 				cgp->cg_initediblk = mininos;
 			pwarn("CYLINDER GROUP %d: RESET FROM %ju TO %d %s\n",
 			    c, i, cgp->cg_initediblk, "VALID INODES");
-			dirty(cgbp);
+			cgdirty(cgbp);
 		}
 		if (inosused < sblock.fs_ipg)
 			continue;

Modified: head/sbin/fsck_ffs/pass5.c
==============================================================================
--- head/sbin/fsck_ffs/pass5.c	Wed Dec  5 00:46:09 2018	(r341509)
+++ head/sbin/fsck_ffs/pass5.c	Wed Dec  5 06:31:50 2018	(r341510)
@@ -182,14 +182,19 @@ pass5(void)
 			ckhash = cg->cg_ckhash;
 			cg->cg_ckhash = 0;
 			thishash = calculate_crc32c(~0L, cg, fs->fs_cgsize);
-			if (ckhash != thishash)
+			if (ckhash == thishash) {
+				cg->cg_ckhash = ckhash;
+			} else {
 				pwarn("CG %d: BAD CHECK-HASH %#x vs %#x\n",
 				    c, ckhash, thishash);
-			cg->cg_ckhash = ckhash;
+				cg->cg_ckhash = thishash;
+				cgdirty(cgbp);
+			}
 		}
 		newcg->cg_time = cg->cg_time;
 		newcg->cg_old_time = cg->cg_old_time;
 		newcg->cg_unrefs = cg->cg_unrefs;
+		newcg->cg_ckhash = cg->cg_ckhash;
 		newcg->cg_cgx = c;
 		dbase = cgbase(fs, c);
 		dmax = dbase + fs->fs_fpg;
@@ -326,11 +331,6 @@ pass5(void)
 				sump[run]++;
 			}
 		}
-		if ((fs->fs_metackhash & CK_CYLGRP) != 0) {
-			newcg->cg_ckhash = 0;
-			newcg->cg_ckhash =
-			    calculate_crc32c(~0L, (void *)newcg, fs->fs_cgsize);
-		}
 
 		if (bkgrdflag != 0) {
 			cstotal.cs_nffree += cg->cg_cs.cs_nffree;
@@ -352,14 +352,14 @@ pass5(void)
 		}
 		if (rewritecg) {
 			memmove(cg, newcg, (size_t)fs->fs_cgsize);
-			dirty(cgbp);
+			cgdirty(cgbp);
 			continue;
 		}
 		if (cursnapshot == 0 &&
 		    memcmp(newcg, cg, basesize) != 0 &&
 		    dofix(&idesc[2], "SUMMARY INFORMATION BAD")) {
 			memmove(cg, newcg, (size_t)basesize);
-			dirty(cgbp);
+			cgdirty(cgbp);
 		}
 		if (bkgrdflag != 0 || usedsoftdep || debug)
 			update_maps(cg, newcg, bkgrdflag);
@@ -368,7 +368,7 @@ pass5(void)
 		    dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) {
 			memmove(cg_inosused(cg), cg_inosused(newcg),
 			      (size_t)mapsize);
-			dirty(cgbp);
+			cgdirty(cgbp);
 		}
 	}
 	if (cursnapshot == 0 &&

Modified: head/sbin/fsck_ffs/setup.c
==============================================================================
--- head/sbin/fsck_ffs/setup.c	Wed Dec  5 00:46:09 2018	(r341509)
+++ head/sbin/fsck_ffs/setup.c	Wed Dec  5 06:31:50 2018	(r341510)
@@ -208,6 +208,13 @@ setup(char *dev)
 		pwarn("USING ALTERNATE SUPERBLOCK AT %jd\n", bflag);
 		bflag = 0;
 	}
+	/* Save copy of things needed by libufs */
+	memcpy(&disk.d_fs, &sblock, sblock.fs_sbsize);
+	disk.d_ufs = (sblock.fs_magic == FS_UFS1_MAGIC) ? 1 : 2;
+	disk.d_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
+	disk.d_sblock = sblock.fs_sblockloc / disk.d_bsize;
+	disk.d_sbcsum = sblock.fs_csp;
+
 	if (skipclean && ckclean && sblock.fs_clean) {
 		pwarn("FILE SYSTEM CLEAN; SKIPPING CHECKS\n");
 		return (-1);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201812050631.wB56VoiL055810>