diff options
-rw-r--r-- | drivers/md/dm-mpath.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 2469ba68dc2b..638dae048b4f 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/time.h> | 19 | #include <linux/time.h> |
20 | #include <linux/workqueue.h> | 20 | #include <linux/workqueue.h> |
21 | #include <linux/delay.h> | ||
21 | #include <scsi/scsi_dh.h> | 22 | #include <scsi/scsi_dh.h> |
22 | #include <linux/atomic.h> | 23 | #include <linux/atomic.h> |
23 | 24 | ||
@@ -486,9 +487,6 @@ static void process_queued_ios(struct work_struct *work) | |||
486 | 487 | ||
487 | spin_lock_irqsave(&m->lock, flags); | 488 | spin_lock_irqsave(&m->lock, flags); |
488 | 489 | ||
489 | if (!m->queue_size) | ||
490 | goto out; | ||
491 | |||
492 | if (!m->current_pgpath) | 490 | if (!m->current_pgpath) |
493 | __choose_pgpath(m, 0); | 491 | __choose_pgpath(m, 0); |
494 | 492 | ||
@@ -501,7 +499,6 @@ static void process_queued_ios(struct work_struct *work) | |||
501 | if (m->pg_init_required && !m->pg_init_in_progress && pgpath) | 499 | if (m->pg_init_required && !m->pg_init_in_progress && pgpath) |
502 | __pg_init_all_paths(m); | 500 | __pg_init_all_paths(m); |
503 | 501 | ||
504 | out: | ||
505 | spin_unlock_irqrestore(&m->lock, flags); | 502 | spin_unlock_irqrestore(&m->lock, flags); |
506 | if (!must_queue) | 503 | if (!must_queue) |
507 | dispatch_queued_ios(m); | 504 | dispatch_queued_ios(m); |
@@ -1522,11 +1519,16 @@ out: | |||
1522 | static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, | 1519 | static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, |
1523 | unsigned long arg) | 1520 | unsigned long arg) |
1524 | { | 1521 | { |
1525 | struct multipath *m = (struct multipath *) ti->private; | 1522 | struct multipath *m = ti->private; |
1526 | struct block_device *bdev = NULL; | 1523 | struct block_device *bdev; |
1527 | fmode_t mode = 0; | 1524 | fmode_t mode; |
1528 | unsigned long flags; | 1525 | unsigned long flags; |
1529 | int r = 0; | 1526 | int r; |
1527 | |||
1528 | again: | ||
1529 | bdev = NULL; | ||
1530 | mode = 0; | ||
1531 | r = 0; | ||
1530 | 1532 | ||
1531 | spin_lock_irqsave(&m->lock, flags); | 1533 | spin_lock_irqsave(&m->lock, flags); |
1532 | 1534 | ||
@@ -1551,6 +1553,12 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, | |||
1551 | if (!r && ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT) | 1553 | if (!r && ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT) |
1552 | r = scsi_verify_blk_ioctl(NULL, cmd); | 1554 | r = scsi_verify_blk_ioctl(NULL, cmd); |
1553 | 1555 | ||
1556 | if (r == -EAGAIN && !fatal_signal_pending(current)) { | ||
1557 | queue_work(kmultipathd, &m->process_queued_ios); | ||
1558 | msleep(10); | ||
1559 | goto again; | ||
1560 | } | ||
1561 | |||
1554 | return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg); | 1562 | return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg); |
1555 | } | 1563 | } |
1556 | 1564 | ||
@@ -1648,7 +1656,7 @@ out: | |||
1648 | *---------------------------------------------------------------*/ | 1656 | *---------------------------------------------------------------*/ |
1649 | static struct target_type multipath_target = { | 1657 | static struct target_type multipath_target = { |
1650 | .name = "multipath", | 1658 | .name = "multipath", |
1651 | .version = {1, 3, 0}, | 1659 | .version = {1, 4, 0}, |
1652 | .module = THIS_MODULE, | 1660 | .module = THIS_MODULE, |
1653 | .ctr = multipath_ctr, | 1661 | .ctr = multipath_ctr, |
1654 | .dtr = multipath_dtr, | 1662 | .dtr = multipath_dtr, |