]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 29 Jul 2014 00:30:46 +0000 (17:30 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 29 Jul 2014 00:30:46 +0000 (17:30 -0700)
added patches:
block-don-t-assume-last-put-of-shared-tags-is-for-the-host.patch

queue-3.4/block-don-t-assume-last-put-of-shared-tags-is-for-the-host.patch [new file with mode: 0644]

diff --git a/queue-3.4/block-don-t-assume-last-put-of-shared-tags-is-for-the-host.patch b/queue-3.4/block-don-t-assume-last-put-of-shared-tags-is-for-the-host.patch
new file mode 100644 (file)
index 0000000..433a223
--- /dev/null
@@ -0,0 +1,90 @@
+From d45b3279a5a2252cafcd665bbf2db8c9b31ef783 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Tue, 8 Jul 2014 12:25:28 +0200
+Subject: block: don't assume last put of shared tags is for the host
+
+From: Christoph Hellwig <hch@lst.de>
+
+commit d45b3279a5a2252cafcd665bbf2db8c9b31ef783 upstream.
+
+There is no inherent reason why the last put of a tag structure must be
+the one for the Scsi_Host, as device model objects can be held for
+arbitrary periods.  Merge blk_free_tags and __blk_free_tags into a single
+funtion that just release a references and get rid of the BUG() when the
+host reference wasn't the last.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ block/blk-tag.c |   33 +++++++--------------------------
+ 1 file changed, 7 insertions(+), 26 deletions(-)
+
+--- a/block/blk-tag.c
++++ b/block/blk-tag.c
+@@ -27,18 +27,15 @@ struct request *blk_queue_find_tag(struc
+ EXPORT_SYMBOL(blk_queue_find_tag);
+ /**
+- * __blk_free_tags - release a given set of tag maintenance info
++ * blk_free_tags - release a given set of tag maintenance info
+  * @bqt:      the tag map to free
+  *
+- * Tries to free the specified @bqt.  Returns true if it was
+- * actually freed and false if there are still references using it
++ * Drop the reference count on @bqt and frees it when the last reference
++ * is dropped.
+  */
+-static int __blk_free_tags(struct blk_queue_tag *bqt)
++void blk_free_tags(struct blk_queue_tag *bqt)
+ {
+-      int retval;
+-
+-      retval = atomic_dec_and_test(&bqt->refcnt);
+-      if (retval) {
++      if (atomic_dec_and_test(&bqt->refcnt)) {
+               BUG_ON(find_first_bit(bqt->tag_map, bqt->max_depth) <
+                                                       bqt->max_depth);
+@@ -50,9 +47,8 @@ static int __blk_free_tags(struct blk_qu
+               kfree(bqt);
+       }
+-
+-      return retval;
+ }
++EXPORT_SYMBOL(blk_free_tags);
+ /**
+  * __blk_queue_free_tags - release tag maintenance info
+@@ -69,28 +65,13 @@ void __blk_queue_free_tags(struct reques
+       if (!bqt)
+               return;
+-      __blk_free_tags(bqt);
++      blk_free_tags(bqt);
+       q->queue_tags = NULL;
+       queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q);
+ }
+ /**
+- * blk_free_tags - release a given set of tag maintenance info
+- * @bqt:      the tag map to free
+- *
+- * For externally managed @bqt frees the map.  Callers of this
+- * function must guarantee to have released all the queues that
+- * might have been using this tag map.
+- */
+-void blk_free_tags(struct blk_queue_tag *bqt)
+-{
+-      if (unlikely(!__blk_free_tags(bqt)))
+-              BUG();
+-}
+-EXPORT_SYMBOL(blk_free_tags);
+-
+-/**
+  * blk_queue_free_tags - release tag maintenance info
+  * @q:  the request queue for the device
+  *