diff options
-rw-r--r-- | drivers/staging/android/binder.c | 34 | ||||
-rw-r--r-- | fs/file.c | 26 | ||||
-rw-r--r-- | fs/open.c | 22 | ||||
-rw-r--r-- | include/linux/fdtable.h | 2 |
4 files changed, 31 insertions, 53 deletions
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 9e1a98a360d4..f71d624995ea 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c | |||
@@ -391,42 +391,16 @@ static void task_fd_install( | |||
391 | } | 391 | } |
392 | 392 | ||
393 | /* | 393 | /* |
394 | * copied from __put_unused_fd in open.c | ||
395 | */ | ||
396 | static void __put_unused_fd(struct files_struct *files, unsigned int fd) | ||
397 | { | ||
398 | struct fdtable *fdt = files_fdtable(files); | ||
399 | __clear_open_fd(fd, fdt); | ||
400 | if (fd < files->next_fd) | ||
401 | files->next_fd = fd; | ||
402 | } | ||
403 | |||
404 | /* | ||
405 | * copied from sys_close | 394 | * copied from sys_close |
406 | */ | 395 | */ |
407 | static long task_close_fd(struct binder_proc *proc, unsigned int fd) | 396 | static long task_close_fd(struct binder_proc *proc, unsigned int fd) |
408 | { | 397 | { |
409 | struct file *filp; | ||
410 | struct files_struct *files = proc->files; | ||
411 | struct fdtable *fdt; | ||
412 | int retval; | 398 | int retval; |
413 | 399 | ||
414 | if (files == NULL) | 400 | if (proc->files == NULL) |
415 | return -ESRCH; | 401 | return -ESRCH; |
416 | 402 | ||
417 | spin_lock(&files->file_lock); | 403 | retval = __close_fd(proc->files, fd); |
418 | fdt = files_fdtable(files); | ||
419 | if (fd >= fdt->max_fds) | ||
420 | goto out_unlock; | ||
421 | filp = fdt->fd[fd]; | ||
422 | if (!filp) | ||
423 | goto out_unlock; | ||
424 | rcu_assign_pointer(fdt->fd[fd], NULL); | ||
425 | __clear_close_on_exec(fd, fdt); | ||
426 | __put_unused_fd(files, fd); | ||
427 | spin_unlock(&files->file_lock); | ||
428 | retval = filp_close(filp, files); | ||
429 | |||
430 | /* can't restart close syscall because file table entry was cleared */ | 404 | /* can't restart close syscall because file table entry was cleared */ |
431 | if (unlikely(retval == -ERESTARTSYS || | 405 | if (unlikely(retval == -ERESTARTSYS || |
432 | retval == -ERESTARTNOINTR || | 406 | retval == -ERESTARTNOINTR || |
@@ -435,10 +409,6 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd) | |||
435 | retval = -EINTR; | 409 | retval = -EINTR; |
436 | 410 | ||
437 | return retval; | 411 | return retval; |
438 | |||
439 | out_unlock: | ||
440 | spin_unlock(&files->file_lock); | ||
441 | return -EBADF; | ||
442 | } | 412 | } |
443 | 413 | ||
444 | static void binder_set_nice(long nice) | 414 | static void binder_set_nice(long nice) |
@@ -626,6 +626,32 @@ void fd_install(unsigned int fd, struct file *file) | |||
626 | 626 | ||
627 | EXPORT_SYMBOL(fd_install); | 627 | EXPORT_SYMBOL(fd_install); |
628 | 628 | ||
629 | /* | ||
630 | * The same warnings as for __alloc_fd()/__fd_install() apply here... | ||
631 | */ | ||
632 | int __close_fd(struct files_struct *files, unsigned fd) | ||
633 | { | ||
634 | struct file *file; | ||
635 | struct fdtable *fdt; | ||
636 | |||
637 | spin_lock(&files->file_lock); | ||
638 | fdt = files_fdtable(files); | ||
639 | if (fd >= fdt->max_fds) | ||
640 | goto out_unlock; | ||
641 | file = fdt->fd[fd]; | ||
642 | if (!file) | ||
643 | goto out_unlock; | ||
644 | rcu_assign_pointer(fdt->fd[fd], NULL); | ||
645 | __clear_close_on_exec(fd, fdt); | ||
646 | __put_unused_fd(files, fd); | ||
647 | spin_unlock(&files->file_lock); | ||
648 | return filp_close(file, files); | ||
649 | |||
650 | out_unlock: | ||
651 | spin_unlock(&files->file_lock); | ||
652 | return -EBADF; | ||
653 | } | ||
654 | |||
629 | struct file *fget(unsigned int fd) | 655 | struct file *fget(unsigned int fd) |
630 | { | 656 | { |
631 | struct file *file; | 657 | struct file *file; |
@@ -994,23 +994,7 @@ EXPORT_SYMBOL(filp_close); | |||
994 | */ | 994 | */ |
995 | SYSCALL_DEFINE1(close, unsigned int, fd) | 995 | SYSCALL_DEFINE1(close, unsigned int, fd) |
996 | { | 996 | { |
997 | struct file * filp; | 997 | int retval = __close_fd(current->files, fd); |
998 | struct files_struct *files = current->files; | ||
999 | struct fdtable *fdt; | ||
1000 | int retval; | ||
1001 | |||
1002 | spin_lock(&files->file_lock); | ||
1003 | fdt = files_fdtable(files); | ||
1004 | if (fd >= fdt->max_fds) | ||
1005 | goto out_unlock; | ||
1006 | filp = fdt->fd[fd]; | ||
1007 | if (!filp) | ||
1008 | goto out_unlock; | ||
1009 | rcu_assign_pointer(fdt->fd[fd], NULL); | ||
1010 | __clear_close_on_exec(fd, fdt); | ||
1011 | __put_unused_fd(files, fd); | ||
1012 | spin_unlock(&files->file_lock); | ||
1013 | retval = filp_close(filp, files); | ||
1014 | 998 | ||
1015 | /* can't restart close syscall because file table entry was cleared */ | 999 | /* can't restart close syscall because file table entry was cleared */ |
1016 | if (unlikely(retval == -ERESTARTSYS || | 1000 | if (unlikely(retval == -ERESTARTSYS || |
@@ -1020,10 +1004,6 @@ SYSCALL_DEFINE1(close, unsigned int, fd) | |||
1020 | retval = -EINTR; | 1004 | retval = -EINTR; |
1021 | 1005 | ||
1022 | return retval; | 1006 | return retval; |
1023 | |||
1024 | out_unlock: | ||
1025 | spin_unlock(&files->file_lock); | ||
1026 | return -EBADF; | ||
1027 | } | 1007 | } |
1028 | EXPORT_SYMBOL(sys_close); | 1008 | EXPORT_SYMBOL(sys_close); |
1029 | 1009 | ||
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h index 59d4fc7f10c8..59488f2392bc 100644 --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h | |||
@@ -123,6 +123,8 @@ extern int __alloc_fd(struct files_struct *files, | |||
123 | unsigned start, unsigned end, unsigned flags); | 123 | unsigned start, unsigned end, unsigned flags); |
124 | extern void __fd_install(struct files_struct *files, | 124 | extern void __fd_install(struct files_struct *files, |
125 | unsigned int fd, struct file *file); | 125 | unsigned int fd, struct file *file); |
126 | extern int __close_fd(struct files_struct *files, | ||
127 | unsigned int fd); | ||
126 | 128 | ||
127 | extern struct kmem_cache *files_cachep; | 129 | extern struct kmem_cache *files_cachep; |
128 | 130 | ||