aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-11-29 22:57:33 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2012-11-29 23:01:30 -0500
commita77cfcb429ed98845a4e4df72473b8f37acd890b (patch)
tree25a10ee731ab94f0ab4cbcd22414b5faff027768
parent21d8a15ac333b05f1fecdf9fdc30996be2e11d60 (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.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/fs/file.c b/fs/file.c
index 7cb71b992603..eff23162485f 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -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;