From patchwork Thu Dec 1 10:59:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfgang Bumiller X-Patchwork-Id: 701461 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3tTvcq24KVz9t0v for ; Thu, 1 Dec 2016 22:07:06 +1100 (AEDT) Received: from localhost ([::1]:55493 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cCPCf-0002zr-UX for incoming@patchwork.ozlabs.org; Thu, 01 Dec 2016 06:07:01 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48925) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cCPBm-0002T0-40 for qemu-devel@nongnu.org; Thu, 01 Dec 2016 06:06:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cCPBk-0003ju-QY for qemu-devel@nongnu.org; Thu, 01 Dec 2016 06:06:06 -0500 Received: from proxmox.maurer-it.com ([212.186.127.180]:1848) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cCPBg-0003gk-Hb; Thu, 01 Dec 2016 06:06:00 -0500 Received: from proxmox.maurer-it.com (localhost [127.0.0.1]) by proxmox.maurer-it.com (Proxmox) with ESMTP id A65E8110E93F; Thu, 1 Dec 2016 11:59:28 +0100 (CET) From: Wolfgang Bumiller To: qemu-devel@nongnu.org Date: Thu, 1 Dec 2016 11:59:24 +0100 Message-Id: <1480589964-29411-1-git-send-email-w.bumiller@proxmox.com> X-Mailer: git-send-email 2.1.4 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 212.186.127.180 Subject: [Qemu-devel] [RFC PATCH] glusterfs: allow partial reads X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Jeff Cody , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Fixes #1644754. Signed-off-by: Wolfgang Bumiller --- I'm not sure what the original rationale was to treat both partial reads as well as well as writes as I/O error. (Seems to have happened from original glusterfs v1 to v2 series with a note but no reasoning for the read side as far as I could see.) The general direction lately seems to be to move away from sector based block APIs. Also eg. the NFS code allows partial reads. (It does, however, have an old patch (c2eb918e3) dedicated to aligning sizes to 512 byte boundaries for file creation for compatibility to other parts of qemu like qcow2. This already happens in glusterfs, though, but if you move a file from a different storage over to glusterfs you may end up with a qcow2 file with eg. the L1 table in the last 80 bytes of the file aligned to _begin_ at a 512 boundary, but not _end_ at one.) block/gluster.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/block/gluster.c b/block/gluster.c index 891c13b..3db0bf8 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -41,6 +41,7 @@ typedef struct GlusterAIOCB { int ret; Coroutine *coroutine; AioContext *aio_context; + bool is_write; } GlusterAIOCB; typedef struct BDRVGlusterState { @@ -716,8 +717,10 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret, void *arg) acb->ret = 0; /* Success */ } else if (ret < 0) { acb->ret = -errno; /* Read/Write failed */ + } else if (acb->is_write) { + acb->ret = -EIO; /* Partial write - fail it */ } else { - acb->ret = -EIO; /* Partial read/write - fail it */ + acb->ret = 0; /* Success */ } aio_bh_schedule_oneshot(acb->aio_context, qemu_gluster_complete_aio, acb); @@ -965,6 +968,7 @@ static coroutine_fn int qemu_gluster_co_pwrite_zeroes(BlockDriverState *bs, acb.ret = 0; acb.coroutine = qemu_coroutine_self(); acb.aio_context = bdrv_get_aio_context(bs); + acb.is_write = true; ret = glfs_zerofill_async(s->fd, offset, size, gluster_finish_aiocb, &acb); if (ret < 0) { @@ -1087,9 +1091,11 @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs, acb.aio_context = bdrv_get_aio_context(bs); if (write) { + acb.is_write = true; ret = glfs_pwritev_async(s->fd, qiov->iov, qiov->niov, offset, 0, gluster_finish_aiocb, &acb); } else { + acb.is_write = false; ret = glfs_preadv_async(s->fd, qiov->iov, qiov->niov, offset, 0, gluster_finish_aiocb, &acb); } @@ -1153,6 +1159,7 @@ static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs) acb.ret = 0; acb.coroutine = qemu_coroutine_self(); acb.aio_context = bdrv_get_aio_context(bs); + acb.is_write = true; ret = glfs_fsync_async(s->fd, gluster_finish_aiocb, &acb); if (ret < 0) { @@ -1199,6 +1206,7 @@ static coroutine_fn int qemu_gluster_co_pdiscard(BlockDriverState *bs, acb.ret = 0; acb.coroutine = qemu_coroutine_self(); acb.aio_context = bdrv_get_aio_context(bs); + acb.is_write = true; ret = glfs_discard_async(s->fd, offset, size, gluster_finish_aiocb, &acb); if (ret < 0) {