svn commit: r277321 - in head/sys: fs/fifofs kern sys

Konstantin Belousov kib at FreeBSD.org
Sun Jan 18 15:03:28 UTC 2015


Author: kib
Date: Sun Jan 18 15:03:26 2015
New Revision: 277321
URL: https://svnweb.freebsd.org/changeset/base/277321

Log:
  Make SIGSTOP working for sleeps done while waiting for fifo readers or
  writers in open(2), when the fifo is located on an NFS mount.
  
  Reported by:	bde
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/sys/fs/fifofs/fifo_vnops.c
  head/sys/kern/kern_sig.c
  head/sys/sys/signalvar.h

Modified: head/sys/fs/fifofs/fifo_vnops.c
==============================================================================
--- head/sys/fs/fifofs/fifo_vnops.c	Sun Jan 18 14:14:47 2015	(r277320)
+++ head/sys/fs/fifofs/fifo_vnops.c	Sun Jan 18 15:03:26 2015	(r277321)
@@ -137,7 +137,7 @@ fifo_open(ap)
 	struct thread *td;
 	struct fifoinfo *fip;
 	struct pipe *fpipe;
-	int error;
+	int error, stops_deferred;
 
 	vp = ap->a_vp;
 	fp = ap->a_fp;
@@ -188,8 +188,11 @@ fifo_open(ap)
 	if ((ap->a_mode & O_NONBLOCK) == 0) {
 		if ((ap->a_mode & FREAD) && fip->fi_writers == 0) {
 			VOP_UNLOCK(vp, 0);
+			stops_deferred = sigallowstop();
 			error = msleep(&fip->fi_readers, PIPE_MTX(fpipe),
 			    PDROP | PCATCH | PSOCK, "fifoor", 0);
+			if (stops_deferred)
+				sigdeferstop();
 			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 			if (error) {
 				fip->fi_readers--;
@@ -212,8 +215,11 @@ fifo_open(ap)
 		}
 		if ((ap->a_mode & FWRITE) && fip->fi_readers == 0) {
 			VOP_UNLOCK(vp, 0);
+			stops_deferred = sigallowstop();
 			error = msleep(&fip->fi_writers, PIPE_MTX(fpipe),
 			    PDROP | PCATCH | PSOCK, "fifoow", 0);
+			if (stops_deferred)
+				sigdeferstop();
 			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 			if (error) {
 				fip->fi_writers--;

Modified: head/sys/kern/kern_sig.c
==============================================================================
--- head/sys/kern/kern_sig.c	Sun Jan 18 14:14:47 2015	(r277320)
+++ head/sys/kern/kern_sig.c	Sun Jan 18 15:03:26 2015	(r277321)
@@ -2587,15 +2587,18 @@ sigdeferstop(void)
  * not immediately suspend if a stop was posted.  Instead, the thread
  * will suspend either via ast() or a subsequent interruptible sleep.
  */
-void
-sigallowstop()
+int
+sigallowstop(void)
 {
 	struct thread *td;
+	int prev;
 
 	td = curthread;
 	thread_lock(td);
+	prev = (td->td_flags & TDF_SBDRY) != 0;
 	td->td_flags &= ~TDF_SBDRY;
 	thread_unlock(td);
+	return (prev);
 }
 
 /*

Modified: head/sys/sys/signalvar.h
==============================================================================
--- head/sys/sys/signalvar.h	Sun Jan 18 14:14:47 2015	(r277320)
+++ head/sys/sys/signalvar.h	Sun Jan 18 15:03:26 2015	(r277321)
@@ -325,7 +325,7 @@ extern struct mtx	sigio_lock;
 
 int	cursig(struct thread *td);
 int	sigdeferstop(void);
-void	sigallowstop(void);
+int	sigallowstop(void);
 void	execsigs(struct proc *p);
 void	gsignal(int pgid, int sig, ksiginfo_t *ksi);
 void	killproc(struct proc *p, char *why);


More information about the svn-src-all mailing list