From 9dd7c9f18ba44141632418c1cf572f288b8cfec5 Mon Sep 17 00:00:00 2001 From: Tomasz Zawadzki Date: Fri, 21 Feb 2020 08:03:39 -0500 Subject: [PATCH] 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 Change-Id: I5420617792aefe8a3ef4e5989b2056504cdd1850 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1394 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- lib/blob/blobstore.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/blob/blobstore.c b/lib/blob/blobstore.c index b2f4ea4c7..aaa640c0f 100644 --- a/lib/blob/blobstore.c +++ b/lib/blob/blobstore.c @@ -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; }