From 8b60d03c38177b3013a74bd24c346da65d708c3f Mon Sep 17 00:00:00 2001 From: Simon Klinkert Date: Wed, 25 Jan 2012 09:51:41 +0100 Subject: [PATCH] Bug fixed: nfs4 mirror mounting facility hangs when the process receives a signal during on-demand mounting. The problem is that nfs4_trigger_domount_args_create() fails to check the return value of nfs4_trigger_ping_server() for EINTR, thus looping endlessly when a signal is pending. See also: https://www.illumos.org/issues/1588 Reported-by: Arne Jansen Signed-off-by: Simon Klinkert --- usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c | 25 ++++++++++++++----------- 1 files changed, 14 insertions(+), 11 deletions(-) diff --git a/usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c b/usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c index 2769081..f0ee2af 100644 --- a/usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c +++ b/usr/src/uts/common/fs/nfs/nfs4_stub_vnops.c @@ -208,7 +208,8 @@ extern int nfs4_realvp(vnode_t *, vnode_t **, caller_context_t *); 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 @@ nfs4_trigger_mount(vnode_t *vp, cred_t *cr, vnode_t **newvpp) 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 @@ -898,16 +897,16 @@ done: /* * 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; + domount_args_t *dma; servinfo4_t *svp; struct nfs_args *nargs, *nargs_head; enum clnt_stat status; ephemeral_servinfo_t *esi, *esi_first; - domount_args_t *dma; mntinfo4_t *mi = VTOMI4(vp); nointr = !(mi->mi_flags & MI4_INT); @@ -920,7 +919,7 @@ nfs4_trigger_domount_args_create(vnode_t *vp, cred_t *cr) 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); @@ -990,8 +989,11 @@ nfs4_trigger_domount_args_create(vnode_t *vp, cred_t *cr) /* 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_SUCCESS) { + if (status == RPC_INTR) + return EINTR; continue; + } esi = nfs4_trigger_esi_create(vp, svp, cr); if (esi == NULL) @@ -1039,8 +1041,9 @@ nfs4_trigger_domount_args_create(vnode_t *vp, cred_t *cr) dma->dma_esi = esi_first; dma->dma_hostlist = hostlist; dma->dma_nargs = nargs_head; + *dmap = dma; - return (dma); + return 0; } static void -- 1.7.7