From fe0344ec7490ce349dd87d4fc7c571602c463ea3 Mon Sep 17 00:00:00 2001 From: Mike Gerdts Date: Fri, 27 Jan 2023 21:47:48 -0600 Subject: [PATCH] lvol: pass non-NULL lvs and lvol to dev_create If an lvol is opened by way of spdk_bs_blob_open() or spontaneously due to blobstore activity (e.g. the blobstore is loading), the esnap_bs_dev_create callback is called with blob_ctx equal to NULL. Under ideal circumstances, blob_ctx refers to the lvol that is being opened. With this change, a NULL blob_ctx triggers lvs_esnap_bs_dev_create() to look through the lvstore's volumes to find the one that uses a blob id that matches the id of the blob that is passed in. Now, lvol library consumers that need to support snapshots can count on both bs_ctx (lvs) and blob_ctx (lvol) to be non-NULL. Signed-off-by: Mike Gerdts Change-Id: Iaaa9cc27664e28e54f0fbd75afe1d6ffbad92580 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16588 Reviewed-by: Jim Harris Community-CI: Mellanox Build Bot Reviewed-by: Ben Walker Tested-by: SPDK CI Jenkins --- lib/lvol/lvol.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/lib/lvol/lvol.c b/lib/lvol/lvol.c index 62ade59a1..832eacc75 100644 --- a/lib/lvol/lvol.c +++ b/lib/lvol/lvol.c @@ -1696,6 +1696,19 @@ spdk_lvs_grow(struct spdk_bs_dev *bs_dev, spdk_lvs_op_with_handle_complete cb_fn spdk_bs_grow(bs_dev, &opts, lvs_load_cb, req); } +static struct spdk_lvol * +lvs_get_lvol_by_blob_id(struct spdk_lvol_store *lvs, spdk_blob_id blob_id) +{ + struct spdk_lvol *lvol; + + TAILQ_FOREACH(lvol, &lvs->lvols, link) { + if (lvol->blob_id == blob_id) { + return lvol; + } + } + return NULL; +} + static int lvs_esnap_bs_dev_create(void *bs_ctx, void *blob_ctx, struct spdk_blob *blob, const void *esnap_id, uint32_t id_len, @@ -1726,5 +1739,21 @@ lvs_esnap_bs_dev_create(void *bs_ctx, void *blob_ctx, struct spdk_blob *blob, return 0; } + if (lvol == NULL) { + spdk_blob_id blob_id = spdk_blob_get_id(blob); + + /* + * If spdk_bs_blob_open() is used instead of spdk_bs_blob_open_ext() the lvol will + * not have been passed in. The same is true if the open happens spontaneously due + * to blobstore activity. + */ + lvol = lvs_get_lvol_by_blob_id(lvs, blob_id); + if (lvol == NULL) { + SPDK_ERRLOG("lvstore %s: no lvol for blob 0x%" PRIx64 "\n", + lvs->name, blob_id); + return -ENODEV; + } + } + return lvs->esnap_bs_dev_create(lvs, lvol, blob, esnap_id, id_len, bs_dev); }