diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-11-29 22:57:33 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-11-29 23:01:30 -0500 |
commit | a77cfcb429ed98845a4e4df72473b8f37acd890b (patch) | |
tree | 25a10ee731ab94f0ab4cbcd22414b5faff027768 | |
parent | 21d8a15ac333b05f1fecdf9fdc30996be2e11d60 (diff) |
fix off-by-one in argument passed by iterate_fd() to callbacks
Noticed by Pavel Roskin; the thing in his patch I disagree with
was compensating for that shite in callbacks instead of fixing
it once in the iterator itself.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/file.c | 14 |
1 files changed, 8 insertions, 6 deletions
@@ -994,16 +994,18 @@ int iterate_fd(struct files_struct *files, unsigned n, | |||
994 | const void *p) | 994 | const void *p) |
995 | { | 995 | { |
996 | struct fdtable *fdt; | 996 | struct fdtable *fdt; |
997 | struct file *file; | ||
998 | int res = 0; | 997 | int res = 0; |
999 | if (!files) | 998 | if (!files) |
1000 | return 0; | 999 | return 0; |
1001 | spin_lock(&files->file_lock); | 1000 | spin_lock(&files->file_lock); |
1002 | fdt = files_fdtable(files); | 1001 | for (fdt = files_fdtable(files); n < fdt->max_fds; n++) { |
1003 | while (!res && n < fdt->max_fds) { | 1002 | struct file *file; |
1004 | file = rcu_dereference_check_fdtable(files, fdt->fd[n++]); | 1003 | file = rcu_dereference_check_fdtable(files, fdt->fd[n]); |
1005 | if (file) | 1004 | if (!file) |
1006 | res = f(p, file, n); | 1005 | continue; |
1006 | res = f(p, file, n); | ||
1007 | if (res) | ||
1008 | break; | ||
1007 | } | 1009 | } |
1008 | spin_unlock(&files->file_lock); | 1010 | spin_unlock(&files->file_lock); |
1009 | return res; | 1011 | return res; |