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
*/