+++ /dev/null
-From: Jens Axboe <jens.axboe@oracle.com>
-Date: Mon Jan 5 10:17:25 2009 +0100
-Subject: block: get rid of the manual directory counting in blktrace
-References: bnc#475149
-
- It can result in a stuck blktrace system, if --kill is used.
-
- Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-
-Acked-by: Jan Blunck <jblunck@suse.de>
----
- block/blktrace.c | 72 ++++++++++++++++---------------------------------------
- 1 file changed, 21 insertions(+), 51 deletions(-)
-
-Index: b/block/blktrace.c
-===================================================================
---- a/block/blktrace.c
-+++ b/block/blktrace.c
-@@ -181,59 +181,12 @@ EXPORT_SYMBOL_GPL(__blk_add_trace);
-
- static struct dentry *blk_tree_root;
- static DEFINE_MUTEX(blk_tree_mutex);
--static unsigned int root_users;
--
--static inline void blk_remove_root(void)
--{
-- if (blk_tree_root) {
-- debugfs_remove(blk_tree_root);
-- blk_tree_root = NULL;
-- }
--}
--
--static void blk_remove_tree(struct dentry *dir)
--{
-- mutex_lock(&blk_tree_mutex);
-- debugfs_remove(dir);
-- if (--root_users == 0)
-- blk_remove_root();
-- mutex_unlock(&blk_tree_mutex);
--}
--
--static struct dentry *blk_create_tree(const char *blk_name)
--{
-- struct dentry *dir = NULL;
-- int created = 0;
--
-- mutex_lock(&blk_tree_mutex);
--
-- if (!blk_tree_root) {
-- blk_tree_root = debugfs_create_dir("block", NULL);
-- if (!blk_tree_root)
-- goto err;
-- created = 1;
-- }
--
-- dir = debugfs_create_dir(blk_name, blk_tree_root);
-- if (dir)
-- root_users++;
-- else {
-- /* Delete root only if we created it */
-- if (created)
-- blk_remove_root();
-- }
--
--err:
-- mutex_unlock(&blk_tree_mutex);
-- return dir;
--}
-
- static void blk_trace_cleanup(struct blk_trace *bt)
- {
-- relay_close(bt->rchan);
- debugfs_remove(bt->msg_file);
- debugfs_remove(bt->dropped_file);
-- blk_remove_tree(bt->dir);
-+ relay_close(bt->rchan);
- free_percpu(bt->sequence);
- free_percpu(bt->msg_data);
- kfree(bt);
-@@ -336,7 +289,18 @@ static int blk_subbuf_start_callback(str
-
- static int blk_remove_buf_file_callback(struct dentry *dentry)
- {
-+ struct dentry *parent = dentry->d_parent;
- debugfs_remove(dentry);
-+
-+ /*
-+ * this will fail for all but the last file, but that is ok. what we
-+ * care about is the top level buts->name directory going away, when
-+ * the last trace file is gone. Then we don't have to rmdir() that
-+ * manually on trace stop, so it nicely solves the issue with
-+ * force killing of running traces.
-+ */
-+
-+ debugfs_remove(parent);
- return 0;
- }
-
-@@ -393,7 +357,15 @@ int do_blk_trace_setup(struct request_qu
- goto err;
-
- ret = -ENOENT;
-- dir = blk_create_tree(buts->name);
-+
-+ if (!blk_tree_root) {
-+ blk_tree_root = debugfs_create_dir("block", NULL);
-+ if (!blk_tree_root)
-+ return -ENOMEM;
-+ }
-+
-+ dir = debugfs_create_dir(buts->name, blk_tree_root);
-+
- if (!dir)
- goto err;
-
-@@ -436,8 +408,6 @@ int do_blk_trace_setup(struct request_qu
-
- return 0;
- err:
-- if (dir)
-- blk_remove_tree(dir);
- if (bt) {
- if (bt->msg_file)
- debugfs_remove(bt->msg_file);