From 4f36557fbe4ab59feb2783cdb5d049cb8c3f34f3 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 24 Nov 2006 13:45:37 -0500 Subject: DebugFS : inotify create/mkdir support Add inotify create and mkdir events to DebugFS. Signed-off-by: Mathieu Desnoyers Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/inode.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'fs/debugfs') diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 137d76c3f90a..020da4c60593 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -24,6 +24,7 @@ #include #include #include +#include #define DEBUGFS_MAGIC 0x64626720 @@ -87,15 +88,22 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; res = debugfs_mknod(dir, dentry, mode, 0); - if (!res) + if (!res) { inc_nlink(dir); + fsnotify_mkdir(dir, dentry); + } return res; } static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode) { + int res; + mode = (mode & S_IALLUGO) | S_IFREG; - return debugfs_mknod(dir, dentry, mode, 0); + res = debugfs_mknod(dir, dentry, mode, 0); + if (!res) + fsnotify_create(dir, dentry); + return res; } static inline int debugfs_positive(struct dentry *dentry) -- cgit v1.2.2 From bafb232ec42aa6862798236009e8e5233d05ab36 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 24 Nov 2006 13:46:30 -0500 Subject: DebugFS : coding style fixes Minor coding style fixes along the way : 80 cols and a white space. Signed-off-by: Mathieu Desnoyers Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/inode.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'fs/debugfs') diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 020da4c60593..05d1a9c4fb76 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -55,7 +55,8 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; - /* directory inodes start off with i_nlink == 2 (for "." entry) */ + /* directory inodes start off with i_nlink == 2 + * (for "." entry) */ inc_nlink(inode); break; } @@ -143,7 +144,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode, * block. A pointer to that is in the struct vfsmount that we * have around. */ - if (!parent ) { + if (!parent) { if (debugfs_mount && debugfs_mount->mnt_sb) { parent = debugfs_mount->mnt_sb->s_root; } -- cgit v1.2.2 From 63223a0654c2a473ae64835819b87826cb7415ee Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 24 Nov 2006 13:48:19 -0500 Subject: DebugFS : file/directory creation error handling Fix error handling of file and directory creation in DebugFS. The error path should release the file system because no _remove will be called for this erroneous creation. Signed-off-by: Mathieu Desnoyers Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/inode.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'fs/debugfs') diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 05d1a9c4fb76..d6c5fb53c746 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -206,13 +206,15 @@ struct dentry *debugfs_create_file(const char *name, mode_t mode, pr_debug("debugfs: creating file '%s'\n",name); - error = simple_pin_fs(&debug_fs_type, &debugfs_mount, &debugfs_mount_count); + error = simple_pin_fs(&debug_fs_type, &debugfs_mount, + &debugfs_mount_count); if (error) goto exit; error = debugfs_create_by_name(name, mode, parent, &dentry); if (error) { dentry = NULL; + simple_release_fs(&debugfs_mount, &debugfs_mount_count); goto exit; } -- cgit v1.2.2 From 65c333367b1aea57d58168ad3dc1df27b0227401 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 24 Nov 2006 13:50:09 -0500 Subject: 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 Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/inode.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'fs/debugfs') diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index d6c5fb53c746..554f4a9dfaf8 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, error = debugfs_mkdir(parent->d_inode, *dentry, mode); else error = debugfs_create(parent->d_inode, *dentry, mode); + dput(*dentry); } else error = PTR_ERR(*dentry); mutex_unlock(&parent->d_inode->i_mutex); @@ -273,6 +274,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_dir); void debugfs_remove(struct dentry *dentry) { struct dentry *parent; + int ret = 0; if (!dentry) return; @@ -284,11 +286,15 @@ void debugfs_remove(struct dentry *dentry) mutex_lock(&parent->d_inode->i_mutex); if (debugfs_positive(dentry)) { if (dentry->d_inode) { - if (S_ISDIR(dentry->d_inode->i_mode)) - simple_rmdir(parent->d_inode, dentry); - else + if (S_ISDIR(dentry->d_inode->i_mode)) { + ret = simple_rmdir(parent->d_inode, dentry); + if (ret) + printk(KERN_ERR + "DebugFS rmdir on %s failed : " + "directory not empty.\n", + dentry->d_name.name); + } else simple_unlink(parent->d_inode, dentry); - dput(dentry); } } mutex_unlock(&parent->d_inode->i_mutex); -- cgit v1.2.2 From 29a7f3ada7fea5510504c5359c3f70d109aeb055 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 24 Nov 2006 13:51:14 -0500 Subject: DebugFS : file/directory removal fix Fix file and directory removal in debugfs. Add inotify support for file removal. The following scenario : create dir a create dir a/b cd a/b (some process goes in cwd a/b) rmdir a/b rmdir a fails due to the fact that "a" appears to be non empty. It is because the "b" dentry is not deleted from "a" and still in use. The same problem happens if "b" is a file. d_delete is nice enough to know when it needs to unhash and free the dentry if nothing else is using it or, if someone is using it, to remove it from the hash queues and wait for it to be deleted when it has no users. The nice side-effect of this fix is that it calls the file removal notification. Signed-off-by: Mathieu Desnoyers Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/inode.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'fs/debugfs') diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 554f4a9dfaf8..c692487346ea 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -286,6 +286,7 @@ void debugfs_remove(struct dentry *dentry) mutex_lock(&parent->d_inode->i_mutex); if (debugfs_positive(dentry)) { if (dentry->d_inode) { + dget(dentry); if (S_ISDIR(dentry->d_inode->i_mode)) { ret = simple_rmdir(parent->d_inode, dentry); if (ret) @@ -295,6 +296,9 @@ void debugfs_remove(struct dentry *dentry) dentry->d_name.name); } else simple_unlink(parent->d_inode, dentry); + if (!ret) + d_delete(dentry); + dput(dentry); } } mutex_unlock(&parent->d_inode->i_mutex); -- cgit v1.2.2