+ if (fp->f_flag & (FSHLOCK|FEXLOCK))
+ vn_unlock(fp, FSHLOCK|FEXLOCK);
+ /*
+ * Must delete vnode reference from this file entry
+ * before VOP_CLOSE, so that only other references
+ * will prevent close.
+ */
+ fp->f_data = (caddr_t) 0;
+ error = VOP_CLOSE(vp, fp->f_flag, u.u_cred);
+ vrele(vp);
+ return (error);
+}
+
+/*
+ * Place an advisory lock on a vnode.
+ * !! THIS IMPLIES THAT ALL STATEFUL FILE SERVERS WILL USE file table entries
+ */
+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;