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);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to