Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 5 Nov 2010 02:12:18 +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: r214819 - in stable/8/sys/fs: nfs nfsclient
Message-ID:  <201011050212.oA52CIQD080481@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Fri Nov  5 02:12:18 2010
New Revision: 214819
URL: http://svn.freebsd.org/changeset/base/214819

Log:
  MFC: r214406
  Add a flag to the experimental NFSv4 client to indicate when
  delegations are being returned for reasons other than a Recall.
  Also, re-organize nfscl_recalldeleg() slightly, so that it leaves
  clearing NMODIFIED to the ncl_flush() call and invalidates the
  attribute cache after flushing. It is hoped that these changes
  might fix the problem others have seen when using the NFSv4
  client with delegations enabled, since I can't reliably reproduce
  the problem. These changes only affect the client when doing NFSv4
  mounts with delegations enabled.

Modified:
  stable/8/sys/fs/nfs/nfsclstate.h
  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)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/fs/nfs/nfsclstate.h
==============================================================================
--- stable/8/sys/fs/nfs/nfsclstate.h	Fri Nov  5 01:50:18 2010	(r214818)
+++ stable/8/sys/fs/nfs/nfsclstate.h	Fri Nov  5 02:12:18 2010	(r214819)
@@ -118,6 +118,7 @@ struct nfscldeleg {
 #define	NFSCLDL_NEEDRECLAIM	0x08
 #define	NFSCLDL_ZAPPED		0x10
 #define	NFSCLDL_MODTIMESET	0x20
+#define	NFSCLDL_DELEGRET	0x40
 
 /*
  * MALLOC'd to the correct length to accommodate the file handle.

Modified: stable/8/sys/fs/nfsclient/nfs_clstate.c
==============================================================================
--- stable/8/sys/fs/nfsclient/nfs_clstate.c	Fri Nov  5 01:50:18 2010	(r214818)
+++ stable/8/sys/fs/nfsclient/nfs_clstate.c	Fri Nov  5 02:12:18 2010	(r214819)
@@ -929,8 +929,10 @@ nfscl_getbytelock(vnode_t vp, u_int64_t 
 		ldp = dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh,
 		    np->n_fhp->nfh_len);
 		/* Just sanity check for correct type of delegation */
-		if (dp != NULL && ((dp->nfsdl_flags & NFSCLDL_RECALL) ||
-		    (type == F_WRLCK && !(dp->nfsdl_flags & NFSCLDL_WRITE))))
+		if (dp != NULL && ((dp->nfsdl_flags &
+		    (NFSCLDL_RECALL | NFSCLDL_DELEGRET)) != 0 ||
+		     (type == F_WRLCK &&
+		      (dp->nfsdl_flags & NFSCLDL_WRITE) == 0)))
 			dp = NULL;
 	}
 	if (dp != NULL) {
@@ -2495,8 +2497,8 @@ tryagain:
 		    if (dp->nfsdl_rwlock.nfslock_usecnt == 0 &&
 			dp->nfsdl_rwlock.nfslock_lock == 0 &&
 			dp->nfsdl_timestamp < NFSD_MONOSEC &&
-			!(dp->nfsdl_flags & (NFSCLDL_RECALL | NFSCLDL_ZAPPED |
-			  NFSCLDL_NEEDRECLAIM))) {
+			(dp->nfsdl_flags & (NFSCLDL_RECALL | NFSCLDL_ZAPPED |
+			  NFSCLDL_NEEDRECLAIM | NFSCLDL_DELEGRET)) == 0) {
 			clearok = 1;
 			LIST_FOREACH(owp, &dp->nfsdl_owner, nfsow_list) {
 			    op = LIST_FIRST(&owp->nfsow_open);
@@ -3086,7 +3088,8 @@ nfscl_docb(struct nfsrv_descript *nd, NF
 				if (clp != NULL) {
 					dp = nfscl_finddeleg(clp, nfhp->nfh_fh,
 					    nfhp->nfh_len);
-					if (dp != NULL) {
+					if (dp != NULL && (dp->nfsdl_flags &
+					    NFSCLDL_DELEGRET) == 0) {
 						dp->nfsdl_flags |=
 						    NFSCLDL_RECALL;
 						wakeup((caddr_t)clp);
@@ -3338,7 +3341,6 @@ nfscl_recalldeleg(struct nfsclclient *cl
 		np = VTONFS(vp);
 	}
 	dp->nfsdl_flags &= ~NFSCLDL_MODTIMESET;
-	NFSINVALATTRCACHE(np);
 
 	/*
 	 * Ok, if it's a write delegation, flush data to the server, so
@@ -3347,21 +3349,14 @@ nfscl_recalldeleg(struct nfsclclient *cl
 	ret = 0;
 	NFSLOCKNODE(np);
 	if ((dp->nfsdl_flags & NFSCLDL_WRITE) && (np->n_flag & NMODIFIED)) {
-#ifdef APPLE
-		OSBitOrAtomic((u_int32_t)NDELEGRECALL, (UInt32 *)&np->n_flag);
-#else
 		np->n_flag |= NDELEGRECALL;
-#endif
 		NFSUNLOCKNODE(np);
 		ret = ncl_flush(vp, MNT_WAIT, cred, p, 1,
 		    called_from_renewthread);
 		NFSLOCKNODE(np);
-#ifdef APPLE
-		OSBitAndAtomic((int32_t)~(NMODIFIED | NDELEGRECALL), (UInt32 *)&np->n_flag);
-#else
-		np->n_flag &= ~(NMODIFIED | NDELEGRECALL);
-#endif
+		np->n_flag &= ~NDELEGRECALL;
 	}
+	NFSINVALATTRCACHE(np);
 	NFSUNLOCKNODE(np);
 	if (ret == EIO && called_from_renewthread != 0) {
 		/*
@@ -3534,8 +3529,10 @@ nfscl_totalrecall(struct nfsclclient *cl
 {
 	struct nfscldeleg *dp;
 
-	TAILQ_FOREACH(dp, &clp->nfsc_deleg, nfsdl_list)
-		dp->nfsdl_flags |= NFSCLDL_RECALL;
+	TAILQ_FOREACH(dp, &clp->nfsc_deleg, nfsdl_list) {
+		if ((dp->nfsdl_flags & NFSCLDL_DELEGRET) == 0)
+			dp->nfsdl_flags |= NFSCLDL_RECALL;
+	}
 }
 
 /*
@@ -3754,8 +3751,9 @@ nfscl_mustflush(vnode_t vp)
 		return (1);
 	}
 	dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, np->n_fhp->nfh_len);
-	if (dp != NULL && (dp->nfsdl_flags & (NFSCLDL_WRITE | NFSCLDL_RECALL))
-	     == NFSCLDL_WRITE &&
+	if (dp != NULL && (dp->nfsdl_flags &
+	    (NFSCLDL_WRITE | NFSCLDL_RECALL | NFSCLDL_DELEGRET)) ==
+	     NFSCLDL_WRITE &&
 	    (dp->nfsdl_sizelimit >= np->n_size ||
 	     !NFSHASSTRICT3530(nmp))) {
 		NFSUNLOCKCLSTATE();
@@ -3787,9 +3785,10 @@ nfscl_nodeleg(vnode_t vp, int writedeleg
 		return (1);
 	}
 	dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, np->n_fhp->nfh_len);
-	if (dp != NULL && (dp->nfsdl_flags & NFSCLDL_RECALL) == 0 &&
-	    (writedeleg == 0 || (dp->nfsdl_flags & NFSCLDL_WRITE)
-	     == NFSCLDL_WRITE)) {
+	if (dp != NULL &&
+	    (dp->nfsdl_flags & (NFSCLDL_RECALL | NFSCLDL_DELEGRET)) == 0 &&
+	    (writedeleg == 0 || (dp->nfsdl_flags & NFSCLDL_WRITE) ==
+	     NFSCLDL_WRITE)) {
 		NFSUNLOCKCLSTATE();
 		return (0);
 	}
@@ -3860,6 +3859,7 @@ nfscl_removedeleg(vnode_t vp, NFSPROC_T 
 			}
 		    }
 		    if (needsrecall && !triedrecall) {
+			dp->nfsdl_flags |= NFSCLDL_DELEGRET;
 			islept = 0;
 			while (!igotlock) {
 			    igotlock = nfsv4_lock(&clp->nfsc_lock, 1,
@@ -3958,6 +3958,7 @@ nfscl_renamedeleg(vnode_t fvp, nfsv4stat
 			}
 		    }
 		    if (needsrecall && !triedrecall) {
+			dp->nfsdl_flags |= NFSCLDL_DELEGRET;
 			islept = 0;
 			while (!igotlock) {
 			    igotlock = nfsv4_lock(&clp->nfsc_lock, 1,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011050212.oA52CIQD080481>