blobstore: fix parent for snapshot of clone
When snapshot is created from a clone, clones parent is not inherited. This patch also updates unit tests covering this case. Change-Id: I42eb00fe2f33504c5b5c5beded20c4ea65eaff67 Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com> Reviewed-on: https://review.gerrithub.io/414804 Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
parent
9d04d0efd5
commit
826aac635e
@ -4303,6 +4303,8 @@ _spdk_bs_snapshot_newblob_sync_cpl(void *cb_arg, int bserrno)
|
||||
_spdk_bs_clone_snapshot_newblob_cleanup(ctx, bserrno);
|
||||
return;
|
||||
}
|
||||
|
||||
_spdk_bs_blob_list_remove(origblob);
|
||||
origblob->parent_id = newblob->id;
|
||||
|
||||
/* Create new back_bs_dev for snapshot */
|
||||
@ -4331,6 +4333,7 @@ _spdk_bs_snapshot_freeze_cpl(void *cb_arg, int rc)
|
||||
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;
|
||||
int bserrno;
|
||||
|
||||
if (rc != 0) {
|
||||
_spdk_bs_clone_snapshot_newblob_cleanup(ctx, rc);
|
||||
@ -4344,6 +4347,18 @@ _spdk_bs_snapshot_freeze_cpl(void *cb_arg, int rc)
|
||||
/* Set invalid flags from origblob */
|
||||
newblob->invalid_flags = origblob->invalid_flags;
|
||||
|
||||
/* inherit parent from original blob if set */
|
||||
newblob->parent_id = origblob->parent_id;
|
||||
if (origblob->parent_id != SPDK_BLOBID_INVALID) {
|
||||
/* Set internal xattr for snapshot id */
|
||||
bserrno = _spdk_blob_set_xattr(newblob, BLOB_SNAPSHOT,
|
||||
&origblob->parent_id, sizeof(spdk_blob_id), true);
|
||||
if (bserrno != 0) {
|
||||
_spdk_bs_clone_snapshot_newblob_cleanup(ctx, bserrno);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy cluster map to snapshot */
|
||||
memcpy(newblob->active.clusters, origblob->active.clusters,
|
||||
origblob->active.num_clusters * sizeof(origblob->active.clusters));
|
||||
|
@ -4088,13 +4088,13 @@ blob_inflate_rw(void)
|
||||
/**
|
||||
* Snapshot-clones relation test
|
||||
*
|
||||
* snapshot
|
||||
* |
|
||||
* +----+----+
|
||||
* | |
|
||||
* blob clone
|
||||
* |
|
||||
* clone2
|
||||
* snapshot
|
||||
* |
|
||||
* +-----+-----+
|
||||
* | |
|
||||
* blob(ro) snapshot2
|
||||
* | |
|
||||
* clone2 clone
|
||||
*/
|
||||
static void
|
||||
blob_relations(void)
|
||||
@ -4103,8 +4103,8 @@ blob_relations(void)
|
||||
struct spdk_bs_dev *dev;
|
||||
struct spdk_bs_opts bs_opts;
|
||||
struct spdk_blob_opts opts;
|
||||
struct spdk_blob *blob, *snapshot, *clone, *clone2;
|
||||
spdk_blob_id blobid, cloneid, snapshotid, cloneid2;
|
||||
struct spdk_blob *blob, *snapshot, *snapshot2, *clone, *clone2;
|
||||
spdk_blob_id blobid, cloneid, snapshotid, cloneid2, snapshotid2;
|
||||
int rc;
|
||||
size_t count;
|
||||
spdk_blob_id ids[10];
|
||||
@ -4139,6 +4139,7 @@ blob_relations(void)
|
||||
CU_ASSERT(!spdk_blob_is_thin_provisioned(blob));
|
||||
|
||||
/* blob should not have underlying snapshot nor clones */
|
||||
CU_ASSERT(blob->parent_id == SPDK_BLOBID_INVALID);
|
||||
CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
|
||||
count = SPDK_COUNTOF(ids);
|
||||
rc = spdk_blob_get_clones(bs, blobid, ids, &count);
|
||||
@ -4161,6 +4162,7 @@ blob_relations(void)
|
||||
CU_ASSERT(spdk_blob_is_read_only(snapshot));
|
||||
CU_ASSERT(spdk_blob_is_snapshot(snapshot));
|
||||
CU_ASSERT(!spdk_blob_is_clone(snapshot));
|
||||
CU_ASSERT(snapshot->parent_id == SPDK_BLOBID_INVALID);
|
||||
CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID);
|
||||
|
||||
/* Check if original blob is converted to the clone of snapshot */
|
||||
@ -4168,7 +4170,7 @@ blob_relations(void)
|
||||
CU_ASSERT(!spdk_blob_is_snapshot(blob));
|
||||
CU_ASSERT(spdk_blob_is_clone(blob));
|
||||
CU_ASSERT(spdk_blob_is_thin_provisioned(blob));
|
||||
|
||||
CU_ASSERT(blob->parent_id == snapshotid);
|
||||
CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
|
||||
|
||||
count = SPDK_COUNTOF(ids);
|
||||
@ -4194,7 +4196,7 @@ blob_relations(void)
|
||||
CU_ASSERT(!spdk_blob_is_snapshot(clone));
|
||||
CU_ASSERT(spdk_blob_is_clone(clone));
|
||||
CU_ASSERT(spdk_blob_is_thin_provisioned(clone));
|
||||
|
||||
CU_ASSERT(clone->parent_id == snapshotid);
|
||||
CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid);
|
||||
|
||||
count = SPDK_COUNTOF(ids);
|
||||
@ -4210,7 +4212,41 @@ blob_relations(void)
|
||||
CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid);
|
||||
|
||||
|
||||
/* 4. Try to create clone from read only blob */
|
||||
/* 4. Create snapshot of the clone */
|
||||
|
||||
spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
|
||||
snapshotid2 = g_blobid;
|
||||
|
||||
spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_blob != NULL);
|
||||
snapshot2 = g_blob;
|
||||
|
||||
CU_ASSERT(spdk_blob_is_read_only(snapshot2));
|
||||
CU_ASSERT(spdk_blob_is_snapshot(snapshot2));
|
||||
CU_ASSERT(spdk_blob_is_clone(snapshot2));
|
||||
CU_ASSERT(snapshot2->parent_id == snapshotid);
|
||||
CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid);
|
||||
|
||||
/* Check if clone is converted to the clone of snapshot2 and snapshot2
|
||||
* is a child of snapshot */
|
||||
CU_ASSERT(!spdk_blob_is_read_only(clone));
|
||||
CU_ASSERT(!spdk_blob_is_snapshot(clone));
|
||||
CU_ASSERT(spdk_blob_is_clone(clone));
|
||||
CU_ASSERT(spdk_blob_is_thin_provisioned(clone));
|
||||
CU_ASSERT(clone->parent_id == snapshotid2);
|
||||
CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2);
|
||||
|
||||
count = SPDK_COUNTOF(ids);
|
||||
rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(count == 1);
|
||||
CU_ASSERT(ids[0] == cloneid);
|
||||
|
||||
|
||||
/* 5. Try to create clone from read only blob */
|
||||
|
||||
/* Mark blob as read only */
|
||||
spdk_blob_set_read_only(blob);
|
||||
@ -4262,10 +4298,16 @@ blob_relations(void)
|
||||
spdk_blob_close(snapshot, blob_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
|
||||
spdk_blob_close(snapshot2, blob_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
|
||||
/* Try to delete snapshot with created clones */
|
||||
spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno != 0);
|
||||
|
||||
spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno != 0);
|
||||
|
||||
spdk_bs_unload(bs, bs_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
g_bs = NULL;
|
||||
@ -4303,7 +4345,7 @@ blob_relations(void)
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(count == 2);
|
||||
CU_ASSERT(ids[0] == blobid || ids[1] == blobid);
|
||||
CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid);
|
||||
CU_ASSERT(ids[0] == snapshotid2 || ids[1] == snapshotid2);
|
||||
|
||||
/* blob */
|
||||
CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
|
||||
@ -4314,12 +4356,20 @@ blob_relations(void)
|
||||
CU_ASSERT(ids[0] == cloneid2);
|
||||
|
||||
/* clone */
|
||||
CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid);
|
||||
CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2);
|
||||
count = SPDK_COUNTOF(ids);
|
||||
rc = spdk_blob_get_clones(bs, cloneid, ids, &count);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(count == 0);
|
||||
|
||||
/* snapshot2 */
|
||||
CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid);
|
||||
count = SPDK_COUNTOF(ids);
|
||||
rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(count == 1);
|
||||
CU_ASSERT(ids[0] == cloneid);
|
||||
|
||||
/* clone2 */
|
||||
CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid);
|
||||
count = SPDK_COUNTOF(ids);
|
||||
@ -4327,15 +4377,23 @@ blob_relations(void)
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(count == 0);
|
||||
|
||||
/* Try to delete all blobs */
|
||||
spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
/* Try to delete all blobs in the worse possible order */
|
||||
|
||||
spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno != 0);
|
||||
|
||||
spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno != 0);
|
||||
|
||||
spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
|
||||
spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
|
||||
/* Try to delete snapshot with clones */
|
||||
spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno != 0);
|
||||
|
||||
/* Try to delete ro blob with clones */
|
||||
spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno != 0);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user