From 15cb6f39dbaf391dd3b70389c2882df998d5189a Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Mon, 12 Jul 2021 21:21:34 -0400 Subject: [PATCH] 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: Mike Snitzer --- drivers/md/dm-writecache.c | 75 ++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c index 2a920e95975a9b..64d7a798244ab6 100644 --- a/drivers/md/dm-writecache.c +++ b/drivers/md/dm-writecache.c @@ -1447,31 +1447,52 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio 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) { 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; wc_lock(wc); if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { - if (writecache_has_error(wc)) - goto unlock_error; - 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; - } + map_op = writecache_map_flush(wc, bio); + goto done; } 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) DMERR("I/O is not aligned, sector %llu, size %u, block size %u", (unsigned long long)bio->bi_iter.bi_sector, 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 (writecache_has_error(wc)) - goto unlock_error; - 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; - } + map_op = writecache_map_discard(wc, bio); + goto done; } if (bio_data_dir(bio) == READ) map_op = writecache_map_read(wc, bio); else map_op = writecache_map_write(wc, bio); - +done: switch (map_op) { case WC_MAP_REMAP_ORIGIN: -unlock_remap_origin: if (likely(wc->pause != 0)) { if (bio_op(bio) == REQ_OP_WRITE) { dm_iot_io_begin(&wc->iot, 1); @@ -1515,7 +1529,6 @@ static int writecache_map(struct dm_target *ti, struct bio *bio) return DM_MAPIO_REMAPPED; case WC_MAP_REMAP: -unlock_remap: /* make sure that writecache_end_io decrements bio_in_progress: */ bio->bi_private = (void *)1; 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) return DM_MAPIO_REMAPPED; case WC_MAP_SUBMIT: -unlock_submit: wc_unlock(wc); bio_endio(bio); return DM_MAPIO_SUBMITTED; case WC_MAP_RETURN: -unlock_return: wc_unlock(wc); return DM_MAPIO_SUBMITTED; case WC_MAP_ERROR: -unlock_error: + default: wc_unlock(wc); bio_io_error(bio); return DM_MAPIO_SUBMITTED;