From nobody Mon Jan 03 03:45:23 2022 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 6DF4F192B437; Mon, 3 Jan 2022 03:45:24 +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 4JS1q80tPbz3KbF; Mon, 3 Jan 2022 03:45:24 +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 F2BD61E66E; Mon, 3 Jan 2022 03:45:23 +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 2033jNFC052688; Mon, 3 Jan 2022 03:45:23 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 2033jN0u052687; Mon, 3 Jan 2022 03:45:23 GMT (envelope-from git) Date: Mon, 3 Jan 2022 03:45:23 GMT Message-Id: <202201030345.2033jN0u052687@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: "Jason A. Harmening" Subject: git: d877dd5767bc - main - unionfs: simplify writecount management 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: jah X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: d877dd5767bcbda5f3138facaceac6cab5820da3 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1641181524; 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=tXQ43atWUUnCXjLTJOsosnYm5icTSvKOWsLwbK3N2/Y=; b=Nzh7J971BKEUWZ9+bNkpmmFB9gT/feARraLpjijZ+1bjL+o2wMYYl5GmaQ4MvG4hg7JuSY 68mK3YhkFstjVoZeUzCqNko6j3D+20Sfki32kNxbkOwzMBt/pTuMQwgmokGgJXJz/fKsgp qE4kgOb7k5Vk35jeYv9VZYlqkGLlXZoL5bcrKw0zOviUahidUPRSzWmiYomesm3FGaVnTx ItAvcd/JhSGjVkAqwKO1PyKgHidQAIpzicJBn8LtC7kVUrmSPO10Gjd7y8Q9xV5uEj730A hKqvamN7BiVL7IR9apIU0DijStdnhCqHWOW9ImiUCiA5I/2GUPDdax2nwdyAgg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1641181524; a=rsa-sha256; cv=none; b=pe4F7h1xruFjAHFVr41z2XiEV6yK1HlkPvJW/HpeEkKCdAibqo1FB7G9IJxWjslkEA6qMT h0XRdXVN5KvpwphCqwmdg20aQ6U+vnGNLjwcoJJMY6QZhaCmjFe0YRsI1PZGY0O+jC1A3T H7Ie91w0lVXQDqWfitxbMpH/YTE/yWRXxvq1OrDZW7YaVQu5VwmDzRCRcJ2OqhJEcWeD4D 9Pzeoy3ZzKR+TkjxQ+P6ELKV3rWmlql51Wx3Zyu0R/ieQvwxpLWJXAljOu+l/ZZEe4H7x1 e2Jhe5MiAfx09zwyAWfSyraDt+jbVFOwHtscHi+LRTzfZF743uOm635xleFLrQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by jah: URL: https://cgit.FreeBSD.org/src/commit/?id=d877dd5767bcbda5f3138facaceac6cab5820da3 commit d877dd5767bcbda5f3138facaceac6cab5820da3 Author: Jason A. Harmening AuthorDate: 2021-12-21 23:49:15 +0000 Commit: Jason A. Harmening CommitDate: 2022-01-03 03:52:58 +0000 unionfs: simplify writecount management Use atomics to track the writecount granted to the underlying FS, and avoid holding the vnode interlock while calling the underling FS' VOP_ADD_WRITECOUNT(). This also fixes a WITNESS warning about nesting the same lock type. Also add comments explaining why we need to track the writecount on the unionfs vnode in the first place. Finally, simplify writecount management to only use the upper vnode and assert that we shouldn't have an active writecount on the lower vnode through unionfs. Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D33611 --- sys/fs/unionfs/union_subr.c | 25 ++++++++++++++++++------- sys/fs/unionfs/union_vnops.c | 36 ++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/sys/fs/unionfs/union_subr.c b/sys/fs/unionfs/union_subr.c index 551553fd8b20..9a706d79f9f7 100644 --- a/sys/fs/unionfs/union_subr.c +++ b/sys/fs/unionfs/union_subr.c @@ -57,6 +57,8 @@ #include #include +#include + #include #include @@ -435,6 +437,7 @@ unionfs_noderem(struct vnode *vp) struct vnode *uvp; struct vnode *dvp; int count; + int writerefs; KASSERT(vp->v_vnlock->lk_recurse == 0, ("%s: vnode %p locked recursively", __func__, vp)); @@ -454,13 +457,6 @@ unionfs_noderem(struct vnode *vp) vp->v_vnlock = &(vp->v_lock); vp->v_data = NULL; vp->v_object = NULL; - if (vp->v_writecount > 0) { - if (uvp != NULL) - VOP_ADD_WRITECOUNT(uvp, -vp->v_writecount); - else if (lvp != NULL) - VOP_ADD_WRITECOUNT(lvp, -vp->v_writecount); - } else if (vp->v_writecount < 0) - vp->v_writecount = 0; if (unp->un_hashtbl != NULL) { /* * Clear out any cached child vnodes. This should only @@ -479,6 +475,19 @@ unionfs_noderem(struct vnode *vp) } VI_UNLOCK(vp); + writerefs = atomic_load_int(&vp->v_writecount); + VNASSERT(writerefs >= 0, vp, + ("%s: write count %d, unexpected text ref", __func__, writerefs)); + /* + * If we were opened for write, we leased the write reference + * to the lower vnode. If this is a reclamation due to the + * forced unmount, undo the reference now. + */ + if (writerefs > 0) { + VNASSERT(uvp != NULL, vp, + ("%s: write reference without upper vnode", __func__)); + VOP_ADD_WRITECOUNT(uvp, -writerefs); + } if (lvp != NULLVP) VOP_UNLOCK(lvp); if (uvp != NULLVP) @@ -805,6 +814,8 @@ unionfs_node_update(struct unionfs_node *unp, struct vnode *uvp, ASSERT_VOP_ELOCKED(uvp, __func__); dvp = unp->un_dvp; + VNASSERT(vp->v_writecount == 0, vp, + ("%s: non-zero writecount", __func__)); /* * Uppdate the upper vnode's lock state to match the lower vnode, * and then switch the unionfs vnode's lock to the upper vnode. diff --git a/sys/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c index 6cedfa3d142d..dc02e20f376f 100644 --- a/sys/fs/unionfs/union_vnops.c +++ b/sys/fs/unionfs/union_vnops.c @@ -61,6 +61,8 @@ #include +#include + #include #include #include @@ -2523,26 +2525,28 @@ unionfs_add_writecount(struct vop_add_writecount_args *ap) { struct vnode *tvp, *vp; struct unionfs_node *unp; - int error; + int error, writerefs; vp = ap->a_vp; unp = VTOUNIONFS(vp); - tvp = unp->un_uppervp != NULL ? unp->un_uppervp : unp->un_lowervp; - VI_LOCK(vp); + tvp = unp->un_uppervp; + KASSERT(tvp != NULL, + ("%s: adding write ref without upper vnode", __func__)); + error = VOP_ADD_WRITECOUNT(tvp, ap->a_inc); + if (error != 0) + return (error); + /* + * We need to track the write refs we've passed to the underlying + * vnodes so that we can undo them in case we are forcibly unmounted. + */ + writerefs = atomic_fetchadd_int(&vp->v_writecount, ap->a_inc); /* text refs are bypassed to lowervp */ - VNASSERT(vp->v_writecount >= 0, vp, ("wrong null writecount")); - VNASSERT(vp->v_writecount + ap->a_inc >= 0, vp, - ("wrong writecount inc %d", ap->a_inc)); - if (tvp != NULL) - error = VOP_ADD_WRITECOUNT(tvp, ap->a_inc); - else if (vp->v_writecount < 0) - error = ETXTBSY; - else - error = 0; - if (error == 0) - vp->v_writecount += ap->a_inc; - VI_UNLOCK(vp); - return (error); + VNASSERT(writerefs >= 0, vp, + ("%s: invalid write count %d", __func__, writerefs)); + VNASSERT(writerefs + ap->a_inc >= 0, vp, + ("%s: invalid write count inc %d + %d", __func__, + writerefs, ap->a_inc)); + return (0); } static int