diff options
| author | Mathieu Desnoyers <compudj@krystal.dyndns.org> | 2006-11-24 13:50:09 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-12-13 18:38:45 -0500 |
| commit | 65c333367b1aea57d58168ad3dc1df27b0227401 (patch) | |
| tree | a90a34d43c815d99de4d40eac372fb98d4dbffd7 /fs/debugfs | |
| parent | 63223a0654c2a473ae64835819b87826cb7415ee (diff) | |
DebugFS : more file/directory creation error handling
Correct dentry count to handle creation errors.
This patch puts a dput at the file creation instead of the file removal :
lookup_one_len already returns a dentry with reference count of 1. Then,
the dget() in simple_mknod increments it when the dentry is associated
with a file. In a scenario where simple_create or simple_mkdir returns
an error, this would lead to an unwanted increment of the reference
counter, therefore making file removal impossible.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/debugfs')
| -rw-r--r-- | fs/debugfs/inode.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index d6c5fb53c74..554f4a9dfaf 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
| @@ -162,6 +162,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode, | |||
| 162 | error = debugfs_mkdir(parent->d_inode, *dentry, mode); | 162 | error = debugfs_mkdir(parent->d_inode, *dentry, mode); |
| 163 | else | 163 | else |
| 164 | error = debugfs_create(parent->d_inode, *dentry, mode); | 164 | error = debugfs_create(parent->d_inode, *dentry, mode); |
| 165 | dput(*dentry); | ||
| 165 | } else | 166 | } else |
| 166 | error = PTR_ERR(*dentry); | 167 | error = PTR_ERR(*dentry); |
| 167 | mutex_unlock(&parent->d_inode->i_mutex); | 168 | mutex_unlock(&parent->d_inode->i_mutex); |
| @@ -273,6 +274,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_dir); | |||
| 273 | void debugfs_remove(struct dentry *dentry) | 274 | void debugfs_remove(struct dentry *dentry) |
| 274 | { | 275 | { |
| 275 | struct dentry *parent; | 276 | struct dentry *parent; |
| 277 | int ret = 0; | ||
| 276 | 278 | ||
| 277 | if (!dentry) | 279 | if (!dentry) |
| 278 | return; | 280 | return; |
| @@ -284,11 +286,15 @@ void debugfs_remove(struct dentry *dentry) | |||
| 284 | mutex_lock(&parent->d_inode->i_mutex); | 286 | mutex_lock(&parent->d_inode->i_mutex); |
| 285 | if (debugfs_positive(dentry)) { | 287 | if (debugfs_positive(dentry)) { |
| 286 | if (dentry->d_inode) { | 288 | if (dentry->d_inode) { |
| 287 | if (S_ISDIR(dentry->d_inode->i_mode)) | 289 | if (S_ISDIR(dentry->d_inode->i_mode)) { |
| 288 | simple_rmdir(parent->d_inode, dentry); | 290 | ret = simple_rmdir(parent->d_inode, dentry); |
| 289 | else | 291 | if (ret) |
| 292 | printk(KERN_ERR | ||
| 293 | "DebugFS rmdir on %s failed : " | ||
| 294 | "directory not empty.\n", | ||
| 295 | dentry->d_name.name); | ||
| 296 | } else | ||
| 290 | simple_unlink(parent->d_inode, dentry); | 297 | simple_unlink(parent->d_inode, dentry); |
| 291 | dput(dentry); | ||
| 292 | } | 298 | } |
| 293 | } | 299 | } |
| 294 | mutex_unlock(&parent->d_inode->i_mutex); | 300 | mutex_unlock(&parent->d_inode->i_mutex); |
