[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

kernel/3757: select() fails on NFS file handles



>Number:         3757
>Category:       kernel
>Synopsis:       select() fails on NFS file handles
>Confidential:   yes
>Severity:       serious
>Priority:       low
>Responsible:    bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Apr 25 16:50:01 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        -current
>Organization:
net
>Environment:
	System      : OpenBSD 3.5
	Architecture: OpenBSD.i386
	Machine     : i386
>Description:
        select() fails to detect when NFS files are readable. Calling
	select with a NULL-timeout blocks forever, when only NFS files
	are open forever.

	The problem manifests itself in nfsnode.h, where nfs_poll is
	defined as a macro that expands to seltrue, because seltrue
	takes different parameters than the nfs_poll vop.
>How-To-Repeat:
	The following code can be used to reproduce the problem (where
	argv[1] should be the path to an NFS file):

	main(int argc, char **argv)
	{
		fd_set  rfds;
		int     fd;
		int     r;

		fd = open(argv[1], O_RDONLY);
		FD_ZERO(&rfds);
		FD_SET(fd, &rfds);

		fprintf(stderr, "select()");
		r = select(fd+1, &rfds, 0, 0, 0);
		fprintf(stderr, " = %d\n", r);

		close(fd);
	}

	If select() successfully detects that fd is readable, then the
	output of this sample program will be "select() = 1"; otherwise
	the program will block after printing "select()".
>Fix:
	This patch is for -current.  The nfs_poll() function created by
	this patch is exactly the same as ufs_poll(), and both are similar
	to seltrue().

Index: nfs_vnops.c
===================================================================
RCS file: /cvs/src/sys/nfs/nfs_vnops.c,v
retrieving revision 1.58
diff -u -r1.58 nfs_vnops.c
--- nfs_vnops.c	2 Mar 2004 05:46:00 -0000	1.58
+++ nfs_vnops.c	20 Apr 2004 13:41:30 -0000
@@ -45,6 +45,7 @@
 #include <sys/kernel.h>
 #include <sys/systm.h>
 #include <sys/resourcevar.h>
+#include <sys/poll.h>
 #include <sys/proc.h>
 #include <sys/mount.h>
 #include <sys/buf.h>
@@ -3062,6 +3063,23 @@
 
 	return (vaccess(va.va_mode, va.va_uid, va.va_gid, ap->a_mode,
 	    ap->a_cred));
+}
+
+/* ARGSUSED */
+int
+nfs_poll(v)
+        void *v;
+{
+	struct vop_poll_args /* {
+		struct	vnode *a_vp;
+		int  a_events;
+		struct	proc *a_p;
+	} */ *ap = v;
+
+	/*
+	 * We should really check to see if I/O is possible.
+	 */
+	return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
 }
 
 /*
Index: nfsnode.h
===================================================================
RCS file: /cvs/src/sys/nfs/nfsnode.h,v
retrieving revision 1.20
diff -u -r1.20 nfsnode.h
--- nfsnode.h	2 Mar 2004 05:46:00 -0000	1.20
+++ nfsnode.h	20 Apr 2004 13:41:30 -0000
@@ -170,7 +170,7 @@
 int	nfsfifo_read(void *);
 int	nfsfifo_write(void *);
 #define nfs_ioctl ((int (*)(void *))enoioctl)
-#define nfs_poll ((int (*)(void *))seltrue)
+int	nfs_poll(void *);
 #define nfs_revoke vop_generic_revoke
 int	nfs_fsync(void *);
 int	nfs_remove(void *);


>Release-Note:
>Audit-Trail:
>Unformatted: