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 mailing list