aboutsummaryrefslogtreecommitdiffstats
path: root/fs/debugfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/debugfs/inode.c')
-rw-r--r--fs/debugfs/inode.c74
1 files changed, 38 insertions, 36 deletions
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index d22438ef7674..049d6c36da09 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -32,7 +32,9 @@ static struct vfsmount *debugfs_mount;
32static int debugfs_mount_count; 32static int debugfs_mount_count;
33static bool debugfs_registered; 33static bool debugfs_registered;
34 34
35static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev) 35static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev,
36 void *data, const struct file_operations *fops)
37
36{ 38{
37 struct inode *inode = new_inode(sb); 39 struct inode *inode = new_inode(sb);
38 40
@@ -44,14 +46,18 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d
44 init_special_inode(inode, mode, dev); 46 init_special_inode(inode, mode, dev);
45 break; 47 break;
46 case S_IFREG: 48 case S_IFREG:
47 inode->i_fop = &debugfs_file_operations; 49 inode->i_fop = fops ? fops : &debugfs_file_operations;
50 inode->i_private = data;
48 break; 51 break;
49 case S_IFLNK: 52 case S_IFLNK:
50 inode->i_op = &debugfs_link_operations; 53 inode->i_op = &debugfs_link_operations;
54 inode->i_fop = fops;
55 inode->i_private = data;
51 break; 56 break;
52 case S_IFDIR: 57 case S_IFDIR:
53 inode->i_op = &simple_dir_inode_operations; 58 inode->i_op = &simple_dir_inode_operations;
54 inode->i_fop = &simple_dir_operations; 59 inode->i_fop = fops ? fops : &simple_dir_operations;
60 inode->i_private = data;
55 61
56 /* directory inodes start off with i_nlink == 2 62 /* directory inodes start off with i_nlink == 2
57 * (for "." entry) */ 63 * (for "." entry) */
@@ -64,7 +70,8 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d
64 70
65/* SMP-safe */ 71/* SMP-safe */
66static int debugfs_mknod(struct inode *dir, struct dentry *dentry, 72static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
67 int mode, dev_t dev) 73 int mode, dev_t dev, void *data,
74 const struct file_operations *fops)
68{ 75{
69 struct inode *inode; 76 struct inode *inode;
70 int error = -EPERM; 77 int error = -EPERM;
@@ -72,7 +79,7 @@ static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
72 if (dentry->d_inode) 79 if (dentry->d_inode)
73 return -EEXIST; 80 return -EEXIST;
74 81
75 inode = debugfs_get_inode(dir->i_sb, mode, dev); 82 inode = debugfs_get_inode(dir->i_sb, mode, dev, data, fops);
76 if (inode) { 83 if (inode) {
77 d_instantiate(dentry, inode); 84 d_instantiate(dentry, inode);
78 dget(dentry); 85 dget(dentry);
@@ -81,12 +88,13 @@ static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
81 return error; 88 return error;
82} 89}
83 90
84static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) 91static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode,
92 void *data, const struct file_operations *fops)
85{ 93{
86 int res; 94 int res;
87 95
88 mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; 96 mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
89 res = debugfs_mknod(dir, dentry, mode, 0); 97 res = debugfs_mknod(dir, dentry, mode, 0, data, fops);
90 if (!res) { 98 if (!res) {
91 inc_nlink(dir); 99 inc_nlink(dir);
92 fsnotify_mkdir(dir, dentry); 100 fsnotify_mkdir(dir, dentry);
@@ -94,18 +102,20 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
94 return res; 102 return res;
95} 103}
96 104
97static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode) 105static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode,
106 void *data, const struct file_operations *fops)
98{ 107{
99 mode = (mode & S_IALLUGO) | S_IFLNK; 108 mode = (mode & S_IALLUGO) | S_IFLNK;
100 return debugfs_mknod(dir, dentry, mode, 0); 109 return debugfs_mknod(dir, dentry, mode, 0, data, fops);
101} 110}
102 111
103static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode) 112static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode,
113 void *data, const struct file_operations *fops)
104{ 114{
105 int res; 115 int res;
106 116
107 mode = (mode & S_IALLUGO) | S_IFREG; 117 mode = (mode & S_IALLUGO) | S_IFREG;
108 res = debugfs_mknod(dir, dentry, mode, 0); 118 res = debugfs_mknod(dir, dentry, mode, 0, data, fops);
109 if (!res) 119 if (!res)
110 fsnotify_create(dir, dentry); 120 fsnotify_create(dir, dentry);
111 return res; 121 return res;
@@ -139,7 +149,9 @@ static struct file_system_type debug_fs_type = {
139 149
140static int debugfs_create_by_name(const char *name, mode_t mode, 150static int debugfs_create_by_name(const char *name, mode_t mode,
141 struct dentry *parent, 151 struct dentry *parent,
142 struct dentry **dentry) 152 struct dentry **dentry,
153 void *data,
154 const struct file_operations *fops)
143{ 155{
144 int error = 0; 156 int error = 0;
145 157
@@ -148,15 +160,8 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
148 * block. A pointer to that is in the struct vfsmount that we 160 * block. A pointer to that is in the struct vfsmount that we
149 * have around. 161 * have around.
150 */ 162 */
151 if (!parent) { 163 if (!parent)
152 if (debugfs_mount && debugfs_mount->mnt_sb) { 164 parent = debugfs_mount->mnt_sb->s_root;
153 parent = debugfs_mount->mnt_sb->s_root;
154 }
155 }
156 if (!parent) {
157 pr_debug("debugfs: Ah! can not find a parent!\n");
158 return -EFAULT;
159 }
160 165
161 *dentry = NULL; 166 *dentry = NULL;
162 mutex_lock(&parent->d_inode->i_mutex); 167 mutex_lock(&parent->d_inode->i_mutex);
@@ -164,13 +169,16 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
164 if (!IS_ERR(*dentry)) { 169 if (!IS_ERR(*dentry)) {
165 switch (mode & S_IFMT) { 170 switch (mode & S_IFMT) {
166 case S_IFDIR: 171 case S_IFDIR:
167 error = debugfs_mkdir(parent->d_inode, *dentry, mode); 172 error = debugfs_mkdir(parent->d_inode, *dentry, mode,
173 data, fops);
168 break; 174 break;
169 case S_IFLNK: 175 case S_IFLNK:
170 error = debugfs_link(parent->d_inode, *dentry, mode); 176 error = debugfs_link(parent->d_inode, *dentry, mode,
177 data, fops);
171 break; 178 break;
172 default: 179 default:
173 error = debugfs_create(parent->d_inode, *dentry, mode); 180 error = debugfs_create(parent->d_inode, *dentry, mode,
181 data, fops);
174 break; 182 break;
175 } 183 }
176 dput(*dentry); 184 dput(*dentry);
@@ -184,7 +192,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
184/** 192/**
185 * debugfs_create_file - create a file in the debugfs filesystem 193 * debugfs_create_file - create a file in the debugfs filesystem
186 * @name: a pointer to a string containing the name of the file to create. 194 * @name: a pointer to a string containing the name of the file to create.
187 * @mode: the permission that the file should have 195 * @mode: the permission that the file should have.
188 * @parent: a pointer to the parent dentry for this file. This should be a 196 * @parent: a pointer to the parent dentry for this file. This should be a
189 * directory dentry if set. If this paramater is NULL, then the 197 * directory dentry if set. If this paramater is NULL, then the
190 * file will be created in the root of the debugfs filesystem. 198 * file will be created in the root of the debugfs filesystem.
@@ -195,8 +203,8 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
195 * this file. 203 * this file.
196 * 204 *
197 * This is the basic "create a file" function for debugfs. It allows for a 205 * This is the basic "create a file" function for debugfs. It allows for a
198 * wide range of flexibility in createing a file, or a directory (if you 206 * wide range of flexibility in creating a file, or a directory (if you want
199 * want to create a directory, the debugfs_create_dir() function is 207 * to create a directory, the debugfs_create_dir() function is
200 * recommended to be used instead.) 208 * recommended to be used instead.)
201 * 209 *
202 * This function will return a pointer to a dentry if it succeeds. This 210 * This function will return a pointer to a dentry if it succeeds. This
@@ -221,19 +229,13 @@ struct dentry *debugfs_create_file(const char *name, mode_t mode,
221 if (error) 229 if (error)
222 goto exit; 230 goto exit;
223 231
224 error = debugfs_create_by_name(name, mode, parent, &dentry); 232 error = debugfs_create_by_name(name, mode, parent, &dentry,
233 data, fops);
225 if (error) { 234 if (error) {
226 dentry = NULL; 235 dentry = NULL;
227 simple_release_fs(&debugfs_mount, &debugfs_mount_count); 236 simple_release_fs(&debugfs_mount, &debugfs_mount_count);
228 goto exit; 237 goto exit;
229 } 238 }
230
231 if (dentry->d_inode) {
232 if (data)
233 dentry->d_inode->i_private = data;
234 if (fops)
235 dentry->d_inode->i_fop = fops;
236 }
237exit: 239exit:
238 return dentry; 240 return dentry;
239} 241}
@@ -494,7 +496,7 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
494 } 496 }
495 d_move(old_dentry, dentry); 497 d_move(old_dentry, dentry);
496 fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name, 498 fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
497 old_dentry->d_name.name, S_ISDIR(old_dentry->d_inode->i_mode), 499 S_ISDIR(old_dentry->d_inode->i_mode),
498 NULL, old_dentry); 500 NULL, old_dentry);
499 fsnotify_oldname_free(old_name); 501 fsnotify_oldname_free(old_name);
500 unlock_rename(new_dir, old_dir); 502 unlock_rename(new_dir, old_dir);