diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-02 23:25:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-02 23:25:04 -0400 |
commit | aab174f0df5d72d31caccf281af5f614fa254578 (patch) | |
tree | 2a172c5009c4ac8755e858593154c258ce7709a0 /fs/select.c | |
parent | ca41cc96b2813221b05af57d0355157924de5a07 (diff) | |
parent | 2bd2c1941f141ad780135ccc1cd08ca71a24f10a (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs update from Al Viro:
- big one - consolidation of descriptor-related logics; almost all of
that is moved to fs/file.c
(BTW, I'm seriously tempted to rename the result to fd.c. As it is,
we have a situation when file_table.c is about handling of struct
file and file.c is about handling of descriptor tables; the reasons
are historical - file_table.c used to be about a static array of
struct file we used to have way back).
A lot of stray ends got cleaned up and converted to saner primitives,
disgusting mess in android/binder.c is still disgusting, but at least
doesn't poke so much in descriptor table guts anymore. A bunch of
relatively minor races got fixed in process, plus an ext4 struct file
leak.
- related thing - fget_light() partially unuglified; see fdget() in
there (and yes, it generates the code as good as we used to have).
- also related - bits of Cyrill's procfs stuff that got entangled into
that work; _not_ all of it, just the initial move to fs/proc/fd.c and
switch of fdinfo to seq_file.
- Alex's fs/coredump.c spiltoff - the same story, had been easier to
take that commit than mess with conflicts. The rest is a separate
pile, this was just a mechanical code movement.
- a few misc patches all over the place. Not all for this cycle,
there'll be more (and quite a few currently sit in akpm's tree)."
Fix up trivial conflicts in the android binder driver, and some fairly
simple conflicts due to two different changes to the sock_alloc_file()
interface ("take descriptor handling from sock_alloc_file() to callers"
vs "net: Providing protocol type via system.sockprotoname xattr of
/proc/PID/fd entries" adding a dentry name to the socket)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (72 commits)
MAX_LFS_FILESIZE should be a loff_t
compat: fs: Generic compat_sys_sendfile implementation
fs: push rcu_barrier() from deactivate_locked_super() to filesystems
btrfs: reada_extent doesn't need kref for refcount
coredump: move core dump functionality into its own file
coredump: prevent double-free on an error path in core dumper
usb/gadget: fix misannotations
fcntl: fix misannotations
ceph: don't abuse d_delete() on failure exits
hypfs: ->d_parent is never NULL or negative
vfs: delete surplus inode NULL check
switch simple cases of fget_light to fdget
new helpers: fdget()/fdput()
switch o2hb_region_dev_write() to fget_light()
proc_map_files_readdir(): don't bother with grabbing files
make get_file() return its argument
vhost_set_vring(): turn pollstart/pollstop into bool
switch prctl_set_mm_exe_file() to fget_light()
switch xfs_find_handle() to fget_light()
switch xfs_swapext() to fget_light()
...
Diffstat (limited to 'fs/select.c')
-rw-r--r-- | fs/select.c | 31 |
1 files changed, 13 insertions, 18 deletions
diff --git a/fs/select.c b/fs/select.c index db14c781335..2ef72d96503 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -220,8 +220,7 @@ static void __pollwait(struct file *filp, wait_queue_head_t *wait_address, | |||
220 | struct poll_table_entry *entry = poll_get_entry(pwq); | 220 | struct poll_table_entry *entry = poll_get_entry(pwq); |
221 | if (!entry) | 221 | if (!entry) |
222 | return; | 222 | return; |
223 | get_file(filp); | 223 | entry->filp = get_file(filp); |
224 | entry->filp = filp; | ||
225 | entry->wait_address = wait_address; | 224 | entry->wait_address = wait_address; |
226 | entry->key = p->_key; | 225 | entry->key = p->_key; |
227 | init_waitqueue_func_entry(&entry->wait, pollwake); | 226 | init_waitqueue_func_entry(&entry->wait, pollwake); |
@@ -429,8 +428,6 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) | |||
429 | for (i = 0; i < n; ++rinp, ++routp, ++rexp) { | 428 | for (i = 0; i < n; ++rinp, ++routp, ++rexp) { |
430 | unsigned long in, out, ex, all_bits, bit = 1, mask, j; | 429 | unsigned long in, out, ex, all_bits, bit = 1, mask, j; |
431 | unsigned long res_in = 0, res_out = 0, res_ex = 0; | 430 | unsigned long res_in = 0, res_out = 0, res_ex = 0; |
432 | const struct file_operations *f_op = NULL; | ||
433 | struct file *file = NULL; | ||
434 | 431 | ||
435 | in = *inp++; out = *outp++; ex = *exp++; | 432 | in = *inp++; out = *outp++; ex = *exp++; |
436 | all_bits = in | out | ex; | 433 | all_bits = in | out | ex; |
@@ -440,20 +437,21 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) | |||
440 | } | 437 | } |
441 | 438 | ||
442 | for (j = 0; j < BITS_PER_LONG; ++j, ++i, bit <<= 1) { | 439 | for (j = 0; j < BITS_PER_LONG; ++j, ++i, bit <<= 1) { |
443 | int fput_needed; | 440 | struct fd f; |
444 | if (i >= n) | 441 | if (i >= n) |
445 | break; | 442 | break; |
446 | if (!(bit & all_bits)) | 443 | if (!(bit & all_bits)) |
447 | continue; | 444 | continue; |
448 | file = fget_light(i, &fput_needed); | 445 | f = fdget(i); |
449 | if (file) { | 446 | if (f.file) { |
450 | f_op = file->f_op; | 447 | const struct file_operations *f_op; |
448 | f_op = f.file->f_op; | ||
451 | mask = DEFAULT_POLLMASK; | 449 | mask = DEFAULT_POLLMASK; |
452 | if (f_op && f_op->poll) { | 450 | if (f_op && f_op->poll) { |
453 | wait_key_set(wait, in, out, bit); | 451 | wait_key_set(wait, in, out, bit); |
454 | mask = (*f_op->poll)(file, wait); | 452 | mask = (*f_op->poll)(f.file, wait); |
455 | } | 453 | } |
456 | fput_light(file, fput_needed); | 454 | fdput(f); |
457 | if ((mask & POLLIN_SET) && (in & bit)) { | 455 | if ((mask & POLLIN_SET) && (in & bit)) { |
458 | res_in |= bit; | 456 | res_in |= bit; |
459 | retval++; | 457 | retval++; |
@@ -726,20 +724,17 @@ static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait) | |||
726 | mask = 0; | 724 | mask = 0; |
727 | fd = pollfd->fd; | 725 | fd = pollfd->fd; |
728 | if (fd >= 0) { | 726 | if (fd >= 0) { |
729 | int fput_needed; | 727 | struct fd f = fdget(fd); |
730 | struct file * file; | ||
731 | |||
732 | file = fget_light(fd, &fput_needed); | ||
733 | mask = POLLNVAL; | 728 | mask = POLLNVAL; |
734 | if (file != NULL) { | 729 | if (f.file) { |
735 | mask = DEFAULT_POLLMASK; | 730 | mask = DEFAULT_POLLMASK; |
736 | if (file->f_op && file->f_op->poll) { | 731 | if (f.file->f_op && f.file->f_op->poll) { |
737 | pwait->_key = pollfd->events|POLLERR|POLLHUP; | 732 | pwait->_key = pollfd->events|POLLERR|POLLHUP; |
738 | mask = file->f_op->poll(file, pwait); | 733 | mask = f.file->f_op->poll(f.file, pwait); |
739 | } | 734 | } |
740 | /* Mask out unneeded events. */ | 735 | /* Mask out unneeded events. */ |
741 | mask &= pollfd->events | POLLERR | POLLHUP; | 736 | mask &= pollfd->events | POLLERR | POLLHUP; |
742 | fput_light(file, fput_needed); | 737 | fdput(f); |
743 | } | 738 | } |
744 | } | 739 | } |
745 | pollfd->revents = mask; | 740 | pollfd->revents = mask; |