diff options
Diffstat (limited to 'fs/debugfs/inode.c')
-rw-r--r-- | fs/debugfs/inode.c | 68 |
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 | } |
369 | EXPORT_SYMBOL_GPL(debugfs_remove); | 364 | EXPORT_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 | */ | ||
385 | struct 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; | ||
421 | exit: | ||
422 | if (dentry && !IS_ERR(dentry)) | ||
423 | dput(dentry); | ||
424 | unlock_rename(new_dir, old_dir); | ||
425 | return NULL; | ||
426 | } | ||
427 | EXPORT_SYMBOL_GPL(debugfs_rename); | ||
428 | |||
371 | static decl_subsys(debug, NULL, NULL); | 429 | static decl_subsys(debug, NULL, NULL); |
372 | 430 | ||
373 | static int __init debugfs_init(void) | 431 | static int __init debugfs_init(void) |