From a66b5aebb7dc9e695dcb4b528906fd398b63f3d9 Mon Sep 17 00:00:00 2001 From: Daniel Stodden Date: Sat, 7 Aug 2010 18:33:17 +0200 Subject: blkfront: Clean up vbd release * Current blkfront_closing is rather a xlvbd_release_gendisk. Renamed in preparation of later patches (need the name again). * Removed the misleading comment -- this only applied to the backend switch handler, and the queue is already flushed btw. * Break out the xenbus call, callers know better when to switch frontend state. Signed-off-by: Daniel Stodden Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Jens Axboe --- drivers/block/xen-blkfront.c | 91 +++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 48 deletions(-) (limited to 'drivers/block/xen-blkfront.c') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 62d3295..d4cb7fd 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -534,6 +534,39 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, return err; } +static void xlvbd_release_gendisk(struct blkfront_info *info) +{ + unsigned int minor, nr_minors; + unsigned long flags; + + if (info->rq == NULL) + 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); + + minor = info->gd->first_minor; + nr_minors = info->gd->minors; + xlbd_release_minors(minor, nr_minors); + + 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)) { @@ -995,49 +1028,6 @@ static void blkfront_connect(struct blkfront_info *info) } /** - * 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. - */ -static void blkfront_closing(struct blkfront_info *info) -{ - unsigned int minor, nr_minors; - unsigned long flags; - - - if (info->rq == NULL) - goto out; - - 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(); - - minor = info->gd->first_minor; - nr_minors = info->gd->minors; - del_gendisk(info->gd); - xlbd_release_minors(minor, nr_minors); - - blk_cleanup_queue(info->rq); - info->rq = NULL; - - put_disk(info->gd); - info->gd = NULL; - - out: - if (info->xbdev) - xenbus_frontend_closed(info->xbdev); -} - -/** * Callback received when the backend's state changes. */ static void blkback_changed(struct xenbus_device *dev, @@ -1073,8 +1063,11 @@ static void blkback_changed(struct xenbus_device *dev, if (info->users > 0) xenbus_dev_error(dev, -EBUSY, "Device in use; refusing to close"); - else - blkfront_closing(info); + else { + xlvbd_release_gendisk(info); + xenbus_frontend_closed(info->xbdev); + } + mutex_unlock(&bd->bd_mutex); bdput(bd); break; @@ -1130,11 +1123,13 @@ static int blkif_release(struct gendisk *disk, fmode_t mode) struct xenbus_device *dev = info->xbdev; if (!dev) { - blkfront_closing(info); + xlvbd_release_gendisk(info); kfree(info); } else if (xenbus_read_driver_state(dev->otherend) - == XenbusStateClosing && info->is_ready) - blkfront_closing(info); + == XenbusStateClosing && info->is_ready) { + xlvbd_release_gendisk(info); + xenbus_frontend_closed(dev); + } } unlock_kernel(); return 0; -- cgit v1.1