Index: fifo_vnops.c
===================================================================
RCS file: /data/ncvs/src/sys/fs/fifofs/fifo_vnops.c,v
retrieving revision 1.85
diff -u -r1.85 fifo_vnops.c
--- fifo_vnops.c	24 Mar 2003 11:03:42 -0000	1.85
+++ fifo_vnops.c	10 May 2003 15:05:25 -0000
@@ -66,6 +66,8 @@
 	long		fi_writers;
 };
 
+static int	fifo_cleanup(struct vnode *vp, int fflags);
+
 static int	fifo_print(struct vop_print_args *);
 static int	fifo_lookup(struct vop_lookup_args *);
 static int	fifo_open(struct vop_open_args *);
@@ -154,6 +156,40 @@
 }
 
 /*
+ * Cleanup when we no longer need a fifo.  May be called with or without
+ * the vnode lock--with the lock in the open() case, and without in the
+ * close() case.
+ */
+static int
+fifo_cleanup(struct vnode *vp, int fflag)
+{
+	register struct fifoinfo *fip = vp->v_fifoinfo;
+	int error1, error2;
+
+	if (fflag & FREAD) {
+		fip->fi_readers--;
+		if (fip->fi_readers == 0)
+			socantsendmore(fip->fi_writesock);
+	}
+	if (fflag & FWRITE) {
+		fip->fi_writers--;
+		if (fip->fi_writers == 0)
+			socantrcvmore(fip->fi_readsock);
+	}
+
+	if (vrefcnt(vp) > 1)
+		return (0);
+
+	error1 = soclose(fip->fi_readsock);
+	error2 = soclose(fip->fi_writesock);
+	FREE(fip, M_VNODE);
+	vp->v_fifoinfo = NULL;
+	if (error1)
+		return (error1);
+	return (error2);
+}
+
+/*
  * Open called to set up a new instance of a fifo or
  * to find an active instance of a fifo.
  */
@@ -264,7 +300,7 @@
 	}
 	return (0);
 bad:
-	VOP_CLOSE(vp, ap->a_mode, ap->a_cred, td);
+	fifo_cleanup(vp, ap->a_mode);
 	return (error);
 }
 
@@ -525,29 +561,8 @@
 		struct thread *a_td;
 	} */ *ap;
 {
-	register struct vnode *vp = ap->a_vp;
-	register struct fifoinfo *fip = vp->v_fifoinfo;
-	int error1, error2;
 
-	if (ap->a_fflag & FREAD) {
-		fip->fi_readers--;
-		if (fip->fi_readers == 0)
-			socantsendmore(fip->fi_writesock);
-	}
-	if (ap->a_fflag & FWRITE) {
-		fip->fi_writers--;
-		if (fip->fi_writers == 0)
-			socantrcvmore(fip->fi_readsock);
-	}
-	if (vrefcnt(vp) > 1)
-		return (0);
-	error1 = soclose(fip->fi_readsock);
-	error2 = soclose(fip->fi_writesock);
-	FREE(fip, M_VNODE);
-	vp->v_fifoinfo = NULL;
-	if (error1)
-		return (error1);
-	return (error2);
+	return (fifo_cleanup(ap->a_vp, ap->a_fflag));
 }
 
 
