diff --git a/kernel-src/fs/ext2.c b/kernel-src/fs/ext2.c index 1fa7e432..ff889e01 100644 --- a/kernel-src/fs/ext2.c +++ b/kernel-src/fs/ext2.c @@ -1062,6 +1062,10 @@ static int ext2_open(vnode_t **vnodep, int flags, cred_t *cred) { vnode_t *fifo; error = pipefs_getbinding(*vnodep, &fifo); VOP_UNLOCK(*vnodep); + if (error) + return error; + + error = VOP_OPEN(&fifo, flags, cred); if (error == 0) *vnodep = fifo; } diff --git a/kernel-src/fs/pipefs.c b/kernel-src/fs/pipefs.c index 3ee3404e..7014e8de 100644 --- a/kernel-src/fs/pipefs.c +++ b/kernel-src/fs/pipefs.c @@ -72,16 +72,14 @@ int pipefs_open(vnode_t **node, int flags, cred_t *cred) { // and there are either no writers or no readers. eventlistener_t listener; EVENT_INITLISTENER(&listener); - EVENT_ATTACH(&listener, &pipenode->openevent); + if (flags & V_FFLAGS_READ) + EVENT_ATTACH(&listener, &pipenode->writeopenevent); + else + EVENT_ATTACH(&listener, &pipenode->readopenevent); - while (1) { - VOP_UNLOCK(*node); - error = EVENT_WAIT(&listener, 0); - VOP_LOCK(*node); - - if (error || (pipenode->writers > 0 && pipenode->readers > 0)) - break; - } + VOP_UNLOCK(*node); + error = EVENT_WAIT(&listener, 0); + VOP_LOCK(*node); EVENT_DETACHALL(&listener); @@ -90,7 +88,10 @@ int pipefs_open(vnode_t **node, int flags, cred_t *cred) { VOP_UNLOCK(*node); pipefs_close(*node, flags, cred); } else { - EVENT_SIGNAL(&pipenode->openevent); + if (flags & V_FFLAGS_READ) + EVENT_SIGNAL(&pipenode->readopenevent); + else + EVENT_SIGNAL(&pipenode->writeopenevent); VOP_UNLOCK(*node); } @@ -374,7 +375,8 @@ static void ctor(scache_t *cache, void *obj) { VOP_INIT(&node->vnode, &vnops, 0, V_TYPE_FIFO, NULL); node->attr.inode = ++currentinode; POLL_INITHEADER(&node->pollheader); - EVENT_INITHEADER(&node->openevent); + EVENT_INITHEADER(&node->writeopenevent); + EVENT_INITHEADER(&node->readopenevent); } void pipefs_init() { @@ -406,6 +408,7 @@ int pipefs_getbinding(vnode_t *node, vnode_t **pipep) { if (node->fifobinding) { *pipep = node->fifobinding; + VOP_HOLD(*pipep); return 0; } @@ -413,6 +416,11 @@ int pipefs_getbinding(vnode_t *node, vnode_t **pipep) { if (error) return error; + VOP_HOLD(*pipep); node->fifobinding = *pipep; return error; } + +void pipefs_leavebinding(vnode_t *pipenode) { + VOP_RELEASE(pipenode); +} diff --git a/kernel-src/fs/tmpfs.c b/kernel-src/fs/tmpfs.c index ab86d9bb..23d0b6f1 100644 --- a/kernel-src/fs/tmpfs.c +++ b/kernel-src/fs/tmpfs.c @@ -155,7 +155,7 @@ static int tmpfs_create(vnode_t *parent, char *name, vattr_t *attr, int type, vn return error; } -static int tmpfs_open(vnode_t **nodep, int flag, cred_t *cred) { +static int tmpfs_open(vnode_t **nodep, int flags, cred_t *cred) { vnode_t *node = *nodep; tmpfsnode_t *tmpnode = (tmpfsnode_t *)node; @@ -176,6 +176,10 @@ static int tmpfs_open(vnode_t **nodep, int flag, cred_t *cred) { vnode_t *fifo; error = pipefs_getbinding(*nodep, &fifo); VOP_UNLOCK(*nodep); + if (error) + return error; + + error = VOP_OPEN(&fifo, flags, cred); if (error == 0) *nodep = fifo; } diff --git a/kernel-src/fs/vfs.c b/kernel-src/fs/vfs.c index e468dec6..3253eb08 100644 --- a/kernel-src/fs/vfs.c +++ b/kernel-src/fs/vfs.c @@ -9,6 +9,7 @@ #include #include #include +#include #define PATHNAME_MAX 512 #define MAXLINKDEPTH 64 @@ -57,8 +58,11 @@ int vfs_register(vfsops_t *ops, char *name) { } void vfs_inactive(vnode_t *vnode) { - if (vnode->socketbinding) + if (vnode->type == V_TYPE_SOCKET && vnode->socketbinding) { localsock_leavebinding(vnode); + } else if (vnode->type == V_TYPE_FIFO) { + pipefs_leavebinding(vnode); + } vnode->ops->inactive(vnode); } diff --git a/kernel-src/include/kernel/pipefs.h b/kernel-src/include/kernel/pipefs.h index 8902ed08..2b95b480 100644 --- a/kernel-src/include/kernel/pipefs.h +++ b/kernel-src/include/kernel/pipefs.h @@ -13,11 +13,13 @@ typedef struct pipenode_t { ringbuffer_t data; size_t readers, writers; pollheader_t pollheader; - eventheader_t openevent; + eventheader_t readopenevent; + eventheader_t writeopenevent; } pipenode_t; void pipefs_init(); int pipefs_newpipe(vnode_t **nodep); int pipefs_getbinding(vnode_t *node, vnode_t **pipep); +void pipefs_leavebinding(vnode_t *pipenode); #endif