diff options
author | truckman <truckman@FreeBSD.org> | 2003-11-10 22:21:00 +0000 |
---|---|---|
committer | truckman <truckman@FreeBSD.org> | 2003-11-10 22:21:00 +0000 |
commit | 23058182407fb7fb4e47e5b3d9c3cd9a1baee996 (patch) | |
tree | 7d95fa7cfd0de0fed388538cac10c6044fef0533 /sys | |
parent | c038927dceca1b1596cfad4d5fec1b0b2c7d99a9 (diff) | |
download | FreeBSD-src-23058182407fb7fb4e47e5b3d9c3cd9a1baee996.zip FreeBSD-src-23058182407fb7fb4e47e5b3d9c3cd9a1baee996.tar.gz |
If fifo_open() is interrupted, fifo_close() may not get called, causing
a resource leak. Move the resource deallocation code from fifo_close()
to a new function, fifo_cleanup(), and call fifo_cleanup() from
fifo_close() and the appropriate places in fifo_open().
Tested by: Lukas Ertl
Pointy hat to: truckman
Diffstat (limited to 'sys')
-rw-r--r-- | sys/fs/fifofs/fifo_vnops.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c index c2df25d..36f8357 100644 --- a/sys/fs/fifofs/fifo_vnops.c +++ b/sys/fs/fifofs/fifo_vnops.c @@ -154,6 +154,26 @@ fifo_lookup(ap) } /* + * Dispose of fifo resources. + * Should be called with vnode locked + */ +static void +fifo_cleanup(struct vnode *vp) +{ + struct fifoinfo *fip = vp->v_fifoinfo; + + VI_LOCK(vp); + if (vp->v_usecount == 1) { + vp->v_fifoinfo = NULL; + VI_UNLOCK(vp); + (void)soclose(fip->fi_readsock); + (void)soclose(fip->fi_writesock); + FREE(fip, M_VNODE); + } else + VI_UNLOCK(vp); +} + +/* * Open called to set up a new instance of a fifo or * to find an active instance of a fifo. */ @@ -249,6 +269,7 @@ fail1: fip->fi_readers--; if (fip->fi_readers == 0) socantsendmore(fip->fi_writesock); + fifo_cleanup(vp); return (error); } VI_LOCK(vp); @@ -268,6 +289,7 @@ fail1: fip->fi_writers--; if (fip->fi_writers == 0) socantrcvmore(fip->fi_readsock); + fifo_cleanup(vp); return (error); } /* @@ -554,15 +576,7 @@ fifo_close(ap) if (fip->fi_writers == 0) socantrcvmore(fip->fi_readsock); } - VI_LOCK(vp); - if (vp->v_usecount == 1) { - vp->v_fifoinfo = NULL; - VI_UNLOCK(vp); - (void)soclose(fip->fi_readsock); - (void)soclose(fip->fi_writesock); - FREE(fip, M_VNODE); - } else - VI_UNLOCK(vp); + fifo_cleanup(vp); VOP_UNLOCK(vp, 0, td); return (0); } |