aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-mpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-mpath.c')
-rw-r--r--drivers/md/dm-mpath.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index aaa6caa46a9f..cfa29f574c2a 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -1537,32 +1537,34 @@ static int multipath_prepare_ioctl(struct dm_target *ti,
1537 struct block_device **bdev, fmode_t *mode) 1537 struct block_device **bdev, fmode_t *mode)
1538{ 1538{
1539 struct multipath *m = ti->private; 1539 struct multipath *m = ti->private;
1540 struct pgpath *pgpath;
1541 unsigned long flags; 1540 unsigned long flags;
1542 int r; 1541 int r;
1543 1542
1544 r = 0;
1545
1546 spin_lock_irqsave(&m->lock, flags); 1543 spin_lock_irqsave(&m->lock, flags);
1547 1544
1548 if (!m->current_pgpath) 1545 if (!m->current_pgpath)
1549 __choose_pgpath(m, 0); 1546 __choose_pgpath(m, 0);
1550 1547
1551 pgpath = m->current_pgpath; 1548 if (m->current_pgpath) {
1552 1549 if (!m->queue_io) {
1553 if (pgpath) { 1550 *bdev = m->current_pgpath->path.dev->bdev;
1554 *bdev = pgpath->path.dev->bdev; 1551 *mode = m->current_pgpath->path.dev->mode;
1555 *mode = pgpath->path.dev->mode; 1552 r = 0;
1553 } else {
1554 /* pg_init has not started or completed */
1555 r = -ENOTCONN;
1556 }
1557 } else {
1558 /* No path is available */
1559 if (m->queue_if_no_path)
1560 r = -ENOTCONN;
1561 else
1562 r = -EIO;
1556 } 1563 }
1557 1564
1558 if ((pgpath && m->queue_io) || (!pgpath && m->queue_if_no_path))
1559 r = -ENOTCONN;
1560 else if (!*bdev)
1561 r = -EIO;
1562
1563 spin_unlock_irqrestore(&m->lock, flags); 1565 spin_unlock_irqrestore(&m->lock, flags);
1564 1566
1565 if (r == -ENOTCONN && !fatal_signal_pending(current)) { 1567 if (r == -ENOTCONN) {
1566 spin_lock_irqsave(&m->lock, flags); 1568 spin_lock_irqsave(&m->lock, flags);
1567 if (!m->current_pg) { 1569 if (!m->current_pg) {
1568 /* Path status changed, redo selection */ 1570 /* Path status changed, redo selection */