The commit is pushed to "branch-rh7-3.10.0-327.36.1.vz7.19.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git after rh7-3.10.0-327.36.1.vz7.19.3 ------> commit f15082476d7879d16faf25e0c76ed332ebebba14 Author: Maxim Patlasov <mpatla...@virtuozzo.com> Date: Mon Oct 24 16:43:16 2016 +0400
md: add support for dm-crypted ploops Previos patch adding support for dm-crypt ploops naively suggested that every time we build dm-crypt device, crypt_ctr() is called, and vice versa - every time we dismantle it, crypt_dtr() is called. But in practice, crypt_ctr/dtr is called more than once because md->map is RCU-protected. For example, during resize, new dm target is constructed and registetred in md->map, then the former md->map is released. Only dm-crypt knows how to find underlaying ploop device. That's why the patch implements ploop_modify methods of dm-crypt target. And only general dm code (dm.c, dm-table.c, dm-ioctl.c and friends) knows which instance of dm-target is actual and which is obsoleted. That's why the patch orchestrates calling this new method from general code, close to __bind/__unbind managing md->map pointer. https://jira.sw.ru/browse/PSBM-53386 Signed-off-by: Maxim Patlasov <mpatla...@virtuozzo.com> Reviewed-by: Andrey Ryabinin <aryabi...@virtuozzo.com> --- drivers/md/dm-crypt.c | 25 ++++++++++++++++++++----- drivers/md/dm-ioctl.c | 3 +++ drivers/md/dm-table.c | 15 +++++++++++++++ drivers/md/dm.c | 4 +++- drivers/md/dm.h | 1 + include/linux/device-mapper.h | 9 +++++++++ 6 files changed, 51 insertions(+), 6 deletions(-) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index bcdd794..41019b8 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -1647,10 +1647,8 @@ static void crypt_dtr(struct dm_target *ti) if (cc->iv_gen_ops && cc->iv_gen_ops->dtr) cc->iv_gen_ops->dtr(cc); - if (cc->dev) { - ploop_set_dm_crypt_bdev(cc->dev->bdev, NULL); + if (cc->dev) dm_put_device(ti, cc->dev); - } kzfree(cc->cipher); kzfree(cc->cipher_string); @@ -1919,8 +1917,6 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad; } - ploop_set_dm_crypt_bdev(cc->dev->bdev, dm_md_get_bdev(dm_table_get_md(ti->table))); - if (sscanf(argv[4], "%llu%c", &tmpll, &dummy) != 1) { ti->error = "Invalid device sector"; goto bad; @@ -2173,6 +2169,24 @@ static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits) limits->max_segment_size = PAGE_SIZE; } +static void crypt_ploop_modify(struct dm_target *ti, int action) +{ + struct crypt_config *cc = ti->private; + + if (cc && cc->dev) + switch (action) { + case DM_PLOOP_ATTACH: + ploop_set_dm_crypt_bdev(cc->dev->bdev, + dm_md_get_bdev(dm_table_get_md(ti->table))); + break; + case DM_PLOOP_DETACH: + ploop_set_dm_crypt_bdev(cc->dev->bdev, NULL); + break; + default: + BUG(); + } +} + static struct target_type crypt_target = { .name = "crypt", .version = {1, 14, 1}, @@ -2188,6 +2202,7 @@ static struct target_type crypt_target = { .merge = crypt_merge, .iterate_devices = crypt_iterate_devices, .io_hints = crypt_io_hints, + .ploop_modify = crypt_ploop_modify, }; static int __init dm_crypt_init(void) diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 0fe4233..fd4b2cc 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -1029,6 +1029,9 @@ static int do_resume(struct dm_ioctl *param) return PTR_ERR(old_map); } + dm_table_ploop_modify(old_map, DM_PLOOP_DETACH); + dm_table_ploop_modify(new_map, DM_PLOOP_ATTACH); + if (dm_table_get_mode(new_map) & FMODE_WRITE) set_disk_ro(dm_disk(md), 0); else diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 16ba55a..e910fbe 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -1705,3 +1705,18 @@ void dm_table_run_md_queue_async(struct dm_table *t) } EXPORT_SYMBOL(dm_table_run_md_queue_async); +void dm_table_ploop_modify(struct dm_table *t, int action) +{ + unsigned int i; + + if (!t) + return; + + /* attach or detach the targets */ + for (i = 0; i < t->num_targets; i++) { + struct dm_target *tgt = t->targets + i; + + if (tgt->type->ploop_modify) + tgt->type->ploop_modify(tgt, action); + } +} diff --git a/drivers/md/dm.c b/drivers/md/dm.c index a7993cf..210221e 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -3088,7 +3088,9 @@ static void __dm_destroy(struct mapped_device *md, bool wait) dm_device_name(md), atomic_read(&md->holders)); dm_sysfs_exit(md); - dm_table_destroy(__unbind(md)); + map = __unbind(md); + dm_table_ploop_modify(map, DM_PLOOP_DETACH); + dm_table_destroy(map); free_dev(md); } diff --git a/drivers/md/dm.h b/drivers/md/dm.h index 815afa5..7330c89 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -76,6 +76,7 @@ bool dm_table_request_based(struct dm_table *t); bool dm_table_mq_request_based(struct dm_table *t); void dm_table_free_md_mempools(struct dm_table *t); struct dm_md_mempools *dm_table_get_md_mempools(struct dm_table *t); +void dm_table_ploop_modify(struct dm_table *t, int action); int dm_queue_merge_is_compulsory(struct request_queue *q); diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 0e7360c..bea9446 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -112,6 +112,14 @@ typedef int (*dm_iterate_devices_fn) (struct dm_target *ti, typedef void (*dm_io_hints_fn) (struct dm_target *ti, struct queue_limits *limits); +typedef void (*dm_ploop_modify_fn) (struct dm_target *ti, int action); + +/* "action" arg of dm_ploop_modify_fn */ +enum { + DM_PLOOP_ATTACH, + DM_PLOOP_DETACH, +}; + /* * Returns: * 0: The target can handle the next I/O immediately. @@ -164,6 +172,7 @@ struct target_type { dm_busy_fn busy; dm_iterate_devices_fn iterate_devices; dm_io_hints_fn io_hints; + dm_ploop_modify_fn ploop_modify; /* For internal device-mapper use. */ struct list_head list; _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel