aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDon Lewis <truckman@FreeBSD.org>2003-06-13 06:58:11 +0000
committerDon Lewis <truckman@FreeBSD.org>2003-06-13 06:58:11 +0000
commitb156281658faa286ccc8fb23e28c18b71b14e749 (patch)
treeb880b4df5a817fe3e66f83f5b7c58a666cfbe449
parent33a609ece0410174e895ff49f019d843456022d1 (diff)
downloadsrc-b156281658faa286ccc8fb23e28c18b71b14e749.tar.gz
src-b156281658faa286ccc8fb23e28c18b71b14e749.zip
Clean up the fifo_open() implementation:
Restructure the error handling portion of the resource allocation code to eliminate duplicated code. Test for the O_NONBLOCK && fi_readers == 0 case before incrementing fi_writers and modifying the the socket flag to avoid having to undo these operations in this error case. Restructure and simplify the code that handles blocking opens. There should be no change to functionality.
Notes
Notes: svn path=/head/; revision=116281
-rw-r--r--sys/fs/fifofs/fifo_vnops.c75
1 files changed, 30 insertions, 45 deletions
diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c
index ef448f755600..95c8a9ee4e72 100644
--- a/sys/fs/fifofs/fifo_vnops.c
+++ b/sys/fs/fifofs/fifo_vnops.c
@@ -172,40 +172,33 @@ fifo_open(ap)
struct vnode *vp = ap->a_vp;
struct fifoinfo *fip;
struct thread *td = ap->a_td;
+ struct ucred *cred = ap->a_cred;
struct socket *rso, *wso;
int error;
if ((fip = vp->v_fifoinfo) == NULL) {
MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
- vp->v_fifoinfo = fip;
- error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0,
- ap->a_td->td_ucred, ap->a_td);
- if (error) {
- free(fip, M_VNODE);
- vp->v_fifoinfo = NULL;
- return (error);
- }
+ error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, cred, td);
+ if (error)
+ goto fail1;
fip->fi_readsock = rso;
- error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0,
- ap->a_td->td_ucred, ap->a_td);
- if (error) {
- (void)soclose(rso);
- free(fip, M_VNODE);
- vp->v_fifoinfo = NULL;
- return (error);
- }
+ error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, cred, td);
+ if (error)
+ goto fail2;
fip->fi_writesock = wso;
error = unp_connect2(wso, rso);
if (error) {
(void)soclose(wso);
+fail2:
(void)soclose(rso);
+fail1:
free(fip, M_VNODE);
- vp->v_fifoinfo = NULL;
return (error);
}
fip->fi_readers = fip->fi_writers = 0;
wso->so_snd.sb_lowat = PIPE_BUF;
rso->so_state |= SS_CANTRCVMORE;
+ vp->v_fifoinfo = fip;
}
/*
@@ -233,6 +226,10 @@ fifo_open(ap)
}
}
if (ap->a_mode & FWRITE) {
+ if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) {
+ VI_UNLOCK(vp);
+ return (ENXIO);
+ }
fip->fi_writers++;
if (fip->fi_writers == 1) {
fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
@@ -244,8 +241,8 @@ fifo_open(ap)
}
}
}
- if ((ap->a_mode & FREAD) && (ap->a_mode & O_NONBLOCK) == 0) {
- if (fip->fi_writers == 0) {
+ if ((ap->a_mode & O_NONBLOCK) == 0) {
+ if ((ap->a_mode & FREAD) && fip->fi_writers == 0) {
VOP_UNLOCK(vp, 0, td);
error = msleep(&fip->fi_readers, VI_MTX(vp),
PCATCH | PSOCK, "fifoor", 0);
@@ -263,36 +260,24 @@ fifo_open(ap)
* that we must wait for.
*/
}
- }
- if (ap->a_mode & FWRITE) {
- if (ap->a_mode & O_NONBLOCK) {
- if (fip->fi_readers == 0) {
- VI_UNLOCK(vp);
+ if ((ap->a_mode & FWRITE) && fip->fi_readers == 0) {
+ VOP_UNLOCK(vp, 0, td);
+ error = msleep(&fip->fi_writers, VI_MTX(vp),
+ PCATCH | PSOCK, "fifoow", 0);
+ vn_lock(vp,
+ LK_EXCLUSIVE | LK_RETRY | LK_INTERLOCK, td);
+ if (error) {
fip->fi_writers--;
if (fip->fi_writers == 0)
socantrcvmore(fip->fi_readsock);
- return (ENXIO);
- }
- } else {
- if (fip->fi_readers == 0) {
- VOP_UNLOCK(vp, 0, td);
- error = msleep(&fip->fi_writers, VI_MTX(vp),
- PCATCH | PSOCK, "fifoow", 0);
- vn_lock(vp,
- LK_EXCLUSIVE | LK_RETRY | LK_INTERLOCK, td);
- if (error) {
- fip->fi_writers--;
- if (fip->fi_writers == 0)
- socantrcvmore(fip->fi_readsock);
- return (error);
- }
- /*
- * We must have got woken up because we had
- * a reader. That (and not still having one)
- * is the condition that we must wait for.
- */
- return (0);
+ return (error);
}
+ /*
+ * We must have got woken up because we had
+ * a reader. That (and not still having one)
+ * is the condition that we must wait for.
+ */
+ return (0);
}
}
VI_UNLOCK(vp);