Commit 45e15720 authored by Kiyoshi Ueda's avatar Kiyoshi Ueda Committed by Linus Torvalds

[PATCH] dm: mpath: use noflush suspending

Implement the pushback feature for the multipath target.

The pushback request is used when:
  1) there are no valid paths;
  2) queue_if_no_path was set;
  3) a suspend is being issued with the DMF_NOFLUSH_SUSPENDING flag.
     Otherwise bios are returned to applications with -EIO.

To check whether queue_if_no_path is specified or not, you need to check
both queue_if_no_path and saved_queue_if_no_path, because presuspend saves
the original queue_if_no_path value to saved_queue_if_no_path.

The check for 1 already exists in both map_io() and do_end_io().
So this patch adds __must_push_back() to check 2 and 3.

Test results:
See the test results in the preceding patch.
Signed-off-by: default avatarKiyoshi Ueda <k-ueda@ct.jp.nec.com>
Signed-off-by: default avatarJun'ichi Nomura <j-nomura@ce.jp.nec.com>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
Cc: dm-devel@redhat.com
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 2e93ccc1
...@@ -282,6 +282,23 @@ failed: ...@@ -282,6 +282,23 @@ failed:
m->current_pg = NULL; m->current_pg = NULL;
} }
/*
* Check whether bios must be queued in the device-mapper core rather
* than here in the target.
*
* m->lock must be held on entry.
*
* If m->queue_if_no_path and m->saved_queue_if_no_path hold the
* same value then we are not between multipath_presuspend()
* and multipath_resume() calls and we have no need to check
* for the DMF_NOFLUSH_SUSPENDING flag.
*/
static int __must_push_back(struct multipath *m)
{
return (m->queue_if_no_path != m->saved_queue_if_no_path &&
dm_noflush_suspending(m->ti));
}
static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio, static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio,
unsigned was_queued) unsigned was_queued)
{ {
...@@ -311,10 +328,12 @@ static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio, ...@@ -311,10 +328,12 @@ static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio,
queue_work(kmultipathd, &m->process_queued_ios); queue_work(kmultipathd, &m->process_queued_ios);
pgpath = NULL; pgpath = NULL;
r = DM_MAPIO_SUBMITTED; r = DM_MAPIO_SUBMITTED;
} else if (!pgpath) } else if (pgpath)
r = -EIO; /* Failed */
else
bio->bi_bdev = pgpath->path.dev->bdev; bio->bi_bdev = pgpath->path.dev->bdev;
else if (__must_push_back(m))
r = DM_MAPIO_REQUEUE;
else
r = -EIO; /* Failed */
mpio->pgpath = pgpath; mpio->pgpath = pgpath;
...@@ -374,6 +393,8 @@ static void dispatch_queued_ios(struct multipath *m) ...@@ -374,6 +393,8 @@ static void dispatch_queued_ios(struct multipath *m)
bio_endio(bio, bio->bi_size, r); bio_endio(bio, bio->bi_size, r);
else if (r == DM_MAPIO_REMAPPED) else if (r == DM_MAPIO_REMAPPED)
generic_make_request(bio); generic_make_request(bio);
else if (r == DM_MAPIO_REQUEUE)
bio_endio(bio, bio->bi_size, -EIO);
bio = next; bio = next;
} }
...@@ -783,7 +804,7 @@ static int multipath_map(struct dm_target *ti, struct bio *bio, ...@@ -783,7 +804,7 @@ static int multipath_map(struct dm_target *ti, struct bio *bio,
map_context->ptr = mpio; map_context->ptr = mpio;
bio->bi_rw |= (1 << BIO_RW_FAILFAST); bio->bi_rw |= (1 << BIO_RW_FAILFAST);
r = map_io(m, bio, mpio, 0); r = map_io(m, bio, mpio, 0);
if (r < 0) if (r < 0 || r == DM_MAPIO_REQUEUE)
mempool_free(mpio, m->mpio_pool); mempool_free(mpio, m->mpio_pool);
return r; return r;
...@@ -1007,7 +1028,10 @@ static int do_end_io(struct multipath *m, struct bio *bio, ...@@ -1007,7 +1028,10 @@ static int do_end_io(struct multipath *m, struct bio *bio,
spin_lock_irqsave(&m->lock, flags); spin_lock_irqsave(&m->lock, flags);
if (!m->nr_valid_paths) { if (!m->nr_valid_paths) {
if (!m->queue_if_no_path) { if (__must_push_back(m)) {
spin_unlock_irqrestore(&m->lock, flags);
return DM_ENDIO_REQUEUE;
} else if (!m->queue_if_no_path) {
spin_unlock_irqrestore(&m->lock, flags); spin_unlock_irqrestore(&m->lock, flags);
return -EIO; return -EIO;
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment