aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-clone-target.c
diff options
context:
space:
mode:
authorNikos Tsironis <ntsironis@arrikto.com>2019-12-04 16:06:53 +0200
committerMike Snitzer <snitzer@redhat.com>2019-12-05 15:27:54 -0500
commit8fdbfe8d1690e8a38d497d83a30607d0d90cc15a (patch)
tree4e46c590e6dc293b0167b51c063025e3288d6678 /drivers/md/dm-clone-target.c
parentdm clone metadata: Track exact changes per transaction (diff)
downloadlinux-dev-8fdbfe8d1690e8a38d497d83a30607d0d90cc15a.tar.xz
linux-dev-8fdbfe8d1690e8a38d497d83a30607d0d90cc15a.zip
dm clone metadata: Use a two phase commit
Split the metadata commit in two parts: 1. dm_clone_metadata_pre_commit(): Prepare the current transaction for committing. After this is called, all subsequent metadata updates, done through either dm_clone_set_region_hydrated() or dm_clone_cond_set_range(), will be part of the next transaction. 2. dm_clone_metadata_commit(): Actually commit the current transaction to disk and start a new transaction. This is required by the following commit. It allows dm-clone to flush the destination device after step (1) to ensure that all freshly hydrated regions, for which we are updating the metadata, are properly written to non-volatile storage and won't be lost in case of a crash. Fixes: 7431b7835f55 ("dm: add clone target") Cc: stable@vger.kernel.org # v5.4+ Signed-off-by: Nikos Tsironis <ntsironis@arrikto.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/dm-clone-target.c')
-rw-r--r--drivers/md/dm-clone-target.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/md/dm-clone-target.c b/drivers/md/dm-clone-target.c
index b3d89072d21c..613c913c296c 100644
--- a/drivers/md/dm-clone-target.c
+++ b/drivers/md/dm-clone-target.c
@@ -1122,8 +1122,13 @@ static int commit_metadata(struct clone *clone)
goto out;
}
- r = dm_clone_metadata_commit(clone->cmd);
+ r = dm_clone_metadata_pre_commit(clone->cmd);
+ if (unlikely(r)) {
+ __metadata_operation_failed(clone, "dm_clone_metadata_pre_commit", r);
+ goto out;
+ }
+ r = dm_clone_metadata_commit(clone->cmd);
if (unlikely(r)) {
__metadata_operation_failed(clone, "dm_clone_metadata_commit", r);
goto out;