| From | "Eric W. Biederman" <> | Date | Mon, 1 Jun 2009 14:50:34 -0700 | Subject | [PATCH 09/23] vfs: Teach poll and select to use file_hotplug_lock |
| |
From: Eric W. Biederman <ebiederm@maxwell.arastra.com>
Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com> --- fs/select.c | 24 +++++++++++++++++------- include/linux/poll.h | 1 + 2 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/fs/select.c b/fs/select.c index 99e4145..fd68da0 100644 --- a/fs/select.c +++ b/fs/select.c @@ -416,10 +416,15 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) continue; file = fget_light(i, &fput_needed); if (file) { - f_op = file->f_op; - mask = DEFAULT_POLLMASK; - if (f_op && f_op->poll) - mask = (*f_op->poll)(file, retval ? NULL : wait); + mask = DEAD_POLLMASK; + if (file_hotplug_read_trylock(file)) { + f_op = file->f_op; + mask = DEFAULT_POLLMASK; + if (f_op && f_op->poll) + mask = (*f_op->poll)(file, retval ? NULL : wait); + + file_hotplug_read_unlock(file); + } fput_light(file, fput_needed); if ((mask & POLLIN_SET) && (in & bit)) { res_in |= bit; @@ -684,9 +689,14 @@ static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait) file = fget_light(fd, &fput_needed); mask = POLLNVAL; if (file != NULL) { - mask = DEFAULT_POLLMASK; - if (file->f_op && file->f_op->poll) - mask = file->f_op->poll(file, pwait); + mask = DEAD_POLLMASK; + if (file_hotplug_read_trylock(file)) { + mask = DEFAULT_POLLMASK; + if (file->f_op && file->f_op->poll) + mask = file->f_op->poll(file, pwait); + + file_hotplug_read_unlock(file); + } /* Mask out unneeded events. */ mask &= pollfd->events | POLLERR | POLLHUP; fput_light(file, fput_needed); diff --git a/include/linux/poll.h b/include/linux/poll.h index d388620..f0512f4 100644 --- a/include/linux/poll.h +++ b/include/linux/poll.h @@ -22,6 +22,7 @@ #define N_INLINE_POLL_ENTRIES (WQUEUES_STACK_ALLOC / sizeof(struct poll_table_entry)) #define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM) +#define DEAD_POLLMASK (DEFAULT_POLLMASK | POLLERR) struct poll_table_struct; -- 1.6.3.1.54.g99dd.dirty
|