From ea69d6d6cc107dd4c39905cbadf6bdf48bc40e48 Mon Sep 17 00:00:00 2001 From: paul luse Date: Wed, 23 Oct 2019 17:34:49 +0000 Subject: [PATCH] lib/blob: store clear_method in per blob metadata Accept a clear method option on blob create by adding clear_method to the opts structure passed in to _spdk_bs_create_blob(). Store these 2 bits in md_ro_flags so that earlier versions without an understanding of these bits can not alter metadata. The new metadata values will be used later in the series. Signed-off-by: paul luse Change-Id: I5440645ca20b426778d13b2e544b65dc2b3b83c7 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/472204 Tested-by: SPDK CI Jenkins Community-CI: SPDK CI Jenkins Reviewed-by: Ben Walker Reviewed-by: Jim Harris --- include/spdk/blob.h | 1 + lib/blob/blobstore.c | 15 +++++++++++++++ lib/blob/blobstore.h | 5 ++++- lib/lvol/lvol.c | 1 + test/unit/lib/blob/blob.c/blob_ut.c | 6 +++++- 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/spdk/blob.h b/include/spdk/blob.h index d496ad09d..d5ddfee67 100644 --- a/include/spdk/blob.h +++ b/include/spdk/blob.h @@ -410,6 +410,7 @@ struct spdk_blob_xattr_opts { struct spdk_blob_opts { uint64_t num_clusters; bool thin_provision; + enum blob_clear_method clear_method; struct spdk_blob_xattr_opts xattrs; }; diff --git a/lib/blob/blobstore.c b/lib/blob/blobstore.c index 15deadf53..18f82fa10 100644 --- a/lib/blob/blobstore.c +++ b/lib/blob/blobstore.c @@ -165,6 +165,7 @@ spdk_blob_opts_init(struct spdk_blob_opts *opts) { opts->num_clusters = 0; opts->thin_provision = false; + opts->clear_method = BLOB_CLEAR_WITH_DEFAULT; _spdk_blob_xattrs_init(&opts->xattrs); } @@ -2712,6 +2713,15 @@ _spdk_blob_set_thin_provision(struct spdk_blob *blob) blob->state = SPDK_BLOB_STATE_DIRTY; } +static void +_spdk_blob_set_clear_method(struct spdk_blob *blob, enum blob_clear_method clear_method) +{ + _spdk_blob_verify_md_op(blob); + blob->clear_method = clear_method; + blob->md_ro_flags |= (clear_method << SPDK_BLOB_CLEAR_METHOD_SHIFT); + blob->state = SPDK_BLOB_STATE_DIRTY; +} + static void _spdk_bs_load_iter(void *arg, struct spdk_blob *blob, int bserrno); static void @@ -4345,6 +4355,8 @@ _spdk_bs_create_blob(struct spdk_blob_store *bs, _spdk_blob_set_thin_provision(blob); } + _spdk_blob_set_clear_method(blob, opts->clear_method); + rc = _spdk_blob_resize(blob, opts->num_clusters); if (rc < 0) { _spdk_blob_free(blob); @@ -4621,6 +4633,9 @@ _spdk_bs_snapshot_freeze_cpl(void *cb_arg, int rc) /* swap cluster maps */ _spdk_bs_snapshot_swap_cluster_maps(newblob, origblob); + /* Set the clear method on the new blob to match the original. */ + _spdk_blob_set_clear_method(newblob, origblob->clear_method); + /* sync snapshot metadata */ spdk_blob_sync_md(newblob, _spdk_bs_snapshot_newblob_sync_cpl, ctx); } diff --git a/lib/blob/blobstore.h b/lib/blob/blobstore.h index 234c952c5..c45e7fcda 100644 --- a/lib/blob/blobstore.h +++ b/lib/blob/blobstore.h @@ -274,7 +274,10 @@ struct spdk_blob_md_descriptor_extent_rle { #define SPDK_BLOB_READ_ONLY (1ULL << 0) #define SPDK_BLOB_DATA_RO_FLAGS_MASK SPDK_BLOB_READ_ONLY -#define SPDK_BLOB_MD_RO_FLAGS_MASK 0 + +#define SPDK_BLOB_CLEAR_METHOD_SHIFT 0 +#define SPDK_BLOB_CLEAR_METHOD (3ULL << SPDK_BLOB_CLEAR_METHOD_SHIFT) +#define SPDK_BLOB_MD_RO_FLAGS_MASK SPDK_BLOB_CLEAR_METHOD struct spdk_blob_md_descriptor_flags { uint8_t type; diff --git a/lib/lvol/lvol.c b/lib/lvol/lvol.c index 17e003753..1038e4fb1 100644 --- a/lib/lvol/lvol.c +++ b/lib/lvol/lvol.c @@ -1066,6 +1066,7 @@ spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, uint64_t sz, spdk_blob_opts_init(&opts); opts.thin_provision = thin_provision; opts.num_clusters = num_clusters; + opts.clear_method = lvol->clear_method; opts.xattrs.count = SPDK_COUNTOF(xattr_names); opts.xattrs.names = xattr_names; opts.xattrs.ctx = lvol; diff --git a/test/unit/lib/blob/blob.c/blob_ut.c b/test/unit/lib/blob/blob.c/blob_ut.c index ec2f4636d..ceffa8fc2 100644 --- a/test/unit/lib/blob/blob.c/blob_ut.c +++ b/test/unit/lib/blob/blob.c/blob_ut.c @@ -4010,10 +4010,12 @@ blob_flags(void) spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; struct spdk_bs_opts opts; + struct spdk_blob_opts blob_opts; int rc; dev = init_dev(); spdk_bs_opts_init(&opts); + spdk_blob_opts_init(&blob_opts); /* Initialize a new blob store */ spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); @@ -4034,7 +4036,8 @@ blob_flags(void) CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); blobid_data_ro = g_blobid; - spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); + blob_opts.clear_method = BLOB_CLEAR_WITH_WRITE_ZEROES; + spdk_bs_create_blob_ext(g_bs, &blob_opts, blob_op_with_id_complete, NULL); poll_threads(); CU_ASSERT(g_bserrno == 0); CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); @@ -4057,6 +4060,7 @@ blob_flags(void) CU_ASSERT(g_bserrno == 0); SPDK_CU_ASSERT_FATAL(g_blob != NULL); blob_md_ro = g_blob; + CU_ASSERT((blob_md_ro->md_ro_flags & SPDK_BLOB_MD_RO_FLAGS_MASK) == BLOB_CLEAR_WITH_WRITE_ZEROES); /* Change the size of blob_data_ro to check if flags are serialized * when blob has non zero number of extents */