From nobody Fri Nov 19 00:00:30 2021 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 517F9188E936; Fri, 19 Nov 2021 00:00:30 +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 4HwGyQ1cl3z4v6X; Fri, 19 Nov 2021 00:00:30 +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 188C31E0BE; Fri, 19 Nov 2021 00:00:30 +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 1AJ00UEZ067629; Fri, 19 Nov 2021 00:00:30 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1AJ00UCC067628; Fri, 19 Nov 2021 00:00:30 GMT (envelope-from git) Date: Fri, 19 Nov 2021 00:00:30 GMT Message-Id: <202111190000.1AJ00UCC067628@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Rick Macklem Subject: git: 82d04e93821d - stable/12 - nfscl: Do pNFS layout return_on_close synchronously 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: rmacklem X-Git-Repository: src X-Git-Refname: refs/heads/stable/12 X-Git-Reftype: branch X-Git-Commit: 82d04e93821d537ab5776c90f73855d5b0367b13 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=82d04e93821d537ab5776c90f73855d5b0367b13 commit 82d04e93821d537ab5776c90f73855d5b0367b13 Author: Rick Macklem AuthorDate: 2021-10-31 23:31:31 +0000 Commit: Rick Macklem CommitDate: 2021-11-18 23:55:39 +0000 nfscl: Do pNFS layout return_on_close synchronously For pNFS servers that specify that Layouts are to be returned upon close, they may expect that LayoutReturn to happen before the associated Close. This patch modifies the NFSv4.1/4.2 pNFS client so that this is done. This only affects a pNFS mount against a non-FreeBSD NFSv4.1/4.2 server that specifies return_on_close in LayoutGet replies. Found during a recent IETF NFSv4 working group testing event. (cherry picked from commit d5d2ce1c8550a41e7374893ccd864c172461221f) --- sys/fs/nfs/nfsclstate.h | 1 + sys/fs/nfsclient/nfs_clstate.c | 63 ++++++++++++++++++++++++++++++------------ 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/sys/fs/nfs/nfsclstate.h b/sys/fs/nfs/nfsclstate.h index 2ada4bfc5540..7f10c058697a 100644 --- a/sys/fs/nfs/nfsclstate.h +++ b/sys/fs/nfs/nfsclstate.h @@ -263,6 +263,7 @@ struct nfscllayout { #define NFSLY_RETONCLOSE 0x0080 #define NFSLY_WRITTEN 0x0100 /* Has been used to write to a DS. */ #define NFSLY_FLEXFILE 0x0200 +#define NFSLY_RETURNED 0x0400 /* * Flex file layout mirror specific stuff for nfsclflayout. diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index 9bd9b8759c51..279f7e38c346 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -122,7 +122,7 @@ static struct nfsclclient *nfscl_getclntsess(uint8_t *); static struct nfscldeleg *nfscl_finddeleg(struct nfsclclient *, u_int8_t *, int); static void nfscl_retoncloselayout(vnode_t, struct nfsclclient *, uint8_t *, - int, struct nfsclrecalllayout **); + int, struct nfsclrecalllayout **, struct nfscllayout **); static void nfscl_reldevinfo_locked(struct nfscldevinfo *); static struct nfscllayout *nfscl_findlayout(struct nfsclclient *, u_int8_t *, int); @@ -2817,7 +2817,8 @@ tryagain2: while (lyp != NULL) { nlyp = TAILQ_PREV(lyp, nfscllayouthead, nfsly_list); if (lyp->nfsly_timestamp < NFSD_MONOSEC && - (lyp->nfsly_flags & NFSLY_RECALL) == 0 && + (lyp->nfsly_flags & (NFSLY_RECALL | + NFSLY_RETONCLOSE)) == 0 && lyp->nfsly_lock.nfslock_usecnt == 0 && lyp->nfsly_lock.nfslock_lock == 0) { NFSCL_DEBUG(4, "ret stale lay=%d\n", @@ -2852,7 +2853,13 @@ tryagain2: TAILQ_REMOVE(&rlh, lyp, nfsly_list); NFSCL_DEBUG(4, "ret layout\n"); nfscl_layoutreturn(clp->nfsc_nmp, lyp, cred, p); - nfscl_freelayout(lyp); + if ((lyp->nfsly_flags & NFSLY_RETONCLOSE) != 0) { + NFSLOCKCLSTATE(); + lyp->nfsly_flags |= NFSLY_RETURNED; + wakeup(lyp); + NFSUNLOCKCLSTATE(); + } else + nfscl_freelayout(lyp); } /* @@ -3217,6 +3224,7 @@ nfscl_doclose(vnode_t vp, struct nfsclclient **clpp, NFSPROC_T *p) struct nfscldeleg *dp; struct nfsfh *nfhp; struct nfsclrecalllayout *recallp; + struct nfscllayout *lyp; int error; error = nfscl_getcl(vnode_mount(vp), NULL, NULL, 1, true, &clp); @@ -3245,7 +3253,8 @@ nfscl_doclose(vnode_t vp, struct nfsclclient **clpp, NFSPROC_T *p) } /* Return any layouts marked return on close. */ - nfscl_retoncloselayout(vp, clp, nfhp->nfh_fh, nfhp->nfh_len, &recallp); + nfscl_retoncloselayout(vp, clp, nfhp->nfh_fh, nfhp->nfh_len, &recallp, + &lyp); /* Now process the opens against the server. */ lookformore: @@ -3268,6 +3277,20 @@ lookformore: } } nfscl_clrelease(clp); + + /* Now, wait for any layout that is returned upon close. */ + if (lyp != NULL) { + while ((lyp->nfsly_flags & NFSLY_RETURNED) == 0) { + if (NFSCL_FORCEDISM(vnode_mount(vp))) { + lyp = NULL; + break; + } + msleep(lyp, NFSCLSTATEMUTEXPTR, PZERO, "nfslroc", hz); + } + if (lyp != NULL) + nfscl_freelayout(lyp); + } + NFSUNLOCKCLSTATE(); /* * recallp has been set NULL by nfscl_retoncloselayout() if it was @@ -5054,28 +5077,34 @@ nfscl_getlayout(struct nfsclclient *clp, uint8_t *fhp, int fhlen, */ static void nfscl_retoncloselayout(vnode_t vp, struct nfsclclient *clp, uint8_t *fhp, - int fhlen, struct nfsclrecalllayout **recallpp) + int fhlen, struct nfsclrecalllayout **recallpp, struct nfscllayout **lypp) { struct nfscllayout *lyp; uint32_t iomode; + *lypp = NULL; if (vp->v_type != VREG || !NFSHASPNFS(VFSTONFS(vnode_mount(vp))) || nfscl_enablecallb == 0 || nfs_numnfscbd == 0 || (VTONFS(vp)->n_flag & NNOLAYOUT) != 0) return; lyp = nfscl_findlayout(clp, fhp, fhlen); - if (lyp != NULL && (lyp->nfsly_flags & (NFSLY_RETONCLOSE | - NFSLY_RECALL)) == NFSLY_RETONCLOSE) { - iomode = 0; - if (!LIST_EMPTY(&lyp->nfsly_flayread)) - iomode |= NFSLAYOUTIOMODE_READ; - if (!LIST_EMPTY(&lyp->nfsly_flayrw)) - iomode |= NFSLAYOUTIOMODE_RW; - (void)nfscl_layoutrecall(NFSLAYOUTRETURN_FILE, lyp, iomode, - 0, UINT64_MAX, lyp->nfsly_stateid.seqid, 0, 0, NULL, - *recallpp); - NFSCL_DEBUG(4, "retoncls recall iomode=%d\n", iomode); - *recallpp = NULL; + if (lyp != NULL && (lyp->nfsly_flags & NFSLY_RETONCLOSE) != 0) { + if ((lyp->nfsly_flags & NFSLY_RECALL) == 0) { + iomode = 0; + if (!LIST_EMPTY(&lyp->nfsly_flayread)) + iomode |= NFSLAYOUTIOMODE_READ; + if (!LIST_EMPTY(&lyp->nfsly_flayrw)) + iomode |= NFSLAYOUTIOMODE_RW; + nfscl_layoutrecall(NFSLAYOUTRETURN_FILE, lyp, iomode, + 0, UINT64_MAX, lyp->nfsly_stateid.seqid, 0, 0, NULL, + *recallpp); + NFSCL_DEBUG(4, "retoncls recall iomode=%d\n", iomode); + *recallpp = NULL; + } + + /* Now, wake up renew thread to do LayoutReturn. */ + wakeup(clp); + *lypp = lyp; } }