diff --git a/include/spdk/blob_bdev.h b/include/spdk/blob_bdev.h index 7193b10a1..0dd122709 100644 --- a/include/spdk/blob_bdev.h +++ b/include/spdk/blob_bdev.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright (C) 2017 Intel Corporation. * All rights reserved. - * Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ /** \file @@ -66,6 +66,10 @@ int spdk_bdev_create_bs_dev(const char *bdev_name, bool write, /** * Claim the bdev module for the given blobstore. * + * If bs_dev was opened read-write using spdk_bdev_create_bs_dev_ext(), a read-write-once claim is + * taken. If bs_dev was opened read-only using spdk_bdev_create_bs_dev_ro(), a read-only-many claim + * is taken. + * * \param bs_dev Blobstore block device. * \param module Bdev module to claim. * diff --git a/module/blob/bdev/blob_bdev.c b/module/blob/bdev/blob_bdev.c index 0a6689357..2494755c5 100644 --- a/module/blob/bdev/blob_bdev.c +++ b/module/blob/bdev/blob_bdev.c @@ -18,6 +18,7 @@ struct blob_bdev { struct spdk_bs_dev bs_dev; struct spdk_bdev *bdev; struct spdk_bdev_desc *desc; + bool write; }; struct blob_resubmit { @@ -325,11 +326,14 @@ bdev_blob_resubmit(void *arg) int spdk_bs_bdev_claim(struct spdk_bs_dev *bs_dev, struct spdk_bdev_module *module) { - struct spdk_bdev_desc *desc = __get_desc(bs_dev); + struct blob_bdev *blob_bdev = (struct blob_bdev *)bs_dev; + struct spdk_bdev_desc *desc = blob_bdev->desc; + enum spdk_bdev_claim_type claim_type; int rc; - rc = spdk_bdev_module_claim_bdev_desc(desc, SPDK_BDEV_CLAIM_READ_MANY_WRITE_ONE, - NULL, module); + claim_type = blob_bdev->write ? SPDK_BDEV_CLAIM_READ_MANY_WRITE_ONE : + SPDK_BDEV_CLAIM_READ_MANY_WRITE_NONE; + rc = spdk_bdev_module_claim_bdev_desc(desc, claim_type, NULL, module); if (rc != 0) { SPDK_ERRLOG("could not claim bs dev\n"); return rc; @@ -442,6 +446,7 @@ spdk_bdev_create_bs_dev(const char *bdev_name, bool write, blob_bdev_init(b, desc); *bs_dev = &b->bs_dev; + b->write = write; return 0; } diff --git a/test/unit/lib/blob/blob_bdev.c/blob_bdev_ut.c b/test/unit/lib/blob/blob_bdev.c/blob_bdev_ut.c index 2243bde4e..625d5122f 100644 --- a/test/unit/lib/blob/blob_bdev.c/blob_bdev_ut.c +++ b/test/unit/lib/blob/blob_bdev.c/blob_bdev_ut.c @@ -315,6 +315,53 @@ claim_bs_dev(void) g_bdev = NULL; } +static void +claim_bs_dev_ro(void) +{ + struct spdk_bdev bdev; + struct spdk_bs_dev *bs_dev = NULL, *bs_dev2 = NULL; + struct blob_bdev *blob_bdev; + int rc; + + init_bdev(&bdev, "bdev0", 16); + g_bdev = &bdev; + + rc = spdk_bdev_create_bs_dev("bdev0", false, NULL, 0, NULL, NULL, &bs_dev); + CU_ASSERT(rc == 0); + SPDK_CU_ASSERT_FATAL(bs_dev != NULL); + + blob_bdev = (struct blob_bdev *)bs_dev; + CU_ASSERT(blob_bdev->desc->claim_type == SPDK_BDEV_CLAIM_NONE); + CU_ASSERT(bdev.claim_type == SPDK_BDEV_CLAIM_NONE); + CU_ASSERT(!blob_bdev->desc->write); + + /* Can get an shared reader claim */ + rc = spdk_bs_bdev_claim(bs_dev, &g_bdev_mod); + CU_ASSERT(rc == 0); + CU_ASSERT(!blob_bdev->desc->write); + CU_ASSERT(bdev.claim_type == SPDK_BDEV_CLAIM_READ_MANY_WRITE_NONE); + CU_ASSERT(bdev.claim_desc == blob_bdev->desc); + + /* Claim blocks a writer without messing up the claim. */ + rc = spdk_bdev_create_bs_dev_ext("bdev0", NULL, NULL, &bs_dev2); + CU_ASSERT(rc == -EPERM); + CU_ASSERT(bdev.claim_type == SPDK_BDEV_CLAIM_READ_MANY_WRITE_NONE); + CU_ASSERT(bdev.claim_desc == blob_bdev->desc); + + /* Another reader is just fine */ + rc = spdk_bdev_create_bs_dev("bdev0", false, NULL, 0, NULL, NULL, &bs_dev2); + CU_ASSERT(rc == 0); + SPDK_CU_ASSERT_FATAL(bs_dev2 != NULL); + bs_dev2->destroy(bs_dev2); + + bs_dev->destroy(bs_dev); + CU_ASSERT(bdev.open_cnt == 0); + CU_ASSERT(bdev.claim_type == SPDK_BDEV_CLAIM_NONE); + CU_ASSERT(bdev.claim_module == NULL); + CU_ASSERT(bdev.claim_desc == NULL); + g_bdev = NULL; +} + int main(int argc, char **argv) { @@ -330,6 +377,7 @@ main(int argc, char **argv) CU_ADD_TEST(suite, create_bs_dev_ro); CU_ADD_TEST(suite, create_bs_dev_rw); CU_ADD_TEST(suite, claim_bs_dev); + CU_ADD_TEST(suite, claim_bs_dev_ro); CU_basic_set_mode(CU_BRM_VERBOSE); CU_basic_run_tests();