diff options
Diffstat (limited to 'usr/src/uts/common/fs/nfs/nfs_server.c')
-rw-r--r-- | usr/src/uts/common/fs/nfs/nfs_server.c | 22 |
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); } |