11 #include <linux/ctype.h>
13 #include <linux/module.h>
14 #include <linux/slab.h>
19 #define DM_MSG_PREFIX "region hash"
62 struct dm_dirty_log *
log;
129 return dm_rh_sector_to_region(rh, bio->bi_sector - rh->
target_begin);
135 return reg->
rh->context;
155 #define RH_HASH_MULT 2654435387U
156 #define RH_HASH_SHIFT 12
158 #define MIN_REGIONS 64
176 max_buckets = nr_regions >> 6;
177 for (nr_buckets = 128
u; nr_buckets < max_buckets; nr_buckets <<= 1)
183 DMERR(
"unable to allocate region hash memory");
197 rh->
mask = nr_buckets - 1;
205 DMERR(
"unable to allocate region hash bucket memory");
211 INIT_LIST_HEAD(rh->
buckets + i);
276 if (reg->
key == region)
284 list_add(®->hash_list, rh->buckets + rh_hash(rh, reg->key));
295 nreg->
state = rh->
log->type->in_sync(rh->
log, region, 1) ?
299 INIT_LIST_HEAD(&nreg->
list);
304 reg = __rh_lookup(rh, region);
309 __rh_insert(rh, nreg);
327 reg = __rh_lookup(rh, region);
330 reg = __rh_alloc(rh, region);
343 reg = __rh_lookup(rh, region);
353 r = rh->
log->type->in_sync(rh->
log, region, may_block);
363 static void complete_resync_work(
struct dm_region *reg,
int success)
367 rh->
log->type->set_region_sync(rh->
log, reg->
key, success);
397 struct dm_dirty_log *
log = rh->
log;
411 log->type->set_region_sync(log, region, 0);
414 reg = __rh_find(rh, region);
435 complete_resync_work(reg, 0);
483 rh->
log->type->clear_region(rh->
log, reg->
key);
484 complete_resync_work(reg, 1);
489 complete_resync_work(reg, errors_handled ? 0 : 1);
494 rh->
log->type->clear_region(rh->
log, reg->
key);
498 rh->
log->type->flush(rh->
log);
507 reg = __rh_find(rh, region);
514 list_del_init(®->
list);
517 rh->
log->type->mark_region(rh->
log, reg->
key);
529 for (bio = bios->head; bio; bio = bio->bi_next) {
544 reg = __rh_lookup(rh, region);
595 r = rh->
log->type->get_resync_work(rh->
log, ®ion);
604 reg = __rh_find(rh, region);
612 list_del_init(®->
list);
628 if (__rh_recovery_prepare(rh) <= 0) {
652 list_del_init(®->
list);
666 list_add(®->
list, ®->
rh->recovered_regions);
668 list_add(®->
list, ®->
rh->failed_recovered_regions);
685 return rh->
log->type->flush(rh->
log);