From owner-svn-src-all@freebsd.org Wed Dec 5 06:31:52 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A00DD132FE80; Wed, 5 Dec 2018 06:31:52 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 46F78866DC; Wed, 5 Dec 2018 06:31:52 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 27A4610BD5; Wed, 5 Dec 2018 06:31:52 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id wB56VqPe055817; Wed, 5 Dec 2018 06:31:52 GMT (envelope-from mckusick@FreeBSD.org) Received: (from mckusick@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id wB56VoiL055810; Wed, 5 Dec 2018 06:31:50 GMT (envelope-from mckusick@FreeBSD.org) Message-Id: <201812050631.wB56VoiL055810@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mckusick set sender to mckusick@FreeBSD.org using -f From: Kirk McKusick Date: Wed, 5 Dec 2018 06:31:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r341510 - head/sbin/fsck_ffs X-SVN-Group: head X-SVN-Commit-Author: mckusick X-SVN-Commit-Paths: head/sbin/fsck_ffs X-SVN-Commit-Revision: 341510 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 46F78866DC X-Spamd-Result: default: False [-0.80 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-0.45)[-0.447,0]; NEURAL_HAM_SHORT(-0.32)[-0.324,0]; NEURAL_HAM_LONG(-0.03)[-0.031,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-Rspamd-Server: mx1.freebsd.org X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 05 Dec 2018 06:31:52 -0000 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);