summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authortruckman <truckman@FreeBSD.org>2003-11-10 22:21:00 +0000
committertruckman <truckman@FreeBSD.org>2003-11-10 22:21:00 +0000
commit23058182407fb7fb4e47e5b3d9c3cd9a1baee996 (patch)
tree7d95fa7cfd0de0fed388538cac10c6044fef0533 /sys
parentc038927dceca1b1596cfad4d5fec1b0b2c7d99a9 (diff)
downloadFreeBSD-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.c32
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);
}
OpenPOWER on IntegriCloud