dm bio prison: introduce support for locking ranges of blocks
authorJoe Thornber <ejt@redhat.com>
Wed, 17 Sep 2014 09:17:39 +0000 (10:17 +0100)
committerMike Snitzer <snitzer@redhat.com>
Mon, 10 Nov 2014 20:25:30 +0000 (15:25 -0500)
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>
drivers/md/dm-bio-prison.c
drivers/md/dm-bio-prison.h
drivers/md/dm-cache-target.c
drivers/md/dm-thin.c

index bbe22a5dc06bfdd4f98dfcb84259f600dc06b8fd..be065300e93c8d16d2a5cc5c7753224932e27836 100644 (file)
@@ -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;
index b03988667740e6cb3e8d68d61bd82c01cebff622..74cf01144b1fc9c12777f669e1cf6e5e23422d44 100644 (file)
  */
 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.
  */
index 69de8b43ca1287c3568e8cfad90e9ea37aecf246..890e2fff4074593380824332326d00e537dd1ae0 100644 (file)
@@ -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;
 }
 
 /*
index fb05f6a4bbfd67d8d4ebeae9ceb6bcdcb7dd47a9..8c5504c0e8943be13f06fec2b511c68d61d4a719 100644 (file)
@@ -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;
 }
 
 /*----------------------------------------------------------------*/