6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
authorshepler
Mon, 11 Jul 2005 17:12:14 -0700
changeset 154 7a745d3804a2
parent 153 b7f7b242faa2
child 155 585e2e169bd6
6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove 6263280 ::svc_pool does not work 6265027 rpc destroys a CV with waiters
usr/src/uts/common/fs/nfs/nfs4_srv.c
usr/src/uts/common/rpc/clnt_cots.c
--- a/usr/src/uts/common/fs/nfs/nfs4_srv.c	Mon Jul 11 11:11:42 2005 -0700
+++ b/usr/src/uts/common/fs/nfs/nfs4_srv.c	Mon Jul 11 17:12:14 2005 -0700
@@ -3709,20 +3709,30 @@
 		if ((error = VOP_REMOVE(dvp, nm, cs->cr)) == 0 &&
 			fp != NULL) {
 			struct vattr va;
-
-			/*
-			 * This is va_seq safe because we are not
-			 * manipulating dvp.
-			 */
-			va.va_mask = AT_NLINK;
-			if (!VOP_GETATTR(fp->vp, &va, 0, cs->cr) &&
-				va.va_nlink == 0) {
-				/* The file is gone and so should the state */
-				if (in_crit) {
-					nbl_end_crit(vp);
-					in_crit = 0;
+			vnode_t *tvp;
+
+			rfs4_dbe_lock(fp->dbe);
+			tvp = fp->vp;
+			if (tvp)
+				VN_HOLD(tvp);
+			rfs4_dbe_unlock(fp->dbe);
+
+			if (tvp) {
+				/*
+				 * This is va_seq safe because we are not
+				 * manipulating dvp.
+				 */
+				va.va_mask = AT_NLINK;
+				if (!VOP_GETATTR(tvp, &va, 0, cs->cr) &&
+					va.va_nlink == 0) {
+					/* Remove state on file remove */
+					if (in_crit) {
+						nbl_end_crit(vp);
+						in_crit = 0;
+					}
+					rfs4_close_all_state(fp);
 				}
-				rfs4_close_all_state(fp);
+				VN_RELE(tvp);
 			}
 		}
 	}
@@ -3968,16 +3978,26 @@
 	if ((error = VOP_RENAME(odvp, onm, ndvp, nnm, cs->cr)) == 0 &&
 		fp != NULL) {
 		struct vattr va;
-
-		va.va_mask = AT_NLINK;
-		if (!VOP_GETATTR(fp->vp, &va, 0, cs->cr) &&
-			va.va_nlink == 0) {
-			/* The file is gone and so should the state */
-			if (in_crit_targ) {
-				nbl_end_crit(targvp);
-				in_crit_targ = 0;
+		vnode_t *tvp;
+
+		rfs4_dbe_lock(fp->dbe);
+		tvp = fp->vp;
+		if (tvp)
+			VN_HOLD(tvp);
+		rfs4_dbe_unlock(fp->dbe);
+
+		if (tvp) {
+			va.va_mask = AT_NLINK;
+			if (!VOP_GETATTR(tvp, &va, 0, cs->cr) &&
+				va.va_nlink == 0) {
+				/* The file is gone and so should the state */
+				if (in_crit_targ) {
+					nbl_end_crit(targvp);
+					in_crit_targ = 0;
+				}
+				rfs4_close_all_state(fp);
 			}
-			rfs4_close_all_state(fp);
+			VN_RELE(tvp);
 		}
 	}
 
--- a/usr/src/uts/common/rpc/clnt_cots.c	Mon Jul 11 11:11:42 2005 -0700
+++ b/usr/src/uts/common/rpc/clnt_cots.c	Mon Jul 11 17:12:14 2005 -0700
@@ -1716,7 +1716,9 @@
 			 * for needs disconnect.
 			 */
 			if (cm_entry->x_needdis) {
+				CONN_HOLD(cm_entry);
 				connmgr_dis_and_wait(cm_entry);
+				connmgr_release(cm_entry);
 				/*
 				 * connmgr_lock could have been
 				 * dropped for the disconnect