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 ] |