From patchwork Wed Apr 23 16:37:36 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Dr. David Alan Gilbert" X-Patchwork-Id: 341943 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id A563E1400F9 for ; Thu, 24 Apr 2014 03:40:36 +1000 (EST) Received: from localhost ([::1]:33812 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wd0FM-0007m4-Fr for incoming@patchwork.ozlabs.org; Wed, 23 Apr 2014 12:42:08 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50762) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wd0BV-0002hz-Hp for qemu-devel@nongnu.org; Wed, 23 Apr 2014 12:38:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Wd0BP-00087H-9x for qemu-devel@nongnu.org; Wed, 23 Apr 2014 12:38:09 -0400 Received: from mx1.redhat.com ([209.132.183.28]:23237) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wd0BP-000870-1T for qemu-devel@nongnu.org; Wed, 23 Apr 2014 12:38:03 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s3NGbxtw002860 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 23 Apr 2014 12:37:59 -0400 Received: from dgilbert-t530.home.treblig.org (vpn1-7-213.ams2.redhat.com [10.36.7.213]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s3NGboKr024273; Wed, 23 Apr 2014 12:37:57 -0400 From: "Dr. David Alan Gilbert (git)" To: qemu-devel@nongnu.org Date: Wed, 23 Apr 2014 17:37:36 +0100 Message-Id: <1398271069-22057-4-git-send-email-dgilbert@redhat.com> In-Reply-To: <1398271069-22057-1-git-send-email-dgilbert@redhat.com> References: <1398271069-22057-1-git-send-email-dgilbert@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: stefanb@linux.vnet.ibm.com, quintela@redhat.com, mdroth@linux.vnet.ibm.com, agraf@suse.de, mst@redhat.com, aliguori@amazon.com, afaerber@suse.de Subject: [Qemu-devel] [RFC PATCH v2 03/16] QEMUFilePart: A shim to read part of a file X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: "Dr. David Alan Gilbert" QEMUFilePart takes a backing QEMUFile and a length, and exposes only 'length' bytes from the backing QEMUFile. Signed-off-by: Dr. David Alan Gilbert --- include/migration/qemu-file.h | 2 ++ qemu-file.c | 73 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h index f066801..88728c9 100644 --- a/include/migration/qemu-file.h +++ b/include/migration/qemu-file.h @@ -121,6 +121,8 @@ QEMUFile *qemu_fdopen(int fd, const char *mode); QEMUFile *qemu_fopen_socket(int fd, const char *mode); QEMUFile *qemu_popen_cmd(const char *command, const char *mode); QEMUFile *qemu_bufopen(const char *mode, QEMUSizedBuffer *input); +QEMUFile *qemu_partopen(const char *mode, QEMUFile *backing, size_t len); + int qemu_get_fd(QEMUFile *f); int qemu_fclose(QEMUFile *f); int64_t qemu_ftell(QEMUFile *f); diff --git a/qemu-file.c b/qemu-file.c index a5bf643..eec4dbc 100644 --- a/qemu-file.c +++ b/qemu-file.c @@ -1244,3 +1244,76 @@ QEMUFile *qemu_bufopen(const char *mode, QEMUSizedBuffer *input) } return s->file; } + +/* + * 'part' QEMUFile is a QEMUFile that will return 'n' bytes from another + * QEMUFile (at it's current pointer) and then stop + * It never reads past 'n' on the backing QEMUFile, thus allowing the caller + * to carry on reading * from the original file. + */ +typedef struct QEMUFilePart { + QEMUFile *backing; + size_t remaining_to_read; /* Bytes left that we can read from backing */ + QEMUFile *file; +} QEMUFilePart; + +static int part_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size) +{ + QEMUFilePart *p = opaque; + int toread, res; + + if (pos != 0) { + /* Not bothering with offsets */ + return -EINVAL; + } + + toread = MIN(size, p->remaining_to_read); + + if (toread == 0) { + /* All done */ + return 0; + } + + res = qemu_get_buffer(p->backing, buf, toread); + + if (res > 0) { + p->remaining_to_read -= res; + } + + return res; +} + +static int part_close(void *opaque) +{ + QEMUFilePart *p = opaque; + + g_free(p); + + /* Note we don't close the backing file, that's still usable */ + + return 0; +} + +static const QEMUFileOps part_read_ops = { + .get_buffer = part_get_buffer, + .close = part_close +}; + +QEMUFile *qemu_partopen(const char *mode, QEMUFile *backing, size_t len) +{ + QEMUFilePart *p; + + if (mode == NULL || strcmp(mode, "r")) { + error_report("qemu_partopen: Only supports 'r' mode"); + return NULL; + } + + p = g_malloc0(sizeof(QEMUFilePart)); + + p->backing = backing; + p->remaining_to_read = len; + p->file = qemu_fopen_ops(p, &part_read_ops); + + return p->file; +} +