]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.fixes/block-get-rid-of-the-manual-directory-counting-in-blktrace.patch
Move xen patchset to new version's subdir.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.fixes / block-get-rid-of-the-manual-directory-counting-in-blktrace.patch
diff --git a/src/patches/suse-2.6.27.31/patches.fixes/block-get-rid-of-the-manual-directory-counting-in-blktrace.patch b/src/patches/suse-2.6.27.31/patches.fixes/block-get-rid-of-the-manual-directory-counting-in-blktrace.patch
new file mode 100644 (file)
index 0000000..21e8eca
--- /dev/null
@@ -0,0 +1,124 @@
+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);