Jan Beulich
2010-Mar-01 09:25 UTC
[Xen-devel] [PATCH] linux/blktap2: Fwd: Re: Crash on blktap shutdown
Subject: blktap2: Fix queue restart, racing block device removal. Makes tapdisk context test dev->gd before attempting a queue restart, with the device lock held. Fixes a race lost against device destruction, which may issued anywhere on the control path. Signed-off-by: Daniel Stodden <daniel.stodden@citrix.com> Signed-off-by: Jan Beulich <jbeulich@novell.com> --- a/drivers/xen/blktap2/device.c +++ b/drivers/xen/blktap2/device.c @@ -946,8 +946,6 @@ struct blktap_device *dev; dev = &tap->device; - if (!dev->gd || !dev->gd->queue) - return; if (blktap_active(tap) && RING_FULL(&tap->ring.ring)) { blktap_defer(tap); @@ -963,11 +961,15 @@ spin_lock_irq(&dev->lock); /* Re-enable calldowns. */ - if (blk_queue_stopped(dev->gd->queue)) - blk_start_queue(dev->gd->queue); + if (dev->gd) { + struct request_queue *rq = dev->gd->queue; - /* Kick things off immediately. */ - blktap_device_do_request(dev->gd->queue); + if (blk_queue_stopped(rq)) + blk_start_queue(rq); + + /* Kick things off immediately. */ + blktap_device_do_request(rq); + } spin_unlock_irq(&dev->lock); } @@ -1056,6 +1058,7 @@ blktap_device_destroy(struct blktap *tap) { struct blktap_device *dev = &tap->device; + struct gendisk *gd = dev->gd; if (!test_bit(BLKTAP_DEVICE, &tap->dev_inuse)) return 0; @@ -1067,8 +1070,9 @@ spin_lock_irq(&dev->lock); /* No more blktap_device_do_request(). */ - blk_stop_queue(dev->gd->queue); + blk_stop_queue(gd->queue); clear_bit(BLKTAP_DEVICE, &tap->dev_inuse); + dev->gd = NULL; spin_unlock_irq(&dev->lock); #ifdef ENABLE_PASSTHROUGH @@ -1076,11 +1080,9 @@ blktap_device_close_bdev(tap); #endif - del_gendisk(dev->gd); - blk_cleanup_queue(dev->gd->queue); - put_disk(dev->gd); - - dev->gd = NULL; + del_gendisk(gd); + blk_cleanup_queue(gd->queue); + put_disk(gd); wake_up(&tap->wq); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel