diff options
author | Mike Snitzer <snitzer@redhat.com> | 2010-09-08 12:07:01 -0400 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-09-10 06:35:38 -0400 |
commit | b372d360df6deaf79a58a02fa0cc0d7e0aa3e92f (patch) | |
tree | e103bc03bae17f7a995ba44825aefd5fc5fdba66 /drivers/md | |
parent | 05447420f99c1c44063c7f00054667c022cc1365 (diff) |
dm: convey that all flushes are processed as empty
Rename __clone_and_map_flush to __clone_and_map_empty_flush for added
clarity.
Simplify logic associated with REQ_FLUSH conditionals.
Introduce a BUG_ON() and add a few more helpful comments to the code
so that it is clear that all flushes are empty.
Cleanup __split_and_process_bio() so that an empty flush isn't processed
by a 'sector_count' focused while loop.
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm.c | 34 |
1 files changed, 15 insertions, 19 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index cd2f7e77b625..f934e9878436 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -621,16 +621,17 @@ static void dec_pending(struct dm_io *io, int error) | |||
621 | if (io_error == DM_ENDIO_REQUEUE) | 621 | if (io_error == DM_ENDIO_REQUEUE) |
622 | return; | 622 | return; |
623 | 623 | ||
624 | if (!(bio->bi_rw & REQ_FLUSH) || !bio->bi_size) { | 624 | if ((bio->bi_rw & REQ_FLUSH) && bio->bi_size) { |
625 | trace_block_bio_complete(md->queue, bio); | ||
626 | bio_endio(bio, io_error); | ||
627 | } else { | ||
628 | /* | 625 | /* |
629 | * Preflush done for flush with data, reissue | 626 | * Preflush done for flush with data, reissue |
630 | * without REQ_FLUSH. | 627 | * without REQ_FLUSH. |
631 | */ | 628 | */ |
632 | bio->bi_rw &= ~REQ_FLUSH; | 629 | bio->bi_rw &= ~REQ_FLUSH; |
633 | queue_io(md, bio); | 630 | queue_io(md, bio); |
631 | } else { | ||
632 | /* done with normal IO or empty flush */ | ||
633 | trace_block_bio_complete(md->queue, bio); | ||
634 | bio_endio(bio, io_error); | ||
634 | } | 635 | } |
635 | } | 636 | } |
636 | } | 637 | } |
@@ -1132,16 +1133,15 @@ static void __issue_target_requests(struct clone_info *ci, struct dm_target *ti, | |||
1132 | __issue_target_request(ci, ti, request_nr, len); | 1133 | __issue_target_request(ci, ti, request_nr, len); |
1133 | } | 1134 | } |
1134 | 1135 | ||
1135 | static int __clone_and_map_flush(struct clone_info *ci) | 1136 | static int __clone_and_map_empty_flush(struct clone_info *ci) |
1136 | { | 1137 | { |
1137 | unsigned target_nr = 0; | 1138 | unsigned target_nr = 0; |
1138 | struct dm_target *ti; | 1139 | struct dm_target *ti; |
1139 | 1140 | ||
1141 | BUG_ON(bio_has_data(ci->bio)); | ||
1140 | while ((ti = dm_table_get_target(ci->map, target_nr++))) | 1142 | while ((ti = dm_table_get_target(ci->map, target_nr++))) |
1141 | __issue_target_requests(ci, ti, ti->num_flush_requests, 0); | 1143 | __issue_target_requests(ci, ti, ti->num_flush_requests, 0); |
1142 | 1144 | ||
1143 | ci->sector_count = 0; | ||
1144 | |||
1145 | return 0; | 1145 | return 0; |
1146 | } | 1146 | } |
1147 | 1147 | ||
@@ -1282,7 +1282,6 @@ static int __clone_and_map(struct clone_info *ci) | |||
1282 | */ | 1282 | */ |
1283 | static void __split_and_process_bio(struct mapped_device *md, struct bio *bio) | 1283 | static void __split_and_process_bio(struct mapped_device *md, struct bio *bio) |
1284 | { | 1284 | { |
1285 | bool is_flush = bio->bi_rw & REQ_FLUSH; | ||
1286 | struct clone_info ci; | 1285 | struct clone_info ci; |
1287 | int error = 0; | 1286 | int error = 0; |
1288 | 1287 | ||
@@ -1302,20 +1301,17 @@ static void __split_and_process_bio(struct mapped_device *md, struct bio *bio) | |||
1302 | ci.sector = bio->bi_sector; | 1301 | ci.sector = bio->bi_sector; |
1303 | ci.idx = bio->bi_idx; | 1302 | ci.idx = bio->bi_idx; |
1304 | 1303 | ||
1305 | if (!is_flush) { | 1304 | start_io_acct(ci.io); |
1305 | if (bio->bi_rw & REQ_FLUSH) { | ||
1306 | ci.bio = &ci.md->flush_bio; | ||
1307 | ci.sector_count = 0; | ||
1308 | error = __clone_and_map_empty_flush(&ci); | ||
1309 | /* dec_pending submits any data associated with flush */ | ||
1310 | } else { | ||
1306 | ci.bio = bio; | 1311 | ci.bio = bio; |
1307 | ci.sector_count = bio_sectors(bio); | 1312 | ci.sector_count = bio_sectors(bio); |
1308 | } else { | 1313 | while (ci.sector_count && !error) |
1309 | ci.bio = &ci.md->flush_bio; | ||
1310 | ci.sector_count = 1; | ||
1311 | } | ||
1312 | |||
1313 | start_io_acct(ci.io); | ||
1314 | while (ci.sector_count && !error) { | ||
1315 | if (!is_flush) | ||
1316 | error = __clone_and_map(&ci); | 1314 | error = __clone_and_map(&ci); |
1317 | else | ||
1318 | error = __clone_and_map_flush(&ci); | ||
1319 | } | 1315 | } |
1320 | 1316 | ||
1321 | /* drop the extra reference count */ | 1317 | /* drop the extra reference count */ |