git: ec1f285f2e63 - main - nfscl: Add support for the NFSv4.1/4.2 WANT_xxx flags
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 12 Jun 2024 23:12:36 UTC
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=ec1f285f2e631b8aae3e08b3f68c6451a45c0941 commit ec1f285f2e631b8aae3e08b3f68c6451a45c0941 Author: Rick Macklem <rmacklem@FreeBSD.org> AuthorDate: 2024-06-12 23:11:10 +0000 Commit: Rick Macklem <rmacklem@FreeBSD.org> CommitDate: 2024-06-12 23:11:10 +0000 nfscl: Add support for the NFSv4.1/4.2 WANT_xxx flags NFSv4.1/4.2 defined new OPEN_WANT_xxx flags that a client can use to hint to the server that delegations are or are not wanted. This patch adds use of those delegations to the client. This patch should only affect the NFSv4.1/4.2 behaviour when delegations are enabled, which is not the default. MFC after: 1 month --- sys/fs/nfsclient/nfs_clrpcops.c | 77 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 9 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 8c5532268287..13bdc74655dd 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -389,13 +389,24 @@ nfsrpc_open(vnode_t vp, int amode, struct ucred *cred, NFSPROC_T *p) mode |= NFSV4OPEN_ACCESSREAD; if (amode & FWRITE) mode |= NFSV4OPEN_ACCESSWRITE; + if (NFSHASNFSV4N(nmp)) { + if (!NFSHASPNFS(nmp) && nfscl_enablecallb != 0 && + nfs_numnfscbd > 0) { + if ((mode & NFSV4OPEN_ACCESSWRITE) != 0) + mode |= NFSV4OPEN_WANTWRITEDELEG; + else + mode |= NFSV4OPEN_WANTANYDELEG; + } else + mode |= NFSV4OPEN_WANTNODELEG; + } nfhp = np->n_fhp; retrycnt = 0; do { dp = NULL; - error = nfscl_open(vp, nfhp->nfh_fh, nfhp->nfh_len, mode, 1, - cred, p, NULL, &op, &newone, &ret, 1, true); + error = nfscl_open(vp, nfhp->nfh_fh, nfhp->nfh_len, + (mode & NFSV4OPEN_ACCESSBOTH), 1, cred, p, NULL, + &op, &newone, &ret, 1, true); if (error) { return (error); } @@ -547,7 +558,8 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen, cred); NFSM_BUILD(tl, u_int32_t *, 5 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(op->nfso_own->nfsow_seqid); - *tl++ = txdr_unsigned(mode & NFSV4OPEN_ACCESSBOTH); + *tl++ = txdr_unsigned(mode & (NFSV4OPEN_ACCESSBOTH | + NFSV4OPEN_WANTDELEGMASK)); *tl++ = txdr_unsigned((mode >> NFSLCK_SHIFT) & NFSV4OPEN_DENYBOTH); tsep = nfsmnt_mdssession(nmp); *tl++ = tsep->nfsess_clientid.lval[0]; @@ -664,6 +676,13 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen, &ret, &acesize, p); if (error) goto nfsmout; + } else if (deleg == NFSV4OPEN_DELEGATENONEEXT && + NFSHASNFSV4N(nmp)) { + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + deleg = fxdr_unsigned(uint32_t, *tl); + if (deleg == NFSV4OPEN_CONTENTION || + deleg == NFSV4OPEN_RESOURCE) + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); } else if (deleg != NFSV4OPEN_DELEGATENONE) { error = NFSERR_BADXDR; goto nfsmout; @@ -1546,7 +1565,7 @@ nfsrpc_lookup(vnode_t dvp, char *name, int len, struct ucred *cred, NFSM_BUILD(tl, uint32_t *, 6 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(NFSV4OP_OPEN); *tl++ = 0; /* seqid, ignored. */ - *tl++ = txdr_unsigned(openmode); + *tl++ = txdr_unsigned(openmode | NFSV4OPEN_WANTNODELEG); *tl++ = txdr_unsigned(NFSV4OPEN_DENYNONE); *tl++ = 0; /* ClientID, ignored. */ *tl = 0; @@ -1668,6 +1687,13 @@ nfsrpc_lookup(vnode_t dvp, char *name, int len, struct ucred *cred, ndp->nfsdl_stateid.other[0] = *tl++; ndp->nfsdl_stateid.other[1] = *tl++; ndp->nfsdl_stateid.other[2] = *tl++; + } else if (deleg == NFSV4OPEN_DELEGATENONEEXT && + NFSHASNFSV4N(nmp)) { + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + deleg = fxdr_unsigned(uint32_t, *tl); + if (deleg == NFSV4OPEN_CONTENTION || + deleg == NFSV4OPEN_RESOURCE) + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); } else if (deleg != NFSV4OPEN_DELEGATENONE) { error = NFSERR_BADXDR; goto nfsmout; @@ -2595,8 +2621,17 @@ nfsrpc_createv4(vnode_t dvp, char *name, int namelen, struct vattr *vap, */ NFSM_BUILD(tl, u_int32_t *, 5 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(owp->nfsow_seqid); - *tl++ = txdr_unsigned(NFSV4OPEN_ACCESSWRITE | - NFSV4OPEN_ACCESSREAD); + if (NFSHASNFSV4N(nmp)) { + if (!NFSHASPNFS(nmp) && nfscl_enablecallb != 0 && + nfs_numnfscbd > 0) + *tl++ = txdr_unsigned(NFSV4OPEN_ACCESSWRITE | + NFSV4OPEN_ACCESSREAD | NFSV4OPEN_WANTWRITEDELEG); + else + *tl++ = txdr_unsigned(NFSV4OPEN_ACCESSWRITE | + NFSV4OPEN_ACCESSREAD | NFSV4OPEN_WANTNODELEG); + } else + *tl++ = txdr_unsigned(NFSV4OPEN_ACCESSWRITE | + NFSV4OPEN_ACCESSREAD); *tl++ = txdr_unsigned(NFSV4OPEN_DENYNONE); tsep = nfsmnt_mdssession(nmp); *tl++ = tsep->nfsess_clientid.lval[0]; @@ -2714,6 +2749,13 @@ nfsrpc_createv4(vnode_t dvp, char *name, int namelen, struct vattr *vap, &ret, &acesize, p); if (error) goto nfsmout; + } else if (deleg == NFSV4OPEN_DELEGATENONEEXT && + NFSHASNFSV4N(nmp)) { + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + deleg = fxdr_unsigned(uint32_t, *tl); + if (deleg == NFSV4OPEN_CONTENTION || + deleg == NFSV4OPEN_RESOURCE) + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); } else if (deleg != NFSV4OPEN_DELEGATENONE) { error = NFSERR_BADXDR; goto nfsmout; @@ -8109,7 +8151,8 @@ nfsrpc_openlayoutrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, 0, 0, cred); NFSM_BUILD(tl, uint32_t *, 5 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(op->nfso_own->nfsow_seqid); - *tl++ = txdr_unsigned(mode & NFSV4OPEN_ACCESSBOTH); + *tl++ = txdr_unsigned(mode & (NFSV4OPEN_ACCESSBOTH | + NFSV4OPEN_WANTDELEGMASK)); *tl++ = txdr_unsigned((mode >> NFSLCK_SHIFT) & NFSV4OPEN_DENYBOTH); tsep = nfsmnt_mdssession(nmp); *tl++ = tsep->nfsess_clientid.lval[0]; @@ -8210,6 +8253,13 @@ nfsrpc_openlayoutrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, &ret, &acesize, p); if (error != 0) goto nfsmout; + } else if (deleg == NFSV4OPEN_DELEGATENONEEXT && + NFSHASNFSV4N(nmp)) { + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + deleg = fxdr_unsigned(uint32_t, *tl); + if (deleg == NFSV4OPEN_CONTENTION || + deleg == NFSV4OPEN_RESOURCE) + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); } else if (deleg != NFSV4OPEN_DELEGATENONE) { error = NFSERR_BADXDR; goto nfsmout; @@ -8301,8 +8351,17 @@ nfsrpc_createlayout(vnode_t dvp, char *name, int namelen, struct vattr *vap, */ NFSM_BUILD(tl, u_int32_t *, 5 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(owp->nfsow_seqid); - *tl++ = txdr_unsigned(NFSV4OPEN_ACCESSWRITE | - NFSV4OPEN_ACCESSREAD); + if (NFSHASNFSV4N(nmp)) { + if (!NFSHASPNFS(nmp) && nfscl_enablecallb != 0 && + nfs_numnfscbd > 0) + *tl++ = txdr_unsigned(NFSV4OPEN_ACCESSWRITE | + NFSV4OPEN_ACCESSREAD | NFSV4OPEN_WANTWRITEDELEG); + else + *tl++ = txdr_unsigned(NFSV4OPEN_ACCESSWRITE | + NFSV4OPEN_ACCESSREAD | NFSV4OPEN_WANTNODELEG); + } else + *tl++ = txdr_unsigned(NFSV4OPEN_ACCESSWRITE | + NFSV4OPEN_ACCESSREAD); *tl++ = txdr_unsigned(NFSV4OPEN_DENYNONE); tsep = nfsmnt_mdssession(nmp); *tl++ = tsep->nfsess_clientid.lval[0];