diff options
Diffstat (limited to 'fs/debugfs/inode.c')
-rw-r--r-- | fs/debugfs/inode.c | 91 |
1 files changed, 44 insertions, 47 deletions
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index b80bc846a15a..d17c20fd74e6 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
@@ -54,13 +54,12 @@ static struct inode *debugfs_get_inode(struct super_block *sb, umode_t mode, dev | |||
54 | break; | 54 | break; |
55 | case S_IFLNK: | 55 | case S_IFLNK: |
56 | inode->i_op = &debugfs_link_operations; | 56 | inode->i_op = &debugfs_link_operations; |
57 | inode->i_fop = fops; | ||
58 | inode->i_private = data; | 57 | inode->i_private = data; |
59 | break; | 58 | break; |
60 | case S_IFDIR: | 59 | case S_IFDIR: |
61 | inode->i_op = &simple_dir_inode_operations; | 60 | inode->i_op = &simple_dir_inode_operations; |
62 | inode->i_fop = fops ? fops : &simple_dir_operations; | 61 | inode->i_fop = &simple_dir_operations; |
63 | inode->i_private = data; | 62 | inode->i_private = NULL; |
64 | 63 | ||
65 | /* directory inodes start off with i_nlink == 2 | 64 | /* directory inodes start off with i_nlink == 2 |
66 | * (for "." entry) */ | 65 | * (for "." entry) */ |
@@ -91,13 +90,12 @@ static int debugfs_mknod(struct inode *dir, struct dentry *dentry, | |||
91 | return error; | 90 | return error; |
92 | } | 91 | } |
93 | 92 | ||
94 | static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode, | 93 | static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
95 | void *data, const struct file_operations *fops) | ||
96 | { | 94 | { |
97 | int res; | 95 | int res; |
98 | 96 | ||
99 | mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; | 97 | mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; |
100 | res = debugfs_mknod(dir, dentry, mode, 0, data, fops); | 98 | res = debugfs_mknod(dir, dentry, mode, 0, NULL, NULL); |
101 | if (!res) { | 99 | if (!res) { |
102 | inc_nlink(dir); | 100 | inc_nlink(dir); |
103 | fsnotify_mkdir(dir, dentry); | 101 | fsnotify_mkdir(dir, dentry); |
@@ -106,10 +104,10 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
106 | } | 104 | } |
107 | 105 | ||
108 | static int debugfs_link(struct inode *dir, struct dentry *dentry, umode_t mode, | 106 | static int debugfs_link(struct inode *dir, struct dentry *dentry, umode_t mode, |
109 | void *data, const struct file_operations *fops) | 107 | void *data) |
110 | { | 108 | { |
111 | mode = (mode & S_IALLUGO) | S_IFLNK; | 109 | mode = (mode & S_IALLUGO) | S_IFLNK; |
112 | return debugfs_mknod(dir, dentry, mode, 0, data, fops); | 110 | return debugfs_mknod(dir, dentry, mode, 0, data, NULL); |
113 | } | 111 | } |
114 | 112 | ||
115 | static int debugfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 113 | static int debugfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
@@ -293,13 +291,19 @@ static struct file_system_type debug_fs_type = { | |||
293 | .kill_sb = kill_litter_super, | 291 | .kill_sb = kill_litter_super, |
294 | }; | 292 | }; |
295 | 293 | ||
296 | static int debugfs_create_by_name(const char *name, umode_t mode, | 294 | struct dentry *__create_file(const char *name, umode_t mode, |
297 | struct dentry *parent, | 295 | struct dentry *parent, void *data, |
298 | struct dentry **dentry, | 296 | const struct file_operations *fops) |
299 | void *data, | ||
300 | const struct file_operations *fops) | ||
301 | { | 297 | { |
302 | int error = 0; | 298 | struct dentry *dentry = NULL; |
299 | int error; | ||
300 | |||
301 | pr_debug("debugfs: creating file '%s'\n",name); | ||
302 | |||
303 | error = simple_pin_fs(&debug_fs_type, &debugfs_mount, | ||
304 | &debugfs_mount_count); | ||
305 | if (error) | ||
306 | goto exit; | ||
303 | 307 | ||
304 | /* If the parent is not specified, we create it in the root. | 308 | /* If the parent is not specified, we create it in the root. |
305 | * We need the root dentry to do this, which is in the super | 309 | * We need the root dentry to do this, which is in the super |
@@ -309,30 +313,35 @@ static int debugfs_create_by_name(const char *name, umode_t mode, | |||
309 | if (!parent) | 313 | if (!parent) |
310 | parent = debugfs_mount->mnt_root; | 314 | parent = debugfs_mount->mnt_root; |
311 | 315 | ||
312 | *dentry = NULL; | 316 | dentry = NULL; |
313 | mutex_lock(&parent->d_inode->i_mutex); | 317 | mutex_lock(&parent->d_inode->i_mutex); |
314 | *dentry = lookup_one_len(name, parent, strlen(name)); | 318 | dentry = lookup_one_len(name, parent, strlen(name)); |
315 | if (!IS_ERR(*dentry)) { | 319 | if (!IS_ERR(dentry)) { |
316 | switch (mode & S_IFMT) { | 320 | switch (mode & S_IFMT) { |
317 | case S_IFDIR: | 321 | case S_IFDIR: |
318 | error = debugfs_mkdir(parent->d_inode, *dentry, mode, | 322 | error = debugfs_mkdir(parent->d_inode, dentry, mode); |
319 | data, fops); | 323 | |
320 | break; | 324 | break; |
321 | case S_IFLNK: | 325 | case S_IFLNK: |
322 | error = debugfs_link(parent->d_inode, *dentry, mode, | 326 | error = debugfs_link(parent->d_inode, dentry, mode, |
323 | data, fops); | 327 | data); |
324 | break; | 328 | break; |
325 | default: | 329 | default: |
326 | error = debugfs_create(parent->d_inode, *dentry, mode, | 330 | error = debugfs_create(parent->d_inode, dentry, mode, |
327 | data, fops); | 331 | data, fops); |
328 | break; | 332 | break; |
329 | } | 333 | } |
330 | dput(*dentry); | 334 | dput(dentry); |
331 | } else | 335 | } else |
332 | error = PTR_ERR(*dentry); | 336 | error = PTR_ERR(dentry); |
333 | mutex_unlock(&parent->d_inode->i_mutex); | 337 | mutex_unlock(&parent->d_inode->i_mutex); |
334 | 338 | ||
335 | return error; | 339 | if (error) { |
340 | dentry = NULL; | ||
341 | simple_release_fs(&debugfs_mount, &debugfs_mount_count); | ||
342 | } | ||
343 | exit: | ||
344 | return dentry; | ||
336 | } | 345 | } |
337 | 346 | ||
338 | /** | 347 | /** |
@@ -365,25 +374,15 @@ struct dentry *debugfs_create_file(const char *name, umode_t mode, | |||
365 | struct dentry *parent, void *data, | 374 | struct dentry *parent, void *data, |
366 | const struct file_operations *fops) | 375 | const struct file_operations *fops) |
367 | { | 376 | { |
368 | struct dentry *dentry = NULL; | 377 | switch (mode & S_IFMT) { |
369 | int error; | 378 | case S_IFREG: |
370 | 379 | case 0: | |
371 | pr_debug("debugfs: creating file '%s'\n",name); | 380 | break; |
372 | 381 | default: | |
373 | error = simple_pin_fs(&debug_fs_type, &debugfs_mount, | 382 | BUG(); |
374 | &debugfs_mount_count); | ||
375 | if (error) | ||
376 | goto exit; | ||
377 | |||
378 | error = debugfs_create_by_name(name, mode, parent, &dentry, | ||
379 | data, fops); | ||
380 | if (error) { | ||
381 | dentry = NULL; | ||
382 | simple_release_fs(&debugfs_mount, &debugfs_mount_count); | ||
383 | goto exit; | ||
384 | } | 383 | } |
385 | exit: | 384 | |
386 | return dentry; | 385 | return __create_file(name, mode, parent, data, fops); |
387 | } | 386 | } |
388 | EXPORT_SYMBOL_GPL(debugfs_create_file); | 387 | EXPORT_SYMBOL_GPL(debugfs_create_file); |
389 | 388 | ||
@@ -407,8 +406,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_file); | |||
407 | */ | 406 | */ |
408 | struct dentry *debugfs_create_dir(const char *name, struct dentry *parent) | 407 | struct dentry *debugfs_create_dir(const char *name, struct dentry *parent) |
409 | { | 408 | { |
410 | return debugfs_create_file(name, | 409 | return __create_file(name, S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, |
411 | S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, | ||
412 | parent, NULL, NULL); | 410 | parent, NULL, NULL); |
413 | } | 411 | } |
414 | EXPORT_SYMBOL_GPL(debugfs_create_dir); | 412 | EXPORT_SYMBOL_GPL(debugfs_create_dir); |
@@ -446,8 +444,7 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, | |||
446 | if (!link) | 444 | if (!link) |
447 | return NULL; | 445 | return NULL; |
448 | 446 | ||
449 | result = debugfs_create_file(name, S_IFLNK | S_IRWXUGO, parent, link, | 447 | result = __create_file(name, S_IFLNK | S_IRWXUGO, parent, link, NULL); |
450 | NULL); | ||
451 | if (!result) | 448 | if (!result) |
452 | kfree(link); | 449 | kfree(link); |
453 | return result; | 450 | return result; |