# HG changeset patch # User Daniel Stodden # Date 1267200152 28800 # Node ID 03ff587d68cd4146470e874c587250d9bc7a2492 # Parent 183cbdaef8d14d863465c18bc06cbc7849c30bbc blkfront: Clean up blkfront_closing. * Call blkfront_closing the xlvbd_release_gendisk it is. * Fix comments regarding device disconnects. Signed-off-by: Daniel Stodden Cc: stable@xxxxxxxxxx diff -r 183cbdaef8d1 -r 03ff587d68cd drivers/block/xen-blkfront.c --- a/drivers/block/xen-blkfront.c Fri Feb 26 08:00:19 2010 -0800 +++ b/drivers/block/xen-blkfront.c Fri Feb 26 08:02:32 2010 -0800 @@ -473,6 +473,37 @@ return err; } +static void xlvbd_release_gendisk(struct blkfront_info *info) +{ + struct xenbus_device *dev = info->xbdev; + unsigned long flags; + + dev_dbg(&dev->dev, "%s: %s removed\n", __func__, dev->nodename); + + if (!info->gd) + return; + + spin_lock_irqsave(&blkif_io_lock, flags); + + /* No more blkif_request(). */ + blk_stop_queue(info->rq); + + /* No more gnttab callback work. */ + gnttab_cancel_free_callback(&info->callback); + spin_unlock_irqrestore(&blkif_io_lock, flags); + + /* Flush gnttab callback work. Must be done with no locks held. */ + flush_scheduled_work(); + + del_gendisk(info->gd); + + blk_cleanup_queue(info->rq); + info->rq = NULL; + + put_disk(info->gd); + info->gd = NULL; +} + static void kick_pending_request_queues(struct blkfront_info *info) { if (!RING_FULL(&info->ring)) { @@ -915,42 +946,10 @@ } /** - * Handle the change of state of the backend to Closing. We must delete our - * device-layer structures now, to ensure that writes are flushed through to - * the backend. Once is this done, we can switch to Closed in - * acknowledgement. + * Handle the change of state of the backend to Closing. Refuse to + * disconnect while the device is still in use. This also ensures that + * writes are flushed through to the backend. */ -static void blkfront_closing(struct xenbus_device *dev) -{ - struct blkfront_info *info = dev_get_drvdata(&dev->dev); - unsigned long flags; - - dev_dbg(&dev->dev, "blkfront_closing: %s removed\n", dev->nodename); - - if (!info->gd) - return; - - spin_lock_irqsave(&blkif_io_lock, flags); - - /* No more blkif_request(). */ - blk_stop_queue(info->rq); - - /* No more gnttab callback work. */ - gnttab_cancel_free_callback(&info->callback); - spin_unlock_irqrestore(&blkif_io_lock, flags); - - /* Flush gnttab callback work. Must be done with no locks held. */ - flush_scheduled_work(); - - del_gendisk(info->gd); - - blk_cleanup_queue(info->rq); - info->rq = NULL; - - put_disk(info->gd); - info->gd = NULL; -} - static void blkfront_close(struct blkfront_info *info) { struct xenbus_device *dev = info->xbdev; @@ -973,7 +972,7 @@ inuse = !!info->users; if (!inuse) - blkfront_closing(dev); + xlvbd_release_gendisk(info); mutex_unlock(&bd->bd_mutex); bdput(bd); @@ -1054,7 +1053,7 @@ enum xenbus_state state = xenbus_read_driver_state(dev->otherend); if (state == XenbusStateClosing && info->is_ready) { - blkfront_closing(dev); + xlvbd_release_gendisk(info); xenbus_frontend_closed(dev); } }