diff --git a/lib/blob/blobstore.c b/lib/blob/blobstore.c index 7f1e8401c..44ef86333 100644 --- a/lib/blob/blobstore.c +++ b/lib/blob/blobstore.c @@ -4344,13 +4344,25 @@ _spdk_bs_clone_snapshot_newblob_cleanup(void *cb_arg, int bserrno) /* START spdk_bs_create_snapshot */ +static void +_spdk_bs_snapshot_swap_cluster_maps(struct spdk_blob *blob1, struct spdk_blob *blob2) +{ + uint64_t *cluster_temp; + + cluster_temp = blob1->active.clusters; + blob1->active.clusters = blob2->active.clusters; + blob2->active.clusters = cluster_temp; +} + static void _spdk_bs_snapshot_origblob_sync_cpl(void *cb_arg, int bserrno) { struct spdk_clone_snapshot_ctx *ctx = (struct spdk_clone_snapshot_ctx *)cb_arg; + struct spdk_blob *origblob = ctx->original.blob; struct spdk_blob *newblob = ctx->new.blob; if (bserrno != 0) { + _spdk_bs_snapshot_swap_cluster_maps(newblob, origblob); _spdk_bs_clone_snapshot_newblob_cleanup(ctx, bserrno); return; } @@ -4378,6 +4390,8 @@ _spdk_bs_snapshot_newblob_sync_cpl(void *cb_arg, int bserrno) struct spdk_blob *newblob = ctx->new.blob; if (bserrno != 0) { + /* return cluster map back to original */ + _spdk_bs_snapshot_swap_cluster_maps(newblob, origblob); _spdk_bs_clone_snapshot_newblob_cleanup(ctx, bserrno); return; } @@ -4385,6 +4399,8 @@ _spdk_bs_snapshot_newblob_sync_cpl(void *cb_arg, int bserrno) /* Set internal xattr for snapshot id */ bserrno = _spdk_blob_set_xattr(origblob, BLOB_SNAPSHOT, &newblob->id, sizeof(spdk_blob_id), true); if (bserrno != 0) { + /* return cluster map back to original */ + _spdk_bs_snapshot_swap_cluster_maps(newblob, origblob); _spdk_bs_clone_snapshot_newblob_cleanup(ctx, bserrno); return; } @@ -4395,6 +4411,8 @@ _spdk_bs_snapshot_newblob_sync_cpl(void *cb_arg, int bserrno) /* Create new back_bs_dev for snapshot */ origblob->back_bs_dev = spdk_bs_create_blob_bs_dev(newblob); if (origblob->back_bs_dev == NULL) { + /* return cluster map back to original */ + _spdk_bs_snapshot_swap_cluster_maps(newblob, origblob); _spdk_bs_clone_snapshot_newblob_cleanup(ctx, -EINVAL); return; } @@ -4404,10 +4422,6 @@ _spdk_bs_snapshot_newblob_sync_cpl(void *cb_arg, int bserrno) _spdk_bs_blob_list_add(newblob); - /* Zero out origblob cluster map */ - memset(origblob->active.clusters, 0, - origblob->active.num_clusters * sizeof(origblob->active.clusters)); - /* sync clone metadata */ spdk_blob_sync_md(origblob, _spdk_bs_snapshot_origblob_sync_cpl, ctx); } @@ -4444,9 +4458,8 @@ _spdk_bs_snapshot_freeze_cpl(void *cb_arg, int rc) } } - /* Copy cluster map to snapshot */ - memcpy(newblob->active.clusters, origblob->active.clusters, - origblob->active.num_clusters * sizeof(origblob->active.clusters)); + /* swap cluster maps */ + _spdk_bs_snapshot_swap_cluster_maps(newblob, origblob); /* sync snapshot metadata */ spdk_blob_sync_md(newblob, _spdk_bs_snapshot_newblob_sync_cpl, ctx); @@ -4466,6 +4479,10 @@ _spdk_bs_snapshot_newblob_open_cpl(void *cb_arg, struct spdk_blob *_blob, int bs ctx->new.blob = newblob; + /* Zero out newblob cluster map */ + memset(newblob->active.clusters, 0, + newblob->active.num_clusters * sizeof(newblob->active.clusters)); + _spdk_blob_freeze_io(origblob, _spdk_bs_snapshot_freeze_cpl, ctx); }