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>
This commit is contained in:
Родитель
f1afb36a61
Коммит
5f274d8865
|
@ -95,10 +95,10 @@ static int cmp_keys(struct dm_cell_key *lhs,
|
||||||
if (lhs->dev > rhs->dev)
|
if (lhs->dev > rhs->dev)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (lhs->block < rhs->block)
|
if (lhs->block_end <= rhs->block_begin)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (lhs->block > rhs->block)
|
if (lhs->block_begin >= rhs->block_end)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -23,11 +23,14 @@
|
||||||
*/
|
*/
|
||||||
struct dm_bio_prison;
|
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 {
|
struct dm_cell_key {
|
||||||
int virtual;
|
int virtual;
|
||||||
dm_thin_id dev;
|
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);
|
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
|
* Returns 1 if pre-existing cell returned, zero if new cell created using
|
||||||
* @cell_prealloc.
|
* @cell_prealloc.
|
||||||
|
@ -70,7 +73,8 @@ int dm_get_cell(struct dm_bio_prison *prison,
|
||||||
struct dm_bio_prison_cell **cell_result);
|
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.
|
* Returns 1 if the cell was already held, 0 if @inmate is the new holder.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -436,7 +436,8 @@ static void build_key(dm_oblock_t oblock, struct dm_cell_key *key)
|
||||||
{
|
{
|
||||||
key->virtual = 0;
|
key->virtual = 0;
|
||||||
key->dev = 0;
|
key->dev = 0;
|
||||||
key->block = from_oblock(oblock);
|
key->block_begin = from_oblock(oblock);
|
||||||
|
key->block_end = key->block_begin + 1ULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -115,7 +115,8 @@ static void build_data_key(struct dm_thin_device *td,
|
||||||
{
|
{
|
||||||
key->virtual = 0;
|
key->virtual = 0;
|
||||||
key->dev = dm_thin_dev_id(td);
|
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,
|
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->virtual = 1;
|
||||||
key->dev = dm_thin_dev_id(td);
|
key->dev = dm_thin_dev_id(td);
|
||||||
key->block = b;
|
key->block_begin = b;
|
||||||
|
key->block_end = b + 1ULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------*/
|
/*----------------------------------------------------------------*/
|
||||||
|
|
Загрузка…
Ссылка в новой задаче