From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58089) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ejroY-0003Ym-Cc for qemu-devel@nongnu.org; Thu, 08 Feb 2018 14:25:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ejroX-0001lo-5C for qemu-devel@nongnu.org; Thu, 08 Feb 2018 14:24:58 -0500 From: Kevin Wolf Date: Thu, 8 Feb 2018 20:23:19 +0100 Message-Id: <20180208192328.16550-19-kwolf@redhat.com> In-Reply-To: <20180208192328.16550-1-kwolf@redhat.com> References: <20180208192328.16550-1-kwolf@redhat.com> Subject: [Qemu-devel] [PATCH 18/27] sheepdog: QAPIfy "redundacy" create option List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-block@nongnu.org Cc: kwolf@redhat.com, mreitz@redhat.com, pkrempa@redhat.com, eblake@redhat.com, jcody@redhat.com, jdurgin@redhat.com, mitake.hitoshi@lab.ntt.co.jp, namei.unix@gmail.com, qemu-devel@nongnu.org The "redundacy" option for Sheepdog image creation is currently a string that can encode one or two integers depending on its format, which at the same time implicitly selects a mode. This patch turns it into a QAPI union and converts the string into such a QAPI object before interpreting the values. Signed-off-by: Kevin Wolf --- qapi/block-core.json | 45 ++++++++++++++++++++++++++ block/sheepdog.c | 89 ++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 107 insertions(+), 27 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index 4e419b147d..7d004dddf9 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -3447,6 +3447,51 @@ '*cluster-size' : 'size' } } ## +# @SheepdogRedundancyType: +# +# @full Create a fully replicated vdi with x copies +# @erasure-coded Create an erasure coded vdi with x data strips and +# y parity strips +# +# Since: 2.12 +## +{ 'enum': 'SheepdogRedundancyType', + 'data': [ 'full', 'erasure-coded' ] } + +## +# @SheepdogRedundancyFull: +# +# @copies Number of copies to use (between 1 and 31) +# +# Since: 2.12 +## +{ 'struct': 'SheepdogRedundancyFull', + 'data': { 'copies': 'int' }} + +## +# @SheepdogRedundancyErasureCoded: +# +# @data-strips Number of data strips to use (one of {2,4,8,16}) +# @parity-strips Number of parity strips to use (between 1 and 15) +# +# Since: 2.12 +## +{ 'struct': 'SheepdogRedundancyErasureCoded', + 'data': { 'data-strips': 'int', + 'parity-strips': 'int' }} + +## +# @SheepdogRedundancy: +# +# Since: 2.12 +## +{ 'union': 'SheepdogRedundancy', + 'base': { 'type': 'SheepdogRedundancyType' }, + 'discriminator': 'type', + 'data': { 'full': 'SheepdogRedundancyFull', + 'erasure-coded': 'SheepdogRedundancyErasureCoded' } } + +## # @BlockdevCreateNotSupported: # # This is used for all drivers that don't support creating images. diff --git a/block/sheepdog.c b/block/sheepdog.c index f684477328..dc0348f120 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -1887,6 +1887,48 @@ out_with_err_set: return ret; } +static int parse_redundancy(BDRVSheepdogState *s, SheepdogRedundancy *opt) +{ + struct SheepdogInode *inode = &s->inode; + + switch (opt->type) { + case SHEEPDOG_REDUNDANCY_TYPE_FULL: + if (opt->u.full.copies > SD_MAX_COPIES || opt->u.full.copies < 1) { + return -EINVAL; + } + inode->copy_policy = 0; + inode->nr_copies = opt->u.full.copies; + return 0; + + case SHEEPDOG_REDUNDANCY_TYPE_ERASURE_CODED: + { + int64_t copy = opt->u.erasure_coded.data_strips; + int64_t parity = opt->u.erasure_coded.parity_strips; + + if (copy != 2 && copy != 4 && copy != 8 && copy != 16) { + return -EINVAL; + } + + if (parity >= SD_EC_MAX_STRIP || parity < 1) { + return -EINVAL; + } + + /* + * 4 bits for parity and 4 bits for data. + * We have to compress upper data bits because it can't represent 16 + */ + inode->copy_policy = ((copy / 2) << 4) + parity; + inode->nr_copies = copy + parity; + return 0; + } + + default: + g_assert_not_reached(); + } + + return -EINVAL; +} + /* * Sheepdog support two kinds of redundancy, full replication and erasure * coding. @@ -1897,9 +1939,9 @@ out_with_err_set: * # create a erasure coded vdi with x data strips and y parity strips * -o redundancy=x:y (x must be one of {2,4,8,16} and 1 <= y < SD_EC_MAX_STRIP) */ -static int parse_redundancy(BDRVSheepdogState *s, const char *opt) +static int parse_redundancy_str(BDRVSheepdogState *s, const char *opt) { - struct SheepdogInode *inode = &s->inode; + struct SheepdogRedundancy redundancy; const char *n1, *n2; long copy, parity; char p[10]; @@ -1912,35 +1954,28 @@ static int parse_redundancy(BDRVSheepdogState *s, const char *opt) return -EINVAL; } - copy = strtol(n1, NULL, 10); /* FIXME fix error checking by switching to qemu_strtol() */ - if (copy > SD_MAX_COPIES || copy < 1) { - return -EINVAL; - } - if (!n2) { - inode->copy_policy = 0; - inode->nr_copies = copy; - return 0; - } + copy = strtol(n1, NULL, 10); - if (copy != 2 && copy != 4 && copy != 8 && copy != 16) { - return -EINVAL; - } + if (!n2) { + redundancy = (SheepdogRedundancy) { + .type = SHEEPDOG_REDUNDANCY_TYPE_FULL, + .u.full.copies = copy, + }; + } else { + /* FIXME fix error checking by switching to qemu_strtol() */ + parity = strtol(n2, NULL, 10); - parity = strtol(n2, NULL, 10); - /* FIXME fix error checking by switching to qemu_strtol() */ - if (parity >= SD_EC_MAX_STRIP || parity < 1) { - return -EINVAL; + redundancy = (SheepdogRedundancy) { + .type = SHEEPDOG_REDUNDANCY_TYPE_ERASURE_CODED, + .u.erasure_coded = { + .data_strips = copy, + .parity_strips = parity, + }, + }; } - /* - * 4 bits for parity and 4 bits for data. - * We have to compress upper data bits because it can't represent 16 - */ - inode->copy_policy = ((copy / 2) << 4) + parity; - inode->nr_copies = copy + parity; - - return 0; + return parse_redundancy(s, &redundancy); } static int parse_block_size_shift(BDRVSheepdogState *s, QemuOpts *opt) @@ -2012,7 +2047,7 @@ static int sd_create(const char *filename, QemuOpts *opts, g_free(buf); buf = qemu_opt_get_del(opts, BLOCK_OPT_REDUNDANCY); if (buf) { - ret = parse_redundancy(s, buf); + ret = parse_redundancy_str(s, buf); if (ret < 0) { error_setg(errp, "Invalid redundancy mode: '%s'", buf); goto out; -- 2.13.6