aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorKiyoshi Ueda <k-ueda@ct.jp.nec.com>2006-12-08 05:41:10 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-08 11:29:09 -0500
commit45e157206c732613d1c07e8ceeb1a3e497fb2abf (patch)
tree327d36f8aea80f3a7fed4bb43232155dd4835145 /drivers/md
parent2e93ccc1933d08d32d9bde3784c3823e67b9b030 (diff)
[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: Kiyoshi Ueda <k-ueda@ct.jp.nec.com> Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com> Cc: dm-devel@redhat.com Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-mpath.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index d325edcbb3f5..3aa013506967 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -282,6 +282,23 @@ failed:
282 m->current_pg = NULL; 282 m->current_pg = NULL;
283} 283}
284 284
285/*
286 * Check whether bios must be queued in the device-mapper core rather
287 * than here in the target.
288 *
289 * m->lock must be held on entry.
290 *
291 * If m->queue_if_no_path and m->saved_queue_if_no_path hold the
292 * same value then we are not between multipath_presuspend()
293 * and multipath_resume() calls and we have no need to check
294 * for the DMF_NOFLUSH_SUSPENDING flag.
295 */
296static int __must_push_back(struct multipath *m)
297{
298 return (m->queue_if_no_path != m->saved_queue_if_no_path &&
299 dm_noflush_suspending(m->ti));
300}
301
285static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio, 302static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio,
286 unsigned was_queued) 303 unsigned was_queued)
287{ 304{
@@ -311,10 +328,12 @@ static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio,
311 queue_work(kmultipathd, &m->process_queued_ios); 328 queue_work(kmultipathd, &m->process_queued_ios);
312 pgpath = NULL; 329 pgpath = NULL;
313 r = DM_MAPIO_SUBMITTED; 330 r = DM_MAPIO_SUBMITTED;
314 } else if (!pgpath) 331 } else if (pgpath)
315 r = -EIO; /* Failed */
316 else
317 bio->bi_bdev = pgpath->path.dev->bdev; 332 bio->bi_bdev = pgpath->path.dev->bdev;
333 else if (__must_push_back(m))
334 r = DM_MAPIO_REQUEUE;
335 else
336 r = -EIO; /* Failed */
318 337
319 mpio->pgpath = pgpath; 338 mpio->pgpath = pgpath;
320 339
@@ -374,6 +393,8 @@ static void dispatch_queued_ios(struct multipath *m)
374 bio_endio(bio, bio->bi_size, r); 393 bio_endio(bio, bio->bi_size, r);
375 else if (r == DM_MAPIO_REMAPPED) 394 else if (r == DM_MAPIO_REMAPPED)
376 generic_make_request(bio); 395 generic_make_request(bio);
396 else if (r == DM_MAPIO_REQUEUE)
397 bio_endio(bio, bio->bi_size, -EIO);
377 398
378 bio = next; 399 bio = next;
379 } 400 }
@@ -783,7 +804,7 @@ static int multipath_map(struct dm_target *ti, struct bio *bio,
783 map_context->ptr = mpio; 804 map_context->ptr = mpio;
784 bio->bi_rw |= (1 << BIO_RW_FAILFAST); 805 bio->bi_rw |= (1 << BIO_RW_FAILFAST);
785 r = map_io(m, bio, mpio, 0); 806 r = map_io(m, bio, mpio, 0);
786 if (r < 0) 807 if (r < 0 || r == DM_MAPIO_REQUEUE)
787 mempool_free(mpio, m->mpio_pool); 808 mempool_free(mpio, m->mpio_pool);
788 809
789 return r; 810 return r;
@@ -1007,7 +1028,10 @@ static int do_end_io(struct multipath *m, struct bio *bio,
1007 1028
1008 spin_lock_irqsave(&m->lock, flags); 1029 spin_lock_irqsave(&m->lock, flags);
1009 if (!m->nr_valid_paths) { 1030 if (!m->nr_valid_paths) {
1010 if (!m->queue_if_no_path) { 1031 if (__must_push_back(m)) {
1032 spin_unlock_irqrestore(&m->lock, flags);
1033 return DM_ENDIO_REQUEUE;
1034 } else if (!m->queue_if_no_path) {
1011 spin_unlock_irqrestore(&m->lock, flags); 1035 spin_unlock_irqrestore(&m->lock, flags);
1012 return -EIO; 1036 return -EIO;
1013 } else { 1037 } else {