summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/nfs/nfs3_srv.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/fs/nfs/nfs3_srv.c')
-rw-r--r--usr/src/uts/common/fs/nfs/nfs3_srv.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/usr/src/uts/common/fs/nfs/nfs3_srv.c b/usr/src/uts/common/fs/nfs/nfs3_srv.c
index c72f823cd3..4acbe92ad9 100644
--- a/usr/src/uts/common/fs/nfs/nfs3_srv.c
+++ b/usr/src/uts/common/fs/nfs/nfs3_srv.c
@@ -433,16 +433,25 @@ rfs3_lookup(LOOKUP3args *args, LOOKUP3res *resp, struct exportinfo *exi,
goto out1;
}
+ exi_hold(exi);
+
/*
* If the public filehandle is used then allow
* a multi-component lookup
*/
if (PUBLIC_FH3(&args->what.dir)) {
+ struct exportinfo *new;
+
publicfh_flag = TRUE;
+
error = rfs_publicfh_mclookup(name, dvp, cr, &vp,
- &exi, &sec);
- if (error && exi != NULL)
- exi_rele(exi); /* See comment below Re: publicfh_flag */
+ &new, &sec);
+
+ if (error == 0) {
+ exi_rele(exi);
+ exi = new;
+ }
+
/*
* Since WebNFS may bypass MOUNT, we need to ensure this
* request didn't come from an unlabeled admin_low client.
@@ -464,8 +473,6 @@ rfs3_lookup(LOOKUP3args *args, LOOKUP3res *resp, struct exportinfo *exi,
if (tp == NULL || tp->tpc_tp.tp_doi !=
l_admin_low->tsl_doi || tp->tpc_tp.host_type !=
SUN_CIPSO) {
- if (exi != NULL)
- exi_rele(exi);
VN_RELE(vp);
resp->status = NFS3ERR_ACCES;
error = 1;
@@ -491,8 +498,6 @@ rfs3_lookup(LOOKUP3args *args, LOOKUP3res *resp, struct exportinfo *exi,
if (!blequal(&l_admin_low->tsl_label, clabel)) {
if (!do_rfs_label_check(clabel, dvp,
DOMINANCE_CHECK, exi)) {
- if (publicfh_flag && exi != NULL)
- exi_rele(exi);
VN_RELE(vp);
resp->status = NFS3ERR_ACCES;
error = 1;
@@ -519,18 +524,10 @@ rfs3_lookup(LOOKUP3args *args, LOOKUP3res *resp, struct exportinfo *exi,
goto out;
}
- /*
- * If publicfh_flag is true then we have called rfs_publicfh_mclookup
- * and have obtained a new exportinfo in exi which needs to be
- * released. Note the the original exportinfo pointed to by exi
- * will be released by the caller, common_dispatch.
- */
- if (publicfh_flag)
- exi_rele(exi);
-
va.va_mask = AT_ALL;
vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
+ exi_rele(exi);
VN_RELE(vp);
resp->status = NFS3_OK;
@@ -552,6 +549,12 @@ rfs3_lookup(LOOKUP3args *args, LOOKUP3res *resp, struct exportinfo *exi,
return;
out:
+ /*
+ * The passed argument exportinfo is released by the
+ * caller, common_dispatch
+ */
+ exi_rele(exi);
+
if (curthread->t_flag & T_WOULDBLOCK) {
curthread->t_flag &= ~T_WOULDBLOCK;
resp->status = NFS3ERR_JUKEBOX;