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 <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
diff --git a/drivers/md/dm-bio-prison.c b/drivers/md/dm-bio-prison.c
index bbe22a5..be06530 100644
--- a/drivers/md/dm-bio-prison.c
+++ b/drivers/md/dm-bio-prison.c
@@ -95,10 +95,10 @@
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 b039886..74cf011 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 @@
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 @@
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 69de8b4..890e2ff 100644
--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -436,7 +436,8 @@
{
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 fb05f6a..8c5504c 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -115,7 +115,8 @@
{
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 @@
{
key->virtual = 1;
key->dev = dm_thin_dev_id(td);
- key->block = b;
+ key->block_begin = b;
+ key->block_end = b + 1ULL;
}
/*----------------------------------------------------------------*/