diff mbox series

[DRAFT,1/4] : tracefs: port to kernfs

Message ID 20240131-tracefs-kernfs-v1-1-f20e2e9a8d61@kernel.org (mailing list archive)
State New, archived
Headers show
Series : Port tracefs to kernfs | expand

Commit Message

Christian Brauner Jan. 31, 2024, 1:36 p.m. UTC
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(-)

Comments

kernel test robot Feb. 1, 2024, 12:37 a.m. UTC | #1
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
kernel test robot Feb. 1, 2024, 12:37 a.m. UTC | #2
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)
kernel test robot Feb. 1, 2024, 7:01 a.m. UTC | #3
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 mbox series

Patch

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;