Print this page
*** NO COMMENTS ***

@@ -19,11 +19,11 @@
  * CDDL HEADER END
  */
 /*
  * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
  *
- * Copyright 2012 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
 /* All Rights Reserved */
 

@@ -380,10 +380,14 @@
         struct sockaddr *ca;
         char *name = NULL;
 
         dvap = NULL;
 
+        /* Take an extra hold here in case of 'exi' switching */
+        if (exi != NULL)
+                exi_hold(exi);
+
         /*
          * Allow lookups from the root - the default
          * location of the public filehandle.
          */
         if (exi != NULL && (exi->exi_export.ex_flags & EX_PUBLIC)) {

@@ -431,12 +435,10 @@
         if (name == NULL) {
                 resp->status = NFS3ERR_ACCES;
                 goto out1;
         }
 
-        exi_hold(exi);
-
         /*
          * If the public filehandle is used then allow
          * a multi-component lookup
          */
         if (PUBLIC_FH3(&args->what.dir)) {

@@ -547,22 +549,19 @@
         VN_RELE(dvp);
 
         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;
         } else
                 resp->status = puterrno3(error);
 out1:
+        if (exi != NULL)
+                exi_rele(exi);
+
         DTRACE_NFSV3_4(op__lookup__done, struct svc_req *, req,
             cred_t *, cr, vnode_t *, dvp, LOOKUP3res *, resp);
 
         if (dvp != NULL)
                 VN_RELE(dvp);