diff options
author | Jens Axboe <axboe@kernel.dk> | 2017-08-29 10:32:58 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2017-08-29 10:32:58 -0400 |
commit | 015a2f823e49927e0da4361a7dfadf0aae33146b (patch) | |
tree | 6c76c0615463bcb79126b99625cb257f09cbd4d2 | |
parent | 22d538213ec4fa65b08b1edbf610066d8aab7bbb (diff) | |
parent | dc52d783d68c07a68743d42ef2f9a6f9a6d80fb1 (diff) |
Merge branch 'stable/for-jens-4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen into for-linus
Pull xen-blkback fix from Konrad:
"[...] A bug-fix when shutting down xen block backend driver with
multiple queues and the driver not clearing all of them."
-rw-r--r-- | drivers/block/xen-blkback/xenbus.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 792da683e70d..2adb8599be93 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c | |||
@@ -244,6 +244,7 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif) | |||
244 | { | 244 | { |
245 | struct pending_req *req, *n; | 245 | struct pending_req *req, *n; |
246 | unsigned int j, r; | 246 | unsigned int j, r; |
247 | bool busy = false; | ||
247 | 248 | ||
248 | for (r = 0; r < blkif->nr_rings; r++) { | 249 | for (r = 0; r < blkif->nr_rings; r++) { |
249 | struct xen_blkif_ring *ring = &blkif->rings[r]; | 250 | struct xen_blkif_ring *ring = &blkif->rings[r]; |
@@ -261,8 +262,10 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif) | |||
261 | * don't have any discard_io or other_io requests. So, checking | 262 | * don't have any discard_io or other_io requests. So, checking |
262 | * for inflight IO is enough. | 263 | * for inflight IO is enough. |
263 | */ | 264 | */ |
264 | if (atomic_read(&ring->inflight) > 0) | 265 | if (atomic_read(&ring->inflight) > 0) { |
265 | return -EBUSY; | 266 | busy = true; |
267 | continue; | ||
268 | } | ||
266 | 269 | ||
267 | if (ring->irq) { | 270 | if (ring->irq) { |
268 | unbind_from_irqhandler(ring->irq, ring); | 271 | unbind_from_irqhandler(ring->irq, ring); |
@@ -300,6 +303,9 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif) | |||
300 | WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages)); | 303 | WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages)); |
301 | ring->active = false; | 304 | ring->active = false; |
302 | } | 305 | } |
306 | if (busy) | ||
307 | return -EBUSY; | ||
308 | |||
303 | blkif->nr_ring_pages = 0; | 309 | blkif->nr_ring_pages = 0; |
304 | /* | 310 | /* |
305 | * blkif->rings was allocated in connect_ring, so we should free it in | 311 | * blkif->rings was allocated in connect_ring, so we should free it in |