[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
kernel/3757: select() fails on NFS file handles
- To: gnats@openbsd.org
- Subject: kernel/3757: select() fails on NFS file handles
- From: foo+openbsd@bsdx.de
- Date: Sun, 25 Apr 2004 18:35:46 +0200 (MEST)
- Resent-Date: Sun, 25 Apr 2004 10:50:03 -0600 (MDT)
- Resent-From: gnats@cvs.openbsd.org (GNATS Filer)
- Resent-Message-Id: <200404251650.i3PGo3Nx016471@cvs.openbsd.org>
- Resent-Reply-To: gnats@cvs.openbsd.org, foo+openbsd@bsdx.de
- Resent-To: bugs@cvs.openbsd.org
>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: