From 208f21cdce9cbb67703e2f93bd7b9c3db1cc473f Mon Sep 17 00:00:00 2001 From: Krzysztof Smolinski Date: Mon, 28 Nov 2022 15:35:25 +0100 Subject: [PATCH] raid1: module implementation * added raid1 module functions * raid1 logical volume can be created using standard SPDK RPC * strip size parameter not supported by raid1 Signed-off-by: Krzysztof Smolinski Change-Id: Id3ee1ba0ec28540ca8eb67b04c3ff655a16b1f19 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13444 Tested-by: SPDK CI Jenkins Community-CI: Mellanox Build Bot Reviewed-by: Jim Harris Reviewed-by: Tomasz Zawadzki Reviewed-by: Krzysztof Karas Reviewed-by: Shuhei Matsumoto Reviewed-by: Konrad Sztyber --- module/bdev/raid/Makefile | 2 +- module/bdev/raid/bdev_raid.c | 9 ++++- module/bdev/raid/bdev_raid.h | 1 + module/bdev/raid/bdev_raid_rpc.c | 5 --- module/bdev/raid/raid1.c | 65 ++++++++++++++++++++++++++++++++ scripts/rpc.py | 2 +- 6 files changed, 76 insertions(+), 8 deletions(-) create mode 100644 module/bdev/raid/raid1.c diff --git a/module/bdev/raid/Makefile b/module/bdev/raid/Makefile index e8bf5efd3..162ecee19 100644 --- a/module/bdev/raid/Makefile +++ b/module/bdev/raid/Makefile @@ -10,7 +10,7 @@ SO_VER := 4 SO_MINOR := 0 CFLAGS += -I$(SPDK_ROOT_DIR)/lib/bdev/ -C_SRCS = bdev_raid.c bdev_raid_rpc.c raid0.c concat.c +C_SRCS = bdev_raid.c bdev_raid_rpc.c raid0.c raid1.c concat.c ifeq ($(CONFIG_RAID5F),y) C_SRCS += raid5f.c diff --git a/module/bdev/raid/bdev_raid.c b/module/bdev/raid/bdev_raid.c index c1f8fd0d1..cf1b91e09 100644 --- a/module/bdev/raid/bdev_raid.c +++ b/module/bdev/raid/bdev_raid.c @@ -738,6 +738,8 @@ static struct { } g_raid_level_names[] = { { "raid0", RAID0 }, { "0", RAID0 }, + { "raid1", RAID1 }, + { "1", RAID1 }, { "raid5f", RAID5F }, { "5f", RAID5F }, { "concat", CONCAT }, @@ -925,7 +927,12 @@ raid_bdev_create(const char *name, uint32_t strip_size, uint8_t num_base_bdevs, return -EEXIST; } - if (strip_size && spdk_u32_is_pow2(strip_size) == false) { + if (level == RAID1) { + if (strip_size != 0) { + SPDK_ERRLOG("Strip size is not supported by raid1\n"); + return -EINVAL; + } + } else if (spdk_u32_is_pow2(strip_size) == false) { SPDK_ERRLOG("Invalid strip size %" PRIu32 "\n", strip_size); return -EINVAL; } diff --git a/module/bdev/raid/bdev_raid.h b/module/bdev/raid/bdev_raid.h index 0f2166ada..c8ac1cdf7 100644 --- a/module/bdev/raid/bdev_raid.h +++ b/module/bdev/raid/bdev_raid.h @@ -11,6 +11,7 @@ enum raid_level { INVALID_RAID_LEVEL = -1, RAID0 = 0, + RAID1 = 1, RAID5F = 95, /* 0x5f */ CONCAT = 99, }; diff --git a/module/bdev/raid/bdev_raid_rpc.c b/module/bdev/raid/bdev_raid_rpc.c index 689618766..7def735e4 100644 --- a/module/bdev/raid/bdev_raid_rpc.c +++ b/module/bdev/raid/bdev_raid_rpc.c @@ -220,11 +220,6 @@ rpc_bdev_raid_create(struct spdk_jsonrpc_request *request, goto cleanup; } - if (req.strip_size_kb == 0) { - spdk_jsonrpc_send_error_response(request, -EINVAL, "strip size not specified"); - goto cleanup; - } - rc = raid_bdev_create(req.name, req.strip_size_kb, req.base_bdevs.num_base_bdevs, req.level, &raid_bdev); if (rc != 0) { diff --git a/module/bdev/raid/raid1.c b/module/bdev/raid/raid1.c new file mode 100644 index 000000000..c76541c56 --- /dev/null +++ b/module/bdev/raid/raid1.c @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (C) 2022 Intel Corporation. + * All rights reserved. + */ + +#include "bdev_raid.h" + +#include "spdk/log.h" + +struct raid1_info { + /* The parent raid bdev */ + struct raid_bdev *raid_bdev; +}; + +static void +raid1_submit_rw_request(struct raid_bdev_io *raid_io) +{ + raid_bdev_io_complete(raid_io, SPDK_BDEV_IO_STATUS_FAILED); +} + +static int +raid1_start(struct raid_bdev *raid_bdev) +{ + uint64_t min_blockcnt = UINT64_MAX; + struct raid_base_bdev_info *base_info; + struct raid1_info *r1info; + + r1info = calloc(1, sizeof(*r1info)); + if (!r1info) { + SPDK_ERRLOG("Failed to allocate RAID1 info device structure\n"); + return -ENOMEM; + } + r1info->raid_bdev = raid_bdev; + + RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) { + min_blockcnt = spdk_min(min_blockcnt, base_info->bdev->blockcnt); + } + + raid_bdev->bdev.blockcnt = min_blockcnt; + raid_bdev->module_private = r1info; + + return 0; +} + +static bool +raid1_stop(struct raid_bdev *raid_bdev) +{ + struct raid1_info *r1info = raid_bdev->module_private; + + free(r1info); + + return true; +} + +static struct raid_bdev_module g_raid1_module = { + .level = RAID1, + .base_bdevs_min = 2, + .base_bdevs_constraint = {CONSTRAINT_MIN_BASE_BDEVS_OPERATIONAL, 1}, + .start = raid1_start, + .stop = raid1_stop, + .submit_rw_request = raid1_submit_rw_request, +}; +RAID_MODULE_REGISTER(&g_raid1_module) + +SPDK_LOG_REGISTER_COMPONENT(bdev_raid1) diff --git a/scripts/rpc.py b/scripts/rpc.py index 8494efdef..65c849a84 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -2049,7 +2049,7 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse p = subparsers.add_parser('bdev_raid_create', help='Create new raid bdev') p.add_argument('-n', '--name', help='raid bdev name', required=True) p.add_argument('-z', '--strip-size-kb', help='strip size in KB', type=int) - p.add_argument('-r', '--raid-level', help='raid level, raid0 and a special level concat are supported', required=True) + p.add_argument('-r', '--raid-level', help='raid level, raid0, raid1 and a special level concat are supported', required=True) p.add_argument('-b', '--base-bdevs', help='base bdevs name, whitespace separated list in quotes', required=True) p.set_defaults(func=bdev_raid_create)