Message ID | 20240131-tracefs-kernfs-v1-1-f20e2e9a8d61@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | : Port tracefs to kernfs | expand |
Hi Christian, kernel test robot noticed the following build errors: [auto build test ERROR on 41bccc98fb7931d63d03f326a746ac4d429c1dd3] url: https://github.com/intel-lab-lkp/linux/commits/Christian-Brauner/tracefs-port-to-kernfs/20240131-214120 base: 41bccc98fb7931d63d03f326a746ac4d429c1dd3 patch link: https://lore.kernel.org/r/20240131-tracefs-kernfs-v1-1-f20e2e9a8d61%40kernel.org patch subject: [PATCH DRAFT 1/4] : tracefs: port to kernfs config: x86_64-kexec (https://download.01.org/0day-ci/archive/20240201/202402010828.cl2RunjG-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240201/202402010828.cl2RunjG-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202402010828.cl2RunjG-lkp@intel.com/ All errors (new ones prefixed by >>): fs/kernfs/mount.c: In function 'kernfs_node_owner': >> fs/kernfs/mount.c:248:20: error: 'struct kernfs_node' has no member named 'iattrs'; did you mean 'iattr'? 248 | return kn->iattrs->ia_uid; | ^~~~~~ | iattr fs/kernfs/mount.c: At top level: >> fs/kernfs/mount.c:251:8: error: conflicting types for 'kernfs_node_group'; have 'kuid_t(struct kernfs_node *)' 251 | kuid_t kernfs_node_group(struct kernfs_node *kn) | ^~~~~~~~~~~~~~~~~ In file included from fs/kernfs/kernfs-internal.h:19, from fs/kernfs/mount.c:22: include/linux/kernfs.h:248:8: note: previous declaration of 'kernfs_node_group' with type 'kgid_t(struct kernfs_node *)' 248 | kgid_t kernfs_node_group(struct kernfs_node *kn); | ^~~~~~~~~~~~~~~~~ fs/kernfs/mount.c: In function 'kernfs_node_group': fs/kernfs/mount.c:253:20: error: 'struct kernfs_node' has no member named 'iattrs'; did you mean 'iattr'? 253 | return kn->iattrs->ia_gid; | ^~~~~~ | iattr fs/kernfs/mount.c: In function 'kernfs_node_owner': fs/kernfs/mount.c:249:1: warning: control reaches end of non-void function [-Wreturn-type] 249 | } | ^ fs/kernfs/mount.c: In function 'kernfs_node_group': fs/kernfs/mount.c:254:1: warning: control reaches end of non-void function [-Wreturn-type] 254 | } | ^ -- kernel/trace/trace.c: In function 'tracing_dentry_percpu': >> kernel/trace/trace.c:8916:56: error: passing argument 2 of 'tracefs_create_dir' from incompatible pointer type [-Werror=incompatible-pointer-types] 8916 | tr->percpu_dir = tracefs_create_dir("per_cpu", d_tracer); | ^~~~~~~~ | | | struct dentry * In file included from kernel/trace/trace.c:24: include/linux/tracefs.h:97:60: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 97 | struct kernfs_node *parent); | ~~~~~~~~~~~~~~~~~~~~^~~~~~ >> kernel/trace/trace.c:8916:24: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 8916 | tr->percpu_dir = tracefs_create_dir("per_cpu", d_tracer); | ^ kernel/trace/trace.c: In function 'tracing_init_tracefs_percpu': kernel/trace/trace.c:8946:45: error: passing argument 2 of 'tracefs_create_dir' from incompatible pointer type [-Werror=incompatible-pointer-types] 8946 | d_cpu = tracefs_create_dir(cpu_dir, d_percpu); | ^~~~~~~~ | | | struct dentry * include/linux/tracefs.h:97:60: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 97 | struct kernfs_node *parent); | ~~~~~~~~~~~~~~~~~~~~^~~~~~ kernel/trace/trace.c:8946:15: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 8946 | d_cpu = tracefs_create_dir(cpu_dir, d_percpu); | ^ kernel/trace/trace.c: In function 'trace_create_file': >> kernel/trace/trace.c:9156:47: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 9156 | ret = tracefs_create_file(name, mode, parent, data, fops); | ^~~~~~ | | | struct dentry * include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 93 | struct kernfs_node *parent, void *data, | ~~~~~~~~~~~~~~~~~~~~^~~~~~ kernel/trace/trace.c:9156:61: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 9156 | ret = tracefs_create_file(name, mode, parent, data, fops); | ^~~~ | | | const struct file_operations * include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *' 94 | const struct kernfs_ops *ops); | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~ kernel/trace/trace.c:9156:13: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 9156 | ret = tracefs_create_file(name, mode, parent, data, fops); | ^ kernel/trace/trace.c: In function 'trace_options_init_dentry': kernel/trace/trace.c:9175:53: error: passing argument 2 of 'tracefs_create_dir' from incompatible pointer type [-Werror=incompatible-pointer-types] 9175 | tr->options = tracefs_create_dir("options", d_tracer); | ^~~~~~~~ | | | struct dentry * include/linux/tracefs.h:97:60: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 97 | struct kernfs_node *parent); | ~~~~~~~~~~~~~~~~~~~~^~~~~~ kernel/trace/trace.c:9175:21: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 9175 | tr->options = tracefs_create_dir("options", d_tracer); | ^ kernel/trace/trace.c: In function 'trace_array_create_dir': kernel/trace/trace.c:9631:17: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 9631 | tr->dir = tracefs_create_dir(tr->name, trace_instance_dir); | ^ >> kernel/trace/trace.c:9637:34: error: passing argument 1 of 'tracefs_remove' from incompatible pointer type [-Werror=incompatible-pointer-types] 9637 | tracefs_remove(tr->dir); | ~~^~~~~ | | | struct dentry * include/linux/tracefs.h:99:41: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 99 | void tracefs_remove(struct kernfs_node *kn); | ~~~~~~~~~~~~~~~~~~~~^~ kernel/trace/trace.c: In function '__remove_instance': kernel/trace/trace.c:9818:26: error: passing argument 1 of 'tracefs_remove' from incompatible pointer type [-Werror=incompatible-pointer-types] 9818 | tracefs_remove(tr->dir); | ~~^~~~~ | | | struct dentry * include/linux/tracefs.h:99:41: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 99 | void tracefs_remove(struct kernfs_node *kn); | ~~~~~~~~~~~~~~~~~~~~^~ cc1: some warnings being treated as errors -- kernel/trace/trace_stat.c: In function 'destroy_session': >> kernel/trace/trace_stat.c:69:31: error: passing argument 1 of 'tracefs_remove' from incompatible pointer type [-Werror=incompatible-pointer-types] 69 | tracefs_remove(session->file); | ~~~~~~~^~~~~~ | | | struct dentry * In file included from kernel/trace/trace_stat.c:16: include/linux/tracefs.h:99:41: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 99 | void tracefs_remove(struct kernfs_node *kn); | ~~~~~~~~~~~~~~~~~~~~^~ kernel/trace/trace_stat.c: In function 'tracing_stat_init': >> kernel/trace/trace_stat.c:285:18: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 285 | stat_dir = tracefs_create_dir("trace_stat", NULL); | ^ kernel/trace/trace_stat.c: In function 'init_stat_file': >> kernel/trace/trace_stat.c:301:45: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 301 | stat_dir, session, | ^~~~~~~~ | | | struct dentry * include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 93 | struct kernfs_node *parent, void *data, | ~~~~~~~~~~~~~~~~~~~~^~~~~~ kernel/trace/trace_stat.c:302:45: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 302 | &tracing_stat_fops); | ^~~~~~~~~~~~~~~~~~ | | | const struct file_operations * include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *' 94 | const struct kernfs_ops *ops); | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~ kernel/trace/trace_stat.c:300:23: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 300 | session->file = tracefs_create_file(session->ts->name, TRACE_MODE_WRITE, | ^ cc1: some warnings being treated as errors -- kernel/trace/trace_events_synth.c: In function 'trace_events_synth_init': >> kernel/trace/trace_events_synth.c:2322:49: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 2322 | NULL, NULL, &synth_events_fops); | ^~~~~~~~~~~~~~~~~~ | | | const struct file_operations * In file included from kernel/trace/trace_events_synth.c:15: include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *' 94 | const struct kernfs_ops *ops); | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~ kernel/trace/trace_events_synth.c:2321:15: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 2321 | entry = tracefs_create_file("synthetic_events", TRACE_MODE_WRITE, | ^ cc1: some warnings being treated as errors vim +248 fs/kernfs/mount.c 245 246 kuid_t kernfs_node_owner(struct kernfs_node *kn) 247 { > 248 return kn->iattrs->ia_uid; 249 } 250 > 251 kuid_t kernfs_node_group(struct kernfs_node *kn) 252 { 253 return kn->iattrs->ia_gid; 254 } 255
Hi Christian, kernel test robot noticed the following build errors: [auto build test ERROR on 41bccc98fb7931d63d03f326a746ac4d429c1dd3] url: https://github.com/intel-lab-lkp/linux/commits/Christian-Brauner/tracefs-port-to-kernfs/20240131-214120 base: 41bccc98fb7931d63d03f326a746ac4d429c1dd3 patch link: https://lore.kernel.org/r/20240131-tracefs-kernfs-v1-1-f20e2e9a8d61%40kernel.org patch subject: [PATCH DRAFT 1/4] : tracefs: port to kernfs config: arc-randconfig-001-20240201 (https://download.01.org/0day-ci/archive/20240201/202402010834.J85Qu3eN-lkp@intel.com/config) compiler: arceb-elf-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240201/202402010834.J85Qu3eN-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202402010834.J85Qu3eN-lkp@intel.com/ All errors (new ones prefixed by >>): kernel/trace/trace_hwlat.c: In function 'init_tracefs': kernel/trace/trace_hwlat.c:778:17: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 778 | top_dir = tracefs_create_dir("hwlat_detector", NULL); | ^ >> kernel/trace/trace_hwlat.c:783:51: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 783 | top_dir, | ^~~~~~~ | | | struct dentry * In file included from kernel/trace/trace_hwlat.c:41: include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 93 | struct kernfs_node *parent, void *data, | ~~~~~~~~~~~~~~~~~~~~^~~~~~ kernel/trace/trace_hwlat.c:785:51: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 785 | &trace_min_max_fops); | ^~~~~~~~~~~~~~~~~~~ | | | const struct file_operations * include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *' 94 | const struct kernfs_ops *ops); | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~ kernel/trace/trace_hwlat.c:782:29: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 782 | hwlat_sample_window = tracefs_create_file("window", TRACE_MODE_WRITE, | ^ kernel/trace/trace_hwlat.c:790:50: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 790 | top_dir, | ^~~~~~~ | | | struct dentry * include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 93 | struct kernfs_node *parent, void *data, | ~~~~~~~~~~~~~~~~~~~~^~~~~~ kernel/trace/trace_hwlat.c:792:50: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 792 | &trace_min_max_fops); | ^~~~~~~~~~~~~~~~~~~ | | | const struct file_operations * include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *' 94 | const struct kernfs_ops *ops); | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~ kernel/trace/trace_hwlat.c:789:28: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 789 | hwlat_sample_width = tracefs_create_file("width", TRACE_MODE_WRITE, | ^ kernel/trace/trace_hwlat.c:806:24: error: passing argument 1 of 'tracefs_remove' from incompatible pointer type [-Werror=incompatible-pointer-types] 806 | tracefs_remove(top_dir); | ^~~~~~~ | | | struct dentry * include/linux/tracefs.h:99:41: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 99 | void tracefs_remove(struct kernfs_node *kn); | ~~~~~~~~~~~~~~~~~~~~^~ cc1: some warnings being treated as errors -- kernel/trace/trace_osnoise.c: In function 'init_timerlat_stack_tracefs': kernel/trace/trace_osnoise.c:2695:68: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 2695 | tmp = tracefs_create_file("print_stack", TRACE_MODE_WRITE, top_dir, | ^~~~~~~ | | | struct dentry * In file included from kernel/trace/trace_osnoise.c:20: include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 93 | struct kernfs_node *parent, void *data, | ~~~~~~~~~~~~~~~~~~~~^~~~~~ kernel/trace/trace_osnoise.c:2696:57: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 2696 | &osnoise_print_stack, &trace_min_max_fops); | ^~~~~~~~~~~~~~~~~~~ | | | const struct file_operations * include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *' 94 | const struct kernfs_ops *ops); | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~ kernel/trace/trace_osnoise.c:2695:13: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 2695 | tmp = tracefs_create_file("print_stack", TRACE_MODE_WRITE, top_dir, | ^ kernel/trace/trace_osnoise.c: In function 'osnoise_create_cpu_timerlat_fd': >> kernel/trace/trace_osnoise.c:2723:49: error: passing argument 2 of 'tracefs_create_dir' from incompatible pointer type [-Werror=incompatible-pointer-types] 2723 | per_cpu = tracefs_create_dir("per_cpu", top_dir); | ^~~~~~~ | | | struct dentry * include/linux/tracefs.h:97:60: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 97 | struct kernfs_node *parent); | ~~~~~~~~~~~~~~~~~~~~^~~~~~ kernel/trace/trace_osnoise.c:2723:17: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 2723 | per_cpu = tracefs_create_dir("per_cpu", top_dir); | ^ kernel/trace/trace_osnoise.c:2729:55: error: passing argument 2 of 'tracefs_create_dir' from incompatible pointer type [-Werror=incompatible-pointer-types] 2729 | cpu_dir = tracefs_create_dir(cpu_str, per_cpu); | ^~~~~~~ | | | struct dentry * include/linux/tracefs.h:97:60: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 97 | struct kernfs_node *parent); | ~~~~~~~~~~~~~~~~~~~~^~~~~~ kernel/trace/trace_osnoise.c:2729:25: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 2729 | cpu_dir = tracefs_create_dir(cpu_str, per_cpu); | ^ kernel/trace/trace_osnoise.c:2745:24: error: passing argument 1 of 'tracefs_remove' from incompatible pointer type [-Werror=incompatible-pointer-types] 2745 | tracefs_remove(per_cpu); | ^~~~~~~ | | | struct dentry * include/linux/tracefs.h:99:41: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 99 | void tracefs_remove(struct kernfs_node *kn); | ~~~~~~~~~~~~~~~~~~~~^~ kernel/trace/trace_osnoise.c: In function 'init_timerlat_tracefs': kernel/trace/trace_osnoise.c:2757:75: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 2757 | tmp = tracefs_create_file("timerlat_period_us", TRACE_MODE_WRITE, top_dir, | ^~~~~~~ | | | struct dentry * include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 93 | struct kernfs_node *parent, void *data, | ~~~~~~~~~~~~~~~~~~~~^~~~~~ kernel/trace/trace_osnoise.c:2758:53: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 2758 | &timerlat_period, &trace_min_max_fops); | ^~~~~~~~~~~~~~~~~~~ | | | const struct file_operations * include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *' 94 | const struct kernfs_ops *ops); | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~ kernel/trace/trace_osnoise.c:2757:13: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 2757 | tmp = tracefs_create_file("timerlat_period_us", TRACE_MODE_WRITE, top_dir, | ^ kernel/trace/trace_osnoise.c: In function 'init_tracefs': kernel/trace/trace_osnoise.c:2792:17: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 2792 | top_dir = tracefs_create_dir("osnoise", NULL); | ^ kernel/trace/trace_osnoise.c:2796:66: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 2796 | tmp = tracefs_create_file("period_us", TRACE_MODE_WRITE, top_dir, | ^~~~~~~ | | | struct dentry * include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 93 | struct kernfs_node *parent, void *data, | ~~~~~~~~~~~~~~~~~~~~^~~~~~ kernel/trace/trace_osnoise.c:2797:52: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 2797 | &osnoise_period, &trace_min_max_fops); | ^~~~~~~~~~~~~~~~~~~ | | | const struct file_operations * include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *' 94 | const struct kernfs_ops *ops); | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~ kernel/trace/trace_osnoise.c:2796:13: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 2796 | tmp = tracefs_create_file("period_us", TRACE_MODE_WRITE, top_dir, | ^ kernel/trace/trace_osnoise.c:2801:67: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 2801 | tmp = tracefs_create_file("runtime_us", TRACE_MODE_WRITE, top_dir, | ^~~~~~~ | | | struct dentry * include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 93 | struct kernfs_node *parent, void *data, | ~~~~~~~~~~~~~~~~~~~~^~~~~~ kernel/trace/trace_osnoise.c:2802:53: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 2802 | &osnoise_runtime, &trace_min_max_fops); | ^~~~~~~~~~~~~~~~~~~ | | | const struct file_operations * include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *' 94 | const struct kernfs_ops *ops); | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~ kernel/trace/trace_osnoise.c:2801:13: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types] 2801 | tmp = tracefs_create_file("runtime_us", TRACE_MODE_WRITE, top_dir, | ^ kernel/trace/trace_osnoise.c:2806:72: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] 2806 | tmp = tracefs_create_file("stop_tracing_us", TRACE_MODE_WRITE, top_dir, | ^~~~~~~ | | | struct dentry * include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *' 93 | struct kernfs_node *parent, void *data, | ~~~~~~~~~~~~~~~~~~~~^~~~~~ kernel/trace/trace_osnoise.c:2807:61: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types] vim +/tracefs_create_file +783 kernel/trace/trace_hwlat.c e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 753) 8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22 754 static const struct file_operations thread_mode_fops = { 8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22 755 .open = hwlat_mode_open, 8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22 756 .read = seq_read, 8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22 757 .llseek = seq_lseek, 8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22 758 .release = seq_release, 8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22 759 .write = hwlat_mode_write 8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22 760 }; e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 761) /** e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 762) * init_tracefs - A function to initialize the tracefs interface files e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 763) * e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 764) * This function creates entries in tracefs for "hwlat_detector". e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 765) * It creates the hwlat_detector directory in the tracing directory, e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 766) * and within that directory is the count, width and window files to e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 767) * change and view those values. e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 768) */ e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 769) static int init_tracefs(void) e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 770) { 22c36b18263426 Wei Yang 2020-07-12 771 int ret; e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 772) struct dentry *top_dir; e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 773) 22c36b18263426 Wei Yang 2020-07-12 774 ret = tracing_init_dentry(); 22c36b18263426 Wei Yang 2020-07-12 775 if (ret) e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 776) return -ENOMEM; e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 777) 22c36b18263426 Wei Yang 2020-07-12 778 top_dir = tracefs_create_dir("hwlat_detector", NULL); e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 779) if (!top_dir) e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 780) return -ENOMEM; e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 781) 21ccc9cd721162 Steven Rostedt (VMware 2021-08-18 782) hwlat_sample_window = tracefs_create_file("window", TRACE_MODE_WRITE, e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 @783) top_dir, f27a1c9e1ba1e4 Daniel Bristot de Oliveira 2021-06-22 784 &hwlat_window, f27a1c9e1ba1e4 Daniel Bristot de Oliveira 2021-06-22 785 &trace_min_max_fops); e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 786) if (!hwlat_sample_window) e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 787) goto err; e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 788) 21ccc9cd721162 Steven Rostedt (VMware 2021-08-18 789) hwlat_sample_width = tracefs_create_file("width", TRACE_MODE_WRITE, e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 790) top_dir, f27a1c9e1ba1e4 Daniel Bristot de Oliveira 2021-06-22 791 &hwlat_width, f27a1c9e1ba1e4 Daniel Bristot de Oliveira 2021-06-22 792 &trace_min_max_fops); e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 793) if (!hwlat_sample_width) e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 794) goto err; e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 795) 21ccc9cd721162 Steven Rostedt (VMware 2021-08-18 796) hwlat_thread_mode = trace_create_file("mode", TRACE_MODE_WRITE, 8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22 797 top_dir, 8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22 798 NULL, 8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22 799 &thread_mode_fops); 8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22 800 if (!hwlat_thread_mode) 8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22 801 goto err; 8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22 802 e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 803) return 0; e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 804) e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 805) err: a3d1e7eb5abe3a Al Viro 2019-11-18 806 tracefs_remove(top_dir); e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 807) return -ENOMEM; e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 808) } e7c15cd8a11333 Steven Rostedt (Red Hat 2016-06-23 809)
Hi Christian, kernel test robot noticed the following build warnings: [auto build test WARNING on 41bccc98fb7931d63d03f326a746ac4d429c1dd3] url: https://github.com/intel-lab-lkp/linux/commits/Christian-Brauner/tracefs-port-to-kernfs/20240131-214120 base: 41bccc98fb7931d63d03f326a746ac4d429c1dd3 patch link: https://lore.kernel.org/r/20240131-tracefs-kernfs-v1-1-f20e2e9a8d61%40kernel.org patch subject: [PATCH DRAFT 1/4] : tracefs: port to kernfs config: i386-randconfig-061-20240201 (https://download.01.org/0day-ci/archive/20240201/202402011431.c6K3rKZS-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240201/202402011431.c6K3rKZS-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202402011431.c6K3rKZS-lkp@intel.com/ sparse warnings: (new ones prefixed by >>) >> fs/tracefs/inode.c:88:27: sparse: sparse: symbol 'global_opts' was not declared. Should it be static? vim +/global_opts +88 fs/tracefs/inode.c 87 > 88 struct tracefs_mount_opts global_opts = { 89 .mode = TRACEFS_DEFAULT_MODE, 90 .uid = GLOBAL_ROOT_UID, 91 .gid = GLOBAL_ROOT_GID, 92 .opts = 0, 93 }; 94
diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c index 0c93cad0f0ac..68907c9f9377 100644 --- a/fs/kernfs/mount.c +++ b/fs/kernfs/mount.c @@ -243,6 +243,16 @@ struct dentry *kernfs_node_dentry(struct kernfs_node *kn, } while (true); } +kuid_t kernfs_node_owner(struct kernfs_node *kn) +{ + return kn->iattrs->ia_uid; +} + +kuid_t kernfs_node_group(struct kernfs_node *kn) +{ + return kn->iattrs->ia_gid; +} + static int kernfs_fill_super(struct super_block *sb, struct kernfs_fs_context *kfc) { struct kernfs_super_info *info = kernfs_info(sb); diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index e1b172c0e091..944a95ff8b48 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/fs.h> +#include <linux/fs_parser.h> #include <linux/mount.h> #include <linux/kobject.h> #include <linux/namei.h> @@ -24,47 +25,41 @@ #include "internal.h" #define TRACEFS_DEFAULT_MODE 0700 -static struct kmem_cache *tracefs_inode_cachep __ro_after_init; +static struct kernfs_root *trace_fs_root; +static struct kernfs_node *trace_kfs_root_node; static struct vfsmount *tracefs_mount; static int tracefs_mount_count; static bool tracefs_registered; -static struct inode *tracefs_alloc_inode(struct super_block *sb) +static ssize_t trace_fs_kf_read(struct kernfs_open_file *of, char *buf, + size_t count, loff_t pos) { - struct tracefs_inode *ti; - - ti = kmem_cache_alloc(tracefs_inode_cachep, GFP_KERNEL); - if (!ti) - return NULL; - - ti->flags = 0; - - return &ti->vfs_inode; + return 0; } -static void tracefs_free_inode(struct inode *inode) +static ssize_t trace_fs_kf_write(struct kernfs_open_file *of, char *buf, + size_t count, loff_t pos) { - kmem_cache_free(tracefs_inode_cachep, get_tracefs(inode)); + return 0; } -static ssize_t default_read_file(struct file *file, char __user *buf, - size_t count, loff_t *ppos) +static loff_t trace_fs_kf_llseek(struct kernfs_open_file *of, loff_t offset, + int whence) { - return 0; + return noop_llseek(of->file, offset, whence); } -static ssize_t default_write_file(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) +static int trace_fs_kf_open(struct kernfs_open_file *of) { - return count; + return 0; } -static const struct file_operations tracefs_file_operations = { - .read = default_read_file, - .write = default_write_file, - .open = simple_open, - .llseek = noop_llseek, +static const struct kernfs_ops tracefs_file_kfops = { + .read = trace_fs_kf_read, + .write = trace_fs_kf_write, + .open = trace_fs_kf_open, + .llseek = trace_fs_kf_llseek, }; static struct tracefs_dir_ops { @@ -72,157 +67,6 @@ static struct tracefs_dir_ops { int (*rmdir)(const char *name); } tracefs_ops __ro_after_init; -static char *get_dname(struct dentry *dentry) -{ - const char *dname; - char *name; - int len = dentry->d_name.len; - - dname = dentry->d_name.name; - name = kmalloc(len + 1, GFP_KERNEL); - if (!name) - return NULL; - memcpy(name, dname, len); - name[len] = 0; - return name; -} - -static int tracefs_syscall_mkdir(struct mnt_idmap *idmap, - struct inode *inode, struct dentry *dentry, - umode_t mode) -{ - struct tracefs_inode *ti; - char *name; - int ret; - - name = get_dname(dentry); - if (!name) - return -ENOMEM; - - /* - * This is a new directory that does not take the default of - * the rootfs. It becomes the default permissions for all the - * files and directories underneath it. - */ - ti = get_tracefs(inode); - ti->flags |= TRACEFS_INSTANCE_INODE; - ti->private = inode; - - /* - * The mkdir call can call the generic functions that create - * the files within the tracefs system. It is up to the individual - * mkdir routine to handle races. - */ - inode_unlock(inode); - ret = tracefs_ops.mkdir(name); - inode_lock(inode); - - kfree(name); - - return ret; -} - -static int tracefs_syscall_rmdir(struct inode *inode, struct dentry *dentry) -{ - char *name; - int ret; - - name = get_dname(dentry); - if (!name) - return -ENOMEM; - - /* - * The rmdir call can call the generic functions that create - * the files within the tracefs system. It is up to the individual - * rmdir routine to handle races. - * This time we need to unlock not only the parent (inode) but - * also the directory that is being deleted. - */ - inode_unlock(inode); - inode_unlock(d_inode(dentry)); - - ret = tracefs_ops.rmdir(name); - - inode_lock_nested(inode, I_MUTEX_PARENT); - inode_lock(d_inode(dentry)); - - kfree(name); - - return ret; -} - -static void set_tracefs_inode_owner(struct inode *inode) -{ - struct tracefs_inode *ti = get_tracefs(inode); - struct inode *root_inode = ti->private; - - /* - * If this inode has never been referenced, then update - * the permissions to the superblock. - */ - if (!(ti->flags & TRACEFS_UID_PERM_SET)) - inode->i_uid = root_inode->i_uid; - - if (!(ti->flags & TRACEFS_GID_PERM_SET)) - inode->i_gid = root_inode->i_gid; -} - -static int tracefs_permission(struct mnt_idmap *idmap, - struct inode *inode, int mask) -{ - set_tracefs_inode_owner(inode); - return generic_permission(idmap, inode, mask); -} - -static int tracefs_getattr(struct mnt_idmap *idmap, - const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags) -{ - struct inode *inode = d_backing_inode(path->dentry); - - set_tracefs_inode_owner(inode); - generic_fillattr(idmap, request_mask, inode, stat); - return 0; -} - -static int tracefs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, - struct iattr *attr) -{ - unsigned int ia_valid = attr->ia_valid; - struct inode *inode = d_inode(dentry); - struct tracefs_inode *ti = get_tracefs(inode); - - if (ia_valid & ATTR_UID) - ti->flags |= TRACEFS_UID_PERM_SET; - - if (ia_valid & ATTR_GID) - ti->flags |= TRACEFS_GID_PERM_SET; - - return simple_setattr(idmap, dentry, attr); -} - -static const struct inode_operations tracefs_instance_dir_inode_operations = { - .lookup = simple_lookup, - .mkdir = tracefs_syscall_mkdir, - .rmdir = tracefs_syscall_rmdir, - .permission = tracefs_permission, - .getattr = tracefs_getattr, - .setattr = tracefs_setattr, -}; - -static const struct inode_operations tracefs_dir_inode_operations = { - .lookup = simple_lookup, - .permission = tracefs_permission, - .getattr = tracefs_getattr, - .setattr = tracefs_setattr, -}; - -static const struct inode_operations tracefs_file_inode_operations = { - .permission = tracefs_permission, - .getattr = tracefs_getattr, - .setattr = tracefs_setattr, -}; - struct inode *tracefs_get_inode(struct super_block *sb) { struct inode *inode = new_inode(sb); @@ -241,80 +85,101 @@ struct tracefs_mount_opts { unsigned int opts; }; -enum { +struct tracefs_mount_opts global_opts = { + .mode = TRACEFS_DEFAULT_MODE, + .uid = GLOBAL_ROOT_UID, + .gid = GLOBAL_ROOT_GID, + .opts = 0, +}; + +enum trace_fs_param { Opt_uid, Opt_gid, Opt_mode, - Opt_err }; -static const match_table_t tokens = { - {Opt_uid, "uid=%u"}, - {Opt_gid, "gid=%u"}, - {Opt_mode, "mode=%o"}, - {Opt_err, NULL} +static const struct fs_parameter_spec trace_fs_parameters[] = { + fsparam_u32 ("gid", Opt_gid), + fsparam_u32oct("mode", Opt_mode), + fsparam_u32 ("uid", Opt_uid), + {} }; -struct tracefs_fs_info { +struct trace_fs_context { + struct kernfs_fs_context kfc; struct tracefs_mount_opts mount_opts; }; -static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts) +static inline struct trace_fs_context *trace_fc2context(struct fs_context *fc) { - substring_t args[MAX_OPT_ARGS]; - int option; - int token; - kuid_t uid; - kgid_t gid; - char *p; - - opts->opts = 0; - opts->mode = TRACEFS_DEFAULT_MODE; - - while ((p = strsep(&data, ",")) != NULL) { - if (!*p) - continue; - - token = match_token(p, tokens, args); - switch (token) { - case Opt_uid: - if (match_int(&args[0], &option)) - return -EINVAL; - uid = make_kuid(current_user_ns(), option); - if (!uid_valid(uid)) - return -EINVAL; - opts->uid = uid; - break; - case Opt_gid: - if (match_int(&args[0], &option)) - return -EINVAL; - gid = make_kgid(current_user_ns(), option); - if (!gid_valid(gid)) - return -EINVAL; - opts->gid = gid; - break; - case Opt_mode: - if (match_octal(&args[0], &option)) - return -EINVAL; - opts->mode = option & S_IALLUGO; - break; + struct kernfs_fs_context *kfc = fc->fs_private; + + return container_of(kfc, struct trace_fs_context, kfc); +} + +static int trace_fs_parse_param(struct fs_context *fc, struct fs_parameter *param) +{ + struct trace_fs_context *ctx = trace_fc2context(fc); + struct tracefs_mount_opts *mount_opts = &ctx->mount_opts; + struct fs_parse_result result; + int opt; + kuid_t kuid; + kgid_t kgid; + + opt = fs_parse(fc, trace_fs_parameters, param, &result); + if (opt < 0) + return opt; + + switch (opt) { + case Opt_mode: + mount_opts->mode = result.uint_32 & 07777; + mount_opts->opts |= BIT(Opt_mode); + break; + case Opt_uid: + kuid = make_kuid(current_user_ns(), result.uint_32); + if (!uid_valid(kuid)) + goto bad_value; + /* - * We might like to report bad mount options here; - * but traditionally tracefs has ignored all mount options + * The requested uid must be representable in the + * filesystem's idmapping. */ - } + if (!kuid_has_mapping(fc->user_ns, kuid)) + goto bad_value; + + mount_opts->uid = kuid; + mount_opts->opts |= BIT(Opt_uid); + break; + case Opt_gid: + kgid = make_kgid(current_user_ns(), result.uint_32); + if (!gid_valid(kgid)) + goto bad_value; - opts->opts |= BIT(token); + /* + * The requested gid must be representable in the + * filesystem's idmapping. + */ + if (!kgid_has_mapping(fc->user_ns, kgid)) + goto bad_value; + + mount_opts->gid = kgid; + mount_opts->opts |= BIT(Opt_gid); + break; + default: + return invalfc(fc, "Unsupported parameter '%s'", param->key); } - return 0; +bad_value: + return invalfc(fc, "Bad value for '%s'", param->key); } static int tracefs_apply_options(struct super_block *sb, bool remount) { - struct tracefs_fs_info *fsi = sb->s_fs_info; struct inode *inode = d_inode(sb->s_root); - struct tracefs_mount_opts *opts = &fsi->mount_opts; + kuid_t kuid = global_opts.uid; + kgid_t kgid = global_opts.gid; + umode_t mode = global_opts.mode; + unsigned int opts = global_opts.opts; umode_t tmp_mode; /* @@ -322,126 +187,126 @@ static int tracefs_apply_options(struct super_block *sb, bool remount) * options. */ - if (!remount || opts->opts & BIT(Opt_mode)) { + if (!remount || opts & BIT(Opt_mode)) { tmp_mode = READ_ONCE(inode->i_mode) & ~S_IALLUGO; - tmp_mode |= opts->mode; + tmp_mode |= mode; WRITE_ONCE(inode->i_mode, tmp_mode); } - if (!remount || opts->opts & BIT(Opt_uid)) - inode->i_uid = opts->uid; + if (!remount || opts & BIT(Opt_uid)) + inode->i_uid = kuid; - if (!remount || opts->opts & BIT(Opt_gid)) - inode->i_gid = opts->gid; + if (!remount || opts & BIT(Opt_gid)) + inode->i_gid = kgid; return 0; } -static int tracefs_remount(struct super_block *sb, int *flags, char *data) +static int trace_fs_reconfigure(struct fs_context *fc) { - int err; - struct tracefs_fs_info *fsi = sb->s_fs_info; + tracefs_apply_options(fc->root->d_sb, true); + return 0; +} - sync_filesystem(sb); - err = tracefs_parse_options(data, &fsi->mount_opts); - if (err) - goto fail; +static int trace_fs_show_options(struct seq_file *seq, struct kernfs_root *kf_root) +{ + kuid_t kuid = global_opts.uid; + kgid_t kgid = global_opts.gid; + umode_t mode = global_opts.mode; - tracefs_apply_options(sb, true); + if (!uid_eq(kuid, GLOBAL_ROOT_UID)) + seq_printf(seq, ",uid=%u", from_kuid_munged(&init_user_ns, kuid)); + if (!gid_eq(kgid, GLOBAL_ROOT_GID)) + seq_printf(seq, ",gid=%u", from_kgid_munged(&init_user_ns, kgid)); + if (mode != TRACEFS_DEFAULT_MODE) + seq_printf(seq, ",mode=%o", mode); -fail: - return err; + return 0; } -static int tracefs_show_options(struct seq_file *m, struct dentry *root) +static int trace_fs_mkdir(struct kernfs_node *parent_kn, const char *name, umode_t mode) { - struct tracefs_fs_info *fsi = root->d_sb->s_fs_info; - struct tracefs_mount_opts *opts = &fsi->mount_opts; - - if (!uid_eq(opts->uid, GLOBAL_ROOT_UID)) - seq_printf(m, ",uid=%u", - from_kuid_munged(&init_user_ns, opts->uid)); - if (!gid_eq(opts->gid, GLOBAL_ROOT_GID)) - seq_printf(m, ",gid=%u", - from_kgid_munged(&init_user_ns, opts->gid)); - if (opts->mode != TRACEFS_DEFAULT_MODE) - seq_printf(m, ",mode=%o", opts->mode); + int ret; + struct kernfs_node *kn; - return 0; -} + if (parent_kn != trace_instance_dir) + return -EPERM; -static const struct super_operations tracefs_super_operations = { - .alloc_inode = tracefs_alloc_inode, - .free_inode = tracefs_free_inode, - .drop_inode = generic_delete_inode, - .statfs = simple_statfs, - .remount_fs = tracefs_remount, - .show_options = tracefs_show_options, -}; + kn = tracefs_create_dir(name, parent_kn); + if (IS_ERR(kn)) + return PTR_ERR(kn); + + ret = tracefs_ops.mkdir(name); + if (ret) + kernfs_remove(kn); + return ret; +} -static void tracefs_dentry_iput(struct dentry *dentry, struct inode *inode) +static int trace_fs_rmdir(struct kernfs_node *kn) { - struct tracefs_inode *ti; + int ret; - if (!dentry || !inode) - return; + if (kn != trace_instance_dir) + return -EPERM; + + ret = tracefs_ops.rmdir(kn->name); + if (!ret) + kernfs_remove(kn); - ti = get_tracefs(inode); - if (ti && ti->flags & TRACEFS_EVENT_INODE) - eventfs_set_ei_status_free(ti, dentry); - iput(inode); + return ret; } -static const struct dentry_operations tracefs_dentry_operations = { - .d_iput = tracefs_dentry_iput, +static struct kernfs_syscall_ops trace_fs_kf_syscall_ops = { + .show_options = trace_fs_show_options, + .mkdir = trace_fs_mkdir, + .rmdir = trace_fs_rmdir, }; -static int trace_fill_super(struct super_block *sb, void *data, int silent) +static int trace_fs_get_tree(struct fs_context *fc) { - static const struct tree_descr trace_files[] = {{""}}; - struct tracefs_fs_info *fsi; - int err; - - fsi = kzalloc(sizeof(struct tracefs_fs_info), GFP_KERNEL); - sb->s_fs_info = fsi; - if (!fsi) { - err = -ENOMEM; - goto fail; - } - - err = tracefs_parse_options(data, &fsi->mount_opts); - if (err) - goto fail; + int ret; - err = simple_fill_super(sb, TRACEFS_MAGIC, trace_files); - if (err) - goto fail; + ret = kernfs_get_tree(fc); + if (!ret) + tracefs_apply_options(fc->root->d_sb, false); + return ret; +} - sb->s_op = &tracefs_super_operations; - sb->s_d_op = &tracefs_dentry_operations; +static void trace_fs_context_free(struct fs_context *fc) +{ + struct trace_fs_context *ctx = trace_fc2context(fc); + kernfs_free_fs_context(fc); + kfree(ctx); +} - tracefs_apply_options(sb, false); +static const struct fs_context_operations trace_fs_context_ops = { + .free = trace_fs_context_free, + .parse_param = trace_fs_parse_param, + .get_tree = trace_fs_get_tree, + .reconfigure = trace_fs_reconfigure, +}; - return 0; +static int trace_fs_init_fs_context(struct fs_context *fc) +{ + struct trace_fs_context *ctx; -fail: - kfree(fsi); - sb->s_fs_info = NULL; - return err; -} + ctx = kzalloc(sizeof(struct trace_fs_context), GFP_KERNEL); + if (!ctx) + return -ENOMEM; -static struct dentry *trace_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, - void *data) -{ - return mount_single(fs_type, flags, data, trace_fill_super); + ctx->kfc.magic = TRACEFS_MAGIC; + ctx->mount_opts.mode = TRACEFS_DEFAULT_MODE; + fc->fs_private = &ctx->kfc; + fc->global = true; + fc->ops = &trace_fs_context_ops; + return 0; } static struct file_system_type trace_fs_type = { - .owner = THIS_MODULE, - .name = "tracefs", - .mount = trace_mount, - .kill_sb = kill_litter_super, + .name = "tracefs", + .init_fs_context = trace_fs_init_fs_context, + .parameters = trace_fs_parameters, + .kill_sb = kill_litter_super, }; MODULE_ALIAS_FS("tracefs"); @@ -566,26 +431,6 @@ struct dentry *eventfs_end_creating(struct dentry *dentry) return dentry; } -/* Find the inode that this will use for default */ -static struct inode *instance_inode(struct dentry *parent, struct inode *inode) -{ - struct tracefs_inode *ti; - - /* If parent is NULL then use root inode */ - if (!parent) - return d_inode(inode->i_sb->s_root); - - /* Find the inode that is flagged as an instance or the root inode */ - while (!IS_ROOT(parent)) { - ti = get_tracefs(d_inode(parent)); - if (ti->flags & TRACEFS_INSTANCE_INODE) - break; - parent = parent->d_parent; - } - - return d_inode(parent); -} - /** * tracefs_create_file - create a file in the tracefs filesystem * @name: a pointer to a string containing the name of the file to create. @@ -612,73 +457,24 @@ static struct inode *instance_inode(struct dentry *parent, struct inode *inode) * If tracefs is not enabled in the kernel, the value -%ENODEV will be * returned. */ -struct dentry *tracefs_create_file(const char *name, umode_t mode, - struct dentry *parent, void *data, - const struct file_operations *fops) +struct kernfs_node *tracefs_create_file(const char *name, umode_t mode, + struct kernfs_node *parent, void *data, + const struct kernfs_ops *ops) { - struct tracefs_inode *ti; - struct dentry *dentry; - struct inode *inode; - if (security_locked_down(LOCKDOWN_TRACEFS)) return NULL; if (!(mode & S_IFMT)) mode |= S_IFREG; BUG_ON(!S_ISREG(mode)); - dentry = tracefs_start_creating(name, parent); - if (IS_ERR(dentry)) - return NULL; + // inode->i_op = &tracefs_file_inode_operations; - inode = tracefs_get_inode(dentry->d_sb); - if (unlikely(!inode)) - return tracefs_failed_creating(dentry); - - ti = get_tracefs(inode); - ti->private = instance_inode(parent, inode); - - inode->i_mode = mode; - inode->i_op = &tracefs_file_inode_operations; - inode->i_fop = fops ? fops : &tracefs_file_operations; - inode->i_private = data; - inode->i_uid = d_inode(dentry->d_parent)->i_uid; - inode->i_gid = d_inode(dentry->d_parent)->i_gid; - d_instantiate(dentry, inode); - fsnotify_create(d_inode(dentry->d_parent), dentry); - return tracefs_end_creating(dentry); -} - -static struct dentry *__create_dir(const char *name, struct dentry *parent, - const struct inode_operations *ops) -{ - struct tracefs_inode *ti; - struct dentry *dentry = tracefs_start_creating(name, parent); - struct inode *inode; - - if (IS_ERR(dentry)) - return NULL; - - inode = tracefs_get_inode(dentry->d_sb); - if (unlikely(!inode)) - return tracefs_failed_creating(dentry); - - /* Do not set bits for OTH */ - inode->i_mode = S_IFDIR | S_IRWXU | S_IRUSR| S_IRGRP | S_IXUSR | S_IXGRP; - inode->i_op = ops; - inode->i_fop = &simple_dir_operations; - inode->i_uid = d_inode(dentry->d_parent)->i_uid; - inode->i_gid = d_inode(dentry->d_parent)->i_gid; - - ti = get_tracefs(inode); - ti->private = instance_inode(parent, inode); - - /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inc_nlink(inode); - d_instantiate(dentry, inode); - inc_nlink(d_inode(dentry->d_parent)); - fsnotify_mkdir(d_inode(dentry->d_parent), dentry); - return tracefs_end_creating(dentry); + return __kernfs_create_file(parent ?: trace_kfs_root_node, name, mode, + kernfs_node_owner(parent), + kernfs_node_group(parent), PAGE_SIZE, + ops ? : &tracefs_file_kfops, data, NULL, + NULL); } /** @@ -698,12 +494,17 @@ static struct dentry *__create_dir(const char *name, struct dentry *parent, * If tracing is not enabled in the kernel, the value -%ENODEV will be * returned. */ -struct dentry *tracefs_create_dir(const char *name, struct dentry *parent) +struct kernfs_node *tracefs_create_dir(const char *name, + struct kernfs_node *parent) { if (security_locked_down(LOCKDOWN_TRACEFS)) - return NULL; + return ERR_PTR(-EINVAL); - return __create_dir(name, parent, &tracefs_dir_inode_operations); + return kernfs_create_dir_ns(parent ?: trace_kfs_root_node, name, + S_IFDIR | S_IRWXU | S_IRUSR | S_IRGRP | + S_IXUSR | S_IXGRP, + kernfs_node_owner(parent), + kernfs_node_group(parent), NULL, NULL); } /** @@ -723,30 +524,23 @@ struct dentry *tracefs_create_dir(const char *name, struct dentry *parent) * * Returns the dentry of the instances directory. */ -__init struct dentry *tracefs_create_instance_dir(const char *name, - struct dentry *parent, - int (*mkdir)(const char *name), - int (*rmdir)(const char *name)) +__init struct kernfs_node * +tracefs_create_instance_dir(int (*mkdir)(const char *name), + int (*rmdir)(const char *name)) { - struct dentry *dentry; + struct kernfs_node *kn; /* Only allow one instance of the instances directory. */ if (WARN_ON(tracefs_ops.mkdir || tracefs_ops.rmdir)) - return NULL; + return ERR_PTR(-EINVAL); - dentry = __create_dir(name, parent, &tracefs_instance_dir_inode_operations); - if (!dentry) - return NULL; + kn = tracefs_create_dir("instances", trace_kfs_root_node); + if (IS_ERR(kn)) + return kn; tracefs_ops.mkdir = mkdir; tracefs_ops.rmdir = rmdir; - - return dentry; -} - -static void remove_one(struct dentry *victim) -{ - simple_release_fs(&tracefs_mount, &tracefs_mount_count); + return kn; } /** @@ -757,14 +551,12 @@ static void remove_one(struct dentry *victim) * was previously created with a call to another tracefs function * (like tracefs_create_file() or variants thereof.) */ -void tracefs_remove(struct dentry *dentry) +void tracefs_remove(struct kernfs_node *kn) { - if (IS_ERR_OR_NULL(dentry)) + if (IS_ERR_OR_NULL(kn)) return; - simple_pin_fs(&trace_fs_type, &tracefs_mount, &tracefs_mount_count); - simple_recursive_removal(dentry, remove_one); - simple_release_fs(&tracefs_mount, &tracefs_mount_count); + kernfs_remove(kn); } /** @@ -775,33 +567,30 @@ bool tracefs_initialized(void) return tracefs_registered; } -static void init_once(void *foo) -{ - struct tracefs_inode *ti = (struct tracefs_inode *) foo; - - inode_init_once(&ti->vfs_inode); -} - static int __init tracefs_init(void) { int retval; + struct kernfs_root *kfs_root; - tracefs_inode_cachep = kmem_cache_create("tracefs_inode_cache", - sizeof(struct tracefs_inode), - 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD| - SLAB_ACCOUNT), - init_once); - if (!tracefs_inode_cachep) - return -ENOMEM; + kfs_root = kernfs_create_root(&trace_fs_kf_syscall_ops, + KERNFS_ROOT_CREATE_DEACTIVATED, NULL); + if (IS_ERR(kfs_root)) + return PTR_ERR(kfs_root); retval = sysfs_create_mount_point(kernel_kobj, "tracing"); - if (retval) + if (retval) { + kernfs_destroy_root(kfs_root); return -EINVAL; + } retval = register_filesystem(&trace_fs_type); if (!retval) tracefs_registered = true; + else + kernfs_destroy_root(kfs_root); + + trace_fs_root = kfs_root; + trace_kfs_root_node = kernfs_root_to_node(kfs_root); return retval; } diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 99aaa050ccb7..50b84a82595f 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -244,6 +244,9 @@ struct kernfs_syscall_ops { struct kernfs_root *root); }; +kuid_t kernfs_node_owner(struct kernfs_node *kn); +kgid_t kernfs_node_group(struct kernfs_node *kn); + struct kernfs_node *kernfs_root_to_node(struct kernfs_root *root); struct kernfs_open_file { diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h index 7a5fe17b6bf9..83f6658e1875 100644 --- a/include/linux/tracefs.h +++ b/include/linux/tracefs.h @@ -14,6 +14,7 @@ #include <linux/fs.h> #include <linux/seq_file.h> +#include <linux/kernfs.h> #include <linux/types.h> @@ -22,6 +23,7 @@ struct file_operations; #ifdef CONFIG_TRACING struct eventfs_file; +extern struct kernfs_node *trace_instance_dir; /** * eventfs_callback - A callback function to create dynamic files in eventfs @@ -87,17 +89,17 @@ struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inode void eventfs_remove_events_dir(struct eventfs_inode *ei); void eventfs_remove_dir(struct eventfs_inode *ei); -struct dentry *tracefs_create_file(const char *name, umode_t mode, - struct dentry *parent, void *data, - const struct file_operations *fops); +struct kernfs_node *tracefs_create_file(const char *name, umode_t mode, + struct kernfs_node *parent, void *data, + const struct kernfs_ops *ops); -struct dentry *tracefs_create_dir(const char *name, struct dentry *parent); +struct kernfs_node *tracefs_create_dir(const char *name, + struct kernfs_node *parent); -void tracefs_remove(struct dentry *dentry); +void tracefs_remove(struct kernfs_node *kn); -struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *parent, - int (*mkdir)(const char *name), - int (*rmdir)(const char *name)); +struct kernfs_node *tracefs_create_instance_dir(int (*mkdir)(const char *name), + int (*rmdir)(const char *name)); bool tracefs_initialized(void); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 2a7c6fd934e9..3afc2dd51233 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -9494,7 +9494,7 @@ static const struct file_operations buffer_subbuf_size_fops = { .llseek = default_llseek, }; -static struct dentry *trace_instance_dir; +struct kernfs_node *trace_instance_dir; static void init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer); @@ -9885,9 +9885,7 @@ static __init void create_trace_instances(struct dentry *d_tracer) { struct trace_array *tr; - trace_instance_dir = tracefs_create_instance_dir("instances", d_tracer, - instance_mkdir, - instance_rmdir); + trace_instance_dir = tracefs_create_instance_dir(instance_mkdir, instance_rmdir); if (MEM_FAIL(!trace_instance_dir, "Failed to create instances directory\n")) return;
Signed-off-by: Christian Brauner <brauner@kernel.org> --- fs/kernfs/mount.c | 10 + fs/tracefs/inode.c | 649 ++++++++++++++++-------------------------------- include/linux/kernfs.h | 3 + include/linux/tracefs.h | 18 +- kernel/trace/trace.c | 6 +- 5 files changed, 244 insertions(+), 442 deletions(-)