Print this page
7378 exported_lock held during nfs4 compound processing

@@ -1920,15 +1920,12 @@
                         if (error == ENOSPC)
                                 error = EREMOTE;
                         break;
                 }
 
-                if (v4srv)
-                        exi = checkexport4(&vp->v_vfsp->vfs_fsid, &fid, vp);
-                else
-                        exi = checkexport(&vp->v_vfsp->vfs_fsid, &fid);
-
+                exi = checkexport(&vp->v_vfsp->vfs_fsid, &fid,
+                    v4srv ? vp : NULL);
                 if (exi != NULL) {
                         /*
                          * Found the export info
                          */
                         break;

@@ -2429,20 +2426,15 @@
                 vp->v_type = VDIR;
         *statp = NFS4_OK;
         return (vp);
 }
 
-/*
- * Find the export structure associated with the given filesystem.
- * If found, then increment the ref count (exi_count).
- */
 struct exportinfo *
-checkexport(fsid_t *fsid, fid_t *fid)
+checkexport_nohold(fsid_t *fsid, fid_t *fid, vnode_t *vp)
 {
         struct exportinfo *exi;
 
-        rw_enter(&exported_lock, RW_READER);
         for (exi = exptable[exptablehash(fsid, fid)];
             exi != NULL;
             exi = exi->fid_hash.next) {
                 if (exportmatch(exi, fsid, fid)) {
                         /*

@@ -2453,63 +2445,43 @@
                          */
                         if (exi->exi_export.ex_flags & EX_PUBLIC) {
                                 exi = exi_public;
                         }
 
-                        exi_hold(exi);
-                        rw_exit(&exported_lock);
+                        /*
+                         * If vp is given, check if vp is the
+                         * same vnode as the exported node.
+                         *
+                         * Since VOP_FID of a lofs node returns the
+                         * fid of its real node (ufs), the exported
+                         * node for lofs and (pseudo) ufs may have
+                         * the same fsid and fid.
+                         */
+                        if (vp == NULL || vp == exi->exi_vp) {
                         return (exi);
                 }
         }
-        rw_exit(&exported_lock);
+        }
         return (NULL);
 }
 
-
 /*
- * "old school" version of checkexport() for NFS4.  NFS4
- * rfs4_compound holds exported_lock for duration of compound
- * processing.  This version doesn't manipulate exi_count
- * since NFS4 breaks fundamental assumptions in the exi_count
- * design.
+ * Find the export structure associated with the given filesystem.
+ * If found, then increment the ref count (exi_count).
  */
 struct exportinfo *
-checkexport4(fsid_t *fsid, fid_t *fid, vnode_t *vp)
+checkexport(fsid_t *fsid, fid_t *fid, vnode_t *vp)
 {
         struct exportinfo *exi;
 
-        ASSERT(RW_LOCK_HELD(&exported_lock));
-
-        for (exi = exptable[exptablehash(fsid, fid)];
-            exi != NULL;
-            exi = exi->fid_hash.next) {
-                if (exportmatch(exi, fsid, fid)) {
-                        /*
-                         * If this is the place holder for the
-                         * public file handle, then return the
-                         * real export entry for the public file
-                         * handle.
-                         */
-                        if (exi->exi_export.ex_flags & EX_PUBLIC) {
-                                exi = exi_public;
-                        }
+        rw_enter(&exported_lock, RW_READER);
+        exi = checkexport_nohold(fsid, fid, vp);
+        if (exi)
+                exi_hold(exi);
+        rw_exit(&exported_lock);
 
-                        /*
-                         * If vp is given, check if vp is the
-                         * same vnode as the exported node.
-                         *
-                         * Since VOP_FID of a lofs node returns the
-                         * fid of its real node (ufs), the exported
-                         * node for lofs and (pseudo) ufs may have
-                         * the same fsid and fid.
-                         */
-                        if (vp == NULL || vp == exi->exi_vp)
                                 return (exi);
-                }
-        }
-
-        return (NULL);
 }
 
 /*
  * Free an entire export list node
  */