Commit fa09c9ac authored by vagrant's avatar vagrant Committed by Tomasz Zawadzki
Browse files

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: default avatarAlex 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: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
parent 5de98ef8
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -6333,7 +6333,6 @@ bs_inflate_blob_done(struct spdk_clone_snapshot_ctx *ctx)
	if (ctx->allocate_all) {
		/* remove thin provisioning */
		bs_blob_list_remove(_blob);
		blob_remove_xattr(_blob, BLOB_SNAPSHOT, true);
		_blob->invalid_flags = _blob->invalid_flags & ~SPDK_BLOB_THIN_PROV;
		_blob->back_bs_dev->destroy(_blob->back_bs_dev);
		_blob->back_bs_dev = NULL;
@@ -6348,7 +6347,6 @@ bs_inflate_blob_done(struct spdk_clone_snapshot_ctx *ctx)
		}

		bs_blob_list_remove(_blob);
		blob_remove_xattr(_blob, BLOB_SNAPSHOT, true);
		_blob->parent_id = SPDK_BLOBID_INVALID;
		_blob->back_bs_dev->destroy(_blob->back_bs_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 */
	_blob->md_ro = false;
	blob_remove_xattr(_blob, BLOB_SNAPSHOT, true);
	_blob->state = SPDK_BLOB_STATE_DIRTY;

	spdk_blob_sync_md(_blob, bs_clone_snapshot_origblob_cleanup, ctx);
+58 −50
Original line number Diff line number Diff line
@@ -7246,6 +7246,7 @@ blob_decouple_snapshot(void)
	spdk_blob_id blobid, snapshotid;
	uint64_t cluster;

	for (int delete_snapshot_first = 0; delete_snapshot_first <= 1; delete_snapshot_first++) {
		channel = spdk_bs_alloc_io_channel(bs);
		SPDK_CU_ASSERT_FATAL(channel != NULL);

@@ -7302,11 +7303,18 @@ blob_decouple_snapshot(void)

		spdk_bs_free_io_channel(channel);

		if (delete_snapshot_first) {
			ut_blob_close_and_delete(bs, snapshot2);
			ut_blob_close_and_delete(bs, snapshot1);
			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();
	}
}

static void
suite_bs_setup(void)