changeset 10085:8d106fa92e56

6858854 jurassic panicked in rfs4_release_share_lock_state; fix for 6711844 suspected
author Robert Mastors <Robert.Mastors@Sun.COM>
date Tue, 14 Jul 2009 19:08:57 -0500
parents 783f82a0c357
children 23349e4f233b
files usr/src/uts/common/fs/nfs/nfs4_srv.c usr/src/uts/common/nfs/nfs4.h
diffstat 2 files changed, 53 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/fs/nfs/nfs4_srv.c	Tue Jul 14 18:57:32 2009 -0400
+++ b/usr/src/uts/common/fs/nfs/nfs4_srv.c	Tue Jul 14 19:08:57 2009 -0500
@@ -6676,6 +6676,21 @@
 		rfs4_recall_deleg(fp, FALSE, sp->rs_owner->ro_client);
 		delay(NFS4_DELEGATION_CONFLICT_DELAY);
 		rfs4_dbe_lock(sp->rs_dbe);
+
+		/* if state closed while lock was dropped */
+		if (sp->rs_closed) {
+			if (dmodes || amodes)
+				(void) rfs4_unshare(sp);
+			rfs4_dbe_unlock(sp->rs_dbe);
+			rfs4_file_rele(fp);
+			/* Not a fully formed open; "close" it */
+			if (screate == TRUE)
+				rfs4_state_close(sp, FALSE, FALSE, cs->cr);
+			rfs4_state_rele(sp);
+			resp->status = NFS4ERR_OLD_STATEID;
+			return;
+		}
+
 		rfs4_dbe_lock(fp->rf_dbe);
 		/* Let's see if the delegation was returned */
 		if (rfs4_check_recall(sp, access)) {
@@ -6743,6 +6758,7 @@
 			fflags |= FWRITE;
 		vn_open_upgrade(cs->vp, fflags);
 	}
+	sp->rs_opened = TRUE;
 
 	if (dmodes & OPEN4_SHARE_DENY_READ)
 		fp->rf_deny_read++;
@@ -8183,35 +8199,6 @@
 	int fflags = 0;
 
 	/*
-	 * Decrement the count for each access and deny bit that this
-	 * state has contributed to the file. If the file counts go to zero
-	 * clear the appropriate bit in the appropriate mask.
-	 */
-
-	if (sp->rs_share_access & OPEN4_SHARE_ACCESS_READ) {
-		fp->rf_access_read--;
-		fflags |= FREAD;
-		if (fp->rf_access_read == 0)
-			fp->rf_share_access &= ~OPEN4_SHARE_ACCESS_READ;
-	}
-	if (sp->rs_share_access & OPEN4_SHARE_ACCESS_WRITE) {
-		fp->rf_access_write--;
-		fflags |= FWRITE;
-		if (fp->rf_access_write == 0)
-			fp->rf_share_access &= ~OPEN4_SHARE_ACCESS_WRITE;
-	}
-	if (sp->rs_share_deny & OPEN4_SHARE_DENY_READ) {
-		fp->rf_deny_read--;
-		if (fp->rf_deny_read == 0)
-			fp->rf_share_deny &= ~OPEN4_SHARE_DENY_READ;
-	}
-	if (sp->rs_share_deny & OPEN4_SHARE_DENY_WRITE) {
-		fp->rf_deny_write--;
-		if (fp->rf_deny_write == 0)
-			fp->rf_share_deny &= ~OPEN4_SHARE_DENY_WRITE;
-	}
-
-	/*
 	 * If this call is part of the larger closing down of client
 	 * state then it is just easier to release all locks
 	 * associated with this client instead of going through each
@@ -8280,7 +8267,41 @@
 	if (sp->rs_owner->ro_client->rc_sysidt != LM_NOSYSID)
 		(void) rfs4_unshare(sp);
 
-	(void) VOP_CLOSE(fp->rf_vp, fflags, 1, (offset_t)0, cr, NULL);
+	if (sp->rs_opened) {
+		/*
+		 * Decrement the count for each access and deny bit that this
+		 * state has contributed to the file.
+		 * If the file counts go to zero
+		 * clear the appropriate bit in the appropriate mask.
+		 */
+		if (sp->rs_share_access & OPEN4_SHARE_ACCESS_READ) {
+			fp->rf_access_read--;
+			fflags |= FREAD;
+			if (fp->rf_access_read == 0)
+				fp->rf_share_access &= ~OPEN4_SHARE_ACCESS_READ;
+		}
+		if (sp->rs_share_access & OPEN4_SHARE_ACCESS_WRITE) {
+			fp->rf_access_write--;
+			fflags |= FWRITE;
+			if (fp->rf_access_write == 0)
+				fp->rf_share_access &=
+				    ~OPEN4_SHARE_ACCESS_WRITE;
+		}
+		if (sp->rs_share_deny & OPEN4_SHARE_DENY_READ) {
+			fp->rf_deny_read--;
+			if (fp->rf_deny_read == 0)
+				fp->rf_share_deny &= ~OPEN4_SHARE_DENY_READ;
+		}
+		if (sp->rs_share_deny & OPEN4_SHARE_DENY_WRITE) {
+			fp->rf_deny_write--;
+			if (fp->rf_deny_write == 0)
+				fp->rf_share_deny &= ~OPEN4_SHARE_DENY_WRITE;
+		}
+
+		(void) VOP_CLOSE(fp->rf_vp, fflags, 1, (offset_t)0, cr, NULL);
+
+		sp->rs_opened = FALSE;
+	}
 }
 
 /*
--- a/usr/src/uts/common/nfs/nfs4.h	Tue Jul 14 18:57:32 2009 -0400
+++ b/usr/src/uts/common/nfs/nfs4.h	Tue Jul 14 19:08:57 2009 -0500
@@ -545,6 +545,7 @@
  * finfo - reference to the open file for this state
  * share_access - how did the openowner OPEN the file (access)
  * share_deny - how did the openowner OPEN the file (deny)
+ * opened - has VOP_OPEN been done
  * closed - has this file been closed?
  * lostatelist - root of list of lo_state associated with this state/file
  * node - node for state struct list of states
@@ -556,6 +557,7 @@
 	struct rfs4_file	*rs_finfo;
 	uint32_t		rs_share_access;
 	uint32_t		rs_share_deny;
+	unsigned		rs_opened:1;
 	unsigned		rs_closed:1;
 	list_t			rs_lostatelist;
 	list_node_t		rs_node;