diff options
Diffstat (limited to 'drivers/md/dm-era-target.c')
| -rw-r--r-- | drivers/md/dm-era-target.c | 163 |
1 files changed, 84 insertions, 79 deletions
diff --git a/drivers/md/dm-era-target.c b/drivers/md/dm-era-target.c index e92c1afc3677..9c84e9d13eca 100644 --- a/drivers/md/dm-era-target.c +++ b/drivers/md/dm-era-target.c @@ -22,9 +22,11 @@ #define INVALID_WRITESET_ROOT SUPERBLOCK_LOCATION #define MIN_BLOCK_SIZE 8 -/*---------------------------------------------------------------- +/* + *-------------------------------------------------------------- * Writeset - *--------------------------------------------------------------*/ + *-------------------------------------------------------------- + */ struct writeset_metadata { uint32_t nr_bits; dm_block_t root; @@ -51,7 +53,7 @@ static void writeset_free(struct writeset *ws) } static int setup_on_disk_bitset(struct dm_disk_bitset *info, - unsigned nr_bits, dm_block_t *root) + unsigned int nr_bits, dm_block_t *root) { int r; @@ -62,7 +64,7 @@ static int setup_on_disk_bitset(struct dm_disk_bitset *info, return dm_bitset_resize(info, *root, 0, nr_bits, false, root); } -static size_t bitset_size(unsigned nr_bits) +static size_t bitset_size(unsigned int nr_bits) { return sizeof(unsigned long) * dm_div_up(nr_bits, BITS_PER_LONG); } @@ -110,13 +112,14 @@ static int writeset_marked_on_disk(struct dm_disk_bitset *info, struct writeset_metadata *m, dm_block_t block, bool *result) { + int r; dm_block_t old = m->root; /* * The bitset was flushed when it was archived, so we know there'll * be no change to the root. */ - int r = dm_bitset_test_bit(info, m->root, block, &m->root, result); + r = dm_bitset_test_bit(info, m->root, block, &m->root, result); if (r) { DMERR("%s: dm_bitset_test_bit failed", __func__); return r; @@ -148,9 +151,11 @@ static int writeset_test_and_set(struct dm_disk_bitset *info, return 1; } -/*---------------------------------------------------------------- +/* + *-------------------------------------------------------------- * On disk metadata layout - *--------------------------------------------------------------*/ + *-------------------------------------------------------------- + */ #define SPACE_MAP_ROOT_SIZE 128 #define UUID_LEN 16 @@ -186,10 +191,12 @@ struct superblock_disk { __le64 metadata_snap; } __packed; -/*---------------------------------------------------------------- +/* + *-------------------------------------------------------------- * Superblock validation - *--------------------------------------------------------------*/ -static void sb_prepare_for_write(struct dm_block_validator *v, + *-------------------------------------------------------------- + */ +static void sb_prepare_for_write(const struct dm_block_validator *v, struct dm_block *b, size_t sb_block_size) { @@ -204,6 +211,7 @@ static void sb_prepare_for_write(struct dm_block_validator *v, static int check_metadata_version(struct superblock_disk *disk) { uint32_t metadata_version = le32_to_cpu(disk->version); + if (metadata_version < MIN_ERA_VERSION || metadata_version > MAX_ERA_VERSION) { DMERR("Era metadata version %u found, but only versions between %u and %u supported.", metadata_version, MIN_ERA_VERSION, MAX_ERA_VERSION); @@ -213,7 +221,7 @@ static int check_metadata_version(struct superblock_disk *disk) return 0; } -static int sb_check(struct dm_block_validator *v, +static int sb_check(const struct dm_block_validator *v, struct dm_block *b, size_t sb_block_size) { @@ -221,15 +229,15 @@ static int sb_check(struct dm_block_validator *v, __le32 csum_le; if (dm_block_location(b) != le64_to_cpu(disk->blocknr)) { - DMERR("sb_check failed: blocknr %llu: wanted %llu", - le64_to_cpu(disk->blocknr), + DMERR("%s failed: blocknr %llu: wanted %llu", + __func__, le64_to_cpu(disk->blocknr), (unsigned long long)dm_block_location(b)); return -ENOTBLK; } if (le64_to_cpu(disk->magic) != SUPERBLOCK_MAGIC) { - DMERR("sb_check failed: magic %llu: wanted %llu", - le64_to_cpu(disk->magic), + DMERR("%s failed: magic %llu: wanted %llu", + __func__, le64_to_cpu(disk->magic), (unsigned long long) SUPERBLOCK_MAGIC); return -EILSEQ; } @@ -238,23 +246,25 @@ static int sb_check(struct dm_block_validator *v, sb_block_size - sizeof(__le32), SUPERBLOCK_CSUM_XOR)); if (csum_le != disk->csum) { - DMERR("sb_check failed: csum %u: wanted %u", - le32_to_cpu(csum_le), le32_to_cpu(disk->csum)); + DMERR("%s failed: csum %u: wanted %u", + __func__, le32_to_cpu(csum_le), le32_to_cpu(disk->csum)); return -EILSEQ; } return check_metadata_version(disk); } -static struct dm_block_validator sb_validator = { +static const struct dm_block_validator sb_validator = { .name = "superblock", .prepare_for_write = sb_prepare_for_write, .check = sb_check }; -/*---------------------------------------------------------------- +/* + *-------------------------------------------------------------- * Low level metadata handling - *--------------------------------------------------------------*/ + *-------------------------------------------------------------- + */ #define DM_ERA_METADATA_BLOCK_SIZE 4096 #define ERA_MAX_CONCURRENT_LOCKS 5 @@ -323,10 +333,10 @@ static int superblock_lock(struct era_metadata *md, static int superblock_all_zeroes(struct dm_block_manager *bm, bool *result) { int r; - unsigned i; + unsigned int i; struct dm_block *b; __le64 *data_le, zero = cpu_to_le64(0); - unsigned sb_block_size = dm_bm_block_size(bm) / sizeof(__le64); + unsigned int sb_block_size = dm_bm_block_size(bm) / sizeof(__le64); /* * We can't use a validator here - it may be all zeroes. @@ -363,12 +373,12 @@ static void ws_unpack(const struct writeset_disk *disk, struct writeset_metadata core->root = le64_to_cpu(disk->root); } -static void ws_inc(void *context, const void *value, unsigned count) +static void ws_inc(void *context, const void *value, unsigned int count) { struct era_metadata *md = context; struct writeset_disk ws_d; dm_block_t b; - unsigned i; + unsigned int i; for (i = 0; i < count; i++) { memcpy(&ws_d, value + (i * sizeof(ws_d)), sizeof(ws_d)); @@ -377,12 +387,12 @@ static void ws_inc(void *context, const void *value, unsigned count) } } -static void ws_dec(void *context, const void *value, unsigned count) +static void ws_dec(void *context, const void *value, unsigned int count) { struct era_metadata *md = context; struct writeset_disk ws_d; dm_block_t b; - unsigned i; + unsigned int i; for (i = 0; i < count; i++) { memcpy(&ws_d, value + (i * sizeof(ws_d)), sizeof(ws_d)); @@ -401,6 +411,7 @@ static int ws_eq(void *context, const void *value1, const void *value2) static void setup_writeset_tree_info(struct era_metadata *md) { struct dm_btree_value_type *vt = &md->writeset_tree_info.value_type; + md->writeset_tree_info.tm = md->tm; md->writeset_tree_info.levels = 1; vt->context = md; @@ -411,9 +422,9 @@ static void setup_writeset_tree_info(struct era_metadata *md) } static void setup_era_array_info(struct era_metadata *md) - { struct dm_btree_value_type vt; + vt.context = NULL; vt.size = sizeof(__le32); vt.inc = NULL; @@ -658,21 +669,23 @@ static void swap_writeset(struct era_metadata *md, struct writeset *new_writeset synchronize_rcu(); } -/*---------------------------------------------------------------- +/* + *------------------------------------------------------------------------ * Writesets get 'digested' into the main era array. * * We're using a coroutine here so the worker thread can do the digestion, * thus avoiding synchronisation of the metadata. Digesting a whole * writeset in one go would cause too much latency. - *--------------------------------------------------------------*/ + *------------------------------------------------------------------------ + */ struct digest { uint32_t era; - unsigned nr_bits, current_bit; + unsigned int nr_bits, current_bit; struct writeset_metadata writeset; __le32 value; struct dm_disk_bitset info; - int (*step)(struct era_metadata *, struct digest *); + int (*step)(struct era_metadata *md, struct digest *d); }; static int metadata_digest_lookup_writeset(struct era_metadata *md, @@ -702,7 +715,7 @@ static int metadata_digest_transcribe_writeset(struct era_metadata *md, { int r; bool marked; - unsigned b, e = min(d->current_bit + INSERTS_PER_STEP, d->nr_bits); + unsigned int b, e = min(d->current_bit + INSERTS_PER_STEP, d->nr_bits); for (b = d->current_bit; b < e; b++) { r = writeset_marked_on_disk(&d->info, &d->writeset, b, &marked); @@ -784,10 +797,12 @@ static int metadata_digest_start(struct era_metadata *md, struct digest *d) return 0; } -/*---------------------------------------------------------------- - * High level metadata interface. Target methods should use these, and not - * the lower level ones. - *--------------------------------------------------------------*/ +/* + *----------------------------------------------------------------- + * High level metadata interface. Target methods should use these, + * and not the lower level ones. + *----------------------------------------------------------------- + */ static struct era_metadata *metadata_open(struct block_device *bdev, sector_t block_size, bool may_format) @@ -1181,17 +1196,19 @@ struct era { struct rpc { struct list_head list; - int (*fn0)(struct era_metadata *); - int (*fn1)(struct era_metadata *, void *); + int (*fn0)(struct era_metadata *md); + int (*fn1)(struct era_metadata *md, void *ref); void *arg; int result; struct completion complete; }; -/*---------------------------------------------------------------- +/* + *--------------------------------------------------------------- * Remapping. - *---------------------------------------------------------------*/ + *--------------------------------------------------------------- + */ static bool block_size_is_power_of_two(struct era *era) { return era->sectors_per_block_shift >= 0; @@ -1214,9 +1231,11 @@ static void remap_to_origin(struct era *era, struct bio *bio) bio_set_dev(bio, era->origin_dev->bdev); } -/*---------------------------------------------------------------- +/* + *-------------------------------------------------------------- * Worker thread - *--------------------------------------------------------------*/ + *-------------------------------------------------------------- + */ static void wake_worker(struct era *era) { if (!atomic_read(&era->suspended)) @@ -1253,8 +1272,7 @@ static void process_deferred_bios(struct era *era) bio_list_init(&marked_bios); spin_lock(&era->deferred_lock); - bio_list_merge(&deferred_bios, &era->deferred_bios); - bio_list_init(&era->deferred_bios); + bio_list_merge_init(&deferred_bios, &era->deferred_bios); spin_unlock(&era->deferred_lock); if (bio_list_empty(&deferred_bios)) @@ -1372,9 +1390,10 @@ static int perform_rpc(struct era *era, struct rpc *rpc) return rpc->result; } -static int in_worker0(struct era *era, int (*fn)(struct era_metadata *)) +static int in_worker0(struct era *era, int (*fn)(struct era_metadata *md)) { struct rpc rpc; + rpc.fn0 = fn; rpc.fn1 = NULL; @@ -1382,9 +1401,10 @@ static int in_worker0(struct era *era, int (*fn)(struct era_metadata *)) } static int in_worker1(struct era *era, - int (*fn)(struct era_metadata *, void *), void *arg) + int (*fn)(struct era_metadata *md, void *ref), void *arg) { struct rpc rpc; + rpc.fn0 = NULL; rpc.fn1 = fn; rpc.arg = arg; @@ -1403,9 +1423,11 @@ static void stop_worker(struct era *era) drain_workqueue(era->wq); } -/*---------------------------------------------------------------- +/* + *-------------------------------------------------------------- * Target methods - *--------------------------------------------------------------*/ + *-------------------------------------------------------------- + */ static void era_destroy(struct era *era) { if (era->md) @@ -1439,7 +1461,7 @@ static bool valid_block_size(dm_block_t block_size) /* * <metadata dev> <data dev> <data block size (sectors)> */ -static int era_ctr(struct dm_target *ti, unsigned argc, char **argv) +static int era_ctr(struct dm_target *ti, unsigned int argc, char **argv) { int r; char dummy; @@ -1459,14 +1481,16 @@ static int era_ctr(struct dm_target *ti, unsigned argc, char **argv) era->ti = ti; - r = dm_get_device(ti, argv[0], FMODE_READ | FMODE_WRITE, &era->metadata_dev); + r = dm_get_device(ti, argv[0], BLK_OPEN_READ | BLK_OPEN_WRITE, + &era->metadata_dev); if (r) { ti->error = "Error opening metadata device"; era_destroy(era); return -EINVAL; } - r = dm_get_device(ti, argv[1], FMODE_READ | FMODE_WRITE, &era->origin_dev); + r = dm_get_device(ti, argv[1], BLK_OPEN_READ | BLK_OPEN_WRITE, + &era->origin_dev); if (r) { ti->error = "Error opening data device"; era_destroy(era); @@ -1618,7 +1642,7 @@ static int era_preresume(struct dm_target *ti) * <current era> <held metadata root | '-'> */ static void era_status(struct dm_target *ti, status_type_t type, - unsigned status_flags, char *result, unsigned maxlen) + unsigned int status_flags, char *result, unsigned int maxlen) { int r; struct era *era = ti->private; @@ -1633,10 +1657,10 @@ static void era_status(struct dm_target *ti, status_type_t type, goto err; DMEMIT("%u %llu/%llu %u", - (unsigned) (DM_ERA_METADATA_BLOCK_SIZE >> SECTOR_SHIFT), + (unsigned int) (DM_ERA_METADATA_BLOCK_SIZE >> SECTOR_SHIFT), (unsigned long long) stats.used, (unsigned long long) stats.total, - (unsigned) stats.era); + (unsigned int) stats.era); if (stats.snap != SUPERBLOCK_LOCATION) DMEMIT(" %llu", stats.snap); @@ -1662,8 +1686,8 @@ err: DMEMIT("Error"); } -static int era_message(struct dm_target *ti, unsigned argc, char **argv, - char *result, unsigned maxlen) +static int era_message(struct dm_target *ti, unsigned int argc, char **argv, + char *result, unsigned int maxlen) { struct era *era = ti->private; @@ -1694,6 +1718,7 @@ static int era_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) { struct era *era = ti->private; + return fn(ti, era->origin_dev, 0, get_dev_size(era->origin_dev), data); } @@ -1708,8 +1733,8 @@ static void era_io_hints(struct dm_target *ti, struct queue_limits *limits) */ if (io_opt_sectors < era->sectors_per_block || do_div(io_opt_sectors, era->sectors_per_block)) { - blk_limits_io_min(limits, 0); - blk_limits_io_opt(limits, era->sectors_per_block << SECTOR_SHIFT); + limits->io_min = 0; + limits->io_opt = era->sectors_per_block << SECTOR_SHIFT; } } @@ -1729,27 +1754,7 @@ static struct target_type era_target = { .iterate_devices = era_iterate_devices, .io_hints = era_io_hints }; - -static int __init dm_era_init(void) -{ - int r; - - r = dm_register_target(&era_target); - if (r) { - DMERR("era target registration failed: %d", r); - return r; - } - - return 0; -} - -static void __exit dm_era_exit(void) -{ - dm_unregister_target(&era_target); -} - -module_init(dm_era_init); -module_exit(dm_era_exit); +module_dm(era); MODULE_DESCRIPTION(DM_NAME " era target"); MODULE_AUTHOR("Joe Thornber <ejt@redhat.com>"); |
