Commit 15cb6f39 authored by Mike Snitzer's avatar Mike Snitzer

dm writecache: further writecache_map() cleanup

Factor out writecache_map_flush() and writecache_map_discard() from
writecache_map(). Also eliminate the various goto labels in
writecache_map().
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent 4d020b3a
...@@ -1447,31 +1447,52 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio ...@@ -1447,31 +1447,52 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio
return WC_MAP_SUBMIT; return WC_MAP_SUBMIT;
} }
static enum wc_map_op writecache_map_flush(struct dm_writecache *wc, struct bio *bio)
{
if (writecache_has_error(wc))
return WC_MAP_ERROR;
if (WC_MODE_PMEM(wc)) {
writecache_flush(wc);
if (writecache_has_error(wc))
return WC_MAP_ERROR;
else if (unlikely(wc->cleaner) || unlikely(wc->metadata_only))
return WC_MAP_REMAP_ORIGIN;
return WC_MAP_SUBMIT;
}
/* SSD: */
if (dm_bio_get_target_bio_nr(bio))
return WC_MAP_REMAP_ORIGIN;
writecache_offload_bio(wc, bio);
return WC_MAP_RETURN;
}
static enum wc_map_op writecache_map_discard(struct dm_writecache *wc, struct bio *bio)
{
if (writecache_has_error(wc))
return WC_MAP_ERROR;
if (WC_MODE_PMEM(wc)) {
writecache_discard(wc, bio->bi_iter.bi_sector, bio_end_sector(bio));
return WC_MAP_REMAP_ORIGIN;
}
/* SSD: */
writecache_offload_bio(wc, bio);
return WC_MAP_RETURN;
}
static int writecache_map(struct dm_target *ti, struct bio *bio) static int writecache_map(struct dm_target *ti, struct bio *bio)
{ {
struct dm_writecache *wc = ti->private; struct dm_writecache *wc = ti->private;
enum wc_map_op map_op = WC_MAP_ERROR; enum wc_map_op map_op;
bio->bi_private = NULL; bio->bi_private = NULL;
wc_lock(wc); wc_lock(wc);
if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
if (writecache_has_error(wc)) map_op = writecache_map_flush(wc, bio);
goto unlock_error; goto done;
if (WC_MODE_PMEM(wc)) {
writecache_flush(wc);
if (writecache_has_error(wc))
goto unlock_error;
if (unlikely(wc->cleaner) || unlikely(wc->metadata_only))
goto unlock_remap_origin;
goto unlock_submit;
} else {
if (dm_bio_get_target_bio_nr(bio))
goto unlock_remap_origin;
writecache_offload_bio(wc, bio);
goto unlock_return;
}
} }
bio->bi_iter.bi_sector = dm_target_offset(ti, bio->bi_iter.bi_sector); bio->bi_iter.bi_sector = dm_target_offset(ti, bio->bi_iter.bi_sector);
...@@ -1481,29 +1502,22 @@ static int writecache_map(struct dm_target *ti, struct bio *bio) ...@@ -1481,29 +1502,22 @@ static int writecache_map(struct dm_target *ti, struct bio *bio)
DMERR("I/O is not aligned, sector %llu, size %u, block size %u", DMERR("I/O is not aligned, sector %llu, size %u, block size %u",
(unsigned long long)bio->bi_iter.bi_sector, (unsigned long long)bio->bi_iter.bi_sector,
bio->bi_iter.bi_size, wc->block_size); bio->bi_iter.bi_size, wc->block_size);
goto unlock_error; map_op = WC_MAP_ERROR;
goto done;
} }
if (unlikely(bio_op(bio) == REQ_OP_DISCARD)) { if (unlikely(bio_op(bio) == REQ_OP_DISCARD)) {
if (writecache_has_error(wc)) map_op = writecache_map_discard(wc, bio);
goto unlock_error; goto done;
if (WC_MODE_PMEM(wc)) {
writecache_discard(wc, bio->bi_iter.bi_sector, bio_end_sector(bio));
goto unlock_remap_origin;
} else {
writecache_offload_bio(wc, bio);
goto unlock_return;
}
} }
if (bio_data_dir(bio) == READ) if (bio_data_dir(bio) == READ)
map_op = writecache_map_read(wc, bio); map_op = writecache_map_read(wc, bio);
else else
map_op = writecache_map_write(wc, bio); map_op = writecache_map_write(wc, bio);
done:
switch (map_op) { switch (map_op) {
case WC_MAP_REMAP_ORIGIN: case WC_MAP_REMAP_ORIGIN:
unlock_remap_origin:
if (likely(wc->pause != 0)) { if (likely(wc->pause != 0)) {
if (bio_op(bio) == REQ_OP_WRITE) { if (bio_op(bio) == REQ_OP_WRITE) {
dm_iot_io_begin(&wc->iot, 1); dm_iot_io_begin(&wc->iot, 1);
...@@ -1515,7 +1529,6 @@ static int writecache_map(struct dm_target *ti, struct bio *bio) ...@@ -1515,7 +1529,6 @@ static int writecache_map(struct dm_target *ti, struct bio *bio)
return DM_MAPIO_REMAPPED; return DM_MAPIO_REMAPPED;
case WC_MAP_REMAP: case WC_MAP_REMAP:
unlock_remap:
/* make sure that writecache_end_io decrements bio_in_progress: */ /* make sure that writecache_end_io decrements bio_in_progress: */
bio->bi_private = (void *)1; bio->bi_private = (void *)1;
atomic_inc(&wc->bio_in_progress[bio_data_dir(bio)]); atomic_inc(&wc->bio_in_progress[bio_data_dir(bio)]);
...@@ -1523,18 +1536,16 @@ static int writecache_map(struct dm_target *ti, struct bio *bio) ...@@ -1523,18 +1536,16 @@ static int writecache_map(struct dm_target *ti, struct bio *bio)
return DM_MAPIO_REMAPPED; return DM_MAPIO_REMAPPED;
case WC_MAP_SUBMIT: case WC_MAP_SUBMIT:
unlock_submit:
wc_unlock(wc); wc_unlock(wc);
bio_endio(bio); bio_endio(bio);
return DM_MAPIO_SUBMITTED; return DM_MAPIO_SUBMITTED;
case WC_MAP_RETURN: case WC_MAP_RETURN:
unlock_return:
wc_unlock(wc); wc_unlock(wc);
return DM_MAPIO_SUBMITTED; return DM_MAPIO_SUBMITTED;
case WC_MAP_ERROR: case WC_MAP_ERROR:
unlock_error: default:
wc_unlock(wc); wc_unlock(wc);
bio_io_error(bio); bio_io_error(bio);
return DM_MAPIO_SUBMITTED; return DM_MAPIO_SUBMITTED;
......
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