bdev: Add spdk_bdev_for_each_bdev_io() to execute function for each bdev_io
Some use cases want to abort every bdev_io submitted to the bdev by traversing the bdev channels. However, struct spdk_bdev_channel is private in lib/bdev/bdev.c. Hence, add a helper function spdk_bdev_for_each_bdev_io() to execute the function on the appropriate thread for every bdev_io submitted to the bdev. This function should be used only from the bdev module and it should be ensured that the bdev is not unregistered during execution. We keep this function as generic as possible because we may have other use cases in future. Signed-off-by: Shuhei Matsumoto <smatsumoto@nvidia.com> Change-Id: Ic0209361bd1228ea8d4cb3241d0df07106be58d9 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12751 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
This commit is contained in:
parent
3851a64f9f
commit
1212b53fb8
@ -17,6 +17,9 @@ an object with an array named "subsystems".
|
||||
|
||||
New RPCs `bdev_xnvme_create` and `bdev_xnvme_delete` were added to support the xNVMe bdev.
|
||||
|
||||
A new API `spdk_bdev_for_each_bdev_io` was added to execute the function on the appropriate
|
||||
thread for each bdev_io submitted to the bdev.
|
||||
|
||||
### sock
|
||||
|
||||
Added new `ssl` based socket implementation, the code is located in module/sock/posix.
|
||||
|
@ -1293,6 +1293,26 @@ int spdk_bdev_push_media_events(struct spdk_bdev *bdev, const struct spdk_bdev_m
|
||||
*/
|
||||
void spdk_bdev_notify_media_management(struct spdk_bdev *bdev);
|
||||
|
||||
typedef int (*spdk_bdev_io_fn)(void *ctx, struct spdk_bdev_io *bdev_io);
|
||||
typedef void (*spdk_bdev_for_each_io_cb)(void *ctx, int rc);
|
||||
|
||||
/**
|
||||
* Call the provided function on the appropriate thread for each bdev_io submitted
|
||||
* to the provided bdev.
|
||||
*
|
||||
* Note: This function should be used only in the bdev module and it should be
|
||||
* ensured that the bdev is not unregistered while executing the function.
|
||||
* Both fn and cb are required to specify.
|
||||
*
|
||||
* \param bdev Block device to query.
|
||||
* \param ctx Context passed to the function for each bdev_io and the completion
|
||||
* callback function.
|
||||
* \param fn Called on the appropriate thread for each bdev_io submitted to the bdev.
|
||||
* \param cb Called when this operation completes.
|
||||
*/
|
||||
void spdk_bdev_for_each_bdev_io(struct spdk_bdev *bdev, void *ctx, spdk_bdev_io_fn fn,
|
||||
spdk_bdev_for_each_io_cb cb);
|
||||
|
||||
/*
|
||||
* Macro used to register module for later initialization.
|
||||
*/
|
||||
|
@ -7739,6 +7739,66 @@ spdk_bdev_get_memory_domains(struct spdk_bdev *bdev, struct spdk_memory_domain *
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct spdk_bdev_for_each_io_ctx {
|
||||
void *ctx;
|
||||
spdk_bdev_io_fn fn;
|
||||
spdk_bdev_for_each_io_cb cb;
|
||||
};
|
||||
|
||||
static void
|
||||
bdev_channel_for_each_io(struct spdk_io_channel_iter *i)
|
||||
{
|
||||
struct spdk_bdev_for_each_io_ctx *ctx = spdk_io_channel_iter_get_ctx(i);
|
||||
struct spdk_io_channel *io_ch = spdk_io_channel_iter_get_channel(i);
|
||||
struct spdk_bdev_channel *bdev_ch = spdk_io_channel_get_ctx(io_ch);
|
||||
struct spdk_bdev_io *bdev_io;
|
||||
int rc = 0;
|
||||
|
||||
TAILQ_FOREACH(bdev_io, &bdev_ch->io_submitted, internal.ch_link) {
|
||||
rc = ctx->fn(ctx->ctx, bdev_io);
|
||||
if (rc != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
spdk_for_each_channel_continue(i, rc);
|
||||
}
|
||||
|
||||
static void
|
||||
bdev_for_each_io_done(struct spdk_io_channel_iter *i, int status)
|
||||
{
|
||||
struct spdk_bdev_for_each_io_ctx *ctx = spdk_io_channel_iter_get_ctx(i);
|
||||
|
||||
ctx->cb(ctx->ctx, status);
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
spdk_bdev_for_each_bdev_io(struct spdk_bdev *bdev, void *_ctx, spdk_bdev_io_fn fn,
|
||||
spdk_bdev_for_each_io_cb cb)
|
||||
{
|
||||
struct spdk_bdev_for_each_io_ctx *ctx;
|
||||
|
||||
assert(fn != NULL && cb != NULL);
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
if (ctx == NULL) {
|
||||
SPDK_ERRLOG("Failed to allocate context.\n");
|
||||
cb(_ctx, -ENOMEM);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->ctx = _ctx;
|
||||
ctx->fn = fn;
|
||||
ctx->cb = cb;
|
||||
|
||||
spdk_for_each_channel(__bdev_to_io_dev(bdev),
|
||||
bdev_channel_for_each_io,
|
||||
ctx,
|
||||
bdev_for_each_io_done);
|
||||
}
|
||||
|
||||
SPDK_LOG_REGISTER_COMPONENT(bdev)
|
||||
|
||||
SPDK_TRACE_REGISTER_FN(bdev_trace, "bdev", TRACE_GROUP_BDEV)
|
||||
|
@ -147,6 +147,7 @@
|
||||
spdk_bdev_part_get_offset_blocks;
|
||||
spdk_bdev_push_media_events;
|
||||
spdk_bdev_notify_media_management;
|
||||
spdk_bdev_for_each_bdev_io;
|
||||
|
||||
# Public functions in bdev_zone.h
|
||||
spdk_bdev_get_zone_size;
|
||||
|
Loading…
Reference in New Issue
Block a user