Message ID | 1674407228-49109-5-git-send-email-akaher@vmware.com (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
Series | [1/8] eventfs: introducing struct tracefs_inode | expand |
Hi Ajay, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on linus/master] [also build test WARNING on v6.2-rc5 next-20230120] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Ajay-Kaher/eventfs-adding-eventfs-dir-add-functions/20230123-010956 patch link: https://lore.kernel.org/r/1674407228-49109-5-git-send-email-akaher%40vmware.com patch subject: [PATCH 5/8] eventfs: adding functions to create eventfs files and directories config: arc-defconfig (https://download.01.org/0day-ci/archive/20230123/202301230242.aRNYHDz2-lkp@intel.com/config) compiler: arc-elf-gcc (GCC) 12.1.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/950ac8561471b622eac5555b4a7502bcd8c20663 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Ajay-Kaher/eventfs-adding-eventfs-dir-add-functions/20230123-010956 git checkout 950ac8561471b622eac5555b4a7502bcd8c20663 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arc olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arc SHELL=/bin/bash fs/tracefs/ kernel/trace/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): >> fs/tracefs/event_inode.c:48:16: warning: no previous prototype for 'eventfs_create_file' [-Wmissing-prototypes] 48 | struct dentry *eventfs_create_file(const char *name, umode_t mode, | ^~~~~~~~~~~~~~~~~~~ >> fs/tracefs/event_inode.c:117:16: warning: no previous prototype for 'eventfs_create_dir' [-Wmissing-prototypes] 117 | struct dentry *eventfs_create_dir(const char *name, umode_t mode, | ^~~~~~~~~~~~~~~~~~ vim +/eventfs_create_file +48 fs/tracefs/event_inode.c 23 24 /** 25 * eventfs_create_file - create a file in the tracefs filesystem 26 * @name: a pointer to a string containing the name of the file to create. 27 * @mode: the permission that the file should have. 28 * @parent: a pointer to the parent dentry for this file. This should be a 29 * directory dentry if set. If this parameter is NULL, then the 30 * file will be created in the root of the tracefs filesystem. 31 * @data: a pointer to something that the caller will want to get to later 32 * on. The inode.i_private pointer will point to this value on 33 * the open() call. 34 * @fops: a pointer to a struct file_operations that should be used for 35 * this file. 36 * 37 * This is the basic "create a file" function for tracefs. It allows for a 38 * wide range of flexibility in creating a file. 39 * 40 * This function will return a pointer to a dentry if it succeeds. This 41 * pointer must be passed to the tracefs_remove() function when the file is 42 * to be removed (no automatic cleanup happens if your module is unloaded, 43 * you are responsible here.) If an error occurs, %NULL will be returned. 44 * 45 * If tracefs is not enabled in the kernel, the value -%ENODEV will be 46 * returned. 47 */ > 48 struct dentry *eventfs_create_file(const char *name, umode_t mode, 49 struct dentry *parent, void *data, 50 const struct file_operations *fop, 51 bool anon) 52 { 53 struct tracefs_inode *ti; 54 struct dentry *dentry; 55 struct inode *inode; 56 57 if (security_locked_down(LOCKDOWN_TRACEFS)) 58 return NULL; 59 60 if (!(mode & S_IFMT)) 61 mode |= S_IFREG; 62 63 if (WARN_ON_ONCE(!S_ISREG(mode))) 64 return NULL; 65 66 dentry = eventfs_start_creating(name, parent); 67 68 if (IS_ERR(dentry)) 69 return dentry; 70 71 inode = tracefs_get_inode(dentry->d_sb); 72 if (unlikely(!inode)) 73 return eventfs_failed_creating(dentry); 74 75 inode->i_mode = mode; 76 inode->i_fop = fop; 77 inode->i_private = data; 78 79 ti = get_tracefs(inode); 80 ti->flags |= TRACEFS_EVENT_INODE; 81 82 if (anon) 83 d_instantiate_anon(dentry, inode); 84 else 85 d_instantiate(dentry, inode); 86 87 fsnotify_create(dentry->d_parent->d_inode, dentry); 88 return eventfs_end_creating(dentry); 89 } 90 91 /** 92 * eventfs_create_dir - create a dir in the tracefs filesystem 93 * @name: a pointer to a string containing the name of the file to create. 94 * @mode: the permission that the file should have. 95 * @parent: a pointer to the parent dentry for this file. This should be a 96 * directory dentry if set. If this parameter is NULL, then the 97 * file will be created in the root of the tracefs filesystem. 98 * @data: a pointer to something that the caller will want to get to later 99 * on. The inode.i_private pointer will point to this value on 100 * the open() call. 101 * @fop: a pointer to a struct file_operations that should be used for 102 * this dir. 103 * @iop: a pointer to a struct inode_operations that should be used for 104 * this dir. 105 * 106 * This is the basic "create a dir" function for eventfs. It allows for a 107 * wide range of flexibility in creating a dir. 108 * 109 * This function will return a pointer to a dentry if it succeeds. This 110 * pointer must be passed to the tracefs_remove() function when the file is 111 * to be removed (no automatic cleanup happens if your module is unloaded, 112 * you are responsible here.) If an error occurs, %NULL will be returned. 113 * 114 * If tracefs is not enabled in the kernel, the value -%ENODEV will be 115 * returned. 116 */ > 117 struct dentry *eventfs_create_dir(const char *name, umode_t mode, 118 struct dentry *parent, void *data, 119 const struct file_operations *fop, 120 const struct inode_operations *iop, 121 bool anon) 122 { 123 struct tracefs_inode *ti; 124 struct dentry *dentry; 125 struct inode *inode; 126 127 if (security_locked_down(LOCKDOWN_TRACEFS)) 128 return NULL; 129 130 WARN_ON(!S_ISDIR(mode)); 131 132 dentry = eventfs_start_creating(name, parent); 133 134 if (IS_ERR(dentry)) 135 return dentry; 136 137 inode = tracefs_get_inode(dentry->d_sb); 138 if (unlikely(!inode)) 139 return eventfs_failed_creating(dentry); 140 141 inode->i_mode = mode; 142 inode->i_op = iop; 143 inode->i_fop = fop; 144 inode->i_private = data; 145 146 ti = get_tracefs(inode); 147 ti->flags |= TRACEFS_EVENT_INODE; 148 149 inc_nlink(inode); 150 if (anon) 151 d_instantiate_anon(dentry, inode); 152 else 153 d_instantiate(dentry, inode); 154 inc_nlink(dentry->d_parent->d_inode); 155 fsnotify_mkdir(dentry->d_parent->d_inode, dentry); 156 return eventfs_end_creating(dentry); 157 } 158
Hi Ajay, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on linus/master] [also build test WARNING on v6.2-rc5] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Ajay-Kaher/eventfs-adding-eventfs-dir-add-functions/20230123-010956 patch link: https://lore.kernel.org/r/1674407228-49109-5-git-send-email-akaher%40vmware.com patch subject: [PATCH 5/8] eventfs: adding functions to create eventfs files and directories config: riscv-buildonly-randconfig-r003-20230123 (https://download.01.org/0day-ci/archive/20230123/202301230304.kKbSbIeq-lkp@intel.com/config) compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 4196ca3278f78c6e19246e54ab0ecb364e37d66a) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install riscv cross compiling tool for clang build # apt-get install binutils-riscv-linux-gnu # https://github.com/intel-lab-lkp/linux/commit/950ac8561471b622eac5555b4a7502bcd8c20663 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Ajay-Kaher/eventfs-adding-eventfs-dir-add-functions/20230123-010956 git checkout 950ac8561471b622eac5555b4a7502bcd8c20663 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash fs/tracefs/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): >> fs/tracefs/event_inode.c:48:16: warning: no previous prototype for function 'eventfs_create_file' [-Wmissing-prototypes] struct dentry *eventfs_create_file(const char *name, umode_t mode, ^ fs/tracefs/event_inode.c:48:1: note: declare 'static' if the function is not intended to be used outside of this translation unit struct dentry *eventfs_create_file(const char *name, umode_t mode, ^ static >> fs/tracefs/event_inode.c:117:16: warning: no previous prototype for function 'eventfs_create_dir' [-Wmissing-prototypes] struct dentry *eventfs_create_dir(const char *name, umode_t mode, ^ fs/tracefs/event_inode.c:117:1: note: declare 'static' if the function is not intended to be used outside of this translation unit struct dentry *eventfs_create_dir(const char *name, umode_t mode, ^ static 2 warnings generated. Kconfig warnings: (for reference only) WARNING: unmet direct dependencies detected for IOMMU_IO_PGTABLE_LPAE Depends on [n]: IOMMU_SUPPORT [=y] && (ARM || ARM64 || COMPILE_TEST [=y] && !GENERIC_ATOMIC64 [=y]) Selected by [y]: - IPMMU_VMSA [=y] && IOMMU_SUPPORT [=y] && (ARCH_RENESAS [=y] || COMPILE_TEST [=y] && !GENERIC_ATOMIC64 [=y]) vim +/eventfs_create_file +48 fs/tracefs/event_inode.c 23 24 /** 25 * eventfs_create_file - create a file in the tracefs filesystem 26 * @name: a pointer to a string containing the name of the file to create. 27 * @mode: the permission that the file should have. 28 * @parent: a pointer to the parent dentry for this file. This should be a 29 * directory dentry if set. If this parameter is NULL, then the 30 * file will be created in the root of the tracefs filesystem. 31 * @data: a pointer to something that the caller will want to get to later 32 * on. The inode.i_private pointer will point to this value on 33 * the open() call. 34 * @fops: a pointer to a struct file_operations that should be used for 35 * this file. 36 * 37 * This is the basic "create a file" function for tracefs. It allows for a 38 * wide range of flexibility in creating a file. 39 * 40 * This function will return a pointer to a dentry if it succeeds. This 41 * pointer must be passed to the tracefs_remove() function when the file is 42 * to be removed (no automatic cleanup happens if your module is unloaded, 43 * you are responsible here.) If an error occurs, %NULL will be returned. 44 * 45 * If tracefs is not enabled in the kernel, the value -%ENODEV will be 46 * returned. 47 */ > 48 struct dentry *eventfs_create_file(const char *name, umode_t mode, 49 struct dentry *parent, void *data, 50 const struct file_operations *fop, 51 bool anon) 52 { 53 struct tracefs_inode *ti; 54 struct dentry *dentry; 55 struct inode *inode; 56 57 if (security_locked_down(LOCKDOWN_TRACEFS)) 58 return NULL; 59 60 if (!(mode & S_IFMT)) 61 mode |= S_IFREG; 62 63 if (WARN_ON_ONCE(!S_ISREG(mode))) 64 return NULL; 65 66 dentry = eventfs_start_creating(name, parent); 67 68 if (IS_ERR(dentry)) 69 return dentry; 70 71 inode = tracefs_get_inode(dentry->d_sb); 72 if (unlikely(!inode)) 73 return eventfs_failed_creating(dentry); 74 75 inode->i_mode = mode; 76 inode->i_fop = fop; 77 inode->i_private = data; 78 79 ti = get_tracefs(inode); 80 ti->flags |= TRACEFS_EVENT_INODE; 81 82 if (anon) 83 d_instantiate_anon(dentry, inode); 84 else 85 d_instantiate(dentry, inode); 86 87 fsnotify_create(dentry->d_parent->d_inode, dentry); 88 return eventfs_end_creating(dentry); 89 } 90 91 /** 92 * eventfs_create_dir - create a dir in the tracefs filesystem 93 * @name: a pointer to a string containing the name of the file to create. 94 * @mode: the permission that the file should have. 95 * @parent: a pointer to the parent dentry for this file. This should be a 96 * directory dentry if set. If this parameter is NULL, then the 97 * file will be created in the root of the tracefs filesystem. 98 * @data: a pointer to something that the caller will want to get to later 99 * on. The inode.i_private pointer will point to this value on 100 * the open() call. 101 * @fop: a pointer to a struct file_operations that should be used for 102 * this dir. 103 * @iop: a pointer to a struct inode_operations that should be used for 104 * this dir. 105 * 106 * This is the basic "create a dir" function for eventfs. It allows for a 107 * wide range of flexibility in creating a dir. 108 * 109 * This function will return a pointer to a dentry if it succeeds. This 110 * pointer must be passed to the tracefs_remove() function when the file is 111 * to be removed (no automatic cleanup happens if your module is unloaded, 112 * you are responsible here.) If an error occurs, %NULL will be returned. 113 * 114 * If tracefs is not enabled in the kernel, the value -%ENODEV will be 115 * returned. 116 */ > 117 struct dentry *eventfs_create_dir(const char *name, umode_t mode, 118 struct dentry *parent, void *data, 119 const struct file_operations *fop, 120 const struct inode_operations *iop, 121 bool anon) 122 { 123 struct tracefs_inode *ti; 124 struct dentry *dentry; 125 struct inode *inode; 126 127 if (security_locked_down(LOCKDOWN_TRACEFS)) 128 return NULL; 129 130 WARN_ON(!S_ISDIR(mode)); 131 132 dentry = eventfs_start_creating(name, parent); 133 134 if (IS_ERR(dentry)) 135 return dentry; 136 137 inode = tracefs_get_inode(dentry->d_sb); 138 if (unlikely(!inode)) 139 return eventfs_failed_creating(dentry); 140 141 inode->i_mode = mode; 142 inode->i_op = iop; 143 inode->i_fop = fop; 144 inode->i_private = data; 145 146 ti = get_tracefs(inode); 147 ti->flags |= TRACEFS_EVENT_INODE; 148 149 inc_nlink(inode); 150 if (anon) 151 d_instantiate_anon(dentry, inode); 152 else 153 d_instantiate(dentry, inode); 154 inc_nlink(dentry->d_parent->d_inode); 155 fsnotify_mkdir(dentry->d_parent->d_inode, dentry); 156 return eventfs_end_creating(dentry); 157 } 158
Hi Ajay, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on linus/master] [also build test WARNING on v6.2-rc5 next-20230123] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Ajay-Kaher/eventfs-adding-eventfs-dir-add-functions/20230123-010956 patch link: https://lore.kernel.org/r/1674407228-49109-5-git-send-email-akaher%40vmware.com patch subject: [PATCH 5/8] eventfs: adding functions to create eventfs files and directories config: x86_64-randconfig-s022 (https://download.01.org/0day-ci/archive/20230123/202301231745.XMv1eJAp-lkp@intel.com/config) compiler: gcc-11 (Debian 11.3.0-8) 11.3.0 reproduce: # apt-get install sparse # sparse version: v0.6.4-39-gce1a6720-dirty # https://github.com/intel-lab-lkp/linux/commit/950ac8561471b622eac5555b4a7502bcd8c20663 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Ajay-Kaher/eventfs-adding-eventfs-dir-add-functions/20230123-010956 git checkout 950ac8561471b622eac5555b4a7502bcd8c20663 # save the config file mkdir build_dir && cp config build_dir/.config make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=x86_64 olddefconfig make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=x86_64 SHELL=/bin/bash fs/tracefs/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> sparse warnings: (new ones prefixed by >>) >> fs/tracefs/event_inode.c:48:15: sparse: sparse: symbol 'eventfs_create_file' was not declared. Should it be static? >> fs/tracefs/event_inode.c:117:15: sparse: sparse: symbol 'eventfs_create_dir' was not declared. Should it be static? fs/tracefs/event_inode.c:162:31: sparse: sparse: symbol 'eventfs_root_dir_inode_operations' was not declared. Should it be static? vim +/eventfs_create_file +48 fs/tracefs/event_inode.c 23 24 /** 25 * eventfs_create_file - create a file in the tracefs filesystem 26 * @name: a pointer to a string containing the name of the file to create. 27 * @mode: the permission that the file should have. 28 * @parent: a pointer to the parent dentry for this file. This should be a 29 * directory dentry if set. If this parameter is NULL, then the 30 * file will be created in the root of the tracefs filesystem. 31 * @data: a pointer to something that the caller will want to get to later 32 * on. The inode.i_private pointer will point to this value on 33 * the open() call. 34 * @fops: a pointer to a struct file_operations that should be used for 35 * this file. 36 * 37 * This is the basic "create a file" function for tracefs. It allows for a 38 * wide range of flexibility in creating a file. 39 * 40 * This function will return a pointer to a dentry if it succeeds. This 41 * pointer must be passed to the tracefs_remove() function when the file is 42 * to be removed (no automatic cleanup happens if your module is unloaded, 43 * you are responsible here.) If an error occurs, %NULL will be returned. 44 * 45 * If tracefs is not enabled in the kernel, the value -%ENODEV will be 46 * returned. 47 */ > 48 struct dentry *eventfs_create_file(const char *name, umode_t mode, 49 struct dentry *parent, void *data, 50 const struct file_operations *fop, 51 bool anon) 52 { 53 struct tracefs_inode *ti; 54 struct dentry *dentry; 55 struct inode *inode; 56 57 if (security_locked_down(LOCKDOWN_TRACEFS)) 58 return NULL; 59 60 if (!(mode & S_IFMT)) 61 mode |= S_IFREG; 62 63 if (WARN_ON_ONCE(!S_ISREG(mode))) 64 return NULL; 65 66 dentry = eventfs_start_creating(name, parent); 67 68 if (IS_ERR(dentry)) 69 return dentry; 70 71 inode = tracefs_get_inode(dentry->d_sb); 72 if (unlikely(!inode)) 73 return eventfs_failed_creating(dentry); 74 75 inode->i_mode = mode; 76 inode->i_fop = fop; 77 inode->i_private = data; 78 79 ti = get_tracefs(inode); 80 ti->flags |= TRACEFS_EVENT_INODE; 81 82 if (anon) 83 d_instantiate_anon(dentry, inode); 84 else 85 d_instantiate(dentry, inode); 86 87 fsnotify_create(dentry->d_parent->d_inode, dentry); 88 return eventfs_end_creating(dentry); 89 } 90 91 /** 92 * eventfs_create_dir - create a dir in the tracefs filesystem 93 * @name: a pointer to a string containing the name of the file to create. 94 * @mode: the permission that the file should have. 95 * @parent: a pointer to the parent dentry for this file. This should be a 96 * directory dentry if set. If this parameter is NULL, then the 97 * file will be created in the root of the tracefs filesystem. 98 * @data: a pointer to something that the caller will want to get to later 99 * on. The inode.i_private pointer will point to this value on 100 * the open() call. 101 * @fop: a pointer to a struct file_operations that should be used for 102 * this dir. 103 * @iop: a pointer to a struct inode_operations that should be used for 104 * this dir. 105 * 106 * This is the basic "create a dir" function for eventfs. It allows for a 107 * wide range of flexibility in creating a dir. 108 * 109 * This function will return a pointer to a dentry if it succeeds. This 110 * pointer must be passed to the tracefs_remove() function when the file is 111 * to be removed (no automatic cleanup happens if your module is unloaded, 112 * you are responsible here.) If an error occurs, %NULL will be returned. 113 * 114 * If tracefs is not enabled in the kernel, the value -%ENODEV will be 115 * returned. 116 */ > 117 struct dentry *eventfs_create_dir(const char *name, umode_t mode, 118 struct dentry *parent, void *data, 119 const struct file_operations *fop, 120 const struct inode_operations *iop, 121 bool anon) 122 { 123 struct tracefs_inode *ti; 124 struct dentry *dentry; 125 struct inode *inode; 126 127 if (security_locked_down(LOCKDOWN_TRACEFS)) 128 return NULL; 129 130 WARN_ON(!S_ISDIR(mode)); 131 132 dentry = eventfs_start_creating(name, parent); 133 134 if (IS_ERR(dentry)) 135 return dentry; 136 137 inode = tracefs_get_inode(dentry->d_sb); 138 if (unlikely(!inode)) 139 return eventfs_failed_creating(dentry); 140 141 inode->i_mode = mode; 142 inode->i_op = iop; 143 inode->i_fop = fop; 144 inode->i_private = data; 145 146 ti = get_tracefs(inode); 147 ti->flags |= TRACEFS_EVENT_INODE; 148 149 inc_nlink(inode); 150 if (anon) 151 d_instantiate_anon(dentry, inode); 152 else 153 d_instantiate(dentry, inode); 154 inc_nlink(dentry->d_parent->d_inode); 155 fsnotify_mkdir(dentry->d_parent->d_inode, dentry); 156 return eventfs_end_creating(dentry); 157 } 158
diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c index 4d47da0..28866c0 100644 --- a/fs/tracefs/event_inode.c +++ b/fs/tracefs/event_inode.c @@ -21,6 +21,141 @@ #include <linux/kref.h> #include "internal.h" +/** + * eventfs_create_file - create a file in the tracefs filesystem + * @name: a pointer to a string containing the name of the file to create. + * @mode: the permission that the file should have. + * @parent: a pointer to the parent dentry for this file. This should be a + * directory dentry if set. If this parameter is NULL, then the + * file will be created in the root of the tracefs filesystem. + * @data: a pointer to something that the caller will want to get to later + * on. The inode.i_private pointer will point to this value on + * the open() call. + * @fops: a pointer to a struct file_operations that should be used for + * this file. + * + * This is the basic "create a file" function for tracefs. It allows for a + * wide range of flexibility in creating a file. + * + * This function will return a pointer to a dentry if it succeeds. This + * pointer must be passed to the tracefs_remove() function when the file is + * to be removed (no automatic cleanup happens if your module is unloaded, + * you are responsible here.) If an error occurs, %NULL will be returned. + * + * If tracefs is not enabled in the kernel, the value -%ENODEV will be + * returned. + */ +struct dentry *eventfs_create_file(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct file_operations *fop, + bool anon) +{ + 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; + + if (WARN_ON_ONCE(!S_ISREG(mode))) + return NULL; + + dentry = eventfs_start_creating(name, parent); + + if (IS_ERR(dentry)) + return dentry; + + inode = tracefs_get_inode(dentry->d_sb); + if (unlikely(!inode)) + return eventfs_failed_creating(dentry); + + inode->i_mode = mode; + inode->i_fop = fop; + inode->i_private = data; + + ti = get_tracefs(inode); + ti->flags |= TRACEFS_EVENT_INODE; + + if (anon) + d_instantiate_anon(dentry, inode); + else + d_instantiate(dentry, inode); + + fsnotify_create(dentry->d_parent->d_inode, dentry); + return eventfs_end_creating(dentry); +} + +/** + * eventfs_create_dir - create a dir in the tracefs filesystem + * @name: a pointer to a string containing the name of the file to create. + * @mode: the permission that the file should have. + * @parent: a pointer to the parent dentry for this file. This should be a + * directory dentry if set. If this parameter is NULL, then the + * file will be created in the root of the tracefs filesystem. + * @data: a pointer to something that the caller will want to get to later + * on. The inode.i_private pointer will point to this value on + * the open() call. + * @fop: a pointer to a struct file_operations that should be used for + * this dir. + * @iop: a pointer to a struct inode_operations that should be used for + * this dir. + * + * This is the basic "create a dir" function for eventfs. It allows for a + * wide range of flexibility in creating a dir. + * + * This function will return a pointer to a dentry if it succeeds. This + * pointer must be passed to the tracefs_remove() function when the file is + * to be removed (no automatic cleanup happens if your module is unloaded, + * you are responsible here.) If an error occurs, %NULL will be returned. + * + * If tracefs is not enabled in the kernel, the value -%ENODEV will be + * returned. + */ +struct dentry *eventfs_create_dir(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct file_operations *fop, + const struct inode_operations *iop, + bool anon) +{ + struct tracefs_inode *ti; + struct dentry *dentry; + struct inode *inode; + + if (security_locked_down(LOCKDOWN_TRACEFS)) + return NULL; + + WARN_ON(!S_ISDIR(mode)); + + dentry = eventfs_start_creating(name, parent); + + if (IS_ERR(dentry)) + return dentry; + + inode = tracefs_get_inode(dentry->d_sb); + if (unlikely(!inode)) + return eventfs_failed_creating(dentry); + + inode->i_mode = mode; + inode->i_op = iop; + inode->i_fop = fop; + inode->i_private = data; + + ti = get_tracefs(inode); + ti->flags |= TRACEFS_EVENT_INODE; + + inc_nlink(inode); + if (anon) + d_instantiate_anon(dentry, inode); + else + d_instantiate(dentry, inode); + inc_nlink(dentry->d_parent->d_inode); + fsnotify_mkdir(dentry->d_parent->d_inode, dentry); + return eventfs_end_creating(dentry); +} + static const struct file_operations eventfs_file_operations = { }; @@ -86,9 +221,9 @@ struct dentry *eventfs_create_events_dir(const char *name, struct dentry *parent */ struct eventfs_file *eventfs_add_subsystem_dir(const char *name, struct dentry *parent) { - struct eventfs_file *ef; struct tracefs_inode *ti_parent; struct eventfs_inode *ei_parent; + struct eventfs_file *ef; if (!parent) return ERR_PTR(-EINVAL); diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index 015b7b8..6d950d1 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c @@ -451,6 +451,53 @@ struct dentry *tracefs_end_creating(struct dentry *dentry) return dentry; } +struct dentry *eventfs_start_creating(const char *name, struct dentry *parent) +{ + struct dentry *dentry; + int error; + + error = simple_pin_fs(&trace_fs_type, &tracefs_mount, + &tracefs_mount_count); + if (error) + return ERR_PTR(error); + + /* + * If the parent is not specified, we create it in the root. + * We need the root dentry to do this, which is in the super + * block. A pointer to that is in the struct vfsmount that we + * have around. + */ + if (!parent) + parent = tracefs_mount->mnt_root; + + if (unlikely(IS_DEADDIR(parent->d_inode))) + dentry = ERR_PTR(-ENOENT); + else + dentry = lookup_one_len(name, parent, strlen(name)); + + if (!IS_ERR(dentry) && dentry->d_inode) { + dput(dentry); + dentry = ERR_PTR(-EEXIST); + } + + if (IS_ERR(dentry)) + simple_release_fs(&tracefs_mount, &tracefs_mount_count); + + return dentry; +} + +struct dentry *eventfs_failed_creating(struct dentry *dentry) +{ + dput(dentry); + simple_release_fs(&tracefs_mount, &tracefs_mount_count); + return NULL; +} + +struct dentry *eventfs_end_creating(struct dentry *dentry) +{ + return dentry; +} + /** * tracefs_create_file - create a file in the tracefs filesystem * @name: a pointer to a string containing the name of the file to create. diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h index b02cbba..52201f3 100644 --- a/include/linux/tracefs.h +++ b/include/linux/tracefs.h @@ -38,6 +38,12 @@ struct eventfs_file { bool created; }; +struct dentry *eventfs_start_creating(const char *name, struct dentry *parent); + +struct dentry *eventfs_failed_creating(struct dentry *dentry); + +struct dentry *eventfs_end_creating(struct dentry *dentry); + struct dentry *eventfs_create_events_dir(const char *name, struct dentry *parent);