diff options
Diffstat (limited to 'fs/file.c')
-rw-r--r-- | fs/file.c | 19 |
1 files changed, 10 insertions, 9 deletions
@@ -685,7 +685,6 @@ void do_close_on_exec(struct files_struct *files) | |||
685 | struct fdtable *fdt; | 685 | struct fdtable *fdt; |
686 | 686 | ||
687 | /* exec unshares first */ | 687 | /* exec unshares first */ |
688 | BUG_ON(atomic_read(&files->count) != 1); | ||
689 | spin_lock(&files->file_lock); | 688 | spin_lock(&files->file_lock); |
690 | for (i = 0; ; i++) { | 689 | for (i = 0; ; i++) { |
691 | unsigned long set; | 690 | unsigned long set; |
@@ -900,7 +899,7 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags) | |||
900 | return __close_fd(files, fd); | 899 | return __close_fd(files, fd); |
901 | 900 | ||
902 | if (fd >= rlimit(RLIMIT_NOFILE)) | 901 | if (fd >= rlimit(RLIMIT_NOFILE)) |
903 | return -EMFILE; | 902 | return -EBADF; |
904 | 903 | ||
905 | spin_lock(&files->file_lock); | 904 | spin_lock(&files->file_lock); |
906 | err = expand_files(files, fd); | 905 | err = expand_files(files, fd); |
@@ -926,7 +925,7 @@ SYSCALL_DEFINE3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags) | |||
926 | return -EINVAL; | 925 | return -EINVAL; |
927 | 926 | ||
928 | if (newfd >= rlimit(RLIMIT_NOFILE)) | 927 | if (newfd >= rlimit(RLIMIT_NOFILE)) |
929 | return -EMFILE; | 928 | return -EBADF; |
930 | 929 | ||
931 | spin_lock(&files->file_lock); | 930 | spin_lock(&files->file_lock); |
932 | err = expand_files(files, newfd); | 931 | err = expand_files(files, newfd); |
@@ -995,16 +994,18 @@ int iterate_fd(struct files_struct *files, unsigned n, | |||
995 | const void *p) | 994 | const void *p) |
996 | { | 995 | { |
997 | struct fdtable *fdt; | 996 | struct fdtable *fdt; |
998 | struct file *file; | ||
999 | int res = 0; | 997 | int res = 0; |
1000 | if (!files) | 998 | if (!files) |
1001 | return 0; | 999 | return 0; |
1002 | spin_lock(&files->file_lock); | 1000 | spin_lock(&files->file_lock); |
1003 | fdt = files_fdtable(files); | 1001 | for (fdt = files_fdtable(files); n < fdt->max_fds; n++) { |
1004 | while (!res && n < fdt->max_fds) { | 1002 | struct file *file; |
1005 | file = rcu_dereference_check_fdtable(files, fdt->fd[n++]); | 1003 | file = rcu_dereference_check_fdtable(files, fdt->fd[n]); |
1006 | if (file) | 1004 | if (!file) |
1007 | res = f(p, file, n); | 1005 | continue; |
1006 | res = f(p, file, n); | ||
1007 | if (res) | ||
1008 | break; | ||
1008 | } | 1009 | } |
1009 | spin_unlock(&files->file_lock); | 1010 | spin_unlock(&files->file_lock); |
1010 | return res; | 1011 | return res; |