lib/blob: Fix deleting a snapshot after decoupling it from its parent

When decoupling a snapshot from its parent, we need to clear its parent.
So we should remove the xattr BLOB_SNAPSHOT. Modifying the xattrs of a blob
only works if its metadata are not in read-only mode.
By default, a snapshot is in read-only mode so this operation fails. When we
later want to delete the snapshot, we will see that it has a parent, so we will
try to remove the snapshot from its parent's clones list. This will cause a
crash.
The fix is to remove the BLOB_SNAPSHOT xattr only after setting the snapshot's
metadata in rw mode.

Signed-off-by: Alex Michon <amichon@kalrayinc.com>
Change-Id: I80efa6dd3dcb38b4c738ce2e97aa2ffc281cefa5
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13723
Community-CI: Mellanox Build Bot
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
This commit is contained in:
vagrant 2022-07-20 09:37:02 +00:00 committed by Tomasz Zawadzki
parent 5de98ef86c
commit fa09c9ac9b
2 changed files with 60 additions and 53 deletions

View File

@ -6333,7 +6333,6 @@ bs_inflate_blob_done(struct spdk_clone_snapshot_ctx *ctx)
if (ctx->allocate_all) { if (ctx->allocate_all) {
/* remove thin provisioning */ /* remove thin provisioning */
bs_blob_list_remove(_blob); bs_blob_list_remove(_blob);
blob_remove_xattr(_blob, BLOB_SNAPSHOT, true);
_blob->invalid_flags = _blob->invalid_flags & ~SPDK_BLOB_THIN_PROV; _blob->invalid_flags = _blob->invalid_flags & ~SPDK_BLOB_THIN_PROV;
_blob->back_bs_dev->destroy(_blob->back_bs_dev); _blob->back_bs_dev->destroy(_blob->back_bs_dev);
_blob->back_bs_dev = NULL; _blob->back_bs_dev = NULL;
@ -6348,7 +6347,6 @@ bs_inflate_blob_done(struct spdk_clone_snapshot_ctx *ctx)
} }
bs_blob_list_remove(_blob); bs_blob_list_remove(_blob);
blob_remove_xattr(_blob, BLOB_SNAPSHOT, true);
_blob->parent_id = SPDK_BLOBID_INVALID; _blob->parent_id = SPDK_BLOBID_INVALID;
_blob->back_bs_dev->destroy(_blob->back_bs_dev); _blob->back_bs_dev->destroy(_blob->back_bs_dev);
_blob->back_bs_dev = bs_create_zeroes_dev(); _blob->back_bs_dev = bs_create_zeroes_dev();
@ -6356,6 +6354,7 @@ bs_inflate_blob_done(struct spdk_clone_snapshot_ctx *ctx)
/* Temporarily override md_ro flag for MD modification */ /* Temporarily override md_ro flag for MD modification */
_blob->md_ro = false; _blob->md_ro = false;
blob_remove_xattr(_blob, BLOB_SNAPSHOT, true);
_blob->state = SPDK_BLOB_STATE_DIRTY; _blob->state = SPDK_BLOB_STATE_DIRTY;
spdk_blob_sync_md(_blob, bs_clone_snapshot_origblob_cleanup, ctx); spdk_blob_sync_md(_blob, bs_clone_snapshot_origblob_cleanup, ctx);

View File

@ -7246,6 +7246,7 @@ blob_decouple_snapshot(void)
spdk_blob_id blobid, snapshotid; spdk_blob_id blobid, snapshotid;
uint64_t cluster; uint64_t cluster;
for (int delete_snapshot_first = 0; delete_snapshot_first <= 1; delete_snapshot_first++) {
channel = spdk_bs_alloc_io_channel(bs); channel = spdk_bs_alloc_io_channel(bs);
SPDK_CU_ASSERT_FATAL(channel != NULL); SPDK_CU_ASSERT_FATAL(channel != NULL);
@ -7302,10 +7303,17 @@ blob_decouple_snapshot(void)
spdk_bs_free_io_channel(channel); spdk_bs_free_io_channel(channel);
if (delete_snapshot_first) {
ut_blob_close_and_delete(bs, snapshot2); ut_blob_close_and_delete(bs, snapshot2);
ut_blob_close_and_delete(bs, snapshot1); ut_blob_close_and_delete(bs, snapshot1);
ut_blob_close_and_delete(bs, blob); ut_blob_close_and_delete(bs, blob);
} else {
ut_blob_close_and_delete(bs, blob);
ut_blob_close_and_delete(bs, snapshot2);
ut_blob_close_and_delete(bs, snapshot1);
}
poll_threads(); poll_threads();
}
} }
static void static void