Commit ecda7c02 authored by Nikos Tsironis's avatar Nikos Tsironis Committed by Mike Snitzer
Browse files

dm thin metadata: Add support for a pre-commit callback



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.

Cc: stable@vger.kernel.org
Signed-off-by: default avatarNikos Tsironis <ntsironis@arrikto.com>
Acked-by: default avatarJoe Thornber <ejt@redhat.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent 8b3fd1f5
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -188,6 +188,15 @@ struct dm_pool_metadata {
	unsigned long flags;
	sector_t data_block_size;

	/*
	 * 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;

	/*
	 * We reserve a section of the metadata for commit overhead.
	 * All reported space does *not* include this.
@@ -826,6 +835,14 @@ static int __commit_transaction(struct dm_pool_metadata *pmd)
	if (unlikely(!pmd->in_service))
		return 0;

	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;
@@ -892,6 +909,8 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
	pmd->in_service = 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) {
@@ -2044,6 +2063,16 @@ int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd,
	return r;
}

void dm_pool_register_pre_commit_callback(struct dm_pool_metadata *pmd,
					  dm_pool_pre_commit_fn fn,
					  void *context)
{
	pmd_write_lock_in_core(pmd);
	pmd->pre_commit_fn = fn;
	pmd->pre_commit_context = context;
	pmd_write_unlock(pmd);
}

int dm_pool_metadata_set_needs_check(struct dm_pool_metadata *pmd)
{
	int r = -EINVAL;
+7 −0
Original line number Diff line number Diff line
@@ -230,6 +230,13 @@ bool dm_pool_metadata_needs_check(struct dm_pool_metadata *pmd);
 */
void dm_pool_issue_prefetches(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