aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/xen-blkfront.c
diff options
context:
space:
mode:
authorDaniel Stodden <daniel.stodden@citrix.com>2010-08-07 12:33:17 -0400
committerJens Axboe <jaxboe@fusionio.com>2010-08-07 12:38:43 -0400
commita66b5aebb7dc9e695dcb4b528906fd398b63f3d9 (patch)
tree684df2ec45c83f1dc267803f4fdf4ac684bf30d0 /drivers/block/xen-blkfront.c
parent9897cb532382f075b337f7933b5a50f0ffc32d35 (diff)
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 <daniel.stodden@citrix.com> Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'drivers/block/xen-blkfront.c')
-rw-r--r--drivers/block/xen-blkfront.c91
1 files changed, 43 insertions, 48 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 62d32959095d..d4cb7fd82b4c 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,
534 return err; 534 return err;
535} 535}
536 536
537static void xlvbd_release_gendisk(struct blkfront_info *info)
538{
539 unsigned int minor, nr_minors;
540 unsigned long flags;
541
542 if (info->rq == NULL)
543 return;
544
545 spin_lock_irqsave(&blkif_io_lock, flags);
546
547 /* No more blkif_request(). */
548 blk_stop_queue(info->rq);
549
550 /* No more gnttab callback work. */
551 gnttab_cancel_free_callback(&info->callback);
552 spin_unlock_irqrestore(&blkif_io_lock, flags);
553
554 /* Flush gnttab callback work. Must be done with no locks held. */
555 flush_scheduled_work();
556
557 del_gendisk(info->gd);
558
559 minor = info->gd->first_minor;
560 nr_minors = info->gd->minors;
561 xlbd_release_minors(minor, nr_minors);
562
563 blk_cleanup_queue(info->rq);
564 info->rq = NULL;
565
566 put_disk(info->gd);
567 info->gd = NULL;
568}
569
537static void kick_pending_request_queues(struct blkfront_info *info) 570static void kick_pending_request_queues(struct blkfront_info *info)
538{ 571{
539 if (!RING_FULL(&info->ring)) { 572 if (!RING_FULL(&info->ring)) {
@@ -995,49 +1028,6 @@ static void blkfront_connect(struct blkfront_info *info)
995} 1028}
996 1029
997/** 1030/**
998 * Handle the change of state of the backend to Closing. We must delete our
999 * device-layer structures now, to ensure that writes are flushed through to
1000 * the backend. Once is this done, we can switch to Closed in
1001 * acknowledgement.
1002 */
1003static void blkfront_closing(struct blkfront_info *info)
1004{
1005 unsigned int minor, nr_minors;
1006 unsigned long flags;
1007
1008
1009 if (info->rq == NULL)
1010 goto out;
1011
1012 spin_lock_irqsave(&blkif_io_lock, flags);
1013
1014 /* No more blkif_request(). */
1015 blk_stop_queue(info->rq);
1016
1017 /* No more gnttab callback work. */
1018 gnttab_cancel_free_callback(&info->callback);
1019 spin_unlock_irqrestore(&blkif_io_lock, flags);
1020
1021 /* Flush gnttab callback work. Must be done with no locks held. */
1022 flush_scheduled_work();
1023
1024 minor = info->gd->first_minor;
1025 nr_minors = info->gd->minors;
1026 del_gendisk(info->gd);
1027 xlbd_release_minors(minor, nr_minors);
1028
1029 blk_cleanup_queue(info->rq);
1030 info->rq = NULL;
1031
1032 put_disk(info->gd);
1033 info->gd = NULL;
1034
1035 out:
1036 if (info->xbdev)
1037 xenbus_frontend_closed(info->xbdev);
1038}
1039
1040/**
1041 * Callback received when the backend's state changes. 1031 * Callback received when the backend's state changes.
1042 */ 1032 */
1043static void blkback_changed(struct xenbus_device *dev, 1033static void blkback_changed(struct xenbus_device *dev,
@@ -1073,8 +1063,11 @@ static void blkback_changed(struct xenbus_device *dev,
1073 if (info->users > 0) 1063 if (info->users > 0)
1074 xenbus_dev_error(dev, -EBUSY, 1064 xenbus_dev_error(dev, -EBUSY,
1075 "Device in use; refusing to close"); 1065 "Device in use; refusing to close");
1076 else 1066 else {
1077 blkfront_closing(info); 1067 xlvbd_release_gendisk(info);
1068 xenbus_frontend_closed(info->xbdev);
1069 }
1070
1078 mutex_unlock(&bd->bd_mutex); 1071 mutex_unlock(&bd->bd_mutex);
1079 bdput(bd); 1072 bdput(bd);
1080 break; 1073 break;
@@ -1130,11 +1123,13 @@ static int blkif_release(struct gendisk *disk, fmode_t mode)
1130 struct xenbus_device *dev = info->xbdev; 1123 struct xenbus_device *dev = info->xbdev;
1131 1124
1132 if (!dev) { 1125 if (!dev) {
1133 blkfront_closing(info); 1126 xlvbd_release_gendisk(info);
1134 kfree(info); 1127 kfree(info);
1135 } else if (xenbus_read_driver_state(dev->otherend) 1128 } else if (xenbus_read_driver_state(dev->otherend)
1136 == XenbusStateClosing && info->is_ready) 1129 == XenbusStateClosing && info->is_ready) {
1137 blkfront_closing(info); 1130 xlvbd_release_gendisk(info);
1131 xenbus_frontend_closed(dev);
1132 }
1138 } 1133 }
1139 unlock_kernel(); 1134 unlock_kernel();
1140 return 0; 1135 return 0;