changeset 13609:7442c4b86390

1588 nfs4 mirror mount hang Reviewed by: Dan McDonald <danmcd@nexenta.com> Reviewed by: Garrett D'Amore <garrett@damore.org> Reviewed by: Dan Kruchinin <dkruchinin@acm.org> Approved by: Richard Lowe <richlowe@richlowe.net>
author Simon Klinkert <klinkert@webgods.de>
date Wed, 15 Feb 2012 12:37:00 +0100
parents eaeddcd0a975
children 32b4d7ddcb1e
files usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c
diffstat 1 files changed, 24 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c	Thu Feb 16 22:14:36 2012 +0000
+++ b/usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c	Wed Feb 15 12:37:00 2012 +0100
@@ -208,7 +208,8 @@
 static int	nfs4_trigger_mount(vnode_t *, cred_t *, vnode_t **);
 static int	nfs4_trigger_domount(vnode_t *, domount_args_t *, vfs_t **,
     cred_t *, vnode_t **);
-static domount_args_t  *nfs4_trigger_domount_args_create(vnode_t *, cred_t *);
+static int 	nfs4_trigger_domount_args_create(vnode_t *, cred_t *,
+    domount_args_t **dmap);
 static void	nfs4_trigger_domount_args_destroy(domount_args_t *dma,
     vnode_t *vp);
 static ephemeral_servinfo_t *nfs4_trigger_esi_create(vnode_t *, servinfo4_t *,
@@ -835,11 +836,9 @@
 
 	must_unlock = TRUE;
 
-	dma = nfs4_trigger_domount_args_create(vp, cr);
-	if (dma == NULL) {
-		error = EINVAL;
+	error = nfs4_trigger_domount_args_create(vp, cr, &dma);
+	if (error)
 		goto done;
-	}
 
 	/*
 	 * Note that since we define mirror mounts to work
@@ -850,6 +849,7 @@
 	mcred = crdup(cr);
 	if (mcred == NULL) {
 		error = EINVAL;
+		nfs4_trigger_domount_args_destroy(dma, vp);
 		goto done;
 	}
 
@@ -898,8 +898,8 @@
 /*
  * Collect together both the generic & mount-type specific args.
  */
-static domount_args_t *
-nfs4_trigger_domount_args_create(vnode_t *vp, cred_t *cr)
+static int
+nfs4_trigger_domount_args_create(vnode_t *vp, cred_t *cr, domount_args_t **dmap)
 {
 	int nointr;
 	char *hostlist;
@@ -920,7 +920,7 @@
 		esi_first = nfs4_trigger_esi_create(vp, svp, cr);
 		if (esi_first == NULL) {
 			kmem_free(hostlist, MAXPATHLEN);
-			return (NULL);
+			return (EINVAL);
 		}
 
 		(void) strlcpy(hostlist, esi_first->esi_hostname, MAXPATHLEN);
@@ -989,9 +989,20 @@
 
 			/* check if the server is responding */
 			status = nfs4_trigger_ping_server(svp, nointr);
-			/* if the server did not respond, ignore it */
-			if (status != RPC_SUCCESS)
+			if (status == RPC_INTR) {
+				kmem_free(hostlist, MAXPATHLEN);
+				nfs4_trigger_esi_destroy(esi_first, vp);
+				nargs = nargs_head;
+				while (nargs != NULL) {
+					next = nargs->nfs_ext_u.nfs_extB.next;
+					nfs4_trigger_nargs_destroy(nargs);
+					nargs = next;
+				}
+				return (EINTR);
+			} else if (status != RPC_SUCCESS) {
+				/* if the server did not respond, ignore it */
 				continue;
+			}
 
 			esi = nfs4_trigger_esi_create(vp, svp, cr);
 			if (esi == NULL)
@@ -1039,8 +1050,9 @@
 	dma->dma_esi = esi_first;
 	dma->dma_hostlist = hostlist;
 	dma->dma_nargs = nargs_head;
-
-	return (dma);
+	*dmap = dma;
+
+	return (0);
 }
 
 static void