bdev/crypto: Add new callback to spdk_bdev_unregister_bdev_by_name()

Currently delete_crypto_disk() calls spdk_bdev_unregister_bdev_by_name()
and immediately after exiting that function, it proceeds to bdev name
deletion. This causes callbacks triggered by above call to run with
references to bdev names that are partially unavailable due to free()
functions in vbdev_crypto_delete_name().

Add an intermediate callback that will call vbdev_crypto_delete_name()
and then the original callback that was sent as an argument to
delete_crypto_disk(). That way we are sure that bdev name deletion
is performed right after bdev unregister.

Change-Id: I483ce5c3c63596f54d44220ca61c5e97c3807faf
Signed-off-by: Krzysztof Karas <krzysztof.karas@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16253
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
This commit is contained in:
Krzysztof Karas 2023-01-11 16:19:04 +01:00 committed by Tomasz Zawadzki
parent 6da9878643
commit 3878371ab2

View File

@ -2085,29 +2085,65 @@ error_vbdev_alloc:
return rc;
}
struct crypto_delete_disk_ctx {
spdk_delete_crypto_complete cb_fn;
void *cb_arg;
char *bdev_name;
};
static void
delete_crypto_disk_bdev_name(void *ctx, int rc)
{
struct bdev_names *name;
struct crypto_delete_disk_ctx *disk_ctx = ctx;
/* Remove the association (vbdev, bdev) from g_bdev_names. This is required so that the
* vbdev does not get re-created if the same bdev is constructed at some other time,
* unless the underlying bdev was hot-removed. */
TAILQ_FOREACH(name, &g_bdev_names, link) {
if (strcmp(name->opts->vbdev_name, disk_ctx->bdev_name) == 0) {
vbdev_crypto_delete_name(name);
break;
}
}
disk_ctx->cb_fn(disk_ctx->cb_arg, rc);
free(disk_ctx->bdev_name);
free(disk_ctx);
}
/* RPC entry for deleting a crypto vbdev. */
void
delete_crypto_disk(const char *bdev_name, spdk_delete_crypto_complete cb_fn,
void *cb_arg)
{
struct bdev_names *name;
int rc;
struct crypto_delete_disk_ctx *ctx;
ctx = calloc(1, sizeof(struct crypto_delete_disk_ctx));
if (!ctx) {
SPDK_ERRLOG("Failed to allocate delete crypto disk ctx\n");
cb_fn(cb_arg, -ENOMEM);
return;
}
ctx->bdev_name = strdup(bdev_name);
if (!ctx->bdev_name) {
SPDK_ERRLOG("Failed to copy bdev_name\n");
free(ctx);
cb_fn(cb_arg, -ENOMEM);
return;
}
ctx->cb_arg = cb_arg;
ctx->cb_fn = cb_fn;
/* Some cleanup happens in the destruct callback. */
rc = spdk_bdev_unregister_by_name(bdev_name, &crypto_if, cb_fn, cb_arg);
if (rc == 0) {
/* Remove the association (vbdev, bdev) from g_bdev_names. This is required so that the
* vbdev does not get re-created if the same bdev is constructed at some other time,
* unless the underlying bdev was hot-removed.
*/
TAILQ_FOREACH(name, &g_bdev_names, link) {
if (strcmp(name->opts->vbdev_name, bdev_name) == 0) {
vbdev_crypto_delete_name(name);
break;
}
}
} else {
rc = spdk_bdev_unregister_by_name(bdev_name, &crypto_if, delete_crypto_disk_bdev_name, ctx);
if (rc != 0) {
SPDK_ERRLOG("Encountered an error during bdev unregistration\n");
cb_fn(cb_arg, rc);
free(ctx->bdev_name);
free(ctx);
}
}