diff --git a/include/spdk/bdev_module.h b/include/spdk/bdev_module.h index fcec8a7e0..6d0c2210f 100644 --- a/include/spdk/bdev_module.h +++ b/include/spdk/bdev_module.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright (C) 2016 Intel Corporation. * All rights reserved. - * Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ /** \file @@ -161,6 +161,17 @@ struct spdk_bdev_module { } internal; }; +/** Claim types */ +enum spdk_bdev_claim_type { + /* Not claimed. Must not be used to request a claim. */ + SPDK_BDEV_CLAIM_NONE = 0, + + /** + * Exclusive writer. + */ + SPDK_BDEV_CLAIM_EXCL_WRITE +}; + /** * Called by a bdev module to lay exclusive claim to a bdev. * @@ -522,6 +533,12 @@ struct spdk_bdev { /** The bdev status */ enum spdk_bdev_status status; + /** + * The claim type: used in conjunction with claim. Must hold spinlock on all + * updates. + */ + enum spdk_bdev_claim_type claim_type; + /** Which module has claimed this bdev. Must hold spinlock on all updates. */ union __bdev_internal_claim { struct __bdev_internal_claim_v1 { diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 83bc61395..8a1c7dbc8 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright (C) 2016 Intel Corporation. All rights reserved. * Copyright (c) 2019 Mellanox Technologies LTD. All rights reserved. - * Copyright (c) 2021, 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ #include "spdk/stdinc.h" @@ -664,8 +664,8 @@ bdev_examine(struct spdk_bdev *bdev) } } - module = bdev->internal.claim.v1.module; - if (module != NULL) { + if (bdev->internal.claim_type != SPDK_BDEV_CLAIM_NONE) { + module = bdev->internal.claim.v1.module; if (module->examine_disk) { spdk_spin_lock(&module->internal.spinlock); module->internal.action_in_progress++; @@ -767,7 +767,7 @@ static struct spdk_bdev * _bdev_next_leaf(struct spdk_bdev *bdev) { while (bdev != NULL) { - if (bdev->internal.claim.v1.module == NULL) { + if (bdev->internal.claim_type == SPDK_BDEV_CLAIM_NONE) { return bdev; } else { bdev = TAILQ_NEXT(bdev, internal.link); @@ -1823,7 +1823,7 @@ bdev_finish_unregister_bdevs_iter(void *cb_arg, int bdeverrno) for (bdev = TAILQ_LAST(&g_bdev_mgr.bdevs, spdk_bdev_list); bdev; bdev = TAILQ_PREV(bdev, spdk_bdev_list, internal.link)) { spdk_spin_lock(&bdev->internal.spinlock); - if (bdev->internal.claim.v1.module != NULL) { + if (bdev->internal.claim_type != SPDK_BDEV_CLAIM_NONE) { SPDK_DEBUGLOG(bdev, "Skipping claimed bdev '%s'(<-'%s').\n", bdev->name, bdev->internal.claim.v1.module->name); spdk_spin_unlock(&bdev->internal.spinlock); @@ -6724,7 +6724,8 @@ bdev_register(struct spdk_bdev *bdev) bdev->internal.status = SPDK_BDEV_STATUS_READY; bdev->internal.measured_queue_depth = UINT64_MAX; - bdev->internal.claim.v1.module = NULL; + bdev->internal.claim_type = SPDK_BDEV_CLAIM_NONE; + memset(&bdev->internal.claim, 0, sizeof(bdev->internal.claim)); bdev->internal.qd_poller = NULL; bdev->internal.qos = NULL; @@ -7056,7 +7057,7 @@ bdev_open(struct spdk_bdev *bdev, bool write, struct spdk_bdev_desc *desc) return -ENODEV; } - if (write && bdev->internal.claim.v1.module) { + if (write && bdev->internal.claim_type != SPDK_BDEV_CLAIM_NONE) { SPDK_ERRLOG("Could not open %s - %s module already claimed it\n", bdev->name, bdev->internal.claim.v1.module->name); spdk_spin_unlock(&bdev->internal.spinlock); @@ -7285,7 +7286,7 @@ spdk_bdev_module_claim_bdev(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, { spdk_spin_lock(&bdev->internal.spinlock); - if (bdev->internal.claim.v1.module != NULL) { + if (bdev->internal.claim_type != SPDK_BDEV_CLAIM_NONE) { SPDK_ERRLOG("bdev %s already claimed by module %s\n", bdev->name, bdev->internal.claim.v1.module->name); spdk_spin_unlock(&bdev->internal.spinlock); @@ -7296,6 +7297,7 @@ spdk_bdev_module_claim_bdev(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, desc->write = true; } + bdev->internal.claim_type = SPDK_BDEV_CLAIM_EXCL_WRITE; bdev->internal.claim.v1.module = module; spdk_spin_unlock(&bdev->internal.spinlock); @@ -7308,6 +7310,8 @@ spdk_bdev_module_release_bdev(struct spdk_bdev *bdev) spdk_spin_lock(&bdev->internal.spinlock); assert(bdev->internal.claim.v1.module != NULL); + assert(bdev->internal.claim_type == SPDK_BDEV_CLAIM_EXCL_WRITE); + bdev->internal.claim_type = SPDK_BDEV_CLAIM_NONE; bdev->internal.claim.v1.module = NULL; spdk_spin_unlock(&bdev->internal.spinlock); diff --git a/lib/bdev/bdev_rpc.c b/lib/bdev/bdev_rpc.c index 3c265aca1..ef90d629f 100644 --- a/lib/bdev/bdev_rpc.c +++ b/lib/bdev/bdev_rpc.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright (C) 2018 Intel Corporation. * All rights reserved. + * Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ #include "spdk/bdev.h" @@ -710,7 +711,8 @@ rpc_dump_bdev_info(void *ctx, struct spdk_bdev *bdev) } spdk_json_write_object_end(w); - spdk_json_write_named_bool(w, "claimed", (bdev->internal.claim.v1.module != NULL)); + spdk_json_write_named_bool(w, "claimed", + (bdev->internal.claim_type != SPDK_BDEV_CLAIM_NONE)); spdk_json_write_named_bool(w, "zoned", bdev->zoned); if (bdev->zoned) { diff --git a/test/unit/lib/bdev/bdev.c/bdev_ut.c b/test/unit/lib/bdev/bdev.c/bdev_ut.c index 066b812d8..25bd02f2a 100644 --- a/test/unit/lib/bdev/bdev.c/bdev_ut.c +++ b/test/unit/lib/bdev/bdev.c/bdev_ut.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright (C) 2017 Intel Corporation. All rights reserved. * Copyright (c) 2019 Mellanox Technologies LTD. All rights reserved. - * Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ #include "spdk_cunit.h" @@ -837,6 +837,7 @@ claim_test(void) rc = spdk_bdev_module_claim_bdev(bdev, NULL, &bdev_ut_if); CU_ASSERT(rc == 0); + CU_ASSERT(bdev->internal.claim_type == SPDK_BDEV_CLAIM_EXCL_WRITE); CU_ASSERT(bdev->internal.claim.v1.module == &bdev_ut_if); /* There should be only one open descriptor and it should still be ro */ @@ -852,6 +853,7 @@ claim_test(void) spdk_bdev_module_release_bdev(bdev); rc = spdk_bdev_module_claim_bdev(bdev, desc, &bdev_ut_if); CU_ASSERT(rc == 0); + CU_ASSERT(bdev->internal.claim_type == SPDK_BDEV_CLAIM_EXCL_WRITE); CU_ASSERT(bdev->internal.claim.v1.module == &bdev_ut_if); /* There should be only one open descriptor and it should be rw */ @@ -6241,6 +6243,7 @@ examine_locks(void) bdev = allocate_bdev_ctx("bdev0", &ctx); CU_ASSERT(ctx.examine_config_count == 1); CU_ASSERT(ctx.examine_disk_count == 1); + CU_ASSERT(bdev->internal.claim_type == SPDK_BDEV_CLAIM_NONE); CU_ASSERT(bdev->internal.claim.v1.module == NULL); free_bdev(bdev); @@ -6251,8 +6254,10 @@ examine_locks(void) bdev = allocate_bdev_ctx("bdev0", &ctx); CU_ASSERT(ctx.examine_config_count == 1); CU_ASSERT(ctx.examine_disk_count == 1); + CU_ASSERT(bdev->internal.claim_type == SPDK_BDEV_CLAIM_EXCL_WRITE); CU_ASSERT(bdev->internal.claim.v1.module == &vbdev_ut_if); spdk_bdev_module_release_bdev(bdev); + CU_ASSERT(bdev->internal.claim_type == SPDK_BDEV_CLAIM_NONE); CU_ASSERT(bdev->internal.claim.v1.module == NULL); free_bdev(bdev); } diff --git a/test/unit/lib/bdev/raid/bdev_raid.c/bdev_raid_ut.c b/test/unit/lib/bdev/raid/bdev_raid.c/bdev_raid_ut.c index 2ac5d2c06..fade64e0b 100644 --- a/test/unit/lib/bdev/raid/bdev_raid.c/bdev_raid_ut.c +++ b/test/unit/lib/bdev/raid/bdev_raid.c/bdev_raid_ut.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright (C) 2018 Intel Corporation. * All rights reserved. - * Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ #include "spdk/stdinc.h" @@ -478,7 +478,9 @@ spdk_bdev_readv_blocks_ext(struct spdk_bdev_desc *desc, struct spdk_io_channel * void spdk_bdev_module_release_bdev(struct spdk_bdev *bdev) { + CU_ASSERT(bdev->internal.claim_type == SPDK_BDEV_CLAIM_EXCL_WRITE); CU_ASSERT(bdev->internal.claim.v1.module != NULL); + bdev->internal.claim_type = SPDK_BDEV_CLAIM_NONE; bdev->internal.claim.v1.module = NULL; } @@ -486,9 +488,12 @@ int spdk_bdev_module_claim_bdev(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_bdev_module *module) { - if (bdev->internal.claim.v1.module != NULL) { + if (bdev->internal.claim_type != SPDK_BDEV_CLAIM_NONE) { + CU_ASSERT(bdev->internal.claim.v1.module != NULL); return -1; } + CU_ASSERT(bdev->internal.claim.v1.module == NULL); + bdev->internal.claim_type = SPDK_BDEV_CLAIM_EXCL_WRITE; bdev->internal.claim.v1.module = module; return 0; } diff --git a/test/unit/lib/bdev/vbdev_zone_block.c/vbdev_zone_block_ut.c b/test/unit/lib/bdev/vbdev_zone_block.c/vbdev_zone_block_ut.c index fcd580a71..11c7e532c 100644 --- a/test/unit/lib/bdev/vbdev_zone_block.c/vbdev_zone_block_ut.c +++ b/test/unit/lib/bdev/vbdev_zone_block.c/vbdev_zone_block_ut.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright (C) 2019 Intel Corporation. * All rights reserved. + * Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ #include "spdk/stdinc.h" @@ -184,9 +185,12 @@ int spdk_bdev_module_claim_bdev(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_bdev_module *module) { - if (bdev->internal.claim.v1.module != NULL) { + if (bdev->internal.claim_type != SPDK_BDEV_CLAIM_NONE) { + CU_ASSERT(bdev->internal.claim.v1.module != NULL); return -1; } + CU_ASSERT(bdev->internal.claim.v1.module == NULL); + bdev->internal.claim_type = SPDK_BDEV_CLAIM_EXCL_WRITE; bdev->internal.claim.v1.module = module; return 0; } @@ -194,7 +198,9 @@ spdk_bdev_module_claim_bdev(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, void spdk_bdev_module_release_bdev(struct spdk_bdev *bdev) { + CU_ASSERT(bdev->internal.claim_type == SPDK_BDEV_CLAIM_EXCL_WRITE); CU_ASSERT(bdev->internal.claim.v1.module != NULL); + bdev->internal.claim_type = SPDK_BDEV_CLAIM_NONE; bdev->internal.claim.v1.module = NULL; }