Commit 52c67d41 authored by Nikos Tsironis's avatar Nikos Tsironis Committed by Mike Snitzer

dm clone: add bucket_lock_irq/bucket_unlock_irq helpers

Introduce bucket_lock_irq() and bucket_unlock_irq() helpers and use them
in places where it is known that interrupts are enabled.
Signed-off-by: default avatarNikos Tsironis <ntsironis@arrikto.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent 6ca43ed8
...@@ -552,6 +552,12 @@ struct hash_table_bucket { ...@@ -552,6 +552,12 @@ struct hash_table_bucket {
#define bucket_unlock_irqrestore(bucket, flags) \ #define bucket_unlock_irqrestore(bucket, flags) \
spin_unlock_irqrestore(&(bucket)->lock, flags) spin_unlock_irqrestore(&(bucket)->lock, flags)
#define bucket_lock_irq(bucket) \
spin_lock_irq(&(bucket)->lock)
#define bucket_unlock_irq(bucket) \
spin_unlock_irq(&(bucket)->lock)
static int hash_table_init(struct clone *clone) static int hash_table_init(struct clone *clone)
{ {
unsigned int i, sz; unsigned int i, sz;
...@@ -849,7 +855,6 @@ static void hydration_overwrite(struct dm_clone_region_hydration *hd, struct bio ...@@ -849,7 +855,6 @@ static void hydration_overwrite(struct dm_clone_region_hydration *hd, struct bio
*/ */
static void hydrate_bio_region(struct clone *clone, struct bio *bio) static void hydrate_bio_region(struct clone *clone, struct bio *bio)
{ {
unsigned long flags;
unsigned long region_nr; unsigned long region_nr;
struct hash_table_bucket *bucket; struct hash_table_bucket *bucket;
struct dm_clone_region_hydration *hd, *hd2; struct dm_clone_region_hydration *hd, *hd2;
...@@ -857,19 +862,19 @@ static void hydrate_bio_region(struct clone *clone, struct bio *bio) ...@@ -857,19 +862,19 @@ static void hydrate_bio_region(struct clone *clone, struct bio *bio)
region_nr = bio_to_region(clone, bio); region_nr = bio_to_region(clone, bio);
bucket = get_hash_table_bucket(clone, region_nr); bucket = get_hash_table_bucket(clone, region_nr);
bucket_lock_irqsave(bucket, flags); bucket_lock_irq(bucket);
hd = __hash_find(bucket, region_nr); hd = __hash_find(bucket, region_nr);
if (hd) { if (hd) {
/* Someone else is hydrating the region */ /* Someone else is hydrating the region */
bio_list_add(&hd->deferred_bios, bio); bio_list_add(&hd->deferred_bios, bio);
bucket_unlock_irqrestore(bucket, flags); bucket_unlock_irq(bucket);
return; return;
} }
if (dm_clone_is_region_hydrated(clone->cmd, region_nr)) { if (dm_clone_is_region_hydrated(clone->cmd, region_nr)) {
/* The region has been hydrated */ /* The region has been hydrated */
bucket_unlock_irqrestore(bucket, flags); bucket_unlock_irq(bucket);
issue_bio(clone, bio); issue_bio(clone, bio);
return; return;
} }
...@@ -878,16 +883,16 @@ static void hydrate_bio_region(struct clone *clone, struct bio *bio) ...@@ -878,16 +883,16 @@ static void hydrate_bio_region(struct clone *clone, struct bio *bio)
* We must allocate a hydration descriptor and start the hydration of * We must allocate a hydration descriptor and start the hydration of
* the corresponding region. * the corresponding region.
*/ */
bucket_unlock_irqrestore(bucket, flags); bucket_unlock_irq(bucket);
hd = alloc_hydration(clone); hd = alloc_hydration(clone);
hydration_init(hd, region_nr); hydration_init(hd, region_nr);
bucket_lock_irqsave(bucket, flags); bucket_lock_irq(bucket);
/* Check if the region has been hydrated in the meantime. */ /* Check if the region has been hydrated in the meantime. */
if (dm_clone_is_region_hydrated(clone->cmd, region_nr)) { if (dm_clone_is_region_hydrated(clone->cmd, region_nr)) {
bucket_unlock_irqrestore(bucket, flags); bucket_unlock_irq(bucket);
free_hydration(hd); free_hydration(hd);
issue_bio(clone, bio); issue_bio(clone, bio);
return; return;
...@@ -897,7 +902,7 @@ static void hydrate_bio_region(struct clone *clone, struct bio *bio) ...@@ -897,7 +902,7 @@ static void hydrate_bio_region(struct clone *clone, struct bio *bio)
if (hd2 != hd) { if (hd2 != hd) {
/* Someone else started the region's hydration. */ /* Someone else started the region's hydration. */
bio_list_add(&hd2->deferred_bios, bio); bio_list_add(&hd2->deferred_bios, bio);
bucket_unlock_irqrestore(bucket, flags); bucket_unlock_irq(bucket);
free_hydration(hd); free_hydration(hd);
return; return;
} }
...@@ -909,7 +914,7 @@ static void hydrate_bio_region(struct clone *clone, struct bio *bio) ...@@ -909,7 +914,7 @@ static void hydrate_bio_region(struct clone *clone, struct bio *bio)
*/ */
if (unlikely(get_clone_mode(clone) >= CM_READ_ONLY)) { if (unlikely(get_clone_mode(clone) >= CM_READ_ONLY)) {
hlist_del(&hd->h); hlist_del(&hd->h);
bucket_unlock_irqrestore(bucket, flags); bucket_unlock_irq(bucket);
free_hydration(hd); free_hydration(hd);
bio_io_error(bio); bio_io_error(bio);
return; return;
...@@ -923,11 +928,11 @@ static void hydrate_bio_region(struct clone *clone, struct bio *bio) ...@@ -923,11 +928,11 @@ static void hydrate_bio_region(struct clone *clone, struct bio *bio)
* to the destination device. * to the destination device.
*/ */
if (is_overwrite_bio(clone, bio)) { if (is_overwrite_bio(clone, bio)) {
bucket_unlock_irqrestore(bucket, flags); bucket_unlock_irq(bucket);
hydration_overwrite(hd, bio); hydration_overwrite(hd, bio);
} else { } else {
bio_list_add(&hd->deferred_bios, bio); bio_list_add(&hd->deferred_bios, bio);
bucket_unlock_irqrestore(bucket, flags); bucket_unlock_irq(bucket);
hydration_copy(hd, 1); hydration_copy(hd, 1);
} }
} }
...@@ -994,7 +999,6 @@ static unsigned long __start_next_hydration(struct clone *clone, ...@@ -994,7 +999,6 @@ static unsigned long __start_next_hydration(struct clone *clone,
unsigned long offset, unsigned long offset,
struct batch_info *batch) struct batch_info *batch)
{ {
unsigned long flags;
struct hash_table_bucket *bucket; struct hash_table_bucket *bucket;
struct dm_clone_region_hydration *hd; struct dm_clone_region_hydration *hd;
unsigned long nr_regions = clone->nr_regions; unsigned long nr_regions = clone->nr_regions;
...@@ -1008,13 +1012,13 @@ static unsigned long __start_next_hydration(struct clone *clone, ...@@ -1008,13 +1012,13 @@ static unsigned long __start_next_hydration(struct clone *clone,
break; break;
bucket = get_hash_table_bucket(clone, offset); bucket = get_hash_table_bucket(clone, offset);
bucket_lock_irqsave(bucket, flags); bucket_lock_irq(bucket);
if (!dm_clone_is_region_hydrated(clone->cmd, offset) && if (!dm_clone_is_region_hydrated(clone->cmd, offset) &&
!__hash_find(bucket, offset)) { !__hash_find(bucket, offset)) {
hydration_init(hd, offset); hydration_init(hd, offset);
__insert_region_hydration(bucket, hd); __insert_region_hydration(bucket, hd);
bucket_unlock_irqrestore(bucket, flags); bucket_unlock_irq(bucket);
/* Batch hydration */ /* Batch hydration */
__batch_hydration(batch, hd); __batch_hydration(batch, hd);
...@@ -1022,7 +1026,7 @@ static unsigned long __start_next_hydration(struct clone *clone, ...@@ -1022,7 +1026,7 @@ static unsigned long __start_next_hydration(struct clone *clone,
return (offset + 1); return (offset + 1);
} }
bucket_unlock_irqrestore(bucket, flags); bucket_unlock_irq(bucket);
} while (++offset < nr_regions); } while (++offset < nr_regions);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment