From owner-dev-commits-src-all@freebsd.org Fri Aug 13 20:36:10 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 81D6465EDED; Fri, 13 Aug 2021 20:36:10 +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 4Gmb1Q37kjz4k7r; Fri, 13 Aug 2021 20:36:10 +0000 (UTC) (envelope-from git@FreeBSD.org) 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 5474A1493A; Fri, 13 Aug 2021 20:36:10 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 17DKaA07021213; Fri, 13 Aug 2021 20:36:10 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 17DKaAsr021212; Fri, 13 Aug 2021 20:36:10 GMT (envelope-from git) Date: Fri, 13 Aug 2021 20:36:10 GMT Message-Id: <202108132036.17DKaAsr021212@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kirk McKusick Subject: git: 654e91791ba3 - stable/13 - Clean up orphaned indirdep dependency structures after disk failure. 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/stable/13 X-Git-Reftype: branch X-Git-Commit: 654e91791ba3230bf26954d3ac1af6848702e4e6 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 13 Aug 2021 20:36:10 -0000 The branch stable/13 has been updated by mckusick: URL: https://cgit.FreeBSD.org/src/commit/?id=654e91791ba3230bf26954d3ac1af6848702e4e6 commit 654e91791ba3230bf26954d3ac1af6848702e4e6 Author: Kirk McKusick AuthorDate: 2021-07-29 23:11:58 +0000 Commit: Kirk McKusick CommitDate: 2021-08-13 17:37:26 +0000 Clean up orphaned indirdep dependency structures after disk failure. (cherry picked from commit 412b5e40a721430adba1b4abae210641f733f976) (cherry picked from commit a91716efeb684c50289c0e1136f5432f880dc873) --- sys/ufs/ffs/ffs_softdep.c | 54 +++++++++++++++++++++++++++++++++++++++++------ sys/ufs/ffs/softdep.h | 4 +--- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 446fc69a6a32..c53ba7c70d2f 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -1233,9 +1233,7 @@ workitem_free(item, type) ump->um_fs->fs_fsmnt, TYPENAME(item->wk_type))); atomic_subtract_long(&dep_current[item->wk_type], 1); ump->softdep_curdeps[item->wk_type] -= 1; -#ifdef INVARIANTS LIST_REMOVE(item, wk_all); -#endif free(item, DtoM(type)); } @@ -1262,9 +1260,7 @@ workitem_alloc(item, type, mp) ump->softdep_curdeps[type] += 1; ump->softdep_deps++; ump->softdep_accdeps++; -#ifdef INVARIANTS LIST_INSERT_HEAD(&ump->softdep_alldeps[type], item, wk_all); -#endif FREE_LOCK(ump); } @@ -1293,6 +1289,8 @@ workitem_reassign(item, newtype) dep_total[newtype]++; FREE_GBLLOCK(&lk); item->wk_type = newtype; + LIST_REMOVE(item, wk_all); + LIST_INSERT_HEAD(&ump->softdep_alldeps[newtype], item, wk_all); } /* @@ -2710,10 +2708,8 @@ softdep_mount(devvp, mp, fs, cred) ump->indir_hash_size = i - 1; for (i = 0; i <= ump->indir_hash_size; i++) TAILQ_INIT(&ump->indir_hashtbl[i]); -#ifdef INVARIANTS for (i = 0; i <= D_LAST; i++) LIST_INIT(&ump->softdep_alldeps[i]); -#endif ACQUIRE_GBLLOCK(&lk); TAILQ_INSERT_TAIL(&softdepmounts, sdp, sd_next); FREE_GBLLOCK(&lk); @@ -14765,9 +14761,12 @@ softdep_check_suspend(struct mount *mp, int secondary_writes, int secondary_accwrites) { + struct buf *bp; struct bufobj *bo; struct ufsmount *ump; struct inodedep *inodedep; + struct indirdep *indirdep; + struct worklist *wk, *nextwk; int error, unlinked; bo = &devvp->v_bufobj; @@ -14843,9 +14842,52 @@ softdep_check_suspend(struct mount *mp, } } + /* + * XXX Check for orphaned indirdep dependency structures. + * + * During forcible unmount after a disk failure there is a + * bug that causes one or more indirdep dependency structures + * to fail to be deallocated. We check for them here and clean + * them up so that the unmount can succeed. + */ + if ((ump->um_flags & UM_FSFAIL_CLEANUP) != 0 && ump->softdep_deps > 0 && + ump->softdep_deps == ump->softdep_curdeps[D_INDIRDEP]) { + LIST_FOREACH_SAFE(wk, &ump->softdep_alldeps[D_INDIRDEP], + wk_all, nextwk) { + indirdep = WK_INDIRDEP(wk); + if ((indirdep->ir_state & (GOINGAWAY | DEPCOMPLETE)) != + (GOINGAWAY | DEPCOMPLETE) || + !TAILQ_EMPTY(&indirdep->ir_trunc) || + !LIST_EMPTY(&indirdep->ir_completehd) || + !LIST_EMPTY(&indirdep->ir_writehd) || + !LIST_EMPTY(&indirdep->ir_donehd) || + !LIST_EMPTY(&indirdep->ir_deplisthd) || + indirdep->ir_saveddata != NULL || + indirdep->ir_savebp == NULL) { + printf("%s: skipping orphaned indirdep %p\n", + __FUNCTION__, indirdep); + continue; + } + printf("%s: freeing orphaned indirdep %p\n", + __FUNCTION__, indirdep); + bp = indirdep->ir_savebp; + indirdep->ir_savebp = NULL; + free_indirdep(indirdep); + FREE_LOCK(ump); + brelse(bp); + while (!TRY_ACQUIRE_LOCK(ump)) { + BO_UNLOCK(bo); + ACQUIRE_LOCK(ump); + FREE_LOCK(ump); + BO_LOCK(bo); + } + } + } + /* * Reasons for needing more work before suspend: * - Dirty buffers on devvp. + * - Dependency structures still exist * - Softdep activity occurred after start of vnode sync loop * - Secondary writes occurred after start of vnode sync loop */ diff --git a/sys/ufs/ffs/softdep.h b/sys/ufs/ffs/softdep.h index 3493aadafc98..41728be3ec0f 100644 --- a/sys/ufs/ffs/softdep.h +++ b/sys/ufs/ffs/softdep.h @@ -213,10 +213,10 @@ struct worklist { struct mount *wk_mp; /* Mount we live in */ unsigned int wk_type:8, /* type of request */ wk_state:24; /* state flags */ + LIST_ENTRY(worklist) wk_all; /* list of deps of this type */ #ifdef INVARIANTS const char *wk_func; /* func where added / removed */ int wk_line; /* line where added / removed */ - LIST_ENTRY(worklist) wk_all; /* list of deps of this type */ #endif }; #define WK_DATA(wk) ((void *)(wk)) @@ -1075,9 +1075,7 @@ struct mount_softdeps { TAILQ_ENTRY(mount_softdeps) sd_next; /* List of softdep filesystem */ struct ufsmount *sd_ump; /* our ufsmount structure */ u_long sd_curdeps[D_LAST + 1]; /* count of current deps */ -#ifdef INVARIANTS struct workhead sd_alldeps[D_LAST + 1];/* Lists of all deps */ -#endif }; /* * Flags for communicating with the syncer thread.