Commit 428b17a0 authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Tomasz Zawadzki
Browse files

bdev: Add spdk_for_each_bdev/bdev_leaf for clean up and further improvements



To execute a callback function for each registered bdev or unclaimed
bdev, add new public APIs, spdk_for_each_bdev() and
spdk_for_each_bdev_leaf().

These functions are safe for race conditions by opening before and
closing after executing the provided callback function.

Signed-off-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
Change-Id: I59b702ffec7b4fc5e9779de5a3a75d44922b829b
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12088


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 941ca7e0
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -14,6 +14,9 @@ Removed deprecated spdk_bdev_module_finish_done(). Use spdk_bdev_module_fini_don

A new API `spdk_bdev_unregister_by_name` was added to handle race conditions correctly.

New APIs, `spdk_for_each_bdev` and `spdk_for_each_bdev_leaf`, were added to provide iteration
safe for race conditions.

### idxd

A new parameter `flags` was added to all low level submission and preparation
+1 −1
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ to tear down the bdev library, call spdk_bdev_finish().
All block devices have a simple string name. At any time, a pointer to the
device object can be obtained by calling spdk_bdev_get_by_name(), or the entire
set of bdevs may be iterated using spdk_bdev_first() and spdk_bdev_next() and
their variants.
their variants or spdk_for_each_bdev() and its variant.

Some block devices may also be given aliases, which are also string names.
Aliases behave like symlinks - they can be used interchangeably with the real
+38 −0
Original line number Diff line number Diff line
@@ -378,6 +378,44 @@ int spdk_bdev_open_ext(const char *bdev_name, bool write, spdk_bdev_event_cb_t e
 */
void spdk_bdev_close(struct spdk_bdev_desc *desc);

/**
 * Callback function for spdk_for_each_bdev() and spdk_for_each_bdev_leaf().
 *
 * \param ctx Context passed to the callback.
 * \param bdev Block device the callback handles.
 */
typedef int (*spdk_for_each_bdev_fn)(void *ctx, struct spdk_bdev *bdev);

/**
 * Call the provided callback function for every registered block device.
 * If fn returns negated errno, spdk_for_each_bdev() terminates iteration.
 *
 * spdk_for_each_bdev() opens before and closes after executing the provided
 * callback function for each bdev internally.
 *
 * \param ctx Context passed to the callback function.
 * \param fn Callback function for each block device.
 *
 * \return 0 if operation is sucessful, or suitable errno value one of the
 * callback returned otherwise.
 */
int spdk_for_each_bdev(void *ctx, spdk_for_each_bdev_fn fn);

/**
 * Call the provided callback function for every block device without virtual
 * block devices on top.
 *
 * spdk_for_each_bdev_leaf() opens before and closes after executing the provided
 * callback function for each unclaimed bdev internally.
 *
 * \param ctx Context passed to the callback function.
 * \param fn Callback funciton for each block device without virtual block devices on top.
 *
 * \return 0 if operation is successful, or suitable errno value one of the
 * callback returned otherwise.
 */
int spdk_for_each_bdev_leaf(void *ctx, spdk_for_each_bdev_fn fn);

/**
 * Get the bdev associated with a bdev descriptor.
 *
+76 −0
Original line number Diff line number Diff line
@@ -6572,6 +6572,82 @@ spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc)
	return desc->bdev;
}

int
spdk_for_each_bdev(void *ctx, spdk_for_each_bdev_fn fn)
{
	struct spdk_bdev *bdev, *tmp;
	struct spdk_bdev_desc *desc;
	int rc = 0;

	assert(fn != NULL);

	pthread_mutex_lock(&g_bdev_mgr.mutex);
	bdev = spdk_bdev_first();
	while (bdev != NULL) {
		rc = bdev_desc_alloc(bdev, _tmp_bdev_event_cb, NULL, &desc);
		if (rc != 0) {
			break;
		}
		rc = bdev_open(bdev, false, desc);
		if (rc != 0) {
			bdev_desc_free(desc);
			break;
		}
		pthread_mutex_unlock(&g_bdev_mgr.mutex);

		rc = fn(ctx, bdev);

		pthread_mutex_lock(&g_bdev_mgr.mutex);
		tmp = spdk_bdev_next(bdev);
		bdev_close(bdev, desc);
		if (rc != 0) {
			break;
		}
		bdev = tmp;
	}
	pthread_mutex_unlock(&g_bdev_mgr.mutex);

	return rc;
}

int
spdk_for_each_bdev_leaf(void *ctx, spdk_for_each_bdev_fn fn)
{
	struct spdk_bdev *bdev, *tmp;
	struct spdk_bdev_desc *desc;
	int rc = 0;

	assert(fn != NULL);

	pthread_mutex_lock(&g_bdev_mgr.mutex);
	bdev = spdk_bdev_first_leaf();
	while (bdev != NULL) {
		rc = bdev_desc_alloc(bdev, _tmp_bdev_event_cb, NULL, &desc);
		if (rc != 0) {
			break;
		}
		rc = bdev_open(bdev, false, desc);
		if (rc != 0) {
			bdev_desc_free(desc);
			break;
		}
		pthread_mutex_unlock(&g_bdev_mgr.mutex);

		rc = fn(ctx, bdev);

		pthread_mutex_lock(&g_bdev_mgr.mutex);
		tmp = spdk_bdev_next_leaf(bdev);
		bdev_close(bdev, desc);
		if (rc != 0) {
			break;
		}
		bdev = tmp;
	}
	pthread_mutex_unlock(&g_bdev_mgr.mutex);

	return rc;
}

void
spdk_bdev_io_get_iovec(struct spdk_bdev_io *bdev_io, struct iovec **iovp, int *iovcntp)
{
+2 −0
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
	spdk_bdev_next;
	spdk_bdev_first_leaf;
	spdk_bdev_next_leaf;
	spdk_for_each_bdev;
	spdk_for_each_bdev_leaf;
	spdk_bdev_open_ext;
	spdk_bdev_close;
	spdk_bdev_desc_get_bdev;
Loading