Module Name:    src
Committed By:   thorpej
Date:           Mon Sep 27 00:51:10 UTC 2021

Modified Files:
        src/sys/kern: sys_pipe.c

Log Message:
Tweak filt_piperead() and filt_pipewrite() so that:
- There is only a single return from the function (and thus a single
  place where the pipe lock must be released).
- kn->kn_data is referenced only inside the lock perimeter.


To generate a diff of this commit:
cvs rdiff -u -r1.155 -r1.156 src/sys/kern/sys_pipe.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/sys_pipe.c
diff -u src/sys/kern/sys_pipe.c:1.155 src/sys/kern/sys_pipe.c:1.156
--- src/sys/kern/sys_pipe.c:1.155	Sun Sep 26 15:48:54 2021
+++ src/sys/kern/sys_pipe.c	Mon Sep 27 00:51:10 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_pipe.c,v 1.155 2021/09/26 15:48:54 thorpej Exp $	*/
+/*	$NetBSD: sys_pipe.c,v 1.156 2021/09/27 00:51:10 thorpej Exp $	*/
 
 /*-
  * Copyright (c) 2003, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.155 2021/09/26 15:48:54 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.156 2021/09/27 00:51:10 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1045,6 +1045,7 @@ filt_piperead(struct knote *kn, long hin
 {
 	struct pipe *rpipe = ((file_t *)kn->kn_obj)->f_pipe;
 	struct pipe *wpipe;
+	int rv;
 
 	if ((hint & NOTE_SUBMIT) == 0) {
 		mutex_enter(rpipe->pipe_lock);
@@ -1055,16 +1056,15 @@ filt_piperead(struct knote *kn, long hin
 	if ((rpipe->pipe_state & PIPE_EOF) ||
 	    (wpipe == NULL) || (wpipe->pipe_state & PIPE_EOF)) {
 		kn->kn_flags |= EV_EOF;
-		if ((hint & NOTE_SUBMIT) == 0) {
-			mutex_exit(rpipe->pipe_lock);
-		}
-		return (1);
+		rv = 1;
+	} else {
+		rv = kn->kn_data > 0;
 	}
 
 	if ((hint & NOTE_SUBMIT) == 0) {
 		mutex_exit(rpipe->pipe_lock);
 	}
-	return (kn->kn_data > 0);
+	return rv;
 }
 
 static int
@@ -1072,6 +1072,7 @@ filt_pipewrite(struct knote *kn, long hi
 {
 	struct pipe *rpipe = ((file_t *)kn->kn_obj)->f_pipe;
 	struct pipe *wpipe;
+	int rv;
 
 	if ((hint & NOTE_SUBMIT) == 0) {
 		mutex_enter(rpipe->pipe_lock);
@@ -1081,17 +1082,16 @@ filt_pipewrite(struct knote *kn, long hi
 	if ((wpipe == NULL) || (wpipe->pipe_state & PIPE_EOF)) {
 		kn->kn_data = 0;
 		kn->kn_flags |= EV_EOF;
-		if ((hint & NOTE_SUBMIT) == 0) {
-			mutex_exit(rpipe->pipe_lock);
-		}
-		return (1);
+		rv = 1;
+	} else {
+		kn->kn_data = wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt;
+		rv = kn->kn_data >= PIPE_BUF;
 	}
-	kn->kn_data = wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt;
 
 	if ((hint & NOTE_SUBMIT) == 0) {
 		mutex_exit(rpipe->pipe_lock);
 	}
-	return (kn->kn_data >= PIPE_BUF);
+	return rv;
 }
 
 static const struct filterops pipe_rfiltops = {

Reply via email to