Commit c22b052b authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Jim Harris
Browse files

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



Implement the resize function for RAID0. raid0_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.

A raid0 bdev always opens all base bdevs. Hence, if the size of base
bdevs are reduced, resize fails now. This limitation will be removed
later.

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

test/iscsi_tgt/resize/resize.sh was used a reference to write the test.
Using jq rather than grep&sed is better and hence replace grep&sed by jq
of test/iscsi_tgt/resize/resize.sh together in this patch.

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


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarArtur Paszkiewicz <artur.paszkiewicz@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: default avatarXiaodong Liu <xiaodong.liu@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent c6d73b5a
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -384,12 +384,36 @@ raid0_start(struct raid_bdev *raid_bdev)
	return 0;
}

static void
raid0_resize(struct raid_bdev *raid_bdev)
{
	uint64_t blockcnt;
	int rc;

	blockcnt = raid0_calculate_blockcnt(raid_bdev);

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

	SPDK_NOTICELOG("raid0 '%s': min blockcount was changed from %" PRIu64 " to %" PRIu64 "\n",
		       raid_bdev->bdev.name,
		       raid_bdev->bdev.blockcnt,
		       blockcnt);

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

static struct raid_bdev_module g_raid0_module = {
	.level = RAID0,
	.base_bdevs_min = 1,
	.start = raid0_start,
	.submit_rw_request = raid0_submit_rw_request,
	.submit_null_payload_request = raid0_submit_null_payload_request,
	.resize = raid0_resize,
};
RAID_MODULE_REGISTER(&g_raid0_module)

+46 −0
Original line number Diff line number Diff line
@@ -247,11 +247,57 @@ function raid_state_function_test() {
	return 0
}

function raid0_resize_test() {
	local blksize=512
	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

	$rootdir/test/app/bdev_svc/bdev_svc -r $rpc_server -i 0 -L bdev_raid &
	raid_pid=$!
	echo "Process raid pid: $raid_pid"
	waitforlisten $raid_pid $rpc_server

	$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

	# Resize Base_1 first.
	$rpc_py bdev_null_resize Base_1 $new_bdev_size_mb

	# 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
		echo "resize failed"
		return 1
	fi

	# Resize Base_2 next.
	$rpc_py bdev_null_resize Base_2 $new_bdev_size_mb

	# 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
		echo "resize failed"
		return 1
	fi

	killprocess $raid_pid

	return 0
}

trap 'on_error_exit;' ERR

raid_function_test raid0
raid_function_test concat
raid_state_function_test raid0
raid_state_function_test concat
raid0_resize_test

rm -f $tmp_file
+2 −2
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ waitforlisten $bdevperf_pid $RESIZE_SOCK
# Resize the Bdev from iSCSI target
$rpc_py bdev_null_resize Null0 $BDEV_NEW_SIZE
# Obtain the Bdev from bdevperf with iSCSI initiator
num_block=$($rpc_py -s $RESIZE_SOCK bdev_get_bdevs | grep num_blocks | sed 's/[^[:digit:]]//g')
num_block=$($rpc_py -s $RESIZE_SOCK bdev_get_bdevs | jq '.[].num_blocks')
# Size is not changed as no IO sent yet and resize notification is deferred.
total_size=$((num_block * BLOCK_SIZE / 1048576))
if [ $total_size != $BDEV_SIZE ]; then
@@ -60,7 +60,7 @@ sleep 2
# Start the bdevperf IO
$rootdir/examples/bdev/bdevperf/bdevperf.py -s $RESIZE_SOCK perform_tests
# Obtain the Bdev from bdevperf with iSCSI initiator
num_block=$($rpc_py -s $RESIZE_SOCK bdev_get_bdevs | grep num_blocks | sed 's/[^[:digit:]]//g')
num_block=$($rpc_py -s $RESIZE_SOCK bdev_get_bdevs | jq '.[].num_blocks')
# Get the new bdev size in MiB.
total_size=$((num_block * BLOCK_SIZE / 1048576))
if [ $total_size != $BDEV_NEW_SIZE ]; then
+1 −0
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ DEFINE_STUB(spdk_bdev_is_md_interleaved, bool, (const struct spdk_bdev *bdev), f
DEFINE_STUB(spdk_bdev_get_dif_type, enum spdk_dif_type, (const struct spdk_bdev *bdev),
	    SPDK_DIF_DISABLE);
DEFINE_STUB(spdk_bdev_is_dif_head_of_md, bool, (const struct spdk_bdev *bdev), false);
DEFINE_STUB(spdk_bdev_notify_blockcnt_change, int, (struct spdk_bdev *bdev, uint64_t size), 0);

struct spdk_io_channel *
spdk_bdev_get_io_channel(struct spdk_bdev_desc *desc)