vfs: provide fake locking primitives for the crossmp vnode

Since the vnode is only expected to be shared locked, we can save a
little overhead by only pretending we are locking in the first place.

Reviewed by:	kib
Tested by:	pho
This commit is contained in:
Mateusz Guzik 2016-12-02 18:03:15 +00:00
parent 488f148604
commit a2d3554542
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=309425

View File

@ -79,6 +79,64 @@ uma_zone_t namei_zone;
/* Placeholder vnode for mp traversal. */
static struct vnode *vp_crossmp;
static int
crossmp_vop_islocked(struct vop_islocked_args *ap)
{
return (LK_SHARED);
}
static int
crossmp_vop_lock1(struct vop_lock1_args *ap)
{
struct vnode *vp;
struct lock *lk;
const char *file;
int flags, line;
vp = ap->a_vp;
lk = vp->v_vnlock;
flags = ap->a_flags;
file = ap->a_file;
line = ap->a_line;
if ((flags & LK_SHARED) == 0)
panic("invalid lock request for crossmp");
WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER, file, line,
flags & LK_INTERLOCK ? &VI_MTX(vp)->lock_object : NULL);
WITNESS_LOCK(&lk->lock_object, 0, file, line);
if ((flags & LK_INTERLOCK) != 0)
VI_UNLOCK(vp);
LOCK_LOG_LOCK("SLOCK", &lk->lock_object, 0, 0, ap->a_file, line);
return (0);
}
static int
crossmp_vop_unlock(struct vop_unlock_args *ap)
{
struct vnode *vp;
struct lock *lk;
int flags;
vp = ap->a_vp;
lk = vp->v_vnlock;
flags = ap->a_flags;
if ((flags & LK_INTERLOCK) != 0)
VI_UNLOCK(vp);
WITNESS_UNLOCK(&lk->lock_object, 0, LOCK_FILE, LOCK_LINE);
LOCK_LOG_LOCK("SUNLOCK", &lk->lock_object, 0, 0, LOCK_FILE,
LOCK_LINE);
return (0);
}
static struct vop_vector crossmp_vnodeops = {
.vop_islocked = crossmp_vop_islocked,
.vop_lock1 = crossmp_vop_lock1,
.vop_unlock = crossmp_vop_unlock,
};
struct nameicap_tracker {
struct vnode *dp;
TAILQ_ENTRY(nameicap_tracker) nm_link;
@ -95,10 +153,7 @@ nameiinit(void *dummy __unused)
UMA_ALIGN_PTR, 0);
nt_zone = uma_zcreate("rentr", sizeof(struct nameicap_tracker),
NULL, NULL, NULL, NULL, sizeof(void *), 0);
getnewvnode("crossmp", NULL, &dead_vnodeops, &vp_crossmp);
vn_lock(vp_crossmp, LK_EXCLUSIVE);
VN_LOCK_ASHARE(vp_crossmp);
VOP_UNLOCK(vp_crossmp, 0);
getnewvnode("crossmp", NULL, &crossmp_vnodeops, &vp_crossmp);
}
SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nameiinit, NULL);