svn commit: r288282 - stable/10/sys/fs/fifofs
Konstantin Belousov
kib at FreeBSD.org
Sun Sep 27 01:06:46 UTC 2015
Author: kib
Date: Sun Sep 27 01:06:45 2015
New Revision: 288282
URL: https://svnweb.freebsd.org/changeset/base/288282
Log:
MFC r288044:
Ensure that when a blockable open of fifo returns success, a valid
file descriptor opened for complimentary access exists as well.
Modified:
stable/10/sys/fs/fifofs/fifo_vnops.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/fs/fifofs/fifo_vnops.c
==============================================================================
--- stable/10/sys/fs/fifofs/fifo_vnops.c Sat Sep 26 22:57:10 2015 (r288281)
+++ stable/10/sys/fs/fifofs/fifo_vnops.c Sun Sep 27 01:06:45 2015 (r288282)
@@ -64,6 +64,8 @@ struct fifoinfo {
struct pipe *fi_pipe;
long fi_readers;
long fi_writers;
+ u_int fi_rgen;
+ u_int fi_wgen;
};
static vop_print_t fifo_print;
@@ -137,6 +139,7 @@ fifo_open(ap)
struct thread *td;
struct fifoinfo *fip;
struct pipe *fpipe;
+ u_int gen;
int error, stops_deferred;
vp = ap->a_vp;
@@ -164,6 +167,7 @@ fifo_open(ap)
PIPE_LOCK(fpipe);
if (ap->a_mode & FREAD) {
fip->fi_readers++;
+ fip->fi_rgen++;
if (fip->fi_readers == 1) {
fpipe->pipe_state &= ~PIPE_EOF;
if (fip->fi_writers > 0)
@@ -179,6 +183,7 @@ fifo_open(ap)
return (ENXIO);
}
fip->fi_writers++;
+ fip->fi_wgen++;
if (fip->fi_writers == 1) {
fpipe->pipe_state &= ~PIPE_EOF;
if (fip->fi_readers > 0)
@@ -187,6 +192,7 @@ fifo_open(ap)
}
if ((ap->a_mode & O_NONBLOCK) == 0) {
if ((ap->a_mode & FREAD) && fip->fi_writers == 0) {
+ gen = fip->fi_wgen;
VOP_UNLOCK(vp, 0);
stops_deferred = sigallowstop();
error = msleep(&fip->fi_readers, PIPE_MTX(fpipe),
@@ -194,7 +200,7 @@ fifo_open(ap)
if (stops_deferred)
sigdeferstop();
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- if (error) {
+ if (error != 0 && gen == fip->fi_wgen) {
fip->fi_readers--;
if (fip->fi_readers == 0) {
PIPE_LOCK(fpipe);
@@ -214,6 +220,7 @@ fifo_open(ap)
*/
}
if ((ap->a_mode & FWRITE) && fip->fi_readers == 0) {
+ gen = fip->fi_rgen;
VOP_UNLOCK(vp, 0);
stops_deferred = sigallowstop();
error = msleep(&fip->fi_writers, PIPE_MTX(fpipe),
@@ -221,7 +228,7 @@ fifo_open(ap)
if (stops_deferred)
sigdeferstop();
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- if (error) {
+ if (error != 0 && gen == fip->fi_rgen) {
fip->fi_writers--;
if (fip->fi_writers == 0) {
PIPE_LOCK(fpipe);
More information about the svn-src-stable-10
mailing list