Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pull-18-rc1-work.fd' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull file descriptor updates from Al Viro.

- Descriptor handling cleanups

* tag 'pull-18-rc1-work.fd' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
Unify the primitives for file descriptor closing
fs: remove fget_many and fput_many interface
io_uring_enter(): don't leave f.flags uninitialized

+55 -94
+1 -1
drivers/android/binder.c
··· 1884 1884 if (!twcb) 1885 1885 return; 1886 1886 init_task_work(&twcb->twork, binder_do_fd_close); 1887 - close_fd_get_file(fd, &twcb->file); 1887 + twcb->file = close_fd_get_file(fd); 1888 1888 if (twcb->file) { 1889 1889 filp_close(twcb->file, current->files); 1890 1890 task_work_add(current, &twcb->twork, TWA_RESUME);
+42 -68
fs/file.c
··· 630 630 * @files: file struct to retrieve file from 631 631 * @fd: file descriptor to retrieve file for 632 632 * 633 - * If this functions returns an EINVAL error pointer the fd was beyond the 634 - * current maximum number of file descriptors for that fdtable. 633 + * Context: files_lock must be held. 635 634 * 636 - * Returns: The file associated with @fd, on error returns an error pointer. 635 + * Returns: The file associated with @fd (NULL if @fd is not open) 637 636 */ 638 637 static struct file *pick_file(struct files_struct *files, unsigned fd) 639 638 { 639 + struct fdtable *fdt = files_fdtable(files); 640 640 struct file *file; 641 - struct fdtable *fdt; 642 641 643 - spin_lock(&files->file_lock); 644 - fdt = files_fdtable(files); 645 - if (fd >= fdt->max_fds) { 646 - file = ERR_PTR(-EINVAL); 647 - goto out_unlock; 648 - } 642 + if (fd >= fdt->max_fds) 643 + return NULL; 644 + 649 645 file = fdt->fd[fd]; 650 - if (!file) { 651 - file = ERR_PTR(-EBADF); 652 - goto out_unlock; 646 + if (file) { 647 + rcu_assign_pointer(fdt->fd[fd], NULL); 648 + __put_unused_fd(files, fd); 653 649 } 654 - rcu_assign_pointer(fdt->fd[fd], NULL); 655 - __put_unused_fd(files, fd); 656 - 657 - out_unlock: 658 - spin_unlock(&files->file_lock); 659 650 return file; 660 651 } 661 652 ··· 655 664 struct files_struct *files = current->files; 656 665 struct file *file; 657 666 667 + spin_lock(&files->file_lock); 658 668 file = pick_file(files, fd); 659 - if (IS_ERR(file)) 669 + spin_unlock(&files->file_lock); 670 + if (!file) 660 671 return -EBADF; 661 672 662 673 return filp_close(file, files); ··· 695 702 static inline void __range_close(struct files_struct *cur_fds, unsigned int fd, 696 703 unsigned int max_fd) 697 704 { 705 + unsigned n; 706 + 707 + rcu_read_lock(); 708 + n = last_fd(files_fdtable(cur_fds)); 709 + rcu_read_unlock(); 710 + max_fd = min(max_fd, n); 711 + 698 712 while (fd <= max_fd) { 699 713 struct file *file; 700 714 715 + spin_lock(&cur_fds->file_lock); 701 716 file = pick_file(cur_fds, fd++); 702 - if (!IS_ERR(file)) { 717 + spin_unlock(&cur_fds->file_lock); 718 + 719 + if (file) { 703 720 /* found a valid file to close */ 704 721 filp_close(file, cur_fds); 705 722 cond_resched(); 706 - continue; 707 723 } 708 - 709 - /* beyond the last fd in that table */ 710 - if (PTR_ERR(file) == -EINVAL) 711 - return; 712 724 } 713 725 } 714 726 ··· 793 795 * See close_fd_get_file() below, this variant assumes current->files->file_lock 794 796 * is held. 795 797 */ 796 - int __close_fd_get_file(unsigned int fd, struct file **res) 798 + struct file *__close_fd_get_file(unsigned int fd) 797 799 { 798 - struct files_struct *files = current->files; 799 - struct file *file; 800 - struct fdtable *fdt; 801 - 802 - fdt = files_fdtable(files); 803 - if (fd >= fdt->max_fds) 804 - goto out_err; 805 - file = fdt->fd[fd]; 806 - if (!file) 807 - goto out_err; 808 - rcu_assign_pointer(fdt->fd[fd], NULL); 809 - __put_unused_fd(files, fd); 810 - get_file(file); 811 - *res = file; 812 - return 0; 813 - out_err: 814 - *res = NULL; 815 - return -ENOENT; 800 + return pick_file(current->files, fd); 816 801 } 817 802 818 803 /* ··· 803 822 * The caller must ensure that filp_close() called on the file, and then 804 823 * an fput(). 805 824 */ 806 - int close_fd_get_file(unsigned int fd, struct file **res) 825 + struct file *close_fd_get_file(unsigned int fd) 807 826 { 808 827 struct files_struct *files = current->files; 809 - int ret; 828 + struct file *file; 810 829 811 830 spin_lock(&files->file_lock); 812 - ret = __close_fd_get_file(fd, res); 831 + file = pick_file(files, fd); 813 832 spin_unlock(&files->file_lock); 814 833 815 - return ret; 834 + return file; 816 835 } 817 836 818 837 void do_close_on_exec(struct files_struct *files) ··· 852 871 } 853 872 854 873 static inline struct file *__fget_files_rcu(struct files_struct *files, 855 - unsigned int fd, fmode_t mask, unsigned int refs) 874 + unsigned int fd, fmode_t mask) 856 875 { 857 876 for (;;) { 858 877 struct file *file; ··· 878 897 * Such a race can take two forms: 879 898 * 880 899 * (a) the file ref already went down to zero, 881 - * and get_file_rcu_many() fails. Just try 882 - * again: 900 + * and get_file_rcu() fails. Just try again: 883 901 */ 884 - if (unlikely(!get_file_rcu_many(file, refs))) 902 + if (unlikely(!get_file_rcu(file))) 885 903 continue; 886 904 887 905 /* ··· 889 909 * pointer having changed, because it always goes 890 910 * hand-in-hand with 'fdt'. 891 911 * 892 - * If so, we need to put our refs and try again. 912 + * If so, we need to put our ref and try again. 893 913 */ 894 914 if (unlikely(rcu_dereference_raw(files->fdt) != fdt) || 895 915 unlikely(rcu_dereference_raw(*fdentry) != file)) { 896 - fput_many(file, refs); 916 + fput(file); 897 917 continue; 898 918 } 899 919 ··· 906 926 } 907 927 908 928 static struct file *__fget_files(struct files_struct *files, unsigned int fd, 909 - fmode_t mask, unsigned int refs) 929 + fmode_t mask) 910 930 { 911 931 struct file *file; 912 932 913 933 rcu_read_lock(); 914 - file = __fget_files_rcu(files, fd, mask, refs); 934 + file = __fget_files_rcu(files, fd, mask); 915 935 rcu_read_unlock(); 916 936 917 937 return file; 918 938 } 919 939 920 - static inline struct file *__fget(unsigned int fd, fmode_t mask, 921 - unsigned int refs) 940 + static inline struct file *__fget(unsigned int fd, fmode_t mask) 922 941 { 923 - return __fget_files(current->files, fd, mask, refs); 924 - } 925 - 926 - struct file *fget_many(unsigned int fd, unsigned int refs) 927 - { 928 - return __fget(fd, FMODE_PATH, refs); 942 + return __fget_files(current->files, fd, mask); 929 943 } 930 944 931 945 struct file *fget(unsigned int fd) 932 946 { 933 - return __fget(fd, FMODE_PATH, 1); 947 + return __fget(fd, FMODE_PATH); 934 948 } 935 949 EXPORT_SYMBOL(fget); 936 950 937 951 struct file *fget_raw(unsigned int fd) 938 952 { 939 - return __fget(fd, 0, 1); 953 + return __fget(fd, 0); 940 954 } 941 955 EXPORT_SYMBOL(fget_raw); 942 956 ··· 940 966 941 967 task_lock(task); 942 968 if (task->files) 943 - file = __fget_files(task->files, fd, 0, 1); 969 + file = __fget_files(task->files, fd, 0); 944 970 task_unlock(task); 945 971 946 972 return file; ··· 1009 1035 return 0; 1010 1036 return (unsigned long)file; 1011 1037 } else { 1012 - file = __fget(fd, mask, 1); 1038 + file = __fget(fd, mask); 1013 1039 if (!file) 1014 1040 return 0; 1015 1041 return FDPUT_FPUT | (unsigned long)file;
+2 -7
fs/file_table.c
··· 368 368 369 369 static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput); 370 370 371 - void fput_many(struct file *file, unsigned int refs) 371 + void fput(struct file *file) 372 372 { 373 - if (atomic_long_sub_and_test(refs, &file->f_count)) { 373 + if (atomic_long_dec_and_test(&file->f_count)) { 374 374 struct task_struct *task = current; 375 375 376 376 if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) { ··· 387 387 if (llist_add(&file->f_u.fu_llist, &delayed_fput_list)) 388 388 schedule_delayed_work(&delayed_fput_work, 1); 389 389 } 390 - } 391 - 392 - void fput(struct file *file) 393 - { 394 - fput_many(file, 1); 395 390 } 396 391 397 392 /*
+1 -1
fs/internal.h
··· 125 125 const char *, const struct open_flags *); 126 126 extern struct open_how build_open_how(int flags, umode_t mode); 127 127 extern int build_open_flags(const struct open_how *how, struct open_flags *op); 128 - extern int __close_fd_get_file(unsigned int fd, struct file **res); 128 + extern struct file *__close_fd_get_file(unsigned int fd); 129 129 130 130 long do_sys_ftruncate(unsigned int fd, loff_t length, int small); 131 131 int chmod_common(const struct path *path, umode_t mode);
+7 -11
fs/io_uring.c
··· 6039 6039 return -EAGAIN; 6040 6040 } 6041 6041 6042 - ret = __close_fd_get_file(close->fd, &file); 6042 + file = __close_fd_get_file(close->fd); 6043 6043 spin_unlock(&files->file_lock); 6044 - if (ret < 0) { 6045 - if (ret == -ENOENT) 6046 - ret = -EBADF; 6044 + if (!file) 6047 6045 goto err; 6048 - } 6049 6046 6050 6047 /* No ->flush() or already async, safely close from here */ 6051 6048 ret = filp_close(file, current->files); ··· 12050 12053 return -EINVAL; 12051 12054 fd = array_index_nospec(fd, IO_RINGFD_REG_MAX); 12052 12055 f.file = tctx->registered_rings[fd]; 12053 - if (unlikely(!f.file)) 12054 - return -EBADF; 12056 + f.flags = 0; 12055 12057 } else { 12056 12058 f = fdget(fd); 12057 - if (unlikely(!f.file)) 12058 - return -EBADF; 12059 12059 } 12060 + 12061 + if (unlikely(!f.file)) 12062 + return -EBADF; 12060 12063 12061 12064 ret = -EOPNOTSUPP; 12062 12065 if (unlikely(f.file->f_op != &io_uring_fops)) ··· 12155 12158 out: 12156 12159 percpu_ref_put(&ctx->refs); 12157 12160 out_fput: 12158 - if (!(flags & IORING_ENTER_REGISTERED_RING)) 12159 - fdput(f); 12161 + fdput(f); 12160 12162 return ret; 12161 12163 } 12162 12164
+1 -1
include/linux/fdtable.h
··· 125 125 126 126 extern int close_fd(unsigned int fd); 127 127 extern int __close_range(unsigned int fd, unsigned int max_fd, unsigned int flags); 128 - extern int close_fd_get_file(unsigned int fd, struct file **res); 128 + extern struct file *close_fd_get_file(unsigned int fd); 129 129 extern int unshare_fd(unsigned long unshare_flags, unsigned int max_fds, 130 130 struct files_struct **new_fdp); 131 131
-2
include/linux/file.h
··· 14 14 struct file; 15 15 16 16 extern void fput(struct file *); 17 - extern void fput_many(struct file *, unsigned int); 18 17 19 18 struct file_operations; 20 19 struct task_struct; ··· 46 47 } 47 48 48 49 extern struct file *fget(unsigned int fd); 49 - extern struct file *fget_many(unsigned int fd, unsigned int refs); 50 50 extern struct file *fget_raw(unsigned int fd); 51 51 extern struct file *fget_task(struct task_struct *task, unsigned int fd); 52 52 extern unsigned long __fdget(unsigned int fd);
+1 -3
include/linux/fs.h
··· 974 974 atomic_long_inc(&f->f_count); 975 975 return f; 976 976 } 977 - #define get_file_rcu_many(x, cnt) \ 978 - atomic_long_add_unless(&(x)->f_count, (cnt), 0) 979 - #define get_file_rcu(x) get_file_rcu_many((x), 1) 977 + #define get_file_rcu(x) atomic_long_inc_not_zero(&(x)->f_count) 980 978 #define file_count(x) atomic_long_read(&(x)->f_count) 981 979 982 980 #define MAX_NON_LFS ((1UL<<31) - 1)