|
@@ -43,6 +43,7 @@
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/mutex.h>
|
|
|
#include <linux/scatterlist.h>
|
|
|
+#include <linux/bitmap.h>
|
|
|
|
|
|
#include <xen/xen.h>
|
|
|
#include <xen/xenbus.h>
|
|
@@ -81,6 +82,7 @@ static const struct block_device_operations xlvbd_block_fops;
|
|
|
*/
|
|
|
struct blkfront_info
|
|
|
{
|
|
|
+ spinlock_t io_lock;
|
|
|
struct mutex mutex;
|
|
|
struct xenbus_device *xbdev;
|
|
|
struct gendisk *gd;
|
|
@@ -105,8 +107,6 @@ struct blkfront_info
|
|
|
int is_ready;
|
|
|
};
|
|
|
|
|
|
-static DEFINE_SPINLOCK(blkif_io_lock);
|
|
|
-
|
|
|
static unsigned int nr_minors;
|
|
|
static unsigned long *minors;
|
|
|
static DEFINE_SPINLOCK(minor_lock);
|
|
@@ -177,8 +177,7 @@ static int xlbd_reserve_minors(unsigned int minor, unsigned int nr)
|
|
|
|
|
|
spin_lock(&minor_lock);
|
|
|
if (find_next_bit(minors, end, minor) >= end) {
|
|
|
- for (; minor < end; ++minor)
|
|
|
- __set_bit(minor, minors);
|
|
|
+ bitmap_set(minors, minor, nr);
|
|
|
rc = 0;
|
|
|
} else
|
|
|
rc = -EBUSY;
|
|
@@ -193,8 +192,7 @@ static void xlbd_release_minors(unsigned int minor, unsigned int nr)
|
|
|
|
|
|
BUG_ON(end > nr_minors);
|
|
|
spin_lock(&minor_lock);
|
|
|
- for (; minor < end; ++minor)
|
|
|
- __clear_bit(minor, minors);
|
|
|
+ bitmap_clear(minors, minor, nr);
|
|
|
spin_unlock(&minor_lock);
|
|
|
}
|
|
|
|
|
@@ -419,7 +417,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
|
|
|
struct request_queue *rq;
|
|
|
struct blkfront_info *info = gd->private_data;
|
|
|
|
|
|
- rq = blk_init_queue(do_blkif_request, &blkif_io_lock);
|
|
|
+ rq = blk_init_queue(do_blkif_request, &info->io_lock);
|
|
|
if (rq == NULL)
|
|
|
return -1;
|
|
|
|
|
@@ -636,14 +634,14 @@ static void xlvbd_release_gendisk(struct blkfront_info *info)
|
|
|
if (info->rq == NULL)
|
|
|
return;
|
|
|
|
|
|
- spin_lock_irqsave(&blkif_io_lock, flags);
|
|
|
+ spin_lock_irqsave(&info->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);
|
|
|
+ spin_unlock_irqrestore(&info->io_lock, flags);
|
|
|
|
|
|
/* Flush gnttab callback work. Must be done with no locks held. */
|
|
|
flush_work_sync(&info->work);
|
|
@@ -675,16 +673,16 @@ static void blkif_restart_queue(struct work_struct *work)
|
|
|
{
|
|
|
struct blkfront_info *info = container_of(work, struct blkfront_info, work);
|
|
|
|
|
|
- spin_lock_irq(&blkif_io_lock);
|
|
|
+ spin_lock_irq(&info->io_lock);
|
|
|
if (info->connected == BLKIF_STATE_CONNECTED)
|
|
|
kick_pending_request_queues(info);
|
|
|
- spin_unlock_irq(&blkif_io_lock);
|
|
|
+ spin_unlock_irq(&info->io_lock);
|
|
|
}
|
|
|
|
|
|
static void blkif_free(struct blkfront_info *info, int suspend)
|
|
|
{
|
|
|
/* Prevent new requests being issued until we fix things up. */
|
|
|
- spin_lock_irq(&blkif_io_lock);
|
|
|
+ spin_lock_irq(&info->io_lock);
|
|
|
info->connected = suspend ?
|
|
|
BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
|
|
|
/* No more blkif_request(). */
|
|
@@ -692,7 +690,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
|
|
|
blk_stop_queue(info->rq);
|
|
|
/* No more gnttab callback work. */
|
|
|
gnttab_cancel_free_callback(&info->callback);
|
|
|
- spin_unlock_irq(&blkif_io_lock);
|
|
|
+ spin_unlock_irq(&info->io_lock);
|
|
|
|
|
|
/* Flush gnttab callback work. Must be done with no locks held. */
|
|
|
flush_work_sync(&info->work);
|
|
@@ -728,10 +726,10 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
|
|
struct blkfront_info *info = (struct blkfront_info *)dev_id;
|
|
|
int error;
|
|
|
|
|
|
- spin_lock_irqsave(&blkif_io_lock, flags);
|
|
|
+ spin_lock_irqsave(&info->io_lock, flags);
|
|
|
|
|
|
if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
|
|
|
- spin_unlock_irqrestore(&blkif_io_lock, flags);
|
|
|
+ spin_unlock_irqrestore(&info->io_lock, flags);
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
|
|
|
@@ -816,7 +814,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
|
|
|
|
|
kick_pending_request_queues(info);
|
|
|
|
|
|
- spin_unlock_irqrestore(&blkif_io_lock, flags);
|
|
|
+ spin_unlock_irqrestore(&info->io_lock, flags);
|
|
|
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
@@ -991,6 +989,7 @@ static int blkfront_probe(struct xenbus_device *dev,
|
|
|
}
|
|
|
|
|
|
mutex_init(&info->mutex);
|
|
|
+ spin_lock_init(&info->io_lock);
|
|
|
info->xbdev = dev;
|
|
|
info->vdevice = vdevice;
|
|
|
info->connected = BLKIF_STATE_DISCONNECTED;
|
|
@@ -1068,7 +1067,7 @@ static int blkif_recover(struct blkfront_info *info)
|
|
|
|
|
|
xenbus_switch_state(info->xbdev, XenbusStateConnected);
|
|
|
|
|
|
- spin_lock_irq(&blkif_io_lock);
|
|
|
+ spin_lock_irq(&info->io_lock);
|
|
|
|
|
|
/* Now safe for us to use the shared ring */
|
|
|
info->connected = BLKIF_STATE_CONNECTED;
|
|
@@ -1079,7 +1078,7 @@ static int blkif_recover(struct blkfront_info *info)
|
|
|
/* Kick any other new requests queued since we resumed */
|
|
|
kick_pending_request_queues(info);
|
|
|
|
|
|
- spin_unlock_irq(&blkif_io_lock);
|
|
|
+ spin_unlock_irq(&info->io_lock);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -1277,10 +1276,10 @@ static void blkfront_connect(struct blkfront_info *info)
|
|
|
xenbus_switch_state(info->xbdev, XenbusStateConnected);
|
|
|
|
|
|
/* Kick pending requests. */
|
|
|
- spin_lock_irq(&blkif_io_lock);
|
|
|
+ spin_lock_irq(&info->io_lock);
|
|
|
info->connected = BLKIF_STATE_CONNECTED;
|
|
|
kick_pending_request_queues(info);
|
|
|
- spin_unlock_irq(&blkif_io_lock);
|
|
|
+ spin_unlock_irq(&info->io_lock);
|
|
|
|
|
|
add_disk(info->gd);
|
|
|
|
|
@@ -1410,7 +1409,6 @@ static int blkif_release(struct gendisk *disk, fmode_t mode)
|
|
|
mutex_lock(&blkfront_mutex);
|
|
|
|
|
|
bdev = bdget_disk(disk, 0);
|
|
|
- bdput(bdev);
|
|
|
|
|
|
if (bdev->bd_openers)
|
|
|
goto out;
|
|
@@ -1441,6 +1439,7 @@ static int blkif_release(struct gendisk *disk, fmode_t mode)
|
|
|
}
|
|
|
|
|
|
out:
|
|
|
+ bdput(bdev);
|
|
|
mutex_unlock(&blkfront_mutex);
|
|
|
return 0;
|
|
|
}
|