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.c68
1 files changed, 63 insertions, 5 deletions
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index ec8896b264de..11be8a325e26 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -345,11 +345,6 @@ void debugfs_remove(struct dentry *dentry)
345 switch (dentry->d_inode->i_mode & S_IFMT) { 345 switch (dentry->d_inode->i_mode & S_IFMT) {
346 case S_IFDIR: 346 case S_IFDIR:
347 ret = simple_rmdir(parent->d_inode, dentry); 347 ret = simple_rmdir(parent->d_inode, dentry);
348 if (ret)
349 printk(KERN_ERR
350 "DebugFS rmdir on %s failed : "
351 "directory not empty.\n",
352 dentry->d_name.name);
353 break; 348 break;
354 case S_IFLNK: 349 case S_IFLNK:
355 kfree(dentry->d_inode->i_private); 350 kfree(dentry->d_inode->i_private);
@@ -368,6 +363,69 @@ void debugfs_remove(struct dentry *dentry)
368} 363}
369EXPORT_SYMBOL_GPL(debugfs_remove); 364EXPORT_SYMBOL_GPL(debugfs_remove);
370 365
366/**
367 * debugfs_rename - rename a file/directory in the debugfs filesystem
368 * @old_dir: a pointer to the parent dentry for the renamed object. This
369 * should be a directory dentry.
370 * @old_dentry: dentry of an object to be renamed.
371 * @new_dir: a pointer to the parent dentry where the object should be
372 * moved. This should be a directory dentry.
373 * @new_name: a pointer to a string containing the target name.
374 *
375 * This function renames a file/directory in debugfs. The target must not
376 * exist for rename to succeed.
377 *
378 * This function will return a pointer to old_dentry (which is updated to
379 * reflect renaming) if it succeeds. If an error occurs, %NULL will be
380 * returned.
381 *
382 * If debugfs is not enabled in the kernel, the value -%ENODEV will be
383 * returned.
384 */
385struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
386 struct dentry *new_dir, const char *new_name)
387{
388 int error;
389 struct dentry *dentry = NULL, *trap;
390 const char *old_name;
391
392 trap = lock_rename(new_dir, old_dir);
393 /* Source or destination directories don't exist? */
394 if (!old_dir->d_inode || !new_dir->d_inode)
395 goto exit;
396 /* Source does not exist, cyclic rename, or mountpoint? */
397 if (!old_dentry->d_inode || old_dentry == trap ||
398 d_mountpoint(old_dentry))
399 goto exit;
400 dentry = lookup_one_len(new_name, new_dir, strlen(new_name));
401 /* Lookup failed, cyclic rename or target exists? */
402 if (IS_ERR(dentry) || dentry == trap || dentry->d_inode)
403 goto exit;
404
405 old_name = fsnotify_oldname_init(old_dentry->d_name.name);
406
407 error = simple_rename(old_dir->d_inode, old_dentry, new_dir->d_inode,
408 dentry);
409 if (error) {
410 fsnotify_oldname_free(old_name);
411 goto exit;
412 }
413 d_move(old_dentry, dentry);
414 fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
415 old_dentry->d_name.name, S_ISDIR(old_dentry->d_inode->i_mode),
416 NULL, old_dentry->d_inode);
417 fsnotify_oldname_free(old_name);
418 unlock_rename(new_dir, old_dir);
419 dput(dentry);
420 return old_dentry;
421exit:
422 if (dentry && !IS_ERR(dentry))
423 dput(dentry);
424 unlock_rename(new_dir, old_dir);
425 return NULL;
426}
427EXPORT_SYMBOL_GPL(debugfs_rename);
428
371static decl_subsys(debug, NULL, NULL); 429static decl_subsys(debug, NULL, NULL);
372 430
373static int __init debugfs_init(void) 431static int __init debugfs_init(void)