diff options
author | Heinz Mauelshagen <heinzm@redhat.com> | 2020-04-29 16:47:03 +0200 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2020-05-15 16:29:35 +0200 |
commit | a5089a95d84c1e861e2d1f549ae368c8e89e3674 (patch) | |
tree | 02c9822fd525f7a33c617238f73c3b7f6c0e21d3 /drivers/md | |
parent | dm bufio: implement discard (diff) | |
download | linux-a5089a95d84c1e861e2d1f549ae368c8e89e3674.tar.xz linux-a5089a95d84c1e861e2d1f549ae368c8e89e3674.zip |
dm ebs: pass discards down to underlying device
Make use of dm_bufio_issue_discard() to pass discards down to the
underlying device.
Signed-off-by: Heinz Mauelshagen <heinzm@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-ebs-target.c | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/md/dm-ebs-target.c b/drivers/md/dm-ebs-target.c index c2bd21fa7002..ae3f5fad3b39 100644 --- a/drivers/md/dm-ebs-target.c +++ b/drivers/md/dm-ebs-target.c @@ -132,16 +132,43 @@ static int __ebs_rw_bio(struct ebs_c *ec, int rw, struct bio *bio) return r; } -/* 'Discard' blocks, i.e. release them from the bufio cache. */ -static int __ebs_forget_bio(struct ebs_c *ec, struct bio *bio) +/* + * Discard bio's blocks, i.e. pass discards down. + * + * Avoid discarding partial blocks at beginning and end; + * return 0 in case no blocks can be discarded as a result. + */ +static int __ebs_discard_bio(struct ebs_c *ec, struct bio *bio) +{ + sector_t block, blocks, sector = bio->bi_iter.bi_sector; + + block = __sector_to_block(ec, sector); + blocks = __nr_blocks(ec, bio); + + /* + * Partial first underlying block (__nr_blocks() may have + * resulted in one block). + */ + if (__block_mod(sector, ec->u_bs)) { + block++; + blocks--; + } + + /* Partial last underlying block if any. */ + if (blocks && __block_mod(bio_end_sector(bio), ec->u_bs)) + blocks--; + + return blocks ? dm_bufio_issue_discard(ec->bufio, block, blocks) : 0; +} + +/* Release blocks them from the bufio cache. */ +static void __ebs_forget_bio(struct ebs_c *ec, struct bio *bio) { sector_t blocks, sector = bio->bi_iter.bi_sector; blocks = __nr_blocks(ec, bio); for (; blocks--; sector += ec->u_bs) dm_bufio_forget(ec->bufio, __sector_to_block(ec, sector)); - - return 0; } /* Worker funtion to process incoming bios. */ @@ -183,8 +210,8 @@ static void __ebs_process_bios(struct work_struct *ws) write = true; r = __ebs_rw_bio(ec, WRITE, bio); } else if (bio_op(bio) == REQ_OP_DISCARD) { - /* FIXME: (optionally) call dm_bufio_discard_buffers() once upstream. */ - r = __ebs_forget_bio(ec, bio); + __ebs_forget_bio(ec, bio); + r = __ebs_discard_bio(ec, bio); } if (r < 0) @@ -409,7 +436,7 @@ static int ebs_iterate_devices(struct dm_target *ti, static struct target_type ebs_target = { .name = "ebs", - .version = {1, 0, 0}, + .version = {1, 0, 1}, .features = DM_TARGET_PASSES_INTEGRITY, .module = THIS_MODULE, .ctr = ebs_ctr, |