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