Commit 3b9baa5f authored by Loïc Yavercovski's avatar Loïc Yavercovski Committed by Tomasz Zawadzki
Browse files

bdev/raid1: Support resize when increasing the size of base bdevs



Implement the resize function for RAID1. raid1_resize() calculate the
new raid_bdev's block count and if it is different from the old block
count, call spdk_bdev_notify_blockcnt_change() with the new block count.

Add a simple functional test for this feature. The test is to create
a raid1 bdev with two null bdevs, resize one null bdev, check if the
raid1 bdev is not resize, resize another null bdev, check if the raid1
bdev is resized.

The commit is an overall copy/adaptation of the work of Shuhei Matsumoto
with raid0.

Change-Id: I0737ba3fe4e1260d35d51e7b022c9cfd1eb6db58
Signed-off-by: default avatarLoïc Yavercovski <loic.yavercovski@gmail.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/22619


Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Reviewed-by: default avatarArtur Paszkiewicz <artur.paszkiewicz@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBen Walker <ben@nvidia.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarSebastian Brzezinka <sebastian.brzezinka@intel.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
parent 25a9ccb9
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -500,6 +500,39 @@ raid1_submit_process_request(struct raid_bdev_process_request *process_req,
	}
}

static bool
raid1_resize(struct raid_bdev *raid_bdev)
{
	int rc;
	uint64_t min_blockcnt = UINT64_MAX;
	struct raid_base_bdev_info *base_info;

	RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
		struct spdk_bdev *base_bdev;

		if (base_info->desc == NULL) {
			continue;
		}
		base_bdev = spdk_bdev_desc_get_bdev(base_info->desc);
		min_blockcnt = spdk_min(min_blockcnt, base_bdev->blockcnt - base_info->data_offset);
	}

	if (min_blockcnt == raid_bdev->bdev.blockcnt) {
		return false;
	}

	rc = spdk_bdev_notify_blockcnt_change(&raid_bdev->bdev, min_blockcnt);
	if (rc != 0) {
		SPDK_ERRLOG("Failed to notify blockcount change\n");
		return false;
	}

	RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
		base_info->data_size = min_blockcnt;
	}
	return true;
}

static struct raid_bdev_module g_raid1_module = {
	.level = RAID1,
	.base_bdevs_min = 2,
@@ -510,6 +543,7 @@ static struct raid_bdev_module g_raid1_module = {
	.submit_rw_request = raid1_submit_rw_request,
	.get_io_channel = raid1_get_io_channel,
	.submit_process_request = raid1_submit_process_request,
	.resize = raid1_resize,
};
RAID_MODULE_REGISTER(&g_raid1_module)

+22 −5
Original line number Diff line number Diff line
@@ -343,13 +343,15 @@ function raid_state_function_test() {
	return 0
}

function raid0_resize_test() {
function raid_resize_test() {
	local raid_level=$1
	local blksize=$base_blocklen
	local bdev_size_mb=32
	local new_bdev_size_mb=$((bdev_size_mb * 2))
	local blkcnt
	local raid_size_mb
	local new_raid_size_mb
	local expected_size

	$rootdir/test/app/bdev_svc/bdev_svc -r $rpc_server -i 0 -L bdev_raid &
	raid_pid=$!
@@ -359,7 +361,11 @@ function raid0_resize_test() {
	$rpc_py bdev_null_create Base_1 $bdev_size_mb $blksize
	$rpc_py bdev_null_create Base_2 $bdev_size_mb $blksize

	$rpc_py bdev_raid_create -z 64 -r 0 -b "Base_1 Base_2" -n Raid
	if [ $raid_level -eq 0 ]; then
		$rpc_py bdev_raid_create -z 64 -r $raid_level -b "Base_1 Base_2" -n Raid
	else
		$rpc_py bdev_raid_create -r $raid_level -b "Base_1 Base_2" -n Raid
	fi

	# Resize Base_1 first.
	$rpc_py bdev_null_resize Base_1 $new_bdev_size_mb
@@ -367,7 +373,12 @@ function raid0_resize_test() {
	# The size of Raid should not be changed.
	blkcnt=$($rpc_py bdev_get_bdevs -b Raid | jq '.[].num_blocks')
	raid_size_mb=$((blkcnt * blksize / 1048576))
	if [ $raid_size_mb != $((bdev_size_mb * 2)) ]; then
	if [ $raid_level -eq 0 ]; then
		expected_size=$((bdev_size_mb * 2))
	else
		expected_size=$bdev_size_mb
	fi
	if [ $raid_size_mb != $expected_size ]; then
		echo "resize failed"
		return 1
	fi
@@ -378,7 +389,12 @@ function raid0_resize_test() {
	# The size of Raid should be updated to the expected value.
	blkcnt=$($rpc_py bdev_get_bdevs -b Raid | jq '.[].num_blocks')
	raid_size_mb=$((blkcnt * blksize / 1048576))
	if [ $raid_size_mb != $((new_bdev_size_mb * 2)) ]; then
	if [ $raid_level -eq 0 ]; then
		expected_size=$((new_bdev_size_mb * 2))
	else
		expected_size=$new_bdev_size_mb
	fi
	if [ $raid_size_mb != $expected_size ]; then
		echo "resize failed"
		return 1
	fi
@@ -860,7 +876,8 @@ if [ $(uname -s) = Linux ] && modprobe -n nbd; then
	run_test "raid_function_test_concat" raid_function_test concat
fi

run_test "raid0_resize_test" raid0_resize_test
run_test "raid0_resize_test" raid_resize_test 0
run_test "raid1_resize_test" raid_resize_test 1

for n in {2..4}; do
	for level in raid0 concat raid1; do
+1 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ DEFINE_STUB_V(raid_bdev_io_init, (struct raid_bdev_io *raid_io,
				  struct spdk_memory_domain *memory_domain, void *memory_domain_ctx));
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);

int
spdk_bdev_readv_blocks_ext(struct spdk_bdev_desc *desc,