summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2007-09-11 15:23:55 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-09-11 17:21:20 -0700
commitdd23aae4f5edf4e1dbd8f7f8013a754ba3253f48 (patch)
treec7babf45f8132876e8a715f0327cf480c05c6131
parent3210f0ecdba6a81c3f8efe6f442d2e1f57db98f9 (diff)
downloadlinux-3.10-dd23aae4f5edf4e1dbd8f7f8013a754ba3253f48.tar.gz
linux-3.10-dd23aae4f5edf4e1dbd8f7f8013a754ba3253f48.tar.bz2
linux-3.10-dd23aae4f5edf4e1dbd8f7f8013a754ba3253f48.zip
Fix select on /proc files without ->poll
Taneli Vähäkangas <vahakang@cs.helsinki.fi> reported that commit 786d7e1612f0b0adb6046f19b906609e4fe8b1ba aka "Fix rmmod/read/write races in /proc entries" broke SBCL + SLIME combo. The old code in do_select() used DEFAULT_POLLMASK, if couldn't find ->poll handler. The new code makes ->poll always there and returns 0 by default, which is not correct. Return DEFAULT_POLLMASK instead. Steps to reproduce: install emacs, SBCL, SLIME emacs M-x slime in *inferior-lisp* buffer [watch it doing "Connecting to Swank on port X.."] Please, apply before 2.6.23. P.S.: why SBCL can't just read(2) /proc/cpuinfo is a mystery. Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Cc: T Taneli Vahakangas <vahakang@cs.helsinki.fi> Cc: Oleg Nesterov <oleg@tv-sign.ru> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/proc/inode.c3
-rw-r--r--fs/select.c2
-rw-r--r--include/linux/poll.h2
3 files changed, 4 insertions, 3 deletions
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index a5b0dfd89a1..0e4d37c93ee 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -11,6 +11,7 @@
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/completion.h>
+#include <linux/poll.h>
#include <linux/file.h>
#include <linux/limits.h>
#include <linux/init.h>
@@ -232,7 +233,7 @@ static ssize_t proc_reg_write(struct file *file, const char __user *buf, size_t
static unsigned int proc_reg_poll(struct file *file, struct poll_table_struct *pts)
{
struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
- unsigned int rv = 0;
+ unsigned int rv = DEFAULT_POLLMASK;
unsigned int (*poll)(struct file *, struct poll_table_struct *);
spin_lock(&pde->pde_unload_lock);
diff --git a/fs/select.c b/fs/select.c
index a974082b082..46dca31c607 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -26,8 +26,6 @@
#include <asm/uaccess.h>
-#define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)
-
struct poll_table_page {
struct poll_table_page * next;
struct poll_table_entry * entry;
diff --git a/include/linux/poll.h b/include/linux/poll.h
index 27690798623..16d813b364e 100644
--- a/include/linux/poll.h
+++ b/include/linux/poll.h
@@ -21,6 +21,8 @@
#define WQUEUES_STACK_ALLOC (MAX_STACK_ALLOC - FRONTEND_STACK_ALLOC)
#define N_INLINE_POLL_ENTRIES (WQUEUES_STACK_ALLOC / sizeof(struct poll_table_entry))
+#define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)
+
struct poll_table_struct;
/*