Module Name:    src
Committed By:   ad
Date:           Sat Apr  4 10:12:52 UTC 2009

Modified Files:
        src/sys/arch/xen/xen: xenevt.c
        src/sys/compat/svr4: svr4_net.c
        src/sys/compat/svr4_32: svr4_32_net.c
        src/sys/dev/dmover: dmover_io.c
        src/sys/dev/putter: putter.c
        src/sys/kern: kern_descrip.c kern_drvctl.c kern_event.c sys_mqueue.c
            sys_pipe.c sys_socket.c uipc_socket.c uipc_syscalls.c vfs_vnops.c
        src/sys/net: bpf.c if_tap.c
        src/sys/opencrypto: cryptodev.c
        src/sys/sys: file.h socketvar.h

Log Message:
Add fileops::fo_drain(), to be called from fd_close() when there is more
than one active reference to a file descriptor. It should dislodge threads
sleeping while holding a reference to the descriptor. Implemented only for
sockets but should be extended to pipes, fifos, etc.

Fixes the case of a multithreaded process doing something like the
following, which would have hung until the process got a signal.

thr0    accept(fd, ...)
thr1    close(fd)


To generate a diff of this commit:
cvs rdiff -u -r1.31 -r1.32 src/sys/arch/xen/xen/xenevt.c
cvs rdiff -u -r1.55 -r1.56 src/sys/compat/svr4/svr4_net.c
cvs rdiff -u -r1.18 -r1.19 src/sys/compat/svr4_32/svr4_32_net.c
cvs rdiff -u -r1.31 -r1.32 src/sys/dev/dmover/dmover_io.c
cvs rdiff -u -r1.20 -r1.21 src/sys/dev/putter/putter.c
cvs rdiff -u -r1.189 -r1.190 src/sys/kern/kern_descrip.c
cvs rdiff -u -r1.22 -r1.23 src/sys/kern/kern_drvctl.c
cvs rdiff -u -r1.63 -r1.64 src/sys/kern/kern_event.c
cvs rdiff -u -r1.13 -r1.14 src/sys/kern/sys_mqueue.c
cvs rdiff -u -r1.108 -r1.109 src/sys/kern/sys_pipe.c
cvs rdiff -u -r1.58 -r1.59 src/sys/kern/sys_socket.c
cvs rdiff -u -r1.187 -r1.188 src/sys/kern/uipc_socket.c
cvs rdiff -u -r1.135 -r1.136 src/sys/kern/uipc_syscalls.c
cvs rdiff -u -r1.163 -r1.164 src/sys/kern/vfs_vnops.c
cvs rdiff -u -r1.143 -r1.144 src/sys/net/bpf.c
cvs rdiff -u -r1.54 -r1.55 src/sys/net/if_tap.c
cvs rdiff -u -r1.46 -r1.47 src/sys/opencrypto/cryptodev.c
cvs rdiff -u -r1.66 -r1.67 src/sys/sys/file.h
cvs rdiff -u -r1.118 -r1.119 src/sys/sys/socketvar.h

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

Modified files:

Index: src/sys/arch/xen/xen/xenevt.c
diff -u src/sys/arch/xen/xen/xenevt.c:1.31 src/sys/arch/xen/xen/xenevt.c:1.32
--- src/sys/arch/xen/xen/xenevt.c:1.31	Tue Mar 10 20:05:31 2009
+++ src/sys/arch/xen/xen/xenevt.c	Sat Apr  4 10:12:51 2009
@@ -1,4 +1,4 @@
-/*      $NetBSD: xenevt.c,v 1.31 2009/03/10 20:05:31 bouyer Exp $      */
+/*      $NetBSD: xenevt.c,v 1.32 2009/04/04 10:12:51 ad Exp $      */
 
 /*
  * Copyright (c) 2005 Manuel Bouyer.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xenevt.c,v 1.31 2009/03/10 20:05:31 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xenevt.c,v 1.32 2009/04/04 10:12:51 ad Exp $");
 
 #include "opt_xen.h"
 #include <sys/param.h>
@@ -80,14 +80,15 @@
 /* static int	xenevt_fkqfilter(struct file *, struct knote *); */
 
 static const struct fileops xenevt_fileops = {
-	xenevt_fread,
-	xenevt_fwrite,
-	xenevt_fioctl,
-	fnullop_fcntl,
-	xenevt_fpoll,
-	fbadop_stat,
-	xenevt_fclose,
-	/* xenevt_fkqfilter */ fnullop_kqfilter
+	.fo_read = xenevt_fread,
+	.fo_write = xenevt_fwrite,
+	.fo_ioctl = xenevt_fioctl,
+	.fo_fcntl = fnullop_fcntl,
+	.fo_poll = xenevt_fpoll,
+	.fo_stat = fbadop_stat,
+	.fo_close = xenevt_fclose,
+	.fo_kqfilter = /* xenevt_fkqfilter */ fnullop_kqfilter,
+	.fo_drain = fnullop_drain,
 };
 
 dev_type_open(xenevtopen);

Index: src/sys/compat/svr4/svr4_net.c
diff -u src/sys/compat/svr4/svr4_net.c:1.55 src/sys/compat/svr4/svr4_net.c:1.56
--- src/sys/compat/svr4/svr4_net.c:1.55	Thu Jan 22 16:10:19 2009
+++ src/sys/compat/svr4/svr4_net.c	Sat Apr  4 10:12:51 2009
@@ -1,7 +1,7 @@
-/*	$NetBSD: svr4_net.c,v 1.55 2009/01/22 16:10:19 cegger Exp $	*/
+/*	$NetBSD: svr4_net.c,v 1.56 2009/04/04 10:12:51 ad Exp $	*/
 
 /*-
- * Copyright (c) 1994, 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 1994, 2008, 2009 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: svr4_net.c,v 1.55 2009/01/22 16:10:19 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: svr4_net.c,v 1.56 2009/04/04 10:12:51 ad Exp $");
 
 #define COMPAT_SVR4 1
 
@@ -100,8 +100,15 @@
 int svr4_soo_close(file_t *);
 
 static const struct fileops svr4_netops = {
-	soo_read, soo_write, soo_ioctl, soo_fcntl, soo_poll,
-	soo_stat, svr4_soo_close, soo_kqfilter
+	.fo_read = soo_read,
+	.fo_write = soo_write,
+	.fo_ioctl = soo_ioctl,
+	.fo_fcntl = soo_fcntl,
+	.fo_poll = soo_poll,
+	.fo_stat = soo_stat,
+	.fo_close = svr4_soo_close,
+	.fo_kqfilter = soo_kqfilter,
+	.fo_drain = soo_drain,
 };
 
 

Index: src/sys/compat/svr4_32/svr4_32_net.c
diff -u src/sys/compat/svr4_32/svr4_32_net.c:1.18 src/sys/compat/svr4_32/svr4_32_net.c:1.19
--- src/sys/compat/svr4_32/svr4_32_net.c:1.18	Mon Apr 28 20:23:46 2008
+++ src/sys/compat/svr4_32/svr4_32_net.c	Sat Apr  4 10:12:51 2009
@@ -1,7 +1,7 @@
-/*	$NetBSD: svr4_32_net.c,v 1.18 2008/04/28 20:23:46 martin Exp $	 */
+/*	$NetBSD: svr4_32_net.c,v 1.19 2009/04/04 10:12:51 ad Exp $	 */
 
 /*-
- * Copyright (c) 1994, 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 1994, 2008, 2009 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: svr4_32_net.c,v 1.18 2008/04/28 20:23:46 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: svr4_32_net.c,v 1.19 2009/04/04 10:12:51 ad Exp $");
 
 #define COMPAT_SVR4 1
 
@@ -95,8 +95,14 @@
 int svr4_ptm_alloc(struct proc *);
 
 static const struct fileops svr4_32_netops = {
-	soo_read, soo_write, soo_ioctl, soo_fcntl, soo_poll,
-	soo_stat, svr4_soo_close, D_OTHER
+	.fo_read = soo_read,
+	.fo_write = soo_write,
+	.fo_ioctl = soo_ioctl,
+	.fo_fcntl = soo_fcntl,
+	.fo_poll = soo_poll,
+	.fo_stat = soo_stat,
+	.fo_close = svr4_soo_close,
+	.fo_drain = soo_drain,
 };
 
 

Index: src/sys/dev/dmover/dmover_io.c
diff -u src/sys/dev/dmover/dmover_io.c:1.31 src/sys/dev/dmover/dmover_io.c:1.32
--- src/sys/dev/dmover/dmover_io.c:1.31	Wed Mar 26 13:33:58 2008
+++ src/sys/dev/dmover/dmover_io.c	Sat Apr  4 10:12:51 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: dmover_io.c,v 1.31 2008/03/26 13:33:58 ad Exp $	*/
+/*	$NetBSD: dmover_io.c,v 1.32 2009/04/04 10:12:51 ad Exp $	*/
 
 /*
  * Copyright (c) 2002, 2003 Wasabi Systems, Inc.
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dmover_io.c,v 1.31 2008/03/26 13:33:58 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dmover_io.c,v 1.32 2009/04/04 10:12:51 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/queue.h>
@@ -729,14 +729,15 @@
 }
 
 static const struct fileops dmio_fileops = {
-	dmio_read,
-	dmio_write,
-	dmio_ioctl,
-	fnullop_fcntl,
-	dmio_poll,
-	fbadop_stat,
-	dmio_close,
-	fnullop_kqfilter
+	.fo_read = dmio_read,
+	.fo_write = dmio_write,
+	.fo_ioctl = dmio_ioctl,
+	.fo_fcntl = fnullop_fcntl,
+	.fo_poll = dmio_poll,
+	.fo_stat = fbadop_stat,
+	.fo_close = dmio_close,
+	.fo_kqfilter = fnullop_kqfilter,
+	.fo_drain = fnullop_drain,
 };
 
 /*

Index: src/sys/dev/putter/putter.c
diff -u src/sys/dev/putter/putter.c:1.20 src/sys/dev/putter/putter.c:1.21
--- src/sys/dev/putter/putter.c:1.20	Wed Mar 18 10:22:41 2009
+++ src/sys/dev/putter/putter.c	Sat Apr  4 10:12:51 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: putter.c,v 1.20 2009/03/18 10:22:41 cegger Exp $	*/
+/*	$NetBSD: putter.c,v 1.21 2009/04/04 10:12:51 ad Exp $	*/
 
 /*
  * Copyright (c) 2006, 2007  Antti Kantee.  All Rights Reserved.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: putter.c,v 1.20 2009/03/18 10:22:41 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: putter.c,v 1.21 2009/04/04 10:12:51 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -176,14 +176,15 @@
 
 
 static const struct fileops putter_fileops = {
-	putter_fop_read,
-	putter_fop_write,
-	putter_fop_ioctl,
-	fnullop_fcntl,
-	putter_fop_poll,
-	fbadop_stat,
-	putter_fop_close,
-	putter_fop_kqfilter
+	.fo_read = putter_fop_read,
+	.fo_write = putter_fop_write,
+	.fo_ioctl = putter_fop_ioctl,
+	.fo_fcntl = fnullop_fcntl,
+	.fo_poll = putter_fop_poll,
+	.fo_stat = fbadop_stat,
+	.fo_close = putter_fop_close,
+	.fo_kqfilter = putter_fop_kqfilter,
+	.fo_drain = fnullop_drain,
 };
 
 static int

Index: src/sys/kern/kern_descrip.c
diff -u src/sys/kern/kern_descrip.c:1.189 src/sys/kern/kern_descrip.c:1.190
--- src/sys/kern/kern_descrip.c:1.189	Sun Mar 29 04:40:01 2009
+++ src/sys/kern/kern_descrip.c	Sat Apr  4 10:12:51 2009
@@ -1,9 +1,12 @@
-/*	$NetBSD: kern_descrip.c,v 1.189 2009/03/29 04:40:01 rmind Exp $	*/
+/*	$NetBSD: kern_descrip.c,v 1.190 2009/04/04 10:12:51 ad Exp $	*/
 
 /*-
- * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -67,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.189 2009/03/29 04:40:01 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.190 2009/04/04 10:12:51 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -578,15 +581,20 @@
 		 *
 		 */
 		atomic_or_uint(&ff->ff_refcnt, FR_CLOSING);
+
 		/*
 		 * Remove any knotes attached to the file.  A knote
 		 * attached to the descriptor can hold references on it.
 		 */
+		mutex_exit(&ff->ff_lock);
 		if (!SLIST_EMPTY(&ff->ff_knlist)) {
-			mutex_exit(&ff->ff_lock);
 			knote_fdclose(fd);
-			mutex_enter(&ff->ff_lock);
 		}
+
+		/* Try to drain out descriptor references. */
+		(*fp->f_ops->fo_drain)(fp);
+		mutex_enter(&ff->ff_lock);
+
 		/*
 		 * We need to see the count drop to zero at least once,
 		 * in order to ensure that all pre-existing references
@@ -1707,6 +1715,12 @@
 	return 0;
 }
 
+void
+fnullop_drain(file_t *fp)
+{
+
+}
+
 int
 fbadop_read(file_t *fp, off_t *offset, struct uio *uio,
 	    kauth_cred_t cred, int flags)

Index: src/sys/kern/kern_drvctl.c
diff -u src/sys/kern/kern_drvctl.c:1.22 src/sys/kern/kern_drvctl.c:1.23
--- src/sys/kern/kern_drvctl.c:1.22	Sat Jan 17 07:02:35 2009
+++ src/sys/kern/kern_drvctl.c	Sat Apr  4 10:12:51 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_drvctl.c,v 1.22 2009/01/17 07:02:35 yamt Exp $ */
+/* $NetBSD: kern_drvctl.c,v 1.23 2009/04/04 10:12:51 ad Exp $ */
 
 /*
  * Copyright (c) 2004
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_drvctl.c,v 1.22 2009/01/17 07:02:35 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_drvctl.c,v 1.23 2009/04/04 10:12:51 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -78,14 +78,15 @@
 static int	drvctl_close(struct file *);
 
 static const struct fileops drvctl_fileops = {
-	drvctl_read,
-	drvctl_write,
-	drvctl_ioctl,
-	fnullop_fcntl,
-	drvctl_poll,
-	fbadop_stat,
-	drvctl_close,
-	fnullop_kqfilter
+	.fo_read = drvctl_read,
+	.fo_write = drvctl_write,
+	.fo_ioctl = drvctl_ioctl,
+	.fo_fcntl = fnullop_fcntl,
+	.fo_poll = drvctl_poll,
+	.fo_stat = fbadop_stat,
+	.fo_close = drvctl_close,
+	.fo_kqfilter = fnullop_kqfilter,
+	.fo_drain = fnullop_drain,
 };
 
 #define MAXLOCATORS 100

Index: src/sys/kern/kern_event.c
diff -u src/sys/kern/kern_event.c:1.63 src/sys/kern/kern_event.c:1.64
--- src/sys/kern/kern_event.c:1.63	Mon Mar 30 22:22:44 2009
+++ src/sys/kern/kern_event.c	Sat Apr  4 10:12:51 2009
@@ -1,9 +1,12 @@
-/*	$NetBSD: kern_event.c,v 1.63 2009/03/30 22:22:44 christos Exp $	*/
+/*	$NetBSD: kern_event.c,v 1.64 2009/04/04 10:12:51 ad Exp $	*/
 
 /*-
- * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -55,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.63 2009/03/30 22:22:44 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.64 2009/04/04 10:12:51 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -104,8 +107,15 @@
 static int	filt_timer(struct knote *, long hint);
 
 static const struct fileops kqueueops = {
-	(void *)enxio, (void *)enxio, kqueue_ioctl, kqueue_fcntl, kqueue_poll,
-	kqueue_stat, kqueue_close, kqueue_kqfilter
+	.fo_read = (void *)enxio,
+	.fo_write = (void *)enxio,
+	.fo_ioctl = kqueue_ioctl,
+	.fo_fcntl = kqueue_fcntl,
+	.fo_poll = kqueue_poll,
+	.fo_stat = kqueue_stat,
+	.fo_close = kqueue_close,
+	.fo_kqfilter = kqueue_kqfilter,
+	.fo_drain = fnullop_drain,
 };
 
 static const struct filterops kqread_filtops =

Index: src/sys/kern/sys_mqueue.c
diff -u src/sys/kern/sys_mqueue.c:1.13 src/sys/kern/sys_mqueue.c:1.14
--- src/sys/kern/sys_mqueue.c:1.13	Sun Jan 11 02:45:52 2009
+++ src/sys/kern/sys_mqueue.c	Sat Apr  4 10:12:51 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_mqueue.c,v 1.13 2009/01/11 02:45:52 christos Exp $	*/
+/*	$NetBSD: sys_mqueue.c,v 1.14 2009/04/04 10:12:51 ad Exp $	*/
 
 /*
  * Copyright (c) 2007, 2008 Mindaugas Rasiukevicius <rmind at NetBSD org>
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_mqueue.c,v 1.13 2009/01/11 02:45:52 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_mqueue.c,v 1.14 2009/04/04 10:12:51 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -89,8 +89,15 @@
 #define	FNOVAL	-1
 
 static const struct fileops mqops = {
-	fbadop_read, fbadop_write, fbadop_ioctl, fnullop_fcntl, mq_poll_fop,
-	fbadop_stat, mq_close_fop, fnullop_kqfilter
+	.fo_read = fbadop_read,
+	.fo_write = fbadop_write,
+	.fo_ioctl = fbadop_ioctl,
+	.fo_fcntl = fnullop_fcntl,
+	.fo_poll = mq_poll_fop,
+	.fo_stat = fbadop_stat,
+	.fo_close = mq_close_fop,
+	.fo_kqfilter = fnullop_kqfilter,
+	.fo_drain = fnullop_drain,
 };
 
 /*

Index: src/sys/kern/sys_pipe.c
diff -u src/sys/kern/sys_pipe.c:1.108 src/sys/kern/sys_pipe.c:1.109
--- src/sys/kern/sys_pipe.c:1.108	Sun Feb 15 00:07:54 2009
+++ src/sys/kern/sys_pipe.c	Sat Apr  4 10:12:51 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_pipe.c,v 1.108 2009/02/15 00:07:54 enami Exp $	*/
+/*	$NetBSD: sys_pipe.c,v 1.109 2009/04/04 10:12:51 ad 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.108 2009/02/15 00:07:54 enami Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.109 2009/04/04 10:12:51 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -112,8 +112,15 @@
 static int pipe_ioctl(struct file *fp, u_long cmd, void *data);
 
 static const struct fileops pipeops = {
-	pipe_read, pipe_write, pipe_ioctl, fnullop_fcntl, pipe_poll,
-	pipe_stat, pipe_close, pipe_kqfilter
+	.fo_read = pipe_read,
+	.fo_write = pipe_write,
+	.fo_ioctl = pipe_ioctl,
+	.fo_fcntl = fnullop_fcntl,
+	.fo_poll = pipe_poll,
+	.fo_stat = pipe_stat,
+	.fo_close = pipe_close,
+	.fo_kqfilter = pipe_kqfilter,
+	.fo_drain = fnullop_drain,
 };
 
 /*

Index: src/sys/kern/sys_socket.c
diff -u src/sys/kern/sys_socket.c:1.58 src/sys/kern/sys_socket.c:1.59
--- src/sys/kern/sys_socket.c:1.58	Tue Apr 29 18:35:14 2008
+++ src/sys/kern/sys_socket.c	Sat Apr  4 10:12:51 2009
@@ -1,9 +1,12 @@
-/*	$NetBSD: sys_socket.c,v 1.58 2008/04/29 18:35:14 ad Exp $	*/
+/*	$NetBSD: sys_socket.c,v 1.59 2009/04/04 10:12:51 ad Exp $	*/
 
 /*-
- * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -58,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_socket.c,v 1.58 2008/04/29 18:35:14 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_socket.c,v 1.59 2009/04/04 10:12:51 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -78,8 +81,15 @@
 #include <net/route.h>
 
 const struct fileops socketops = {
-	soo_read, soo_write, soo_ioctl, soo_fcntl, soo_poll,
-	soo_stat, soo_close, soo_kqfilter
+	.fo_read = soo_read,
+	.fo_write = soo_write,
+	.fo_ioctl = soo_ioctl,
+	.fo_fcntl = soo_fcntl,
+	.fo_poll = soo_poll,
+	.fo_stat = soo_stat,
+	.fo_close = soo_close,
+	.fo_kqfilter = soo_kqfilter,
+	.fo_drain = soo_drain,
 };
 
 /* ARGSUSED */
@@ -248,3 +258,10 @@
 
 	return error;
 }
+
+void
+soo_drain(file_t *fp)
+{
+
+	(void)sodrain(fp->f_data);
+}

Index: src/sys/kern/uipc_socket.c
diff -u src/sys/kern/uipc_socket.c:1.187 src/sys/kern/uipc_socket.c:1.188
--- src/sys/kern/uipc_socket.c:1.187	Sun Mar 15 17:14:40 2009
+++ src/sys/kern/uipc_socket.c	Sat Apr  4 10:12:51 2009
@@ -1,11 +1,11 @@
-/*	$NetBSD: uipc_socket.c,v 1.187 2009/03/15 17:14:40 cegger Exp $	*/
+/*	$NetBSD: uipc_socket.c,v 1.188 2009/04/04 10:12:51 ad Exp $	*/
 
 /*-
- * Copyright (c) 2002, 2007, 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
- * by Jason R. Thorpe of Wasabi Systems, Inc.
+ * by Jason R. Thorpe of Wasabi Systems, Inc, and by Andrew Doran.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -63,7 +63,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.187 2009/03/15 17:14:40 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.188 2009/04/04 10:12:51 ad Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_sock_counters.h"
@@ -1547,6 +1547,20 @@
 	return error;
 }
 
+int
+sodrain(struct socket *so)
+{
+	int error;
+
+	solock(so);
+	so->so_state |= SS_ISDRAINING;
+	cv_broadcast(&so->so_cv);
+	error = soshutdown(so, SHUT_RDWR);
+	sounlock(so);
+
+	return error;
+}
+
 void
 sorflush(struct socket *so)
 {

Index: src/sys/kern/uipc_syscalls.c
diff -u src/sys/kern/uipc_syscalls.c:1.135 src/sys/kern/uipc_syscalls.c:1.136
--- src/sys/kern/uipc_syscalls.c:1.135	Wed Jan 21 06:59:29 2009
+++ src/sys/kern/uipc_syscalls.c	Sat Apr  4 10:12:51 2009
@@ -1,9 +1,12 @@
-/*	$NetBSD: uipc_syscalls.c,v 1.135 2009/01/21 06:59:29 yamt Exp $	*/
+/*	$NetBSD: uipc_syscalls.c,v 1.136 2009/04/04 10:12:51 ad Exp $	*/
 
 /*-
- * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -58,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.135 2009/01/21 06:59:29 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.136 2009/04/04 10:12:51 ad Exp $");
 
 #include "opt_pipe.h"
 
@@ -300,7 +303,7 @@
 	}
 	solock(so);
 	MCLAIM(nam, so->so_mowner);
-	if (so->so_state & SS_ISCONNECTING) {
+	if ((so->so_state & SS_ISCONNECTING) != 0) {
 		error = EALREADY;
 		goto out;
 	}
@@ -308,12 +311,17 @@
 	error = soconnect(so, nam, l);
 	if (error)
 		goto bad;
-	if (so->so_nbio && (so->so_state & SS_ISCONNECTING)) {
+	if (so->so_nbio && (so->so_state & SS_ISCONNECTING) != 0) {
 		error = EINPROGRESS;
 		goto out;
 	}
-	while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
+	while ((so->so_state & SS_ISCONNECTING) != 0 && so->so_error == 0) {
 		error = sowait(so, true, 0);
+		if (__predict_false((so->so_state & SS_ISDRAINING) != 0)) {
+			error = EPIPE;
+			interrupted = 1;
+			break;
+		}
 		if (error) {
 			if (error == EINTR || error == ERESTART)
 				interrupted = 1;

Index: src/sys/kern/vfs_vnops.c
diff -u src/sys/kern/vfs_vnops.c:1.163 src/sys/kern/vfs_vnops.c:1.164
--- src/sys/kern/vfs_vnops.c:1.163	Wed Feb 11 00:19:11 2009
+++ src/sys/kern/vfs_vnops.c	Sat Apr  4 10:12:51 2009
@@ -1,4 +1,33 @@
-/*	$NetBSD: vfs_vnops.c,v 1.163 2009/02/11 00:19:11 enami Exp $	*/
+/*	$NetBSD: vfs_vnops.c,v 1.164 2009/04/04 10:12:51 ad Exp $	*/
+
+/*-
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -37,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.163 2009/02/11 00:19:11 enami Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.164 2009/04/04 10:12:51 ad Exp $");
 
 #include "veriexec.h"
 
@@ -85,8 +114,15 @@
 static int vn_ioctl(file_t *fp, u_long com, void *data);
 
 const struct fileops vnops = {
-	vn_read, vn_write, vn_ioctl, vn_fcntl, vn_poll,
-	vn_statfile, vn_closefile, vn_kqfilter
+	.fo_read = vn_read,
+	.fo_write = vn_write,
+	.fo_ioctl = vn_ioctl,
+	.fo_fcntl = vn_fcntl,
+	.fo_poll = vn_poll,
+	.fo_stat = vn_statfile,
+	.fo_close = vn_closefile,
+	.fo_kqfilter = vn_kqfilter,
+	.fo_drain = fnullop_drain,
 };
 
 /*

Index: src/sys/net/bpf.c
diff -u src/sys/net/bpf.c:1.143 src/sys/net/bpf.c:1.144
--- src/sys/net/bpf.c:1.143	Wed Mar 11 05:55:22 2009
+++ src/sys/net/bpf.c	Sat Apr  4 10:12:51 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: bpf.c,v 1.143 2009/03/11 05:55:22 mrg Exp $	*/
+/*	$NetBSD: bpf.c,v 1.144 2009/04/04 10:12:51 ad Exp $	*/
 
 /*
  * Copyright (c) 1990, 1991, 1993
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.143 2009/03/11 05:55:22 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.144 2009/04/04 10:12:51 ad Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_bpf.h"
@@ -156,14 +156,15 @@
 static void	bpf_softintr(void *);
 
 static const struct fileops bpf_fileops = {
-	bpf_read,
-	bpf_write,
-	bpf_ioctl,
-	fnullop_fcntl,
-	bpf_poll,
-	fbadop_stat,
-	bpf_close,
-	bpf_kqfilter,
+	.fo_read = bpf_read,
+	.fo_write = bpf_write,
+	.fo_ioctl = bpf_ioctl,
+	.fo_fcntl = fnullop_fcntl,
+	.fo_poll = bpf_poll,
+	.fo_stat = fbadop_stat,
+	.fo_close = bpf_close,
+	.fo_kqfilter = bpf_kqfilter,
+	.fo_drain = fnullop_drain,
 };
 
 dev_type_open(bpfopen);

Index: src/sys/net/if_tap.c
diff -u src/sys/net/if_tap.c:1.54 src/sys/net/if_tap.c:1.55
--- src/sys/net/if_tap.c:1.54	Fri Mar 13 18:40:10 2009
+++ src/sys/net/if_tap.c	Sat Apr  4 10:12:51 2009
@@ -1,7 +1,7 @@
-/*	$NetBSD: if_tap.c,v 1.54 2009/03/13 18:40:10 plunky Exp $	*/
+/*	$NetBSD: if_tap.c,v 1.55 2009/04/04 10:12:51 ad Exp $	*/
 
 /*
- *  Copyright (c) 2003, 2004, 2008 The NetBSD Foundation.
+ *  Copyright (c) 2003, 2004, 2008, 2009 The NetBSD Foundation.
  *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_tap.c,v 1.54 2009/03/13 18:40:10 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_tap.c,v 1.55 2009/04/04 10:12:51 ad Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "bpfilter.h"
@@ -148,14 +148,15 @@
 static int	tap_fops_kqfilter(file_t *, struct knote *);
 
 static const struct fileops tap_fileops = {
-	tap_fops_read,
-	tap_fops_write,
-	tap_fops_ioctl,
-	fnullop_fcntl,
-	tap_fops_poll,
-	fbadop_stat,
-	tap_fops_close,
-	tap_fops_kqfilter,
+	.fo_read = tap_fops_read,
+	.fo_write = tap_fops_write,
+	.fo_ioctl = tap_fops_ioctl,
+	.fo_fcntl = fnullop_fcntl,
+	.fo_poll = tap_fops_poll,
+	.fo_stat = fbadop_stat,
+	.fo_close = tap_fops_close,
+	.fo_kqfilter = tap_fops_kqfilter,
+	.fo_drain = fnullop_drain,
 };
 
 /* Helper for cloning open() */

Index: src/sys/opencrypto/cryptodev.c
diff -u src/sys/opencrypto/cryptodev.c:1.46 src/sys/opencrypto/cryptodev.c:1.47
--- src/sys/opencrypto/cryptodev.c:1.46	Wed Mar 25 01:26:13 2009
+++ src/sys/opencrypto/cryptodev.c	Sat Apr  4 10:12:52 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: cryptodev.c,v 1.46 2009/03/25 01:26:13 darran Exp $ */
+/*	$NetBSD: cryptodev.c,v 1.47 2009/04/04 10:12:52 ad Exp $ */
 /*	$FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.4.2.4 2003/06/03 00:09:02 sam Exp $	*/
 /*	$OpenBSD: cryptodev.c,v 1.53 2002/07/10 22:21:30 mickey Exp $	*/
 
@@ -64,7 +64,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cryptodev.c,v 1.46 2009/03/25 01:26:13 darran Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cryptodev.c,v 1.47 2009/04/04 10:12:52 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -144,14 +144,15 @@
 static int 	cryptof_poll(struct file *, int);
 
 static const struct fileops cryptofops = {
-	cryptof_read,
-	cryptof_write,
-	cryptof_ioctl,
-	fnullop_fcntl,
-	cryptof_poll,
-	fbadop_stat,
-	cryptof_close,
-	fnullop_kqfilter
+	.fo_read = cryptof_read,
+	.fo_write = cryptof_write,
+	.fo_ioctl = cryptof_ioctl,
+	.fo_fcntl = fnullop_fcntl,
+	.fo_poll = cryptof_poll,
+	.fo_stat = fbadop_stat,
+	.fo_close = cryptof_close,
+	.fo_kqfilter = fnullop_kqfilter,
+	.fo_drain = fnullop_drain,
 };
 
 struct csession *cryptodev_csefind(struct fcrypt *, u_int);

Index: src/sys/sys/file.h
diff -u src/sys/sys/file.h:1.66 src/sys/sys/file.h:1.67
--- src/sys/sys/file.h:1.66	Wed Mar 11 06:05:29 2009
+++ src/sys/sys/file.h	Sat Apr  4 10:12:52 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: file.h,v 1.66 2009/03/11 06:05:29 mrg Exp $	*/
+/*	$NetBSD: file.h,v 1.67 2009/04/04 10:12:52 ad Exp $	*/
 
 /*-
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -100,6 +100,9 @@
 		int	(*fo_stat)	(struct file *, struct stat *);
 		int	(*fo_close)	(struct file *);
 		int	(*fo_kqfilter)	(struct file *, struct knote *);
+		void	(*fo_drain)	(struct file *);
+		void	(*fo_spare1)	(void);
+		void	(*fo_spare2)	(void);
 	} *f_ops;
 	void		*f_data;	/* descriptor data, e.g. vnode/socket */
 	LIST_ENTRY(file) f_list;	/* list of active files */
@@ -162,6 +165,7 @@
 int	fbadop_ioctl(struct file *, u_long, void *);
 int	fbadop_close(struct file *);
 int	fbadop_stat(struct file *, struct stat *);
+void	fnullop_drain(struct file *);
 
 #endif /* _KERNEL */
 

Index: src/sys/sys/socketvar.h
diff -u src/sys/sys/socketvar.h:1.118 src/sys/sys/socketvar.h:1.119
--- src/sys/sys/socketvar.h:1.118	Wed Jan 21 06:59:29 2009
+++ src/sys/sys/socketvar.h	Sat Apr  4 10:12:52 2009
@@ -1,9 +1,12 @@
-/*	$NetBSD: socketvar.h,v 1.118 2009/01/21 06:59:29 yamt Exp $	*/
+/*	$NetBSD: socketvar.h,v 1.119 2009/04/04 10:12:52 ad Exp $	*/
 
 /*-
- * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -195,6 +198,7 @@
 #define	SS_CANTSENDMORE		0x010	/* can't send more data to peer */
 #define	SS_CANTRCVMORE		0x020	/* can't receive more data from peer */
 #define	SS_RCVATMARK		0x040	/* at mark on input */
+#define	SS_ISDRAINING		0x080	/* draining fd references */
 #define	SS_ISDISCONNECTED	0x800	/* socket disconnected from peer */
 
 #define	SS_ASYNC		0x100	/* async i/o notify */
@@ -252,6 +256,7 @@
 int	soo_kqfilter(file_t *, struct knote *);
 int 	soo_close(file_t *);
 int	soo_stat(file_t *, struct stat *);
+void	soo_drain(file_t *);
 void	sbappend(struct sockbuf *, struct mbuf *);
 void	sbappendstream(struct sockbuf *, struct mbuf *);
 int	sbappendaddr(struct sockbuf *, const struct sockaddr *, struct mbuf *,
@@ -307,6 +312,7 @@
 int	sosetopt(struct socket *, struct sockopt *);
 int	so_setsockopt(struct lwp *, struct socket *, int, int, const void *, size_t);
 int	soshutdown(struct socket *, int);
+int	sodrain(struct socket *);
 void	sowakeup(struct socket *, struct sockbuf *, int);
 int	sockargs(struct mbuf **, const void *, size_t, int);
 int	sopoll(struct socket *, int);

Reply via email to