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.

get rid of ...lookup...fdget_rcu() family

Once upon a time, predecessors of those used to do file lookup
without bumping a refcount, provided that caller held rcu_read_lock()
across the lookup and whatever it wanted to read from the struct
file found. When struct file allocation switched to SLAB_TYPESAFE_BY_RCU,
that stopped being feasible and these primitives started to bump the
file refcount for lookup result, requiring the caller to call fput()
afterwards.

But that turned them pointless - e.g.
rcu_read_lock();
file = lookup_fdget_rcu(fd);
rcu_read_unlock();
is equivalent to
file = fget_raw(fd);
and all callers of lookup_fdget_rcu() are of that form. Similarly,
task_lookup_fdget_rcu() calls can be replaced with calling fget_task().
task_lookup_next_fdget_rcu() doesn't have direct counterparts, but
its callers would be happier if we replaced it with an analogue that
deals with RCU internally.

Reviewed-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 8fd3395e 8cf0b939

+14 -62
+1 -3
arch/powerpc/platforms/cell/spufs/coredump.c
··· 73 73 return NULL; 74 74 *fd = n - 1; 75 75 76 - rcu_read_lock(); 77 - file = lookup_fdget_rcu(*fd); 78 - rcu_read_unlock(); 76 + file = fget_raw(*fd); 79 77 if (file) { 80 78 ctx = SPUFS_I(file_inode(file))->i_ctx; 81 79 get_spu_context(ctx);
+4 -24
fs/file.c
··· 1037 1037 return file; 1038 1038 } 1039 1039 1040 - struct file *lookup_fdget_rcu(unsigned int fd) 1041 - { 1042 - return __fget_files_rcu(current->files, fd, 0); 1043 - 1044 - } 1045 - EXPORT_SYMBOL_GPL(lookup_fdget_rcu); 1046 - 1047 - struct file *task_lookup_fdget_rcu(struct task_struct *task, unsigned int fd) 1048 - { 1049 - /* Must be called with rcu_read_lock held */ 1050 - struct files_struct *files; 1051 - struct file *file = NULL; 1052 - 1053 - task_lock(task); 1054 - files = task->files; 1055 - if (files) 1056 - file = __fget_files_rcu(files, fd, 0); 1057 - task_unlock(task); 1058 - 1059 - return file; 1060 - } 1061 - 1062 - struct file *task_lookup_next_fdget_rcu(struct task_struct *task, unsigned int *ret_fd) 1040 + struct file *fget_task_next(struct task_struct *task, unsigned int *ret_fd) 1063 1041 { 1064 1042 /* Must be called with rcu_read_lock held */ 1065 1043 struct files_struct *files; ··· 1047 1069 task_lock(task); 1048 1070 files = task->files; 1049 1071 if (files) { 1072 + rcu_read_lock(); 1050 1073 for (; fd < files_fdtable(files)->max_fds; fd++) { 1051 1074 file = __fget_files_rcu(files, fd, 0); 1052 1075 if (file) 1053 1076 break; 1054 1077 } 1078 + rcu_read_unlock(); 1055 1079 } 1056 1080 task_unlock(task); 1057 1081 *ret_fd = fd; 1058 1082 return file; 1059 1083 } 1060 - EXPORT_SYMBOL(task_lookup_next_fdget_rcu); 1084 + EXPORT_SYMBOL(fget_task_next); 1061 1085 1062 1086 /* 1063 1087 * Lightweight file lookup - no refcnt increment if fd table isn't shared.
+2 -10
fs/gfs2/glock.c
··· 34 34 #include <linux/lockref.h> 35 35 #include <linux/rhashtable.h> 36 36 #include <linux/pid_namespace.h> 37 - #include <linux/fdtable.h> 38 37 #include <linux/file.h> 39 38 40 39 #include "gfs2.h" ··· 2767 2768 i->file = NULL; 2768 2769 } 2769 2770 2770 - rcu_read_lock(); 2771 2771 for(;; i->fd++) { 2772 - struct inode *inode; 2773 - 2774 - i->file = task_lookup_next_fdget_rcu(i->task, &i->fd); 2772 + i->file = fget_task_next(i->task, &i->fd); 2775 2773 if (!i->file) { 2776 2774 i->fd = 0; 2777 2775 break; 2778 2776 } 2779 2777 2780 - inode = file_inode(i->file); 2781 - if (inode->i_sb == i->sb) 2778 + if (file_inode(i->file)->i_sb == i->sb) 2782 2779 break; 2783 2780 2784 - rcu_read_unlock(); 2785 2781 fput(i->file); 2786 - rcu_read_lock(); 2787 2782 } 2788 - rcu_read_unlock(); 2789 2783 return i->file; 2790 2784 } 2791 2785
+1 -4
fs/notify/dnotify/dnotify.c
··· 16 16 #include <linux/security.h> 17 17 #include <linux/spinlock.h> 18 18 #include <linux/slab.h> 19 - #include <linux/fdtable.h> 20 19 #include <linux/fsnotify_backend.h> 21 20 22 21 static int dir_notify_enable __read_mostly = 1; ··· 346 347 new_fsn_mark = NULL; 347 348 } 348 349 349 - rcu_read_lock(); 350 - f = lookup_fdget_rcu(fd); 351 - rcu_read_unlock(); 350 + f = fget_raw(fd); 352 351 353 352 /* if (f != filp) means that we lost a race and another task/thread 354 353 * actually closed the fd we are still playing with before we grabbed
+3 -9
fs/proc/fd.c
··· 116 116 { 117 117 struct file *file; 118 118 119 - rcu_read_lock(); 120 - file = task_lookup_fdget_rcu(task, fd); 121 - rcu_read_unlock(); 119 + file = fget_task(task, fd); 122 120 if (file) { 123 121 *mode = file->f_mode; 124 122 fput(file); ··· 256 258 if (!dir_emit_dots(file, ctx)) 257 259 goto out; 258 260 259 - rcu_read_lock(); 260 261 for (fd = ctx->pos - 2;; fd++) { 261 262 struct file *f; 262 263 struct fd_data data; 263 264 char name[10 + 1]; 264 265 unsigned int len; 265 266 266 - f = task_lookup_next_fdget_rcu(p, &fd); 267 + f = fget_task_next(p, &fd); 267 268 ctx->pos = fd + 2LL; 268 269 if (!f) 269 270 break; 270 271 data.mode = f->f_mode; 271 - rcu_read_unlock(); 272 272 fput(f); 273 273 data.fd = fd; 274 274 ··· 274 278 if (!proc_fill_cache(file, ctx, 275 279 name, len, instantiate, p, 276 280 &data)) 277 - goto out; 281 + break; 278 282 cond_resched(); 279 - rcu_read_lock(); 280 283 } 281 - rcu_read_unlock(); 282 284 out: 283 285 put_task_struct(p); 284 286 return 0;
-4
include/linux/fdtable.h
··· 92 92 return files_lookup_fd_raw(files, fd); 93 93 } 94 94 95 - struct file *lookup_fdget_rcu(unsigned int fd); 96 - struct file *task_lookup_fdget_rcu(struct task_struct *task, unsigned int fd); 97 - struct file *task_lookup_next_fdget_rcu(struct task_struct *task, unsigned int *fd); 98 - 99 95 static inline bool close_on_exec(unsigned int fd, const struct files_struct *files) 100 96 { 101 97 return test_bit(fd, files_fdtable(files)->close_on_exec);
+1
include/linux/file.h
··· 72 72 extern struct file *fget(unsigned int fd); 73 73 extern struct file *fget_raw(unsigned int fd); 74 74 extern struct file *fget_task(struct task_struct *task, unsigned int fd); 75 + extern struct file *fget_task_next(struct task_struct *task, unsigned int *fd); 75 76 extern void __f_unlock_pos(struct file *); 76 77 77 78 struct fd fdget(unsigned int fd);
+1 -5
kernel/bpf/task_iter.c
··· 5 5 #include <linux/namei.h> 6 6 #include <linux/pid_namespace.h> 7 7 #include <linux/fs.h> 8 - #include <linux/fdtable.h> 9 8 #include <linux/filter.h> 10 9 #include <linux/bpf_mem_alloc.h> 11 10 #include <linux/btf_ids.h> ··· 285 286 curr_fd = 0; 286 287 } 287 288 288 - rcu_read_lock(); 289 - f = task_lookup_next_fdget_rcu(curr_task, &curr_fd); 289 + f = fget_task_next(curr_task, &curr_fd); 290 290 if (f) { 291 291 /* set info->fd */ 292 292 info->fd = curr_fd; 293 - rcu_read_unlock(); 294 293 return f; 295 294 } 296 295 297 296 /* the current task is done, go to the next task */ 298 - rcu_read_unlock(); 299 297 put_task_struct(curr_task); 300 298 301 299 if (info->common.type == BPF_TASK_ITER_TID) {
+1 -3
kernel/kcmp.c
··· 63 63 { 64 64 struct file *file; 65 65 66 - rcu_read_lock(); 67 - file = task_lookup_fdget_rcu(task, idx); 68 - rcu_read_unlock(); 66 + file = fget_task(task, idx); 69 67 if (file) 70 68 fput(file); 71 69