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:
parent
6da9878643
commit
3878371ab2
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user