From nobody Fri Aug 11 06:03:59 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4RMYC348J5z4mJYX; Fri, 11 Aug 2023 06:03:59 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4RMYC33Zm0z3CKy; Fri, 11 Aug 2023 06:03:59 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1691733839; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=KBJVJDX85Wsgav8Ya9g1dwl8EFOzxCKyOHs0nQYtD+I=; b=l8C+m/NZYXcHmgCc4XukNgWTrwUZYYmMbry8z4ISaF0jmxFYTBB1yjBilOeotJCA89sHxt PmE5IKb0J1YQGD8J9IRBwLV4eygVLbCJP2v6O+/C1nBpTKMofM9JXOU6rM96/Wg7g+AhNJ uW+rNKMT3OlClP6JZf39KWdo0v58bhkNcNVileJU3CxOG5GLuo6OWzsQ3UayWqCIhDIxbp 1gqCh/WNvr7HVTRBYI3ldBOeOUAQBbafuwkR1WB9JYZCo5ZOaJubdyByxucHzQJa0gVWs8 tHHAyasEmppweVJcI38KbtVgmd+DHybJB5kLsKa1uGjIv+p7bYqXeC+14R+OsQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1691733839; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=KBJVJDX85Wsgav8Ya9g1dwl8EFOzxCKyOHs0nQYtD+I=; b=w3x0vWRnGqHmfeOez9BMUxizEEIm6NWpVvnM9lugVY3POnsC3gLkpO76/xZwqLRXX1P0YN lm7orMMv5Zrk7KqrS7dmVotN1xvhVdSgnaM8bz08p4zx/xaG4KuUYBN8MFtss3j4ebw1Am Hc+VcfbyhJAKR7NkTFbVxd1CjJzyVuwl3b+k8AvQLJx8HnDgD8aJZ5rRhaSWHttrYntOSG c59gArJ93wm388ArpKHY0TLdOd5IdqzR00tH1h54aDwHjsVGWuHCDsxq7pVmZKYGKGw0zT wXVp+mot8ULwu4x7dJ4xhtaLi+xaUjzpTZ4X8H8y1haqp8nKy9pKIuqOoW3xpw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1691733839; a=rsa-sha256; cv=none; b=rtPYYfsbDJtoxnxZ1ej7Uz3xpQiU2/eqXs6oGAag6+fwPZC6Aiy9tDo8M4oGtnKgztXfgF kOt3t/fMDhfOBYUiR8dnmmwFphqy/o3AkdPsAk9ay2D6NIGogKB5IZA1aUFzUoUysGFPRH 3y9/UwPN9Zp5St/SvSpbE6W8+6mpyLh9PGM12DkPRROENDg6ZL+8z0CFNTRfb1ppDUeTFS kDXQUBxnHdkWdGPMv8H6nmV7iS4AP6/eI0YkV1Jka8u4coFTrRpVxaAokwRCzZcNX8lwtC 28+pIk9lCfDC4STKug1qQetqKVbq62GBeYbUFiFaxoc9Beov9XLsJ+RJ1iN43A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4RMYC32f2mzCVD; Fri, 11 Aug 2023 06:03:59 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 37B63xcg092591; Fri, 11 Aug 2023 06:03:59 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 37B63xaG092588; Fri, 11 Aug 2023 06:03:59 GMT (envelope-from git) Date: Fri, 11 Aug 2023 06:03:59 GMT Message-Id: <202308110603.37B63xaG092588@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kirk McKusick Subject: git: c3046779b241 - main - Optimize operations on UFS/FFS filesystems with bad cylinder group(s). List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mckusick X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: c3046779b241768394a336de115e88cc7c10d922 Auto-Submitted: auto-generated The branch main has been updated by mckusick: URL: https://cgit.FreeBSD.org/src/commit/?id=c3046779b241768394a336de115e88cc7c10d922 commit c3046779b241768394a336de115e88cc7c10d922 Author: Kirk McKusick AuthorDate: 2023-08-11 06:02:47 +0000 Commit: Kirk McKusick CommitDate: 2023-08-11 06:02:47 +0000 Optimize operations on UFS/FFS filesystems with bad cylinder group(s). If a UFS/FFS filesystem develops a broken cylinder group (which is usually detected when its check hash fails), that cylinder group will not be usable until the filesystem has been unmounted and fsck has been run to repair it. On the first attempt to to allocate resources from the broken cylinder group, its available resources are set to zero in the superblock summary information. Since it will appear to have no resources available, no further calls will be made to allocate resources from it. When resources are freed to the broken cylinder group, the resource free routines will find the cylinder group unusable so the resource will simply be discarded and thus will not show up in the superblock summary information until they are recovered by fsck. Reported-by: Peter Holm Tested-by: Peter Holm MFC-after: 1 week Sponsored-by: The FreeBSD Foundation --- sys/ufs/ffs/ffs_alloc.c | 53 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index 166c5bc7c65c..d2627647360a 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -116,6 +116,7 @@ static void ffs_blkfree_cg(struct ufsmount *, struct fs *, #ifdef INVARIANTS static int ffs_checkfreeblk(struct inode *, ufs2_daddr_t, long); #endif +static void ffs_checkcgintegrity(struct fs *, uint64_t, int); static ufs2_daddr_t ffs_clusteralloc(struct inode *, uint64_t, ufs2_daddr_t, int); static ino_t ffs_dirpref(struct inode *); @@ -1722,8 +1723,10 @@ ffs_fragextend(struct inode *ip, return (0); } UFS_UNLOCK(ump); - if ((error = ffs_getcg(fs, ump->um_devvp, cg, 0, &bp, &cgp)) != 0) + if ((error = ffs_getcg(fs, ump->um_devvp, cg, 0, &bp, &cgp)) != 0) { + ffs_checkcgintegrity(fs, cg, error); goto fail; + } bno = dtogd(fs, bprev); blksfree = cg_blksfree(cgp); for (i = numfrags(fs, osize); i < frags; i++) @@ -1793,8 +1796,10 @@ ffs_alloccg(struct inode *ip, return (0); UFS_UNLOCK(ump); if ((error = ffs_getcg(fs, ump->um_devvp, cg, 0, &bp, &cgp)) != 0 || - (cgp->cg_cs.cs_nbfree == 0 && size == fs->fs_bsize)) + (cgp->cg_cs.cs_nbfree == 0 && size == fs->fs_bsize)) { + ffs_checkcgintegrity(fs, cg, error); goto fail; + } if (size == fs->fs_bsize) { UFS_LOCK(ump); blkno = ffs_alloccgblk(ip, bp, bpref, rsize); @@ -1971,6 +1976,7 @@ ffs_clusteralloc(struct inode *ip, return (0); UFS_UNLOCK(ump); if ((error = ffs_getcg(fs, ump->um_devvp, cg, 0, &bp, &cgp)) != 0) { + ffs_checkcgintegrity(fs, cg, error); UFS_LOCK(ump); return (0); } @@ -2115,6 +2121,7 @@ check_nifree: return (0); UFS_UNLOCK(ump); if ((error = ffs_getcg(fs, ump->um_devvp, cg, 0, &bp, &cgp)) != 0) { + ffs_checkcgintegrity(fs, cg, error); UFS_LOCK(ump); return (0); } @@ -2762,7 +2769,7 @@ ffs_checkfreeblk(struct inode *ip, struct cg *cgp; struct buf *bp; ufs1_daddr_t cgbno; - int i, error, frags, blkalloced; + int i, frags, blkalloced; uint8_t *blksfree; fs = ITOFS(ip); @@ -2773,9 +2780,8 @@ ffs_checkfreeblk(struct inode *ip, } if ((uint64_t)bno >= fs->fs_size) panic("ffs_checkfreeblk: too big block %jd", (intmax_t)bno); - error = ffs_getcg(fs, ITODEVVP(ip), dtog(fs, bno), 0, &bp, &cgp); - if (error) - panic("ffs_checkfreeblk: cylinder group read failed"); + if (ffs_getcg(fs, ITODEVVP(ip), dtog(fs, bno), 0, &bp, &cgp) != 0) + return (0); blksfree = cg_blksfree(cgp); cgbno = dtogd(fs, bno); if (size == fs->fs_bsize) { @@ -3042,7 +3048,7 @@ ffs_getcg(struct fs *fs, bp->b_flags &= ~B_CKHASH; bp->b_flags |= B_INVAL | B_NOCACHE; brelse(bp); - return (EIO); + return (EINTEGRITY); } if (!cg_chkmagic(cgp) || cgp->cg_cgx != cg) { if (ppsratecheck(&VFSTOUFS(mp)->um_last_integritymsg, @@ -3062,7 +3068,7 @@ ffs_getcg(struct fs *fs, bp->b_flags &= ~B_CKHASH; bp->b_flags |= B_INVAL | B_NOCACHE; brelse(bp); - return (EIO); + return (EINTEGRITY); } bp->b_flags &= ~B_CKHASH; bp->b_xflags |= BX_BKGRDWRITE; @@ -3096,6 +3102,37 @@ ffs_ckhash_cg(struct buf *bp) cgp->cg_ckhash = ckhash; } +/* + * Called when a cylinder group read has failed. If an integrity check + * is the cause of failure then the cylinder group will not be usable + * until the filesystem has been unmounted and fsck has been run to + * repair it. To avoid future attempts to allocate resources from the + * cylinder group, its available resources are set to zero in the + * superblock summary information. Since it will appear to have no + * resources available, no further calls will be made to allocate + * resources from it. When resources are freed to the cylinder group + * the resource free routines will find the cylinder group unusable so + * the resource will simply be discarded and thus will not show up in + * the superblock summary information until they are recovered by fsck. + */ +static void +ffs_checkcgintegrity(struct fs *fs, + uint64_t cg, + int error) +{ + + if (error != EINTEGRITY) + return; + fs->fs_cstotal.cs_nffree -= fs->fs_cs(fs, cg).cs_nffree; + fs->fs_cs(fs, cg).cs_nffree = 0; + fs->fs_cstotal.cs_nbfree -= fs->fs_cs(fs, cg).cs_nbfree; + fs->fs_cs(fs, cg).cs_nbfree = 0; + fs->fs_cstotal.cs_nifree -= fs->fs_cs(fs, cg).cs_nifree; + fs->fs_cs(fs, cg).cs_nifree = 0; + fs->fs_maxcluster[cg] = 0; + fs->fs_fmod = 1; +} + /* * Fserr prints the name of a filesystem with an error diagnostic. *