summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2012-07-31 05:48:35 +0000
committerdavidxu <davidxu@FreeBSD.org>2012-07-31 05:48:35 +0000
commitc8c77f184e05b058ac40c9c1e4ecb44628ee06fe (patch)
tree5639cee7976a84e093e17117a4da2ed8e242033a /sys/fs
parent712f939cb3d3a683ddbac7fdbf56303f087597ee (diff)
downloadFreeBSD-src-c8c77f184e05b058ac40c9c1e4ecb44628ee06fe.zip
FreeBSD-src-c8c77f184e05b058ac40c9c1e4ecb44628ee06fe.tar.gz
I am comparing current pipe code with the one in 8.3-STABLE r236165,
I found 8.3 is a history BSD version using socket to implement FIFO pipe, it uses per-file seqcount to compare with writer generation stored in per-pipe object. The concept is after all writers are gone, the pipe enters next generation, all old readers have not closed the pipe should get the indication that the pipe is disconnected, result is they should get EPIPE, SIGPIPE or get POLLHUP in poll(). But newcomer should not know that previous writters were gone, it should treat it as a fresh session. I am trying to bring back FIFO pipe to history behavior. It is still unclear that if single EOF flag can represent SBS_CANTSENDMORE and SBS_CANTRCVMORE which socket-based version is using, but I have run the poll regression test in tool directory, output is same as the one on 8.3-STABLE now. I think the output "not ok 18 FIFO state 6b: poll result 0 expected 1. expected POLLHUP; got 0" might be bogus, because newcomer should not know that old writers were gone. I got the same behavior on Linux. Our implementation always return POLLIN for disconnected pipe even it should return POLLHUP, but I think it is not wise to remove POLLIN for compatible reason, this is our history behavior. Regression test: /usr/src/tools/regression/poll
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/fifofs/fifo_vnops.c21
1 files changed, 4 insertions, 17 deletions
diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c
index 859f68c..bdb1367 100644
--- a/sys/fs/fifofs/fifo_vnops.c
+++ b/sys/fs/fifofs/fifo_vnops.c
@@ -59,23 +59,13 @@
* Notes about locking:
* - fi_pipe is invariant since init time.
* - fi_readers and fi_writers are protected by the vnode lock.
- * - fi_wgen and fi_seqcount are protected by the pipe mutex.
*/
struct fifoinfo {
struct pipe *fi_pipe;
long fi_readers;
long fi_writers;
- int fi_wgen;
- int fi_seqcount;
};
-#define FIFO_UPDWGEN(fip, pip) do { \
- if ((fip)->fi_wgen == (fip)->fi_seqcount) \
- (pip)->pipe_state |= PIPE_SAMEWGEN; \
- else \
- (pip)->pipe_state &= ~PIPE_SAMEWGEN; \
-} while (0)
-
static vop_print_t fifo_print;
static vop_open_t fifo_open;
static vop_close_t fifo_close;
@@ -161,7 +151,7 @@ fifo_open(ap)
return (error);
fip = malloc(sizeof(*fip), M_VNODE, M_WAITOK);
fip->fi_pipe = fpipe;
- fip->fi_wgen = fip->fi_readers = fip->fi_writers = 0;
+ fpipe->pipe_wgen = fip->fi_readers = fip->fi_writers = 0;
KASSERT(vp->v_fifoinfo == NULL, ("fifo_open: v_fifoinfo race"));
vp->v_fifoinfo = fip;
}
@@ -181,8 +171,7 @@ fifo_open(ap)
if (fip->fi_writers > 0)
wakeup(&fip->fi_writers);
}
- fip->fi_seqcount = fip->fi_wgen - fip->fi_writers;
- FIFO_UPDWGEN(fip, fpipe);
+ fp->f_seqcount = fpipe->pipe_wgen - fip->fi_writers;
}
if (ap->a_mode & FWRITE) {
if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) {
@@ -235,8 +224,7 @@ fifo_open(ap)
fpipe->pipe_state |= PIPE_EOF;
if (fpipe->pipe_state & PIPE_WANTR)
wakeup(fpipe);
- fip->fi_wgen++;
- FIFO_UPDWGEN(fip, fpipe);
+ fpipe->pipe_wgen++;
PIPE_UNLOCK(fpipe);
fifo_cleanup(vp);
}
@@ -300,8 +288,7 @@ fifo_close(ap)
cpipe->pipe_state &= ~PIPE_WANTR;
wakeup(cpipe);
}
- fip->fi_wgen++;
- FIFO_UPDWGEN(fip, cpipe);
+ cpipe->pipe_wgen++;
pipeselwakeup(cpipe);
PIPE_UNLOCK(cpipe);
}
OpenPOWER on IntegriCloud