Print this page
7378 exported_lock held during nfs4 compound processing
*** 1920,1934 ****
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);
!
if (exi != NULL) {
/*
* Found the export info
*/
break;
--- 1920,1931 ----
if (error == ENOSPC)
error = EREMOTE;
break;
}
! exi = checkexport(&vp->v_vfsp->vfs_fsid, &fid,
! v4srv ? vp : NULL);
if (exi != NULL) {
/*
* Found the export info
*/
break;
*** 2429,2448 ****
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)
{
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)) {
/*
--- 2426,2440 ----
vp->v_type = VDIR;
*statp = NFS4_OK;
return (vp);
}
struct exportinfo *
! checkexport_nohold(fsid_t *fsid, fid_t *fid, vnode_t *vp)
{
struct exportinfo *exi;
for (exi = exptable[exptablehash(fsid, fid)];
exi != NULL;
exi = exi->fid_hash.next) {
if (exportmatch(exi, fsid, fid)) {
/*
*** 2453,2515 ****
*/
if (exi->exi_export.ex_flags & EX_PUBLIC) {
exi = exi_public;
}
! exi_hold(exi);
! rw_exit(&exported_lock);
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.
*/
struct exportinfo *
! checkexport4(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;
! }
- /*
- * 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
*/
--- 2445,2487 ----
*/
if (exi->exi_export.ex_flags & EX_PUBLIC) {
exi = exi_public;
}
! /*
! * 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);
}
/*
! * 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, vnode_t *vp)
{
struct exportinfo *exi;
! rw_enter(&exported_lock, RW_READER);
! exi = checkexport_nohold(fsid, fid, vp);
! if (exi)
! exi_hold(exi);
! rw_exit(&exported_lock);
return (exi);
}
/*
* Free an entire export list node
*/