aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/xen-blkfront.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/xen-blkfront.c')
-rw-r--r--drivers/block/xen-blkfront.c41
1 files changed, 20 insertions, 21 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 98cbeba8cd53..4e86393a09cf 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -43,6 +43,7 @@
43#include <linux/slab.h> 43#include <linux/slab.h>
44#include <linux/mutex.h> 44#include <linux/mutex.h>
45#include <linux/scatterlist.h> 45#include <linux/scatterlist.h>
46#include <linux/bitmap.h>
46 47
47#include <xen/xen.h> 48#include <xen/xen.h>
48#include <xen/xenbus.h> 49#include <xen/xenbus.h>
@@ -81,6 +82,7 @@ static const struct block_device_operations xlvbd_block_fops;
81 */ 82 */
82struct blkfront_info 83struct blkfront_info
83{ 84{
85 spinlock_t io_lock;
84 struct mutex mutex; 86 struct mutex mutex;
85 struct xenbus_device *xbdev; 87 struct xenbus_device *xbdev;
86 struct gendisk *gd; 88 struct gendisk *gd;
@@ -105,8 +107,6 @@ struct blkfront_info
105 int is_ready; 107 int is_ready;
106}; 108};
107 109
108static DEFINE_SPINLOCK(blkif_io_lock);
109
110static unsigned int nr_minors; 110static unsigned int nr_minors;
111static unsigned long *minors; 111static unsigned long *minors;
112static DEFINE_SPINLOCK(minor_lock); 112static DEFINE_SPINLOCK(minor_lock);
@@ -177,8 +177,7 @@ static int xlbd_reserve_minors(unsigned int minor, unsigned int nr)
177 177
178 spin_lock(&minor_lock); 178 spin_lock(&minor_lock);
179 if (find_next_bit(minors, end, minor) >= end) { 179 if (find_next_bit(minors, end, minor) >= end) {
180 for (; minor < end; ++minor) 180 bitmap_set(minors, minor, nr);
181 __set_bit(minor, minors);
182 rc = 0; 181 rc = 0;
183 } else 182 } else
184 rc = -EBUSY; 183 rc = -EBUSY;
@@ -193,8 +192,7 @@ static void xlbd_release_minors(unsigned int minor, unsigned int nr)
193 192
194 BUG_ON(end > nr_minors); 193 BUG_ON(end > nr_minors);
195 spin_lock(&minor_lock); 194 spin_lock(&minor_lock);
196 for (; minor < end; ++minor) 195 bitmap_clear(minors, minor, nr);
197 __clear_bit(minor, minors);
198 spin_unlock(&minor_lock); 196 spin_unlock(&minor_lock);
199} 197}
200 198
@@ -419,7 +417,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
419 struct request_queue *rq; 417 struct request_queue *rq;
420 struct blkfront_info *info = gd->private_data; 418 struct blkfront_info *info = gd->private_data;
421 419
422 rq = blk_init_queue(do_blkif_request, &blkif_io_lock); 420 rq = blk_init_queue(do_blkif_request, &info->io_lock);
423 if (rq == NULL) 421 if (rq == NULL)
424 return -1; 422 return -1;
425 423
@@ -636,14 +634,14 @@ static void xlvbd_release_gendisk(struct blkfront_info *info)
636 if (info->rq == NULL) 634 if (info->rq == NULL)
637 return; 635 return;
638 636
639 spin_lock_irqsave(&blkif_io_lock, flags); 637 spin_lock_irqsave(&info->io_lock, flags);
640 638
641 /* No more blkif_request(). */ 639 /* No more blkif_request(). */
642 blk_stop_queue(info->rq); 640 blk_stop_queue(info->rq);
643 641
644 /* No more gnttab callback work. */ 642 /* No more gnttab callback work. */
645 gnttab_cancel_free_callback(&info->callback); 643 gnttab_cancel_free_callback(&info->callback);
646 spin_unlock_irqrestore(&blkif_io_lock, flags); 644 spin_unlock_irqrestore(&info->io_lock, flags);
647 645
648 /* Flush gnttab callback work. Must be done with no locks held. */ 646 /* Flush gnttab callback work. Must be done with no locks held. */
649 flush_work_sync(&info->work); 647 flush_work_sync(&info->work);
@@ -675,16 +673,16 @@ static void blkif_restart_queue(struct work_struct *work)
675{ 673{
676 struct blkfront_info *info = container_of(work, struct blkfront_info, work); 674 struct blkfront_info *info = container_of(work, struct blkfront_info, work);
677 675
678 spin_lock_irq(&blkif_io_lock); 676 spin_lock_irq(&info->io_lock);
679 if (info->connected == BLKIF_STATE_CONNECTED) 677 if (info->connected == BLKIF_STATE_CONNECTED)
680 kick_pending_request_queues(info); 678 kick_pending_request_queues(info);
681 spin_unlock_irq(&blkif_io_lock); 679 spin_unlock_irq(&info->io_lock);
682} 680}
683 681
684static void blkif_free(struct blkfront_info *info, int suspend) 682static void blkif_free(struct blkfront_info *info, int suspend)
685{ 683{
686 /* Prevent new requests being issued until we fix things up. */ 684 /* Prevent new requests being issued until we fix things up. */
687 spin_lock_irq(&blkif_io_lock); 685 spin_lock_irq(&info->io_lock);
688 info->connected = suspend ? 686 info->connected = suspend ?
689 BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED; 687 BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
690 /* No more blkif_request(). */ 688 /* No more blkif_request(). */
@@ -692,7 +690,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
692 blk_stop_queue(info->rq); 690 blk_stop_queue(info->rq);
693 /* No more gnttab callback work. */ 691 /* No more gnttab callback work. */
694 gnttab_cancel_free_callback(&info->callback); 692 gnttab_cancel_free_callback(&info->callback);
695 spin_unlock_irq(&blkif_io_lock); 693 spin_unlock_irq(&info->io_lock);
696 694
697 /* Flush gnttab callback work. Must be done with no locks held. */ 695 /* Flush gnttab callback work. Must be done with no locks held. */
698 flush_work_sync(&info->work); 696 flush_work_sync(&info->work);
@@ -728,10 +726,10 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
728 struct blkfront_info *info = (struct blkfront_info *)dev_id; 726 struct blkfront_info *info = (struct blkfront_info *)dev_id;
729 int error; 727 int error;
730 728
731 spin_lock_irqsave(&blkif_io_lock, flags); 729 spin_lock_irqsave(&info->io_lock, flags);
732 730
733 if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) { 731 if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
734 spin_unlock_irqrestore(&blkif_io_lock, flags); 732 spin_unlock_irqrestore(&info->io_lock, flags);
735 return IRQ_HANDLED; 733 return IRQ_HANDLED;
736 } 734 }
737 735
@@ -816,7 +814,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
816 814
817 kick_pending_request_queues(info); 815 kick_pending_request_queues(info);
818 816
819 spin_unlock_irqrestore(&blkif_io_lock, flags); 817 spin_unlock_irqrestore(&info->io_lock, flags);
820 818
821 return IRQ_HANDLED; 819 return IRQ_HANDLED;
822} 820}
@@ -991,6 +989,7 @@ static int blkfront_probe(struct xenbus_device *dev,
991 } 989 }
992 990
993 mutex_init(&info->mutex); 991 mutex_init(&info->mutex);
992 spin_lock_init(&info->io_lock);
994 info->xbdev = dev; 993 info->xbdev = dev;
995 info->vdevice = vdevice; 994 info->vdevice = vdevice;
996 info->connected = BLKIF_STATE_DISCONNECTED; 995 info->connected = BLKIF_STATE_DISCONNECTED;
@@ -1068,7 +1067,7 @@ static int blkif_recover(struct blkfront_info *info)
1068 1067
1069 xenbus_switch_state(info->xbdev, XenbusStateConnected); 1068 xenbus_switch_state(info->xbdev, XenbusStateConnected);
1070 1069
1071 spin_lock_irq(&blkif_io_lock); 1070 spin_lock_irq(&info->io_lock);
1072 1071
1073 /* Now safe for us to use the shared ring */ 1072 /* Now safe for us to use the shared ring */
1074 info->connected = BLKIF_STATE_CONNECTED; 1073 info->connected = BLKIF_STATE_CONNECTED;
@@ -1079,7 +1078,7 @@ static int blkif_recover(struct blkfront_info *info)
1079 /* Kick any other new requests queued since we resumed */ 1078 /* Kick any other new requests queued since we resumed */
1080 kick_pending_request_queues(info); 1079 kick_pending_request_queues(info);
1081 1080
1082 spin_unlock_irq(&blkif_io_lock); 1081 spin_unlock_irq(&info->io_lock);
1083 1082
1084 return 0; 1083 return 0;
1085} 1084}
@@ -1277,10 +1276,10 @@ static void blkfront_connect(struct blkfront_info *info)
1277 xenbus_switch_state(info->xbdev, XenbusStateConnected); 1276 xenbus_switch_state(info->xbdev, XenbusStateConnected);
1278 1277
1279 /* Kick pending requests. */ 1278 /* Kick pending requests. */
1280 spin_lock_irq(&blkif_io_lock); 1279 spin_lock_irq(&info->io_lock);
1281 info->connected = BLKIF_STATE_CONNECTED; 1280 info->connected = BLKIF_STATE_CONNECTED;
1282 kick_pending_request_queues(info); 1281 kick_pending_request_queues(info);
1283 spin_unlock_irq(&blkif_io_lock); 1282 spin_unlock_irq(&info->io_lock);
1284 1283
1285 add_disk(info->gd); 1284 add_disk(info->gd);
1286 1285
@@ -1410,7 +1409,6 @@ static int blkif_release(struct gendisk *disk, fmode_t mode)
1410 mutex_lock(&blkfront_mutex); 1409 mutex_lock(&blkfront_mutex);
1411 1410
1412 bdev = bdget_disk(disk, 0); 1411 bdev = bdget_disk(disk, 0);
1413 bdput(bdev);
1414 1412
1415 if (bdev->bd_openers) 1413 if (bdev->bd_openers)
1416 goto out; 1414 goto out;
@@ -1441,6 +1439,7 @@ static int blkif_release(struct gendisk *disk, fmode_t mode)
1441 } 1439 }
1442 1440
1443out: 1441out:
1442 bdput(bdev);
1444 mutex_unlock(&blkfront_mutex); 1443 mutex_unlock(&blkfront_mutex);
1445 return 0; 1444 return 0;
1446} 1445}