Loading include/spdk/bdev.h +21 −3 Original line number Diff line number Diff line Loading @@ -55,10 +55,20 @@ #define SPDK_BDEV_MAX_NAME_LENGTH 16 #define SPDK_BDEV_MAX_PRODUCT_NAME_LENGTH 50 typedef void (*spdk_bdev_remove_cb_t)(void *remove_ctx); struct spdk_bdev_io; struct spdk_bdev_fn_table; struct spdk_json_write_ctx; /** Blockdev status */ enum spdk_bdev_status { SPDK_BDEV_STATUS_INVALID, SPDK_BDEV_STATUS_UNCLAIMED, SPDK_BDEV_STATUS_CLAIMED, SPDK_BDEV_STATUS_REMOVING, }; /** * \brief SPDK block device. * Loading Loading @@ -104,8 +114,14 @@ struct spdk_bdev { /** Mutex protecting claimed */ pthread_mutex_t mutex; /** True if another blockdev or a LUN is using this device */ bool claimed; /** The bdev status */ enum spdk_bdev_status status; /** Remove callback function pointer to upper level stack */ spdk_bdev_remove_cb_t remove_cb; /** Callback context for hot remove the device */ void *remove_ctx; TAILQ_ENTRY(spdk_bdev) link; }; Loading Loading @@ -305,9 +321,11 @@ struct spdk_bdev *spdk_bdev_next(struct spdk_bdev *prev); * When the ownership of the bdev is no longer needed, the user should call spdk_bdev_unclaim(). * * \param bdev Block device to claim. * \param remove_cb callback function for hot remove the device. * \param remove_ctx param for hot removal callback function. * \return true if the caller claimed the bdev, or false if it was already claimed by another user. */ bool spdk_bdev_claim(struct spdk_bdev *bdev); bool spdk_bdev_claim(struct spdk_bdev *bdev, spdk_bdev_remove_cb_t remove_cb, void *remove_ctx); /** * Release claim of ownership of a block device. Loading lib/bdev/bdev.c +42 −9 Original line number Diff line number Diff line Loading @@ -546,6 +546,7 @@ spdk_bdev_read(struct spdk_bdev *bdev, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io; int rc; assert(bdev->status != SPDK_BDEV_STATUS_UNCLAIMED); if (spdk_bdev_io_valid(bdev, offset, nbytes) != 0) { return NULL; } Loading Loading @@ -585,6 +586,7 @@ spdk_bdev_readv(struct spdk_bdev *bdev, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io; int rc; assert(bdev->status != SPDK_BDEV_STATUS_UNCLAIMED); if (spdk_bdev_io_valid(bdev, offset, nbytes) != 0) { return NULL; } Loading Loading @@ -621,6 +623,7 @@ spdk_bdev_write(struct spdk_bdev *bdev, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io; int rc; assert(bdev->status != SPDK_BDEV_STATUS_UNCLAIMED); if (spdk_bdev_io_valid(bdev, offset, nbytes) != 0) { return NULL; } Loading Loading @@ -659,6 +662,7 @@ spdk_bdev_writev(struct spdk_bdev *bdev, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io; int rc; assert(bdev->status != SPDK_BDEV_STATUS_UNCLAIMED); if (spdk_bdev_io_valid(bdev, offset, len) != 0) { return NULL; } Loading Loading @@ -695,6 +699,7 @@ spdk_bdev_unmap(struct spdk_bdev *bdev, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io; int rc; assert(bdev->status != SPDK_BDEV_STATUS_UNCLAIMED); if (bdesc_count == 0) { SPDK_ERRLOG("Invalid bdesc_count 0\n"); return NULL; Loading Loading @@ -735,6 +740,7 @@ spdk_bdev_flush(struct spdk_bdev *bdev, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io; int rc; assert(bdev->status != SPDK_BDEV_STATUS_UNCLAIMED); bdev_io = spdk_bdev_get_io(); if (!bdev_io) { SPDK_ERRLOG("bdev_io memory allocation failed duing flush\n"); Loading Loading @@ -763,6 +769,7 @@ spdk_bdev_reset(struct spdk_bdev *bdev, enum spdk_bdev_reset_type reset_type, struct spdk_bdev_io *bdev_io; int rc; assert(bdev->status != SPDK_BDEV_STATUS_UNCLAIMED); bdev_io = spdk_bdev_get_io(); if (!bdev_io) { SPDK_ERRLOG("bdev_io memory allocation failed duing reset\n"); Loading Loading @@ -921,8 +928,7 @@ spdk_bdev_register(struct spdk_bdev *bdev) bdev->gencnt = 0; pthread_mutex_init(&bdev->mutex, NULL); bdev->claimed = false; bdev->status = SPDK_BDEV_STATUS_UNCLAIMED; SPDK_TRACELOG(SPDK_TRACE_DEBUG, "Inserting bdev %s into list\n", bdev->name); TAILQ_INSERT_TAIL(&spdk_bdev_list, bdev, link); } Loading @@ -933,7 +939,22 @@ spdk_bdev_unregister(struct spdk_bdev *bdev) int rc; SPDK_TRACELOG(SPDK_TRACE_DEBUG, "Removing bdev %s from list\n", bdev->name); pthread_mutex_lock(&bdev->mutex); assert(bdev->status == SPDK_BDEV_STATUS_CLAIMED || bdev->status == SPDK_BDEV_STATUS_UNCLAIMED); if (bdev->status == SPDK_BDEV_STATUS_CLAIMED) { if (bdev->remove_cb) { bdev->status = SPDK_BDEV_STATUS_REMOVING; pthread_mutex_unlock(&bdev->mutex); bdev->remove_cb(bdev->remove_ctx); return; } else { bdev->status = SPDK_BDEV_STATUS_UNCLAIMED; } } TAILQ_REMOVE(&spdk_bdev_list, bdev, link); pthread_mutex_unlock(&bdev->mutex); pthread_mutex_destroy(&bdev->mutex); Loading @@ -944,15 +965,18 @@ spdk_bdev_unregister(struct spdk_bdev *bdev) } bool spdk_bdev_claim(struct spdk_bdev *bdev) spdk_bdev_claim(struct spdk_bdev *bdev, spdk_bdev_remove_cb_t remove_cb, void *remove_ctx) { bool success; pthread_mutex_lock(&bdev->mutex); if (!bdev->claimed) { if (bdev->status != SPDK_BDEV_STATUS_CLAIMED) { /* Take ownership of bdev. */ bdev->claimed = true; bdev->remove_cb = remove_cb; bdev->remove_ctx = remove_ctx; bdev->status = SPDK_BDEV_STATUS_CLAIMED; success = true; } else { /* bdev is already claimed. */ Loading @@ -967,12 +991,21 @@ spdk_bdev_claim(struct spdk_bdev *bdev) void spdk_bdev_unclaim(struct spdk_bdev *bdev) { pthread_mutex_lock(&bdev->mutex); assert(bdev->claimed); bdev->claimed = false; bool do_unregister = false; pthread_mutex_lock(&bdev->mutex); assert(bdev->status == SPDK_BDEV_STATUS_CLAIMED || bdev->status == SPDK_BDEV_STATUS_REMOVING); if (bdev->status == SPDK_BDEV_STATUS_REMOVING) { do_unregister = true; } bdev->remove_cb = NULL; bdev->remove_ctx = NULL; bdev->status = SPDK_BDEV_STATUS_UNCLAIMED; pthread_mutex_unlock(&bdev->mutex); if (do_unregister == true) { spdk_bdev_unregister(bdev); } } void Loading lib/bdev/rpc/bdev_rpc.c +5 −1 Original line number Diff line number Diff line Loading @@ -72,7 +72,11 @@ spdk_rpc_get_bdevs(struct spdk_jsonrpc_server_conn *conn, spdk_json_write_uint64(w, bdev->blockcnt); spdk_json_write_name(w, "claimed"); spdk_json_write_bool(w, bdev->claimed); if (bdev->status == SPDK_BDEV_STATUS_CLAIMED) { spdk_json_write_bool(w, true); } else { spdk_json_write_bool(w, false); } spdk_json_write_name(w, "driver_specific"); spdk_json_write_object_begin(w); Loading lib/bdev/split/vbdev_split.c +1 −1 Original line number Diff line number Diff line Loading @@ -241,7 +241,7 @@ vbdev_split_create(struct spdk_bdev *base_bdev, uint64_t split_count, uint64_t s int rc; struct split_base *split_base; if (!spdk_bdev_claim(base_bdev)) { if (!spdk_bdev_claim(base_bdev, NULL, NULL)) { SPDK_ERRLOG("Split bdev %s is already claimed\n", base_bdev->name); return -1; } Loading lib/nvmf/subsystem.c +1 −1 Original line number Diff line number Diff line Loading @@ -412,7 +412,7 @@ spdk_nvmf_subsystem_add_ns(struct spdk_nvmf_subsystem *subsystem, struct spdk_bd { int i = 0; if (!spdk_bdev_claim(bdev)) { if (!spdk_bdev_claim(bdev, NULL, NULL)) { SPDK_ERRLOG("Subsystem %s: bdev %s is already claimed\n", subsystem->subnqn, bdev->name); return -1; Loading Loading
include/spdk/bdev.h +21 −3 Original line number Diff line number Diff line Loading @@ -55,10 +55,20 @@ #define SPDK_BDEV_MAX_NAME_LENGTH 16 #define SPDK_BDEV_MAX_PRODUCT_NAME_LENGTH 50 typedef void (*spdk_bdev_remove_cb_t)(void *remove_ctx); struct spdk_bdev_io; struct spdk_bdev_fn_table; struct spdk_json_write_ctx; /** Blockdev status */ enum spdk_bdev_status { SPDK_BDEV_STATUS_INVALID, SPDK_BDEV_STATUS_UNCLAIMED, SPDK_BDEV_STATUS_CLAIMED, SPDK_BDEV_STATUS_REMOVING, }; /** * \brief SPDK block device. * Loading Loading @@ -104,8 +114,14 @@ struct spdk_bdev { /** Mutex protecting claimed */ pthread_mutex_t mutex; /** True if another blockdev or a LUN is using this device */ bool claimed; /** The bdev status */ enum spdk_bdev_status status; /** Remove callback function pointer to upper level stack */ spdk_bdev_remove_cb_t remove_cb; /** Callback context for hot remove the device */ void *remove_ctx; TAILQ_ENTRY(spdk_bdev) link; }; Loading Loading @@ -305,9 +321,11 @@ struct spdk_bdev *spdk_bdev_next(struct spdk_bdev *prev); * When the ownership of the bdev is no longer needed, the user should call spdk_bdev_unclaim(). * * \param bdev Block device to claim. * \param remove_cb callback function for hot remove the device. * \param remove_ctx param for hot removal callback function. * \return true if the caller claimed the bdev, or false if it was already claimed by another user. */ bool spdk_bdev_claim(struct spdk_bdev *bdev); bool spdk_bdev_claim(struct spdk_bdev *bdev, spdk_bdev_remove_cb_t remove_cb, void *remove_ctx); /** * Release claim of ownership of a block device. Loading
lib/bdev/bdev.c +42 −9 Original line number Diff line number Diff line Loading @@ -546,6 +546,7 @@ spdk_bdev_read(struct spdk_bdev *bdev, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io; int rc; assert(bdev->status != SPDK_BDEV_STATUS_UNCLAIMED); if (spdk_bdev_io_valid(bdev, offset, nbytes) != 0) { return NULL; } Loading Loading @@ -585,6 +586,7 @@ spdk_bdev_readv(struct spdk_bdev *bdev, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io; int rc; assert(bdev->status != SPDK_BDEV_STATUS_UNCLAIMED); if (spdk_bdev_io_valid(bdev, offset, nbytes) != 0) { return NULL; } Loading Loading @@ -621,6 +623,7 @@ spdk_bdev_write(struct spdk_bdev *bdev, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io; int rc; assert(bdev->status != SPDK_BDEV_STATUS_UNCLAIMED); if (spdk_bdev_io_valid(bdev, offset, nbytes) != 0) { return NULL; } Loading Loading @@ -659,6 +662,7 @@ spdk_bdev_writev(struct spdk_bdev *bdev, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io; int rc; assert(bdev->status != SPDK_BDEV_STATUS_UNCLAIMED); if (spdk_bdev_io_valid(bdev, offset, len) != 0) { return NULL; } Loading Loading @@ -695,6 +699,7 @@ spdk_bdev_unmap(struct spdk_bdev *bdev, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io; int rc; assert(bdev->status != SPDK_BDEV_STATUS_UNCLAIMED); if (bdesc_count == 0) { SPDK_ERRLOG("Invalid bdesc_count 0\n"); return NULL; Loading Loading @@ -735,6 +740,7 @@ spdk_bdev_flush(struct spdk_bdev *bdev, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io; int rc; assert(bdev->status != SPDK_BDEV_STATUS_UNCLAIMED); bdev_io = spdk_bdev_get_io(); if (!bdev_io) { SPDK_ERRLOG("bdev_io memory allocation failed duing flush\n"); Loading Loading @@ -763,6 +769,7 @@ spdk_bdev_reset(struct spdk_bdev *bdev, enum spdk_bdev_reset_type reset_type, struct spdk_bdev_io *bdev_io; int rc; assert(bdev->status != SPDK_BDEV_STATUS_UNCLAIMED); bdev_io = spdk_bdev_get_io(); if (!bdev_io) { SPDK_ERRLOG("bdev_io memory allocation failed duing reset\n"); Loading Loading @@ -921,8 +928,7 @@ spdk_bdev_register(struct spdk_bdev *bdev) bdev->gencnt = 0; pthread_mutex_init(&bdev->mutex, NULL); bdev->claimed = false; bdev->status = SPDK_BDEV_STATUS_UNCLAIMED; SPDK_TRACELOG(SPDK_TRACE_DEBUG, "Inserting bdev %s into list\n", bdev->name); TAILQ_INSERT_TAIL(&spdk_bdev_list, bdev, link); } Loading @@ -933,7 +939,22 @@ spdk_bdev_unregister(struct spdk_bdev *bdev) int rc; SPDK_TRACELOG(SPDK_TRACE_DEBUG, "Removing bdev %s from list\n", bdev->name); pthread_mutex_lock(&bdev->mutex); assert(bdev->status == SPDK_BDEV_STATUS_CLAIMED || bdev->status == SPDK_BDEV_STATUS_UNCLAIMED); if (bdev->status == SPDK_BDEV_STATUS_CLAIMED) { if (bdev->remove_cb) { bdev->status = SPDK_BDEV_STATUS_REMOVING; pthread_mutex_unlock(&bdev->mutex); bdev->remove_cb(bdev->remove_ctx); return; } else { bdev->status = SPDK_BDEV_STATUS_UNCLAIMED; } } TAILQ_REMOVE(&spdk_bdev_list, bdev, link); pthread_mutex_unlock(&bdev->mutex); pthread_mutex_destroy(&bdev->mutex); Loading @@ -944,15 +965,18 @@ spdk_bdev_unregister(struct spdk_bdev *bdev) } bool spdk_bdev_claim(struct spdk_bdev *bdev) spdk_bdev_claim(struct spdk_bdev *bdev, spdk_bdev_remove_cb_t remove_cb, void *remove_ctx) { bool success; pthread_mutex_lock(&bdev->mutex); if (!bdev->claimed) { if (bdev->status != SPDK_BDEV_STATUS_CLAIMED) { /* Take ownership of bdev. */ bdev->claimed = true; bdev->remove_cb = remove_cb; bdev->remove_ctx = remove_ctx; bdev->status = SPDK_BDEV_STATUS_CLAIMED; success = true; } else { /* bdev is already claimed. */ Loading @@ -967,12 +991,21 @@ spdk_bdev_claim(struct spdk_bdev *bdev) void spdk_bdev_unclaim(struct spdk_bdev *bdev) { pthread_mutex_lock(&bdev->mutex); assert(bdev->claimed); bdev->claimed = false; bool do_unregister = false; pthread_mutex_lock(&bdev->mutex); assert(bdev->status == SPDK_BDEV_STATUS_CLAIMED || bdev->status == SPDK_BDEV_STATUS_REMOVING); if (bdev->status == SPDK_BDEV_STATUS_REMOVING) { do_unregister = true; } bdev->remove_cb = NULL; bdev->remove_ctx = NULL; bdev->status = SPDK_BDEV_STATUS_UNCLAIMED; pthread_mutex_unlock(&bdev->mutex); if (do_unregister == true) { spdk_bdev_unregister(bdev); } } void Loading
lib/bdev/rpc/bdev_rpc.c +5 −1 Original line number Diff line number Diff line Loading @@ -72,7 +72,11 @@ spdk_rpc_get_bdevs(struct spdk_jsonrpc_server_conn *conn, spdk_json_write_uint64(w, bdev->blockcnt); spdk_json_write_name(w, "claimed"); spdk_json_write_bool(w, bdev->claimed); if (bdev->status == SPDK_BDEV_STATUS_CLAIMED) { spdk_json_write_bool(w, true); } else { spdk_json_write_bool(w, false); } spdk_json_write_name(w, "driver_specific"); spdk_json_write_object_begin(w); Loading
lib/bdev/split/vbdev_split.c +1 −1 Original line number Diff line number Diff line Loading @@ -241,7 +241,7 @@ vbdev_split_create(struct spdk_bdev *base_bdev, uint64_t split_count, uint64_t s int rc; struct split_base *split_base; if (!spdk_bdev_claim(base_bdev)) { if (!spdk_bdev_claim(base_bdev, NULL, NULL)) { SPDK_ERRLOG("Split bdev %s is already claimed\n", base_bdev->name); return -1; } Loading
lib/nvmf/subsystem.c +1 −1 Original line number Diff line number Diff line Loading @@ -412,7 +412,7 @@ spdk_nvmf_subsystem_add_ns(struct spdk_nvmf_subsystem *subsystem, struct spdk_bd { int i = 0; if (!spdk_bdev_claim(bdev)) { if (!spdk_bdev_claim(bdev, NULL, NULL)) { SPDK_ERRLOG("Subsystem %s: bdev %s is already claimed\n", subsystem->subnqn, bdev->name); return -1; Loading