3.16.83-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Nikos Tsironis <ntsironis@xxxxxxxxxxx> commit ecda7c0280e6b3398459dc589b9a41c1adb45529 upstream. Add support for one pre-commit callback which is run right before the metadata are committed. This allows the thin provisioning target to run a callback before the metadata are committed and is required by the next commit. Signed-off-by: Nikos Tsironis <ntsironis@xxxxxxxxxxx> Acked-by: Joe Thornber <ejt@xxxxxxxxxx> Signed-off-by: Mike Snitzer <snitzer@xxxxxxxxxx> [bwh: Backported to 3.16: - Open-code pmd_write_{lock_in_core,unlock}() - Adjust context] Signed-off-by: Ben Hutchings <ben@xxxxxxxxxxxxxxx> --- drivers/md/dm-thin-metadata.c | 29 +++++++++++++++++++++++++++++ drivers/md/dm-thin-metadata.h | 7 +++++++ 2 files changed, 36 insertions(+) --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c @@ -198,6 +198,15 @@ struct dm_pool_metadata { bool fail_io:1; /* + * Pre-commit callback. + * + * This allows the thin provisioning target to run a callback before + * the metadata are committed. + */ + dm_pool_pre_commit_fn pre_commit_fn; + void *pre_commit_context; + + /* * Reading the space map roots can fail, so we read it into these * buffers before the superblock is locked and updated. */ @@ -784,6 +793,14 @@ static int __commit_transaction(struct d */ BUILD_BUG_ON(sizeof(struct thin_disk_superblock) > 512); + if (pmd->pre_commit_fn) { + r = pmd->pre_commit_fn(pmd->pre_commit_context); + if (r < 0) { + DMERR("pre-commit callback failed"); + return r; + } + } + r = __write_changed_details(pmd); if (r < 0) return r; @@ -844,6 +861,8 @@ struct dm_pool_metadata *dm_pool_metadat pmd->fail_io = false; pmd->bdev = bdev; pmd->data_block_size = data_block_size; + pmd->pre_commit_fn = NULL; + pmd->pre_commit_context = NULL; r = __create_persistent_data_objects(pmd, format_device); if (r) { @@ -1789,6 +1808,16 @@ int dm_pool_register_metadata_threshold( return r; } +void dm_pool_register_pre_commit_callback(struct dm_pool_metadata *pmd, + dm_pool_pre_commit_fn fn, + void *context) +{ + down_write(&pmd->root_lock); + pmd->pre_commit_fn = fn; + pmd->pre_commit_context = context; + up_write(&pmd->root_lock); +} + int dm_pool_metadata_set_needs_check(struct dm_pool_metadata *pmd) { int r; --- a/drivers/md/dm-thin-metadata.h +++ b/drivers/md/dm-thin-metadata.h @@ -213,6 +213,13 @@ int dm_pool_register_metadata_threshold( int dm_pool_metadata_set_needs_check(struct dm_pool_metadata *pmd); bool dm_pool_metadata_needs_check(struct dm_pool_metadata *pmd); +/* Pre-commit callback */ +typedef int (*dm_pool_pre_commit_fn)(void *context); + +void dm_pool_register_pre_commit_callback(struct dm_pool_metadata *pmd, + dm_pool_pre_commit_fn fn, + void *context); + /*----------------------------------------------------------------*/ #endif