Commit 93ae89ab authored by Yalong Wang's avatar Yalong Wang Committed by Jim Harris
Browse files

raid1: forward UNMAP/FLUSH to base bdev if supported



If the base bdev supports the unmap or flush command, the unmap request
received by the RAID1 bdev will be passed through directly to the base bdev.

Change-Id: I4f101878258cf12d48ea974b7fce0504cdc58e0e
Signed-off-by: default avatarYalong Wang <yalong9@staff.sina.com.cn>
Reviewed-on: https://review.spdk.io/c/spdk/spdk/+/25787


Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK Automated Test System <spdkbot@gmail.com>
Reviewed-by: default avatarMateusz Kozlowski <mateusz.kozlowski@solidigm.com>
Reviewed-by: default avatarArtur Paszkiewicz <artur.paszkiewicz@solidigm.com>
Reviewed-by: default avatarJim Harris <jim.harris@nvidia.com>
parent 5a5e2183
Loading
Loading
Loading
Loading
+84 −0
Original line number Diff line number Diff line
@@ -349,6 +349,89 @@ raid1_submit_rw_request(struct raid_bdev_io *raid_io)
	}
}

static void raid1_submit_null_payload_request(struct raid_bdev_io *raid_io);

static void
_raid1_submit_null_payload_request(void *_raid_io)
{
	struct raid_bdev_io *raid_io = _raid_io;

	raid1_submit_null_payload_request(raid_io);
}

static inline void
raid1_null_payload_request_io_completion(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
{
	raid1_write_bdev_io_completion(bdev_io, success, cb_arg);
}

static void
raid1_submit_null_payload_request(struct raid_bdev_io *raid_io)
{
	struct raid_bdev *raid_bdev = raid_io->raid_bdev;
	struct spdk_bdev_ext_io_opts io_opts;
	struct raid_base_bdev_info *base_info;
	struct spdk_io_channel *base_ch;
	uint8_t idx;
	uint64_t base_bdev_io_not_submitted;
	int ret = 0;

	if (raid_io->base_bdev_io_submitted == 0) {
		raid_io->base_bdev_io_remaining = raid_bdev->num_base_bdevs;
		raid_bdev_io_set_default_status(raid_io, SPDK_BDEV_IO_STATUS_FAILED);
	}

	raid1_init_ext_io_opts(&io_opts, raid_io);
	for (idx = raid_io->base_bdev_io_submitted; idx < raid_bdev->num_base_bdevs; idx++) {
		base_info = &raid_bdev->base_bdev_info[idx];
		base_ch = raid_bdev_channel_get_base_channel(raid_io->raid_ch, idx);

		if (base_ch == NULL) {
			/* skip a missing base bdev's slot */
			raid_io->base_bdev_io_submitted++;
			raid_bdev_io_complete_part(raid_io, 1, SPDK_BDEV_IO_STATUS_FAILED);
			continue;
		}

		switch (raid_io->type) {
		case SPDK_BDEV_IO_TYPE_UNMAP:
			ret = raid_bdev_unmap_blocks(base_info, base_ch,
						     raid_io->offset_blocks, raid_io->num_blocks,
						     raid1_null_payload_request_io_completion, raid_io);
			break;

		case SPDK_BDEV_IO_TYPE_FLUSH:
			ret = raid_bdev_flush_blocks(base_info, base_ch,
						     raid_io->offset_blocks, raid_io->num_blocks,
						     raid1_null_payload_request_io_completion, raid_io);
			break;

		default:
			SPDK_ERRLOG("submit request, invalid io type with null payload %u\n", raid_io->type);
			assert(false);
			ret = -EIO;
		}

		if (spdk_unlikely(ret != 0)) {
			if (spdk_unlikely(ret == -ENOMEM)) {
				raid_bdev_queue_io_wait(raid_io, spdk_bdev_desc_get_bdev(base_info->desc),
							base_ch, _raid1_submit_null_payload_request);
				return;
			}

			base_bdev_io_not_submitted = raid_bdev->num_base_bdevs -
						     raid_io->base_bdev_io_submitted;
			raid_bdev_io_complete_part(raid_io, base_bdev_io_not_submitted,
						   SPDK_BDEV_IO_STATUS_FAILED);
			return;
		}

		raid_io->base_bdev_io_submitted++;
	}

	assert(raid_io->base_bdev_io_submitted != 0);
}

static void
raid1_ioch_destroy(void *io_device, void *ctx_buf)
{
@@ -541,6 +624,7 @@ static struct raid_bdev_module g_raid1_module = {
	.start = raid1_start,
	.stop = raid1_stop,
	.submit_rw_request = raid1_submit_rw_request,
	.submit_null_payload_request = raid1_submit_null_payload_request,
	.get_io_channel = raid1_get_io_channel,
	.submit_process_request = raid1_submit_process_request,
	.resize = raid1_resize,
+10 −4
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ function cleanup() {
	rm -rf "$tmp_dir"
}

function raid_function_test() {
function raid_unmap_function_test() {
	local raid_level=$1
	local nbd=/dev/nbd0
	local raid_bdev
@@ -72,7 +72,12 @@ function raid_function_test() {

	$rpc_py bdev_malloc_create 32 $base_blocklen $base_malloc_params -b Base_1
	$rpc_py bdev_malloc_create 32 $base_blocklen $base_malloc_params -b Base_2

	if [ "$raid_level" = "raid1" ]; then
		$rpc_py bdev_raid_create -r $raid_level -b "'Base_1 Base_2'" -n raid
	else
		$rpc_py bdev_raid_create -z 64 -r $raid_level -b "'Base_1 Base_2'" -n raid
	fi

	raid_bdev=$($rpc_py bdev_raid_get_bdevs online | jq -r '.[0]["name"] | select(.)')
	if [ $raid_bdev = "" ]; then
@@ -956,8 +961,9 @@ run_test "raid1_resize_superblock_test" raid_resize_superblock_test 1
if [ $(uname -s) = Linux ] && modprobe -n nbd; then
	has_nbd=true
	modprobe nbd
	run_test "raid_function_test_raid0" raid_function_test raid0
	run_test "raid_function_test_concat" raid_function_test concat
	run_test "raid_unmap_function_test_raid0" raid_unmap_function_test raid0
	run_test "raid_unmap_function_test_concat" raid_unmap_function_test concat
	run_test "raid_unmap_function_test_raid1" raid_unmap_function_test raid1
fi

run_test "raid0_resize_test" raid_resize_test 0
+6 −0
Original line number Diff line number Diff line
@@ -31,6 +31,12 @@ DEFINE_STUB_V(raid_bdev_io_init, (struct raid_bdev_io *raid_io,
DEFINE_STUB(raid_bdev_remap_dix_reftag, int, (void *md_buf, uint64_t num_blocks,
		struct spdk_bdev *bdev, uint32_t remapped_offset), -1);
DEFINE_STUB(spdk_bdev_notify_blockcnt_change, int, (struct spdk_bdev *bdev, uint64_t size), 0);
DEFINE_STUB(spdk_bdev_flush_blocks, int, (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
		uint64_t offset_blocks, uint64_t num_blocks, spdk_bdev_io_completion_cb cb,
		void *cb_arg), 0);
DEFINE_STUB(spdk_bdev_unmap_blocks, int, (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
		uint64_t offset_blocks, uint64_t num_blocks, spdk_bdev_io_completion_cb cb,
		void *cb_arg), 0);

int
spdk_bdev_readv_blocks_ext(struct spdk_bdev_desc *desc,