From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60107) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vdhlk-00050F-Ho for qemu-devel@nongnu.org; Tue, 05 Nov 2013 09:38:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Vdhlb-0005Tn-Q9 for qemu-devel@nongnu.org; Tue, 05 Nov 2013 09:38:12 -0500 Received: from mail-wg0-x22d.google.com ([2a00:1450:400c:c00::22d]:57441) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vdhlb-0005Tb-JN for qemu-devel@nongnu.org; Tue, 05 Nov 2013 09:38:03 -0500 Received: by mail-wg0-f45.google.com with SMTP id z12so3570203wgg.0 for ; Tue, 05 Nov 2013 06:38:02 -0800 (PST) Date: Tue, 5 Nov 2013 15:37:59 +0100 From: Stefan Hajnoczi Message-ID: <20131105143759.GE16457@stefanha-thinkpad.redhat.com> References: <1383318613-490-1-git-send-email-namei.unix@gmail.com> <1383318613-490-3-git-send-email-namei.unix@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1383318613-490-3-git-send-email-namei.unix@gmail.com> Subject: Re: [Qemu-devel] [PATCH v5 2/2] sheepdog: support user-defined redundancy option List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Liu Yuan Cc: Kevin Wolf , sheepdog@lists.wpkg.org, qemu-devel@nongnu.org, Stefan Hajnoczi On Fri, Nov 01, 2013 at 11:10:13PM +0800, Liu Yuan wrote: > diff --git a/block/sheepdog.c b/block/sheepdog.c > index 66b3ea8..a267d31 100644 > --- a/block/sheepdog.c > +++ b/block/sheepdog.c > @@ -91,6 +91,14 @@ > #define SD_NR_VDIS (1U << 24) > #define SD_DATA_OBJ_SIZE (UINT64_C(1) << 22) > #define SD_MAX_VDI_SIZE (SD_DATA_OBJ_SIZE * MAX_DATA_OBJS) > +/* > + * For erasure coding, we use at most SD_EC_MAX_STRIP for data strips and > + * (SD_EC_MAX_STRIP - 1) for parity strips > + * > + * SD_MAX_COPIES is sum of number of data trips and parity strips. s/data trips/data strips/ > +static bool is_numeric(const char *s) > +{ > + const char *p = s; > + > + if (*p) { > + char c; > + > + while ((c = *p++)) > + if (!isdigit(c)) { > + return false; > + } > + return true; > + } > + return false; > +} > + > +/* > + * Sheepdog support two kinds of redundancy, full replication and erasure > + * coding. > + * > + * # create a fully replicated vdi with x copies > + * -o redundancy=x (1 <= x <= SD_MAX_COPIES) > + * > + * # 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) > +{ > + struct SheepdogInode *inode = &s->inode; > + const char *n1, *n2; > + uint8_t copy, parity; > + char p[10]; > + > + pstrcpy(p, sizeof(p), opt); > + n1 = strtok(p, ":"); > + n2 = strtok(NULL, ":"); > + > + if (!n1 || !is_numeric(n1) || (n2 && !is_numeric(n2))) { > + return -EINVAL; > + } > + > + copy = strtol(n1, NULL, 10); > + if (copy > SD_MAX_COPIES) { > + return -EINVAL; > + } > + if (!n2) { > + inode->copy_policy = 0; > + inode->nr_copies = copy; > + return 0; > + } > + > + if (copy != 2 && copy != 4 && copy != 8 && copy != 16) { > + return -EINVAL; > + } > + > + parity = strtol(n2, NULL, 10); > + if (parity >= SD_EC_MAX_STRIP || parity == 0) { > + 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; > +} The string manipulation can be simplified using sscanf(3) and is_numeric() can be dropped: static int parse_redundancy(BDRVSheepdogState *s, const char *opt) { struct SheepdogInode *inode = &s->inode; uint8_t copy, parity; int n; n = sscanf(opt, "%hhu:%hhu", ©, &parity); if (n != 1 && n != 2) { return -EINVAL; } if (copy > SD_MAX_COPIES) { return -EINVAL; } if (n == 1) { inode->copy_policy = 0; inode->nr_copies = copy; return 0; } if (copy != 2 && copy != 4 && copy != 8 && copy != 16) { return -EINVAL; } if (parity >= SD_EC_MAX_STRIP || parity == 0) { 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; }