Skip site navigation (1)Skip section navigation (2)
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>