| From: Kent Overstreet <kent.overstreet@gmail.com> |
| Subject: proc: commit to genradix |
| |
| The new generic radix trees have a simpler API and implementation, and no |
| limitations on number of elements, so all flex_array users are being |
| converted |
| |
| Link: http://lkml.kernel.org/r/20181217131929.11727-6-kent.overstreet@gmail.com |
| Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> |
| Reviewed-by: Alexey Dobriyan <adobriyan@gmail.com> |
| Cc: Al Viro <viro@zeniv.linux.org.uk> |
| Cc: Dave Hansen <dave.hansen@intel.com> |
| Cc: Eric Paris <eparis@parisplace.org> |
| Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> |
| Cc: Matthew Wilcox <willy@infradead.org> |
| Cc: Neil Horman <nhorman@tuxdriver.com> |
| Cc: Paul Moore <paul@paul-moore.com> |
| Cc: Pravin B Shelar <pshelar@ovn.org> |
| Cc: Shaohua Li <shli@kernel.org> |
| Cc: Stephen Smalley <sds@tycho.nsa.gov> |
| Cc: Vlad Yasevich <vyasevich@gmail.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| |
| --- a/fs/proc/base.c~proc-commit-to-genradix |
| +++ a/fs/proc/base.c |
| @@ -59,6 +59,7 @@ |
| #include <linux/capability.h> |
| #include <linux/file.h> |
| #include <linux/fdtable.h> |
| +#include <linux/generic-radix-tree.h> |
| #include <linux/string.h> |
| #include <linux/seq_file.h> |
| #include <linux/namei.h> |
| @@ -92,7 +93,6 @@ |
| #include <linux/sched/coredump.h> |
| #include <linux/sched/debug.h> |
| #include <linux/sched/stat.h> |
| -#include <linux/flex_array.h> |
| #include <linux/posix-timers.h> |
| #include <trace/events/oom.h> |
| #include "internal.h" |
| @@ -2142,11 +2142,12 @@ proc_map_files_readdir(struct file *file |
| struct task_struct *task; |
| struct mm_struct *mm; |
| unsigned long nr_files, pos, i; |
| - struct flex_array *fa = NULL; |
| - struct map_files_info info; |
| + GENRADIX(struct map_files_info) fa; |
| struct map_files_info *p; |
| int ret; |
| |
| + genradix_init(&fa); |
| + |
| ret = -ENOENT; |
| task = get_proc_task(file_inode(file)); |
| if (!task) |
| @@ -2178,35 +2179,22 @@ proc_map_files_readdir(struct file *file |
| */ |
| |
| for (vma = mm->mmap, pos = 2; vma; vma = vma->vm_next) { |
| - if (vma->vm_file && ++pos > ctx->pos) |
| - nr_files++; |
| - } |
| + if (!vma->vm_file) |
| + continue; |
| + if (++pos <= ctx->pos) |
| + continue; |
| |
| - if (nr_files) { |
| - fa = flex_array_alloc(sizeof(info), nr_files, |
| - GFP_KERNEL); |
| - if (!fa || flex_array_prealloc(fa, 0, nr_files, |
| - GFP_KERNEL)) { |
| + p = genradix_ptr_alloc(&fa, nr_files++, GFP_KERNEL); |
| + if (!p) { |
| ret = -ENOMEM; |
| - if (fa) |
| - flex_array_free(fa); |
| up_read(&mm->mmap_sem); |
| mmput(mm); |
| goto out_put_task; |
| } |
| - for (i = 0, vma = mm->mmap, pos = 2; vma; |
| - vma = vma->vm_next) { |
| - if (!vma->vm_file) |
| - continue; |
| - if (++pos <= ctx->pos) |
| - continue; |
| |
| - info.start = vma->vm_start; |
| - info.end = vma->vm_end; |
| - info.mode = vma->vm_file->f_mode; |
| - if (flex_array_put(fa, i++, &info, GFP_KERNEL)) |
| - BUG(); |
| - } |
| + p->start = vma->vm_start; |
| + p->end = vma->vm_end; |
| + p->mode = vma->vm_file->f_mode; |
| } |
| up_read(&mm->mmap_sem); |
| mmput(mm); |
| @@ -2215,7 +2203,7 @@ proc_map_files_readdir(struct file *file |
| char buf[4 * sizeof(long) + 2]; /* max: %lx-%lx\0 */ |
| unsigned int len; |
| |
| - p = flex_array_get(fa, i); |
| + p = genradix_ptr(&fa, i); |
| len = snprintf(buf, sizeof(buf), "%lx-%lx", p->start, p->end); |
| if (!proc_fill_cache(file, ctx, |
| buf, len, |
| @@ -2225,12 +2213,11 @@ proc_map_files_readdir(struct file *file |
| break; |
| ctx->pos++; |
| } |
| - if (fa) |
| - flex_array_free(fa); |
| |
| out_put_task: |
| put_task_struct(task); |
| out: |
| + genradix_free(&fa); |
| return ret; |
| } |
| |
| _ |