we can't use the vnode's v_usecount to track how many times the vnode

has been VOP_OPEN()'d.  if the fifo is being accessed via a layered fs,
v_usecount is always one (representing the hold by the layered vnode)
regardless of how many times the vnode has been opened.  instead, keep a
separate counter for opens.  fixes PR 17195 and probably 17724.
This commit is contained in:
chs 2002-07-27 16:43:36 +00:00
parent ee28fd70d7
commit e697956ce6
1 changed files with 12 additions and 12 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: fifo_vnops.c,v 1.33 2001/12/06 04:27:41 chs Exp $ */
/* $NetBSD: fifo_vnops.c,v 1.34 2002/07/27 16:43:36 chs Exp $ */
/*
* Copyright (c) 1990, 1993, 1995
@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fifo_vnops.c,v 1.33 2001/12/06 04:27:41 chs Exp $");
__KERNEL_RCSID(0, "$NetBSD: fifo_vnops.c,v 1.34 2002/07/27 16:43:36 chs Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -64,6 +64,7 @@ __KERNEL_RCSID(0, "$NetBSD: fifo_vnops.c,v 1.33 2001/12/06 04:27:41 chs Exp $");
struct fifoinfo {
struct socket *fi_readsock;
struct socket *fi_writesock;
long fi_opencount;
long fi_readers;
long fi_writers;
};
@ -184,9 +185,11 @@ fifo_open(void *v)
return (error);
}
fip->fi_readers = fip->fi_writers = 0;
fip->fi_opencount = 0;
wso->so_state |= SS_CANTRCVMORE;
rso->so_state |= SS_CANTSENDMORE;
}
fip->fi_opencount++;
if (ap->a_mode & FREAD) {
if (fip->fi_readers++ == 0) {
fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
@ -427,7 +430,6 @@ fifo_close(void *v)
} */ *ap = v;
struct vnode *vp;
struct fifoinfo *fip;
int error1, error2;
vp = ap->a_vp;
fip = vp->v_fifoinfo;
@ -439,15 +441,13 @@ fifo_close(void *v)
if (--fip->fi_writers == 0)
socantrcvmore(fip->fi_readsock);
}
if (vp->v_usecount > 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);
if (--fip->fi_opencount == 0) {
(void) soclose(fip->fi_readsock);
(void) soclose(fip->fi_writesock);
FREE(fip, M_VNODE);
vp->v_fifoinfo = NULL;
}
return (0);
}
/*