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);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to