VOP_LOCK, VOP_UNLOCK, VOP_ISLOCKED, vn_lock -- serialize access to a
vnode
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/vnode.h>
int
VOP_LOCK(struct vnode *vp, int flags, struct thread *td);
int
VOP_UNLOCK(struct vnode *vp, int flags, struct thread *td);
int
VOP_ISLOCKED(struct vnode *vp, struct thread *td);
int
vn_lock(struct vnode *vp, int flags, struct thread *td);
These calls are used to serialize access to the file system, such as to
prevent two writes to the same file from happening at the same time.
The arguments are:
vp the vnode being locked or unlocked
flags One of the lock request types:
LK_SHARED Shared lock
LK_EXCLUSIVE Exclusive lock
LK_UPGRADE Shared-to-exclusive upgrade
LK_EXCLUPGRADE First shared-to-exclusive upgrade
LK_DOWNGRADE Exclusive-to-shared downgrade
LK_RELEASE Release any type of lock
LK_DRAIN Wait for all lock activity to end
The lock type may be or'ed with these lock flags:
LK_NOWAIT Do not sleep to wait for lock
LK_SLEEPFAIL Sleep, then return failure
LK_CANRECURSE Allow recursive exclusive lock
LK_REENABLE Lock is to be reenabled after drain
LK_NOPAUSE No spinloop
The lock type may be or'ed with these control flags:
LK_INTERLOCK Specify when the caller already has a simple
lock (VOP_LOCK will unlock the simple lock
after getting the lock)
LK_RETRY Retry until locked
LK_NOOBJ Don't create object
td thread context to use for the locks
Kernel code should use vn_lock() to lock a vnode rather than calling
VOP_LOCK() directly.
Zero is returned on success, otherwise an error is returned.
struct vopnode {
int von_flag;
/*
* Other file system specific data.
*/
...;
};
#define VON_LOCKED 1
#define VON_WANTED 2
#define VTOVON(vp) ((struct vopnode *) (vp)->v_data)
int
vop_lock(struct vnode *vp)
{
struct vopnode* vop;
start:
while (vp->v_flag & VXLOCK) {
vp->v_flag |= VXWANT;
tsleep((caddr_t)vp, PINOD, "voplk1", 0);
}
if (vp->v_tag == VT_NON)
return ENOENT;
vop = VTOVON(vp);
if (vop->von_flag & VON_LOCKED) {
vop->von_flag |= VON_WANTED;
tsleep((caddr_t) vop, PINOD, "voplk2", 0);
goto start;
}
vop->von_flag |= VON_LOCKED;
return 0;
}
int
vop_unlock(struct vnode *vp)
{
struct vopnode *vop = VTOVON(vp);
if ((vop->von_flag & VON_LOCKED) == 0) {
panic("vop_unlock not locked");
}
vop->von_flag &= ~VON_LOCKED;
if (vop->von_flag & VON_WANTED) {
vop->von_flag &= ~VON_WANTED;
wakeup((caddr_t) vop);
}
return 0;
}
int
vop_islocked(struct vnode *vp)
{
struct vopnode *vop = VTOVON(vp);
if (vop->von_flag & VON_LOCKED)
return 1;
else
return 0;
}
vnode(9)
This man page was written by Doug Rabson.
FreeBSD 5.2.1 July 24, 1996 FreeBSD 5.2.1 [ Back ] |