Date: Sun, 17 Jul 2011 20:49:39 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r224149 - in stable/8/sys/fs: nfs nfsclient Message-ID: <201107172049.p6HKndJj089602@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Sun Jul 17 20:49:38 2011 New Revision: 224149 URL: http://svn.freebsd.org/changeset/base/224149 Log: MFC: r223747 Modify the new NFSv4 client so that it appends a file handle to the lock_owner4 string that goes on the wire. Also, add code to do a ReleaseLockOwner Op on the lock_owner4 string before a Close. Apparently not all NFSv4 servers handle multiple instances of the same lock_owner4 string, at least not in a compatible way. This patch avoids having multiple instances, except for one unusual case, which will be fixed by a future commit. Found at the recent NFSv4 interoperability Bakeathon. Modified: stable/8/sys/fs/nfs/nfs_var.h stable/8/sys/fs/nfsclient/nfs_clrpcops.c stable/8/sys/fs/nfsclient/nfs_clstate.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/fs/nfs/nfs_var.h ============================================================================== --- stable/8/sys/fs/nfs/nfs_var.h Sun Jul 17 20:47:34 2011 (r224148) +++ stable/8/sys/fs/nfs/nfs_var.h Sun Jul 17 20:49:38 2011 (r224149) @@ -438,6 +438,7 @@ int nfscl_getcl(vnode_t, struct ucred *, struct nfsclclient *nfscl_findcl(struct nfsmount *); void nfscl_clientrelease(struct nfsclclient *); void nfscl_freelock(struct nfscllock *, int); +void nfscl_freelockowner(struct nfscllockowner *, int); int nfscl_getbytelock(vnode_t, u_int64_t, u_int64_t, short, struct ucred *, NFSPROC_T *, struct nfsclclient *, int, void *, int, u_int8_t *, u_int8_t *, struct nfscllockowner **, int *, int *); Modified: stable/8/sys/fs/nfsclient/nfs_clrpcops.c ============================================================================== --- stable/8/sys/fs/nfsclient/nfs_clrpcops.c Sun Jul 17 20:47:34 2011 (r224148) +++ stable/8/sys/fs/nfsclient/nfs_clrpcops.c Sun Jul 17 20:49:38 2011 (r224149) @@ -585,7 +585,7 @@ APPLESTATIC void nfsrpc_doclose(struct nfsmount *nmp, struct nfsclopen *op, NFSPROC_T *p) { struct nfsrv_descript nfsd, *nd = &nfsd; - struct nfscllockowner *lp; + struct nfscllockowner *lp, *nlp; struct nfscllock *lop, *nlop; struct ucred *tcred; u_int64_t off = 0, len = 0; @@ -642,6 +642,14 @@ nfsrpc_doclose(struct nfsmount *nmp, str } nfscl_freelock(lop, 0); } + /* + * Do a ReleaseLockOwner. + * The lock owner name nfsl_owner may be used by other opens for + * other files but the lock_owner4 name that nfsrpc_rellockown() + * puts on the wire has the file handle for this file appended + * to it, so it can be done now. + */ + (void)nfsrpc_rellockown(nmp, lp, tcred, p); } /* @@ -659,20 +667,8 @@ nfsrpc_doclose(struct nfsmount *nmp, str NFSLOCKCLSTATE(); nfscl_lockunlock(&op->nfso_own->nfsow_rwlock); - /* - * Move the lockowner to nfsc_defunctlockowner, - * so the Renew thread will do the ReleaseLockOwner - * Op on it later. There might still be other - * opens using the same lockowner name. - */ - lp = LIST_FIRST(&op->nfso_lock); - if (lp != NULL) { - while (LIST_NEXT(lp, nfsl_list) != NULL) - lp = LIST_NEXT(lp, nfsl_list); - LIST_PREPEND(&nmp->nm_clp->nfsc_defunctlockowner, - &op->nfso_lock, lp, nfsl_list); - LIST_INIT(&op->nfso_lock); - } + LIST_FOREACH_SAFE(lp, &op->nfso_lock, nfsl_list, nlp) + nfscl_freelockowner(lp, 0); nfscl_freeopen(op, 0); NFSUNLOCKCLSTATE(); NFSFREECRED(tcred); @@ -3629,7 +3625,8 @@ nfsrpc_lockt(struct nfsrv_descript *nd, { u_int32_t *tl; int error, type, size; - u_int8_t own[NFSV4CL_LOCKNAMELEN]; + uint8_t own[NFSV4CL_LOCKNAMELEN + NFSX_V4FHMAX]; + struct nfsnode *np; NFSCL_REQSTART(nd, NFSPROC_LOCKT, vp); NFSM_BUILD(tl, u_int32_t *, 7 * NFSX_UNSIGNED); @@ -3644,7 +3641,10 @@ nfsrpc_lockt(struct nfsrv_descript *nd, *tl++ = clp->nfsc_clientid.lval[0]; *tl = clp->nfsc_clientid.lval[1]; nfscl_filllockowner(id, own, flags); - (void) nfsm_strtom(nd, own, NFSV4CL_LOCKNAMELEN); + np = VTONFS(vp); + NFSBCOPY(np->n_fhp->nfh_fh, &own[NFSV4CL_LOCKNAMELEN], + np->n_fhp->nfh_len); + (void)nfsm_strtom(nd, own, NFSV4CL_LOCKNAMELEN + np->n_fhp->nfh_len); error = nfscl_request(nd, vp, p, cred, NULL); if (error) return (error); @@ -3744,6 +3744,7 @@ nfsrpc_lock(struct nfsrv_descript *nd, s { u_int32_t *tl; int error, size; + uint8_t own[NFSV4CL_LOCKNAMELEN + NFSX_V4FHMAX]; nfscl_reqstart(nd, NFSPROC_LOCK, nmp, nfhp, fhlen, NULL); NFSM_BUILD(tl, u_int32_t *, 7 * NFSX_UNSIGNED); @@ -3768,7 +3769,9 @@ nfsrpc_lock(struct nfsrv_descript *nd, s *tl++ = txdr_unsigned(lp->nfsl_seqid); *tl++ = lp->nfsl_open->nfso_own->nfsow_clp->nfsc_clientid.lval[0]; *tl = lp->nfsl_open->nfso_own->nfsow_clp->nfsc_clientid.lval[1]; - (void) nfsm_strtom(nd, lp->nfsl_owner, NFSV4CL_LOCKNAMELEN); + NFSBCOPY(lp->nfsl_owner, own, NFSV4CL_LOCKNAMELEN); + NFSBCOPY(nfhp, &own[NFSV4CL_LOCKNAMELEN], fhlen); + (void)nfsm_strtom(nd, own, NFSV4CL_LOCKNAMELEN + fhlen); } else { *tl = newnfs_false; NFSM_BUILD(tl, u_int32_t *, NFSX_STATEID + NFSX_UNSIGNED); @@ -4029,12 +4032,17 @@ nfsrpc_rellockown(struct nfsmount *nmp, struct nfsrv_descript nfsd, *nd = &nfsd; u_int32_t *tl; int error; + uint8_t own[NFSV4CL_LOCKNAMELEN + NFSX_V4FHMAX]; nfscl_reqstart(nd, NFSPROC_RELEASELCKOWN, nmp, NULL, 0, NULL); NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); *tl++ = nmp->nm_clp->nfsc_clientid.lval[0]; *tl = nmp->nm_clp->nfsc_clientid.lval[1]; - (void) nfsm_strtom(nd, lp->nfsl_owner, NFSV4CL_LOCKNAMELEN); + NFSBCOPY(lp->nfsl_owner, own, NFSV4CL_LOCKNAMELEN); + NFSBCOPY(lp->nfsl_open->nfso_fh, &own[NFSV4CL_LOCKNAMELEN], + lp->nfsl_open->nfso_fhlen); + (void)nfsm_strtom(nd, own, NFSV4CL_LOCKNAMELEN + + lp->nfsl_open->nfso_fhlen); nd->nd_flag |= ND_USEGSSNAME; error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred, NFS_PROG, NFS_VER4, NULL, 1, NULL); Modified: stable/8/sys/fs/nfsclient/nfs_clstate.c ============================================================================== --- stable/8/sys/fs/nfsclient/nfs_clstate.c Sun Jul 17 20:47:34 2011 (r224148) +++ stable/8/sys/fs/nfsclient/nfs_clstate.c Sun Jul 17 20:49:38 2011 (r224149) @@ -114,7 +114,6 @@ static struct nfscldeleg *nfscl_finddele int); static int nfscl_checkconflict(struct nfscllockownerhead *, struct nfscllock *, u_int8_t *, struct nfscllock **); -static void nfscl_freelockowner(struct nfscllockowner *, int); static void nfscl_freealllocks(struct nfscllockownerhead *, int); static int nfscl_localconflict(struct nfsclclient *, u_int8_t *, int, struct nfscllock *, u_int8_t *, struct nfscldeleg *, struct nfscllock **); @@ -1450,7 +1449,7 @@ nfscl_freeopenowner(struct nfsclowner *o /* * Free up a byte range lock owner structure. */ -static void +APPLESTATIC void nfscl_freelockowner(struct nfscllockowner *lp, int local) { struct nfscllock *lop, *nlop;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201107172049.p6HKndJj089602>