Skip to content

Commit 2394b31

Browse files
committed
Merge branch 'vfs.file' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs into for-6.8/io_uring
Merge vfs.file from the VFS tree to avoid conflicts with receive_fd() now having 3 arguments rather than just 2. * 'vfs.file' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: file: remove __receive_fd() file: stop exposing receive_fd_user() fs: replace f_rcuhead with f_task_work file: remove pointless wrapper file: s/close_fd_get_file()/file_close_fd()/g Improve __fget_files_rcu() code generation (and thus __fget_light()) file: massage cleanup of files that failed to open
2 parents a39b6ac + 4e94ddf commit 2394b31

16 files changed

Lines changed: 95 additions & 92 deletions

File tree

drivers/android/binder.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1921,7 +1921,7 @@ static void binder_deferred_fd_close(int fd)
19211921
if (!twcb)
19221922
return;
19231923
init_task_work(&twcb->twork, binder_do_fd_close);
1924-
twcb->file = close_fd_get_file(fd);
1924+
twcb->file = file_close_fd(fd);
19251925
if (twcb->file) {
19261926
// pin it until binder_do_fd_close(); see comments there
19271927
get_file(twcb->file);

drivers/vdpa/vdpa_user/vduse_dev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1157,7 +1157,7 @@ static long vduse_dev_ioctl(struct file *file, unsigned int cmd,
11571157
fput(f);
11581158
break;
11591159
}
1160-
ret = receive_fd(f, perm_to_file_flags(entry.perm));
1160+
ret = receive_fd(f, NULL, perm_to_file_flags(entry.perm));
11611161
fput(f);
11621162
break;
11631163
}

fs/file.c

Lines changed: 53 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -629,19 +629,23 @@ void fd_install(unsigned int fd, struct file *file)
629629
EXPORT_SYMBOL(fd_install);
630630

631631
/**
632-
* pick_file - return file associatd with fd
632+
* file_close_fd_locked - return file associated with fd
633633
* @files: file struct to retrieve file from
634634
* @fd: file descriptor to retrieve file for
635635
*
636+
* Doesn't take a separate reference count.
637+
*
636638
* Context: files_lock must be held.
637639
*
638640
* Returns: The file associated with @fd (NULL if @fd is not open)
639641
*/
640-
static struct file *pick_file(struct files_struct *files, unsigned fd)
642+
struct file *file_close_fd_locked(struct files_struct *files, unsigned fd)
641643
{
642644
struct fdtable *fdt = files_fdtable(files);
643645
struct file *file;
644646

647+
lockdep_assert_held(&files->file_lock);
648+
645649
if (fd >= fdt->max_fds)
646650
return NULL;
647651

@@ -660,7 +664,7 @@ int close_fd(unsigned fd)
660664
struct file *file;
661665

662666
spin_lock(&files->file_lock);
663-
file = pick_file(files, fd);
667+
file = file_close_fd_locked(files, fd);
664668
spin_unlock(&files->file_lock);
665669
if (!file)
666670
return -EBADF;
@@ -707,7 +711,7 @@ static inline void __range_close(struct files_struct *files, unsigned int fd,
707711
max_fd = min(max_fd, n);
708712

709713
for (; fd <= max_fd; fd++) {
710-
file = pick_file(files, fd);
714+
file = file_close_fd_locked(files, fd);
711715
if (file) {
712716
spin_unlock(&files->file_lock);
713717
filp_close(file, files);
@@ -795,26 +799,21 @@ int __close_range(unsigned fd, unsigned max_fd, unsigned int flags)
795799
return 0;
796800
}
797801

798-
/*
799-
* See close_fd_get_file() below, this variant assumes current->files->file_lock
800-
* is held.
801-
*/
802-
struct file *__close_fd_get_file(unsigned int fd)
803-
{
804-
return pick_file(current->files, fd);
805-
}
806-
807-
/*
808-
* variant of close_fd that gets a ref on the file for later fput.
809-
* The caller must ensure that filp_close() called on the file.
802+
/**
803+
* file_close_fd - return file associated with fd
804+
* @fd: file descriptor to retrieve file for
805+
*
806+
* Doesn't take a separate reference count.
807+
*
808+
* Returns: The file associated with @fd (NULL if @fd is not open)
810809
*/
811-
struct file *close_fd_get_file(unsigned int fd)
810+
struct file *file_close_fd(unsigned int fd)
812811
{
813812
struct files_struct *files = current->files;
814813
struct file *file;
815814

816815
spin_lock(&files->file_lock);
817-
file = pick_file(files, fd);
816+
file = file_close_fd_locked(files, fd);
818817
spin_unlock(&files->file_lock);
819818

820819
return file;
@@ -959,39 +958,54 @@ static inline struct file *__fget_files_rcu(struct files_struct *files,
959958
struct file *file;
960959
struct fdtable *fdt = rcu_dereference_raw(files->fdt);
961960
struct file __rcu **fdentry;
961+
unsigned long nospec_mask;
962962

963-
if (unlikely(fd >= fdt->max_fds))
964-
return NULL;
965-
966-
fdentry = fdt->fd + array_index_nospec(fd, fdt->max_fds);
963+
/* Mask is a 0 for invalid fd's, ~0 for valid ones */
964+
nospec_mask = array_index_mask_nospec(fd, fdt->max_fds);
967965

968966
/*
969-
* Ok, we have a file pointer. However, because we do
970-
* this all locklessly under RCU, we may be racing with
971-
* that file being closed.
972-
*
973-
* Such a race can take two forms:
974-
*
975-
* (a) the file ref already went down to zero and the
976-
* file hasn't been reused yet or the file count
977-
* isn't zero but the file has already been reused.
967+
* fdentry points to the 'fd' offset, or fdt->fd[0].
968+
* Loading from fdt->fd[0] is always safe, because the
969+
* array always exists.
978970
*/
979-
file = __get_file_rcu(fdentry);
971+
fdentry = fdt->fd + (fd & nospec_mask);
972+
973+
/* Do the load, then mask any invalid result */
974+
file = rcu_dereference_raw(*fdentry);
975+
file = (void *)(nospec_mask & (unsigned long)file);
980976
if (unlikely(!file))
981977
return NULL;
982978

983-
if (unlikely(IS_ERR(file)))
979+
/*
980+
* Ok, we have a file pointer that was valid at
981+
* some point, but it might have become stale since.
982+
*
983+
* We need to confirm it by incrementing the refcount
984+
* and then check the lookup again.
985+
*
986+
* atomic_long_inc_not_zero() gives us a full memory
987+
* barrier. We only really need an 'acquire' one to
988+
* protect the loads below, but we don't have that.
989+
*/
990+
if (unlikely(!atomic_long_inc_not_zero(&file->f_count)))
984991
continue;
985992

986993
/*
994+
* Such a race can take two forms:
995+
*
996+
* (a) the file ref already went down to zero and the
997+
* file hasn't been reused yet or the file count
998+
* isn't zero but the file has already been reused.
999+
*
9871000
* (b) the file table entry has changed under us.
9881001
* Note that we don't need to re-check the 'fdt->fd'
9891002
* pointer having changed, because it always goes
9901003
* hand-in-hand with 'fdt'.
9911004
*
9921005
* If so, we need to put our ref and try again.
9931006
*/
994-
if (unlikely(rcu_dereference_raw(files->fdt) != fdt)) {
1007+
if (unlikely(file != rcu_dereference_raw(*fdentry)) ||
1008+
unlikely(rcu_dereference_raw(files->fdt) != fdt)) {
9951009
fput(file);
9961010
continue;
9971011
}
@@ -1128,13 +1142,13 @@ static unsigned long __fget_light(unsigned int fd, fmode_t mask)
11281142
* atomic_read_acquire() pairs with atomic_dec_and_test() in
11291143
* put_files_struct().
11301144
*/
1131-
if (atomic_read_acquire(&files->count) == 1) {
1145+
if (likely(atomic_read_acquire(&files->count) == 1)) {
11321146
file = files_lookup_fd_raw(files, fd);
11331147
if (!file || unlikely(file->f_mode & mask))
11341148
return 0;
11351149
return (unsigned long)file;
11361150
} else {
1137-
file = __fget(fd, mask);
1151+
file = __fget_files(files, fd, mask);
11381152
if (!file)
11391153
return 0;
11401154
return FDPUT_FPUT | (unsigned long)file;
@@ -1282,7 +1296,7 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags)
12821296
}
12831297

12841298
/**
1285-
* __receive_fd() - Install received file into file descriptor table
1299+
* receive_fd() - Install received file into file descriptor table
12861300
* @file: struct file that was received from another process
12871301
* @ufd: __user pointer to write new fd number to
12881302
* @o_flags: the O_* flags to apply to the new fd entry
@@ -1296,7 +1310,7 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags)
12961310
*
12971311
* Returns newly install fd or -ve on error.
12981312
*/
1299-
int __receive_fd(struct file *file, int __user *ufd, unsigned int o_flags)
1313+
int receive_fd(struct file *file, int __user *ufd, unsigned int o_flags)
13001314
{
13011315
int new_fd;
13021316
int error;
@@ -1321,6 +1335,7 @@ int __receive_fd(struct file *file, int __user *ufd, unsigned int o_flags)
13211335
__receive_sock(file);
13221336
return new_fd;
13231337
}
1338+
EXPORT_SYMBOL_GPL(receive_fd);
13241339

13251340
int receive_fd_replace(int new_fd, struct file *file, unsigned int o_flags)
13261341
{
@@ -1336,12 +1351,6 @@ int receive_fd_replace(int new_fd, struct file *file, unsigned int o_flags)
13361351
return new_fd;
13371352
}
13381353

1339-
int receive_fd(struct file *file, unsigned int o_flags)
1340-
{
1341-
return __receive_fd(file, NULL, o_flags);
1342-
}
1343-
EXPORT_SYMBOL_GPL(receive_fd);
1344-
13451354
static int ksys_dup3(unsigned int oldfd, unsigned int newfd, int flags)
13461355
{
13471356
int err = -EBADF;

fs/file_table.c

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -75,18 +75,6 @@ static inline void file_free(struct file *f)
7575
}
7676
}
7777

78-
void release_empty_file(struct file *f)
79-
{
80-
WARN_ON_ONCE(f->f_mode & (FMODE_BACKING | FMODE_OPENED));
81-
if (atomic_long_dec_and_test(&f->f_count)) {
82-
security_file_free(f);
83-
put_cred(f->f_cred);
84-
if (likely(!(f->f_mode & FMODE_NOACCOUNT)))
85-
percpu_counter_dec(&nr_files);
86-
kmem_cache_free(filp_cachep, f);
87-
}
88-
}
89-
9078
/*
9179
* Return the total number of open files in the system
9280
*/
@@ -419,7 +407,7 @@ static void delayed_fput(struct work_struct *unused)
419407

420408
static void ____fput(struct callback_head *work)
421409
{
422-
__fput(container_of(work, struct file, f_rcuhead));
410+
__fput(container_of(work, struct file, f_task_work));
423411
}
424412

425413
/*
@@ -445,9 +433,13 @@ void fput(struct file *file)
445433
if (atomic_long_dec_and_test(&file->f_count)) {
446434
struct task_struct *task = current;
447435

436+
if (unlikely(!(file->f_mode & (FMODE_BACKING | FMODE_OPENED)))) {
437+
file_free(file);
438+
return;
439+
}
448440
if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) {
449-
init_task_work(&file->f_rcuhead, ____fput);
450-
if (!task_work_add(task, &file->f_rcuhead, TWA_RESUME))
441+
init_task_work(&file->f_task_work, ____fput);
442+
if (!task_work_add(task, &file->f_task_work, TWA_RESUME))
451443
return;
452444
/*
453445
* After this task has run exit_task_work(),

fs/internal.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ extern void chroot_fs_refs(const struct path *, const struct path *);
9494
struct file *alloc_empty_file(int flags, const struct cred *cred);
9595
struct file *alloc_empty_file_noaccount(int flags, const struct cred *cred);
9696
struct file *alloc_empty_backing_file(int flags, const struct cred *cred);
97-
void release_empty_file(struct file *f);
9897

9998
static inline void file_put_write_access(struct file *file)
10099
{
@@ -180,7 +179,7 @@ extern struct file *do_file_open_root(const struct path *,
180179
const char *, const struct open_flags *);
181180
extern struct open_how build_open_how(int flags, umode_t mode);
182181
extern int build_open_flags(const struct open_how *how, struct open_flags *op);
183-
extern struct file *__close_fd_get_file(unsigned int fd);
182+
struct file *file_close_fd_locked(struct files_struct *files, unsigned fd);
184183

185184
long do_sys_ftruncate(unsigned int fd, loff_t length, int small);
186185
int chmod_common(const struct path *path, umode_t mode);

fs/namei.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3785,10 +3785,7 @@ static struct file *path_openat(struct nameidata *nd,
37853785
WARN_ON(1);
37863786
error = -EINVAL;
37873787
}
3788-
if (unlikely(file->f_mode & FMODE_OPENED))
3789-
fput(file);
3790-
else
3791-
release_empty_file(file);
3788+
fput(file);
37923789
if (error == -EOPENSTALE) {
37933790
if (flags & LOOKUP_RCU)
37943791
error = -ECHILD;

fs/open.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1577,7 +1577,7 @@ SYSCALL_DEFINE1(close, unsigned int, fd)
15771577
int retval;
15781578
struct file *file;
15791579

1580-
file = close_fd_get_file(fd);
1580+
file = file_close_fd(fd);
15811581
if (!file)
15821582
return -EBADF;
15831583

include/linux/fdtable.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,17 @@ struct dentry;
8383
static inline struct file *files_lookup_fd_raw(struct files_struct *files, unsigned int fd)
8484
{
8585
struct fdtable *fdt = rcu_dereference_raw(files->fdt);
86-
87-
if (fd < fdt->max_fds) {
88-
fd = array_index_nospec(fd, fdt->max_fds);
89-
return rcu_dereference_raw(fdt->fd[fd]);
90-
}
91-
return NULL;
86+
unsigned long mask = array_index_mask_nospec(fd, fdt->max_fds);
87+
struct file *needs_masking;
88+
89+
/*
90+
* 'mask' is zero for an out-of-bounds fd, all ones for ok.
91+
* 'fd&mask' is 'fd' for ok, or 0 for out of bounds.
92+
*
93+
* Accessing fdt->fd[0] is ok, but needs masking of the result.
94+
*/
95+
needs_masking = rcu_dereference_raw(fdt->fd[fd&mask]);
96+
return (struct file *)(mask & (unsigned long)needs_masking);
9297
}
9398

9499
static inline struct file *files_lookup_fd_locked(struct files_struct *files, unsigned int fd)
@@ -114,7 +119,7 @@ int iterate_fd(struct files_struct *, unsigned,
114119

115120
extern int close_fd(unsigned int fd);
116121
extern int __close_range(unsigned int fd, unsigned int max_fd, unsigned int flags);
117-
extern struct file *close_fd_get_file(unsigned int fd);
122+
extern struct file *file_close_fd(unsigned int fd);
118123
extern int unshare_fd(unsigned long unshare_flags, unsigned int max_fds,
119124
struct files_struct **new_fdp);
120125

include/linux/file.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,18 +96,8 @@ DEFINE_CLASS(get_unused_fd, int, if (_T >= 0) put_unused_fd(_T),
9696

9797
extern void fd_install(unsigned int fd, struct file *file);
9898

99-
extern int __receive_fd(struct file *file, int __user *ufd,
100-
unsigned int o_flags);
99+
int receive_fd(struct file *file, int __user *ufd, unsigned int o_flags);
101100

102-
extern int receive_fd(struct file *file, unsigned int o_flags);
103-
104-
static inline int receive_fd_user(struct file *file, int __user *ufd,
105-
unsigned int o_flags)
106-
{
107-
if (ufd == NULL)
108-
return -EFAULT;
109-
return __receive_fd(file, ufd, o_flags);
110-
}
111101
int receive_fd_replace(int new_fd, struct file *file, unsigned int o_flags);
112102

113103
extern void flush_delayed_fput(void);

include/linux/fs.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -991,8 +991,10 @@ static inline int ra_has_index(struct file_ra_state *ra, pgoff_t index)
991991
*/
992992
struct file {
993993
union {
994+
/* fput() uses task work when closing and freeing file (default). */
995+
struct callback_head f_task_work;
996+
/* fput() must use workqueue (most kernel threads). */
994997
struct llist_node f_llist;
995-
struct rcu_head f_rcuhead;
996998
unsigned int f_iocb_flags;
997999
};
9981000

0 commit comments

Comments
 (0)