-vn_lock(fp, cmd)
- register struct file *fp;
- int cmd;
-{
- register int priority = PLOCK;
- register struct vnode *vp = (struct vnode *)fp->f_data;
-
- if ((cmd & LOCK_EX) == 0)
- priority += 4;
- if (setjmp(&u.u_qsave)) {
- if ((u.u_sigintr & sigmask(u.u_procp->p_cursig)) != 0)
- return(EINTR);
- u.u_eosys = RESTARTSYS;
- return (0);
- }
- /*
- * If there's a exclusive lock currently applied
- * to the file, then we've gotta wait for the
- * lock with everyone else.
- */
-again:
- while (vp->v_flag & VEXLOCK) {
- /*
- * If we're holding an exclusive
- * lock, then release it.
- */
- if (fp->f_flag & FEXLOCK) {
- vn_unlock(fp, FEXLOCK);
- continue;
- }
- if (cmd & LOCK_NB)
- return (EWOULDBLOCK);
- vp->v_flag |= VLWAIT;
- tsleep((caddr_t)&vp->v_exlockc, priority, SLP_EXLCK, 0);
- }
- if ((cmd & LOCK_EX) && (vp->v_flag & VSHLOCK)) {
- /*
- * Must wait for any shared locks to finish
- * before we try to apply a exclusive lock.
- *
- * If we're holding a shared
- * lock, then release it.
- */
- if (fp->f_flag & FSHLOCK) {
- vn_unlock(fp, FSHLOCK);
- goto again;
- }
- if (cmd & LOCK_NB)
- return (EWOULDBLOCK);
- vp->v_flag |= VLWAIT;
- tsleep((caddr_t)&vp->v_shlockc, PLOCK, SLP_SHLCK, 0);
- goto again;
- }
- if (fp->f_flag & FEXLOCK)
- panic("vn_lock");
- if (cmd & LOCK_EX) {
- cmd &= ~LOCK_SH;
- vp->v_exlockc++;
- vp->v_flag |= VEXLOCK;
- fp->f_flag |= FEXLOCK;
- }
- if ((cmd & LOCK_SH) && (fp->f_flag & FSHLOCK) == 0) {
- vp->v_shlockc++;
- vp->v_flag |= VSHLOCK;
- fp->f_flag |= FSHLOCK;
- }
- return (0);
-}
-
-/*
- * Unlock a file.
- */
-vn_unlock(fp, kind)
- register struct file *fp;
- int kind;
-{
- register struct vnode *vp = (struct vnode *)fp->f_data;