From 5f274d886598c9fd26d2499bf3f68306f170e9db Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Wed, 17 Sep 2014 10:17:39 +0100 Subject: [PATCH] dm bio prison: introduce support for locking ranges of blocks Ranges will be placed in the same cell if they overlap. Range locking is a prerequisite for more efficient multi-block discard support in both the cache and thin-provisioning targets. Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer --- drivers/md/dm-bio-prison.c | 4 ++-- drivers/md/dm-bio-prison.h | 12 ++++++++---- drivers/md/dm-cache-target.c | 3 ++- drivers/md/dm-thin.c | 6 ++++-- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/md/dm-bio-prison.c b/drivers/md/dm-bio-prison.c index bbe22a5dc06b..be065300e93c 100644 --- a/drivers/md/dm-bio-prison.c +++ b/drivers/md/dm-bio-prison.c @@ -95,10 +95,10 @@ static int cmp_keys(struct dm_cell_key *lhs, if (lhs->dev > rhs->dev) return 1; - if (lhs->block < rhs->block) + if (lhs->block_end <= rhs->block_begin) return -1; - if (lhs->block > rhs->block) + if (lhs->block_begin >= rhs->block_end) return 1; return 0; diff --git a/drivers/md/dm-bio-prison.h b/drivers/md/dm-bio-prison.h index b03988667740..74cf01144b1f 100644 --- a/drivers/md/dm-bio-prison.h +++ b/drivers/md/dm-bio-prison.h @@ -23,11 +23,14 @@ */ struct dm_bio_prison; -/* FIXME: this needs to be more abstract */ +/* + * Keys define a range of blocks within either a virtual or physical + * device. + */ struct dm_cell_key { int virtual; dm_thin_id dev; - dm_block_t block; + dm_block_t block_begin, block_end; }; /* @@ -59,7 +62,7 @@ void dm_bio_prison_free_cell(struct dm_bio_prison *prison, struct dm_bio_prison_cell *cell); /* - * Creates, or retrieves a cell for the given key. + * Creates, or retrieves a cell that overlaps the given key. * * Returns 1 if pre-existing cell returned, zero if new cell created using * @cell_prealloc. @@ -70,7 +73,8 @@ int dm_get_cell(struct dm_bio_prison *prison, struct dm_bio_prison_cell **cell_result); /* - * An atomic op that combines retrieving a cell, and adding a bio to it. + * An atomic op that combines retrieving or creating a cell, and adding a + * bio to it. * * Returns 1 if the cell was already held, 0 if @inmate is the new holder. */ diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 69de8b43ca12..890e2fff4074 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -436,7 +436,8 @@ static void build_key(dm_oblock_t oblock, struct dm_cell_key *key) { key->virtual = 0; key->dev = 0; - key->block = from_oblock(oblock); + key->block_begin = from_oblock(oblock); + key->block_end = key->block_begin + 1ULL; } /* diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index fb05f6a4bbfd..8c5504c0e894 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -115,7 +115,8 @@ static void build_data_key(struct dm_thin_device *td, { key->virtual = 0; key->dev = dm_thin_dev_id(td); - key->block = b; + key->block_begin = b; + key->block_end = b + 1ULL; } static void build_virtual_key(struct dm_thin_device *td, dm_block_t b, @@ -123,7 +124,8 @@ static void build_virtual_key(struct dm_thin_device *td, dm_block_t b, { key->virtual = 1; key->dev = dm_thin_dev_id(td); - key->block = b; + key->block_begin = b; + key->block_end = b + 1ULL; } /*----------------------------------------------------------------*/ -- 2.20.1