lib/blob: Set thin_provision back when sync fails on snapshot creation

When creating snapshot, 'original' blob will end up being a thin provisioned clone.
Before that first thin_provisioned 'newblob' is created during this process.

If the first md sync for 'newblob' fails, it means that only valid references to
clusters are still only present in 'original' blob. The 'newblob' can be safely
cleaned up.

Unfortunetly 'newblob' inherited some of 'original' blob properties before sync.
Cluster maps were already swaped in current cleanup code. But during blob close
of 'newblob' - persist blob code expects clusters to be 0 only for thin_provisioned
blobs. If original blob was thick, then it triggers an assert within persist code.

This patch makes sure to set thin_provision to 'newblob', to align with its creation.

Added asserts to verify that clusters maps are 0's, which should be the case
as I/O to origblob is frozen.

Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Change-Id: I5420617792aefe8a3ef4e5989b2056504cdd1850
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1394
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Tomasz Zawadzki 2020-02-21 08:03:39 -05:00
parent 68d3bb2de4
commit 9dd7c9f18b

View File

@ -5397,6 +5397,16 @@ _spdk_bs_snapshot_newblob_sync_cpl(void *cb_arg, int bserrno)
if (bserrno != 0) {
/* return cluster map back to original */
_spdk_bs_snapshot_swap_cluster_maps(newblob, origblob);
/* Newblob md sync failed. Valid clusters are only present in origblob.
* Since I/O is frozen on origblob, not changes to zeroed out cluster map should have occured.
* Newblob needs to be reverted to thin_provisioned state at creation to properly close. */
_spdk_blob_set_thin_provision(newblob);
assert(spdk_mem_all_zero(newblob->active.clusters,
newblob->active.num_clusters * sizeof(*newblob->active.clusters)));
assert(spdk_mem_all_zero(newblob->active.extent_pages,
newblob->active.num_extent_pages * sizeof(*newblob->active.extent_pages)));
_spdk_bs_clone_snapshot_newblob_cleanup(ctx, bserrno);
return;
}