diff options
author | Daniel Stodden <daniel.stodden@citrix.com> | 2010-08-07 12:33:17 -0400 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-08-07 12:38:43 -0400 |
commit | a66b5aebb7dc9e695dcb4b528906fd398b63f3d9 (patch) | |
tree | 684df2ec45c83f1dc267803f4fdf4ac684bf30d0 /drivers/block | |
parent | 9897cb532382f075b337f7933b5a50f0ffc32d35 (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')
-rw-r--r-- | drivers/block/xen-blkfront.c | 91 |
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 | ||
537 | static 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 | |||
537 | static void kick_pending_request_queues(struct blkfront_info *info) | 570 | static 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 | */ | ||
1003 | static 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 | */ |
1043 | static void blkback_changed(struct xenbus_device *dev, | 1033 | static 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; |