diff options
author | Jan Kara <jack@suse.cz> | 2007-05-09 07:19:52 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-07-11 19:09:00 -0400 |
commit | cfc94cdf8e0f14e692a5a40ef3cc10f464b2511b (patch) | |
tree | 041391e492d909e41e70ac67da53a1025ecf629d | |
parent | 46336009b5009e9fab3bd623a3beb9c7421545ac (diff) |
debugfs: add rename for debugfs files
Implement debugfs_rename() to allow renaming files/directories in debugfs.
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | fs/debugfs/inode.c | 63 | ||||
-rw-r--r-- | include/linux/debugfs.h | 9 |
2 files changed, 72 insertions, 0 deletions
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index ec8896b264d..1d533a2ec3a 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
@@ -368,6 +368,69 @@ void debugfs_remove(struct dentry *dentry) | |||
368 | } | 368 | } |
369 | EXPORT_SYMBOL_GPL(debugfs_remove); | 369 | EXPORT_SYMBOL_GPL(debugfs_remove); |
370 | 370 | ||
371 | /** | ||
372 | * debugfs_rename - rename a file/directory in the debugfs filesystem | ||
373 | * @old_dir: a pointer to the parent dentry for the renamed object. This | ||
374 | * should be a directory dentry. | ||
375 | * @old_dentry: dentry of an object to be renamed. | ||
376 | * @new_dir: a pointer to the parent dentry where the object should be | ||
377 | * moved. This should be a directory dentry. | ||
378 | * @new_name: a pointer to a string containing the target name. | ||
379 | * | ||
380 | * This function renames a file/directory in debugfs. The target must not | ||
381 | * exist for rename to succeed. | ||
382 | * | ||
383 | * This function will return a pointer to old_dentry (which is updated to | ||
384 | * reflect renaming) if it succeeds. If an error occurs, %NULL will be | ||
385 | * returned. | ||
386 | * | ||
387 | * If debugfs is not enabled in the kernel, the value -%ENODEV will be | ||
388 | * returned. | ||
389 | */ | ||
390 | struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, | ||
391 | struct dentry *new_dir, const char *new_name) | ||
392 | { | ||
393 | int error; | ||
394 | struct dentry *dentry = NULL, *trap; | ||
395 | const char *old_name; | ||
396 | |||
397 | trap = lock_rename(new_dir, old_dir); | ||
398 | /* Source or destination directories don't exist? */ | ||
399 | if (!old_dir->d_inode || !new_dir->d_inode) | ||
400 | goto exit; | ||
401 | /* Source does not exist, cyclic rename, or mountpoint? */ | ||
402 | if (!old_dentry->d_inode || old_dentry == trap || | ||
403 | d_mountpoint(old_dentry)) | ||
404 | goto exit; | ||
405 | dentry = lookup_one_len(new_name, new_dir, strlen(new_name)); | ||
406 | /* Lookup failed, cyclic rename or target exists? */ | ||
407 | if (IS_ERR(dentry) || dentry == trap || dentry->d_inode) | ||
408 | goto exit; | ||
409 | |||
410 | old_name = fsnotify_oldname_init(old_dentry->d_name.name); | ||
411 | |||
412 | error = simple_rename(old_dir->d_inode, old_dentry, new_dir->d_inode, | ||
413 | dentry); | ||
414 | if (error) { | ||
415 | fsnotify_oldname_free(old_name); | ||
416 | goto exit; | ||
417 | } | ||
418 | d_move(old_dentry, dentry); | ||
419 | fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name, | ||
420 | old_dentry->d_name.name, S_ISDIR(old_dentry->d_inode->i_mode), | ||
421 | NULL, old_dentry->d_inode); | ||
422 | fsnotify_oldname_free(old_name); | ||
423 | unlock_rename(new_dir, old_dir); | ||
424 | dput(dentry); | ||
425 | return old_dentry; | ||
426 | exit: | ||
427 | if (dentry && !IS_ERR(dentry)) | ||
428 | dput(dentry); | ||
429 | unlock_rename(new_dir, old_dir); | ||
430 | return NULL; | ||
431 | } | ||
432 | EXPORT_SYMBOL_GPL(debugfs_rename); | ||
433 | |||
371 | static decl_subsys(debug, NULL, NULL); | 434 | static decl_subsys(debug, NULL, NULL); |
372 | 435 | ||
373 | static int __init debugfs_init(void) | 436 | static int __init debugfs_init(void) |
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 5a9c49534d0..104e51e20e1 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h | |||
@@ -38,6 +38,9 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, | |||
38 | 38 | ||
39 | void debugfs_remove(struct dentry *dentry); | 39 | void debugfs_remove(struct dentry *dentry); |
40 | 40 | ||
41 | struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, | ||
42 | struct dentry *new_dir, const char *new_name); | ||
43 | |||
41 | struct dentry *debugfs_create_u8(const char *name, mode_t mode, | 44 | struct dentry *debugfs_create_u8(const char *name, mode_t mode, |
42 | struct dentry *parent, u8 *value); | 45 | struct dentry *parent, u8 *value); |
43 | struct dentry *debugfs_create_u16(const char *name, mode_t mode, | 46 | struct dentry *debugfs_create_u16(const char *name, mode_t mode, |
@@ -85,6 +88,12 @@ static inline struct dentry *debugfs_create_symlink(const char *name, | |||
85 | static inline void debugfs_remove(struct dentry *dentry) | 88 | static inline void debugfs_remove(struct dentry *dentry) |
86 | { } | 89 | { } |
87 | 90 | ||
91 | static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, | ||
92 | struct dentry *new_dir, char *new_name) | ||
93 | { | ||
94 | return ERR_PTR(-ENODEV); | ||
95 | } | ||
96 | |||
88 | static inline struct dentry *debugfs_create_u8(const char *name, mode_t mode, | 97 | static inline struct dentry *debugfs_create_u8(const char *name, mode_t mode, |
89 | struct dentry *parent, | 98 | struct dentry *parent, |
90 | u8 *value) | 99 | u8 *value) |