From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52338) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WGyM6-00034c-HT for qemu-devel@nongnu.org; Fri, 21 Feb 2014 17:14:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WGyM0-0000gi-PV for qemu-devel@nongnu.org; Fri, 21 Feb 2014 17:14:02 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52127) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WGyM0-0000gU-IY for qemu-devel@nongnu.org; Fri, 21 Feb 2014 17:13:56 -0500 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s1LMDtQI018709 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 21 Feb 2014 17:13:55 -0500 From: Kevin Wolf Date: Fri, 21 Feb 2014 23:12:41 +0100 Message-Id: <1393020771-32712-45-git-send-email-kwolf@redhat.com> In-Reply-To: <1393020771-32712-1-git-send-email-kwolf@redhat.com> References: <1393020771-32712-1-git-send-email-kwolf@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PULL 44/54] blkverify: Extract qemu_iovec_clone() and qemu_iovec_compare() from blkverify. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com From: Beno=C3=AEt Canet qemu_iovec_compare() will be used to compare IOs vectors in quorum blkver= ify mode. The patch extracts these functions in order to factorize the code. Signed-off-by: Benoit Canet Reviewed-by: Max Reitz Signed-off-by: Kevin Wolf --- block/blkverify.c | 108 +-------------------------------------------= ------ include/qemu-common.h | 2 + util/iov.c | 106 ++++++++++++++++++++++++++++++++++++++++++++= +++++ 3 files changed, 110 insertions(+), 106 deletions(-) diff --git a/block/blkverify.c b/block/blkverify.c index 0e28502..b98b08b 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -173,110 +173,6 @@ static int64_t blkverify_getlength(BlockDriverState= *bs) return bdrv_getlength(s->test_file); } =20 -/** - * Check that I/O vector contents are identical - * - * @a: I/O vector - * @b: I/O vector - * @ret: Offset to first mismatching byte or -1 if match - */ -static ssize_t blkverify_iovec_compare(QEMUIOVector *a, QEMUIOVector *b) -{ - int i; - ssize_t offset =3D 0; - - assert(a->niov =3D=3D b->niov); - for (i =3D 0; i < a->niov; i++) { - size_t len =3D 0; - uint8_t *p =3D (uint8_t *)a->iov[i].iov_base; - uint8_t *q =3D (uint8_t *)b->iov[i].iov_base; - - assert(a->iov[i].iov_len =3D=3D b->iov[i].iov_len); - while (len < a->iov[i].iov_len && *p++ =3D=3D *q++) { - len++; - } - - offset +=3D len; - - if (len !=3D a->iov[i].iov_len) { - return offset; - } - } - return -1; -} - -typedef struct { - int src_index; - struct iovec *src_iov; - void *dest_base; -} IOVectorSortElem; - -static int sortelem_cmp_src_base(const void *a, const void *b) -{ - const IOVectorSortElem *elem_a =3D a; - const IOVectorSortElem *elem_b =3D b; - - /* Don't overflow */ - if (elem_a->src_iov->iov_base < elem_b->src_iov->iov_base) { - return -1; - } else if (elem_a->src_iov->iov_base > elem_b->src_iov->iov_base) { - return 1; - } else { - return 0; - } -} - -static int sortelem_cmp_src_index(const void *a, const void *b) -{ - const IOVectorSortElem *elem_a =3D a; - const IOVectorSortElem *elem_b =3D b; - - return elem_a->src_index - elem_b->src_index; -} - -/** - * Copy contents of I/O vector - * - * The relative relationships of overlapping iovecs are preserved. This= is - * necessary to ensure identical semantics in the cloned I/O vector. - */ -static void blkverify_iovec_clone(QEMUIOVector *dest, const QEMUIOVector= *src, - void *buf) -{ - IOVectorSortElem sortelems[src->niov]; - void *last_end; - int i; - - /* Sort by source iovecs by base address */ - for (i =3D 0; i < src->niov; i++) { - sortelems[i].src_index =3D i; - sortelems[i].src_iov =3D &src->iov[i]; - } - qsort(sortelems, src->niov, sizeof(sortelems[0]), sortelem_cmp_src_b= ase); - - /* Allocate buffer space taking into account overlapping iovecs */ - last_end =3D NULL; - for (i =3D 0; i < src->niov; i++) { - struct iovec *cur =3D sortelems[i].src_iov; - ptrdiff_t rewind =3D 0; - - /* Detect overlap */ - if (last_end && last_end > cur->iov_base) { - rewind =3D last_end - cur->iov_base; - } - - sortelems[i].dest_base =3D buf - rewind; - buf +=3D cur->iov_len - MIN(rewind, cur->iov_len); - last_end =3D MAX(cur->iov_base + cur->iov_len, last_end); - } - - /* Sort by source iovec index and build destination iovec */ - qsort(sortelems, src->niov, sizeof(sortelems[0]), sortelem_cmp_src_i= ndex); - for (i =3D 0; i < src->niov; i++) { - qemu_iovec_add(dest, sortelems[i].dest_base, src->iov[i].iov_len= ); - } -} - static BlkverifyAIOCB *blkverify_aio_get(BlockDriverState *bs, bool is_w= rite, int64_t sector_num, QEMUIOVecto= r *qiov, int nb_sectors, @@ -340,7 +236,7 @@ static void blkverify_aio_cb(void *opaque, int ret) =20 static void blkverify_verify_readv(BlkverifyAIOCB *acb) { - ssize_t offset =3D blkverify_iovec_compare(acb->qiov, &acb->raw_qiov= ); + ssize_t offset =3D qemu_iovec_compare(acb->qiov, &acb->raw_qiov); if (offset !=3D -1) { blkverify_err(acb, "contents mismatch in sector %" PRId64, acb->sector_num + (int64_t)(offset / BDRV_SECTOR_S= IZE)); @@ -358,7 +254,7 @@ static BlockDriverAIOCB *blkverify_aio_readv(BlockDri= verState *bs, acb->verify =3D blkverify_verify_readv; acb->buf =3D qemu_blockalign(bs->file, qiov->size); qemu_iovec_init(&acb->raw_qiov, acb->qiov->niov); - blkverify_iovec_clone(&acb->raw_qiov, qiov, acb->buf); + qemu_iovec_clone(&acb->raw_qiov, qiov, acb->buf); =20 bdrv_aio_readv(s->test_file, sector_num, qiov, nb_sectors, blkverify_aio_cb, acb); diff --git a/include/qemu-common.h b/include/qemu-common.h index b0e34b2..20ace93 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -338,6 +338,8 @@ size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t= offset, const void *buf, size_t bytes); size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset, int fillc, size_t bytes); +ssize_t qemu_iovec_compare(QEMUIOVector *a, QEMUIOVector *b); +void qemu_iovec_clone(QEMUIOVector *dest, const QEMUIOVector *src, void = *buf); =20 bool buffer_is_zero(const void *buf, size_t len); =20 diff --git a/util/iov.c b/util/iov.c index bb46c04..03934da 100644 --- a/util/iov.c +++ b/util/iov.c @@ -378,6 +378,112 @@ size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t= offset, return iov_memset(qiov->iov, qiov->niov, offset, fillc, bytes); } =20 +/** + * Check that I/O vector contents are identical + * + * The IO vectors must have the same structure (same length of all parts= ). + * A typical usage is to compare vectors created with qemu_iovec_clone(). + * + * @a: I/O vector + * @b: I/O vector + * @ret: Offset to first mismatching byte or -1 if match + */ +ssize_t qemu_iovec_compare(QEMUIOVector *a, QEMUIOVector *b) +{ + int i; + ssize_t offset =3D 0; + + assert(a->niov =3D=3D b->niov); + for (i =3D 0; i < a->niov; i++) { + size_t len =3D 0; + uint8_t *p =3D (uint8_t *)a->iov[i].iov_base; + uint8_t *q =3D (uint8_t *)b->iov[i].iov_base; + + assert(a->iov[i].iov_len =3D=3D b->iov[i].iov_len); + while (len < a->iov[i].iov_len && *p++ =3D=3D *q++) { + len++; + } + + offset +=3D len; + + if (len !=3D a->iov[i].iov_len) { + return offset; + } + } + return -1; +} + +typedef struct { + int src_index; + struct iovec *src_iov; + void *dest_base; +} IOVectorSortElem; + +static int sortelem_cmp_src_base(const void *a, const void *b) +{ + const IOVectorSortElem *elem_a =3D a; + const IOVectorSortElem *elem_b =3D b; + + /* Don't overflow */ + if (elem_a->src_iov->iov_base < elem_b->src_iov->iov_base) { + return -1; + } else if (elem_a->src_iov->iov_base > elem_b->src_iov->iov_base) { + return 1; + } else { + return 0; + } +} + +static int sortelem_cmp_src_index(const void *a, const void *b) +{ + const IOVectorSortElem *elem_a =3D a; + const IOVectorSortElem *elem_b =3D b; + + return elem_a->src_index - elem_b->src_index; +} + +/** + * Copy contents of I/O vector + * + * The relative relationships of overlapping iovecs are preserved. This= is + * necessary to ensure identical semantics in the cloned I/O vector. + */ +void qemu_iovec_clone(QEMUIOVector *dest, const QEMUIOVector *src, void = *buf) +{ + IOVectorSortElem sortelems[src->niov]; + void *last_end; + int i; + + /* Sort by source iovecs by base address */ + for (i =3D 0; i < src->niov; i++) { + sortelems[i].src_index =3D i; + sortelems[i].src_iov =3D &src->iov[i]; + } + qsort(sortelems, src->niov, sizeof(sortelems[0]), sortelem_cmp_src_b= ase); + + /* Allocate buffer space taking into account overlapping iovecs */ + last_end =3D NULL; + for (i =3D 0; i < src->niov; i++) { + struct iovec *cur =3D sortelems[i].src_iov; + ptrdiff_t rewind =3D 0; + + /* Detect overlap */ + if (last_end && last_end > cur->iov_base) { + rewind =3D last_end - cur->iov_base; + } + + sortelems[i].dest_base =3D buf - rewind; + buf +=3D cur->iov_len - MIN(rewind, cur->iov_len); + last_end =3D MAX(cur->iov_base + cur->iov_len, last_end); + } + + /* Sort by source iovec index and build destination iovec */ + qsort(sortelems, src->niov, sizeof(sortelems[0]), sortelem_cmp_src_i= ndex); + for (i =3D 0; i < src->niov; i++) { + qemu_iovec_add(dest, sortelems[i].dest_base, src->iov[i].iov_len= ); + } +} + size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt, size_t bytes) { --=20 1.8.1.4