aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2007-05-09 07:19:52 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-07-11 19:09:00 -0400
commitcfc94cdf8e0f14e692a5a40ef3cc10f464b2511b (patch)
tree041391e492d909e41e70ac67da53a1025ecf629d
parent46336009b5009e9fab3bd623a3beb9c7421545ac (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.c63
-rw-r--r--include/linux/debugfs.h9
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}
369EXPORT_SYMBOL_GPL(debugfs_remove); 369EXPORT_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 */
390struct 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;
426exit:
427 if (dentry && !IS_ERR(dentry))
428 dput(dentry);
429 unlock_rename(new_dir, old_dir);
430 return NULL;
431}
432EXPORT_SYMBOL_GPL(debugfs_rename);
433
371static decl_subsys(debug, NULL, NULL); 434static decl_subsys(debug, NULL, NULL);
372 435
373static int __init debugfs_init(void) 436static 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
39void debugfs_remove(struct dentry *dentry); 39void debugfs_remove(struct dentry *dentry);
40 40
41struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
42 struct dentry *new_dir, const char *new_name);
43
41struct dentry *debugfs_create_u8(const char *name, mode_t mode, 44struct dentry *debugfs_create_u8(const char *name, mode_t mode,
42 struct dentry *parent, u8 *value); 45 struct dentry *parent, u8 *value);
43struct dentry *debugfs_create_u16(const char *name, mode_t mode, 46struct dentry *debugfs_create_u16(const char *name, mode_t mode,
@@ -85,6 +88,12 @@ static inline struct dentry *debugfs_create_symlink(const char *name,
85static inline void debugfs_remove(struct dentry *dentry) 88static inline void debugfs_remove(struct dentry *dentry)
86{ } 89{ }
87 90
91static 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
88static inline struct dentry *debugfs_create_u8(const char *name, mode_t mode, 97static 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)