summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/nfs/nfs_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/fs/nfs/nfs_server.c')
-rw-r--r--usr/src/uts/common/fs/nfs/nfs_server.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/usr/src/uts/common/fs/nfs/nfs_server.c b/usr/src/uts/common/fs/nfs/nfs_server.c
index bb625bb175..22d1ad4d68 100644
--- a/usr/src/uts/common/fs/nfs/nfs_server.c
+++ b/usr/src/uts/common/fs/nfs/nfs_server.c
@@ -22,6 +22,7 @@
* Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 Bayard G. Bell. All rights reserved.
* Copyright (c) 2012 Joyent, Inc. All rights reserved.
+ * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -2804,8 +2805,8 @@ rfs_publicfh_mclookup(char *p, vnode_t *dvp, cred_t *cr, vnode_t **vpp,
*/
/* Release the reference on the old exi value */
- ASSERT(*exi != NULL);
exi_rele(*exi);
+ *exi = NULL;
if (error = nfs_check_vpexi(mc_dvp, *vpp, kcred, exi)) {
VN_RELE(*vpp);
@@ -2818,6 +2819,9 @@ publicfh_done:
if (mc_dvp)
VN_RELE(mc_dvp);
+ if (error && *exi != NULL)
+ exi_rele(*exi);
+
return (error);
}
@@ -2963,16 +2967,19 @@ URLparse(char *str)
/*
* Get the export information for the lookup vnode, and verify its
* useable.
+ *
+ * Set @exip only in success
*/
int
nfs_check_vpexi(vnode_t *mc_dvp, vnode_t *vp, cred_t *cr,
- struct exportinfo **exi)
+ struct exportinfo **exip)
{
int walk;
int error = 0;
+ struct exportinfo *exi;
- *exi = nfs_vptoexi(mc_dvp, vp, cr, &walk, NULL, FALSE);
- if (*exi == NULL)
+ exi = nfs_vptoexi(mc_dvp, vp, cr, &walk, NULL, FALSE);
+ if (exi == NULL)
error = EACCES;
else {
/*
@@ -2981,10 +2988,13 @@ nfs_check_vpexi(vnode_t *mc_dvp, vnode_t *vp, cred_t *cr,
* must not terminate below the
* exported directory.
*/
- if ((*exi)->exi_export.ex_flags & EX_NOSUB && walk > 0)
+ if (exi->exi_export.ex_flags & EX_NOSUB && walk > 0) {
error = EACCES;
+ exi_rele(exi);
+ }
}
-
+ if (error == 0)
+ *exip = exi;
return (error);
}