Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 104779
b: refs/heads/master
c: 9505e63
h: refs/heads/master
i:
  104777: 358e622
  104775: 32f4765
v: v3
  • Loading branch information
Haavard Skinnemoen authored and Greg Kroah-Hartman committed Jul 22, 2008
1 parent 9b857b7 commit 7124798
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 43166141f73f969794bd7c850c89913631df99e4
refs/heads/master: 9505e6375640fc61d92d36c8e9f25a6a218f3f57
114 changes: 96 additions & 18 deletions trunk/fs/debugfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,31 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
}
EXPORT_SYMBOL_GPL(debugfs_create_symlink);

static void __debugfs_remove(struct dentry *dentry, struct dentry *parent)
{
int ret = 0;

if (debugfs_positive(dentry)) {
if (dentry->d_inode) {
dget(dentry);
switch (dentry->d_inode->i_mode & S_IFMT) {
case S_IFDIR:
ret = simple_rmdir(parent->d_inode, dentry);
break;
case S_IFLNK:
kfree(dentry->d_inode->i_private);
/* fall through */
default:
simple_unlink(parent->d_inode, dentry);
break;
}
if (!ret)
d_delete(dentry);
dput(dentry);
}
}
}

/**
* debugfs_remove - removes a file or directory from the debugfs filesystem
* @dentry: a pointer to a the dentry of the file or directory to be
Expand All @@ -325,7 +350,6 @@ EXPORT_SYMBOL_GPL(debugfs_create_symlink);
void debugfs_remove(struct dentry *dentry)
{
struct dentry *parent;
int ret = 0;

if (!dentry)
return;
Expand All @@ -335,29 +359,83 @@ void debugfs_remove(struct dentry *dentry)
return;

mutex_lock(&parent->d_inode->i_mutex);
if (debugfs_positive(dentry)) {
if (dentry->d_inode) {
dget(dentry);
switch (dentry->d_inode->i_mode & S_IFMT) {
case S_IFDIR:
ret = simple_rmdir(parent->d_inode, dentry);
break;
case S_IFLNK:
kfree(dentry->d_inode->i_private);
/* fall through */
default:
simple_unlink(parent->d_inode, dentry);
__debugfs_remove(dentry, parent);
mutex_unlock(&parent->d_inode->i_mutex);
simple_release_fs(&debugfs_mount, &debugfs_mount_count);
}
EXPORT_SYMBOL_GPL(debugfs_remove);

/**
* debugfs_remove_recursive - recursively removes a directory
* @dentry: a pointer to a the dentry of the directory to be removed.
*
* This function recursively removes a directory tree in debugfs that
* was previously created with a call to another debugfs function
* (like debugfs_create_file() or variants thereof.)
*
* This function is required to be called in order for the file to be
* removed, no automatic cleanup of files will happen when a module is
* removed, you are responsible here.
*/
void debugfs_remove_recursive(struct dentry *dentry)
{
struct dentry *child;
struct dentry *parent;

if (!dentry)
return;

parent = dentry->d_parent;
if (!parent || !parent->d_inode)
return;

parent = dentry;
mutex_lock(&parent->d_inode->i_mutex);

while (1) {
/*
* When all dentries under "parent" has been removed,
* walk up the tree until we reach our starting point.
*/
if (list_empty(&parent->d_subdirs)) {
mutex_unlock(&parent->d_inode->i_mutex);
if (parent == dentry)
break;
}
if (!ret)
d_delete(dentry);
dput(dentry);
parent = parent->d_parent;
mutex_lock(&parent->d_inode->i_mutex);
}
child = list_entry(parent->d_subdirs.next, struct dentry,
d_u.d_child);

/*
* If "child" isn't empty, walk down the tree and
* remove all its descendants first.
*/
if (!list_empty(&child->d_subdirs)) {
mutex_unlock(&parent->d_inode->i_mutex);
parent = child;
mutex_lock(&parent->d_inode->i_mutex);
continue;
}
__debugfs_remove(child, parent);
if (parent->d_subdirs.next == &child->d_u.d_child) {
/*
* Avoid infinite loop if we fail to remove
* one dentry.
*/
mutex_unlock(&parent->d_inode->i_mutex);
break;
}
simple_release_fs(&debugfs_mount, &debugfs_mount_count);
}

parent = dentry->d_parent;
mutex_lock(&parent->d_inode->i_mutex);
__debugfs_remove(dentry, parent);
mutex_unlock(&parent->d_inode->i_mutex);
simple_release_fs(&debugfs_mount, &debugfs_mount_count);
}
EXPORT_SYMBOL_GPL(debugfs_remove);
EXPORT_SYMBOL_GPL(debugfs_remove_recursive);

/**
* debugfs_rename - rename a file/directory in the debugfs filesystem
Expand Down
4 changes: 4 additions & 0 deletions trunk/include/linux/debugfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
const char *dest);

void debugfs_remove(struct dentry *dentry);
void debugfs_remove_recursive(struct dentry *dentry);

struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
struct dentry *new_dir, const char *new_name);
Expand Down Expand Up @@ -101,6 +102,9 @@ static inline struct dentry *debugfs_create_symlink(const char *name,
static inline void debugfs_remove(struct dentry *dentry)
{ }

static inline void debugfs_remove_recursive(struct dentry *dentry)
{ }

static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
struct dentry *new_dir, char *new_name)
{
Expand Down

0 comments on commit 7124798

Please sign in to comment.