qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/21] Block patches
@ 2010-05-14 17:10 Kevin Wolf
  0 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2010-05-14 17:10 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

The following changes since commit 14ac15d3ac8e0ef1c91204e2ac772b6412a6b99e:
  Anthony Liguori (1):
        Update SeaBIOS

are available in the git repository at:

  git://repo.or.cz/qemu/kevin.git block

Bruce Rogers (1):
      use qemu_free() instead of free()

Christoph Hellwig (9):
      cloop: use pread
      cloop: use qemu block API
      bochs: use pread
      bochs: use qemu block API
      parallels: use pread
      parallels: use qemu block API
      dmg: fix reading of uncompressed chunks
      dmg: use pread
      dmg: use qemu block API

Daniel P. Berrange (1):
      Fix docs for block stats monitor command

Kevin Wolf (5):
      ide: Fix ide_dma_cancel
      block: Avoid unchecked casts for AIOCBs
      block: Fix protocol detection for Windows devices
      block: Fix bdrv_commit
      block: Remove special case for vvfat

Ryota Ozaki (1):
      qemu-nbd: Improve error reporting

Stefan Hajnoczi (1):
      block: Remove semicolon in BDRV_SECTOR_MASK macro

Stefan Weil (3):
      block/vdi: Allow disk images of size 0
      block/vpc: Fix conversion from size to disk geometry
      block/vdi: Fix image opening and creation for odd disk sizes

 block.c           |   49 +++++++++++-------------
 block.h           |    2 +-
 block/blkdebug.c  |    4 +-
 block/bochs.c     |   81 +++++++++++----------------------------
 block/cloop.c     |   48 ++++++++++++------------
 block/dmg.c       |  109 +++++++++++++++++++++++++++++------------------------
 block/parallels.c |   51 +++++++------------------
 block/qcow.c      |    2 +-
 block/qcow2.c     |    2 +-
 block/vdi.c       |   34 ++++++++++++-----
 block/vpc.c       |   21 ++++++----
 hw/ide/core.c     |    8 ++--
 qemu-nbd.c        |   34 ++++++++++++-----
 13 files changed, 213 insertions(+), 232 deletions(-)

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PULL 00/21] Block patches
@ 2011-07-19 10:15 Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 01/21] sheepdog: add full data preallocation support Kevin Wolf
                   ` (20 more replies)
  0 siblings, 21 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

The following changes since commit 89b9ba661bd2d6155308f895ec075d813f0e129b:

  Fix signal handling of SIG_IPI when io-thread is enabled (2011-07-16 19:43:00 +0000)

are available in the git repository at:
  git://repo.or.cz/qemu/kevin.git for-anthony

Devin Nakamura (2):
      qemu-io: Fix formatting
      qemu-io: Fix if scoping bug

Fam Zheng (12):
      VMDK: introduce VmdkExtent
      VMDK: bugfix, align offset to cluster in get_whole_cluster
      VMDK: probe for monolithicFlat images
      VMDK: separate vmdk_open by format version
      VMDK: add field BDRVVmdkState.desc_offset
      VMDK: flush multiple extents
      VMDK: move 'static' cid_update flag to bs field
      VMDK: change get_cluster_offset return type
      VMDK: open/read/write for monolithicFlat image
      VMDK: create different subformats
      VMDK: fix coding style
      block: add bdrv_get_allocated_file_size() operation

Hannes Reinecke (4):
      iov: Update parameter usage in iov_(to|from)_buf()
      scsi: Add 'hba_private' to SCSIRequest
      scsi-disk: Fixup debugging statement
      scsi-disk: Mask out serial number EVPD

Luiz Capitulino (2):
      qemu-options.hx: Document missing -drive options
      qemu-config: Document -drive options

MORITA Kazutaka (1):
      sheepdog: add full data preallocation support

 block.c                |   19 +
 block.h                |    1 +
 block/raw-posix.c      |   21 +
 block/raw-win32.c      |   29 +
 block/sheepdog.c       |   71 ++-
 block/vmdk.c           | 1297 ++++++++++++++++--------
 block_int.h            |    2 +
 hw/esp.c               |    2 +-
 hw/lsi53c895a.c        |   22 +-
 hw/scsi-bus.c          |    9 +-
 hw/scsi-disk.c         |   21 +-
 hw/scsi-generic.c      |    5 +-
 hw/scsi.h              |   10 +-
 hw/spapr_vscsi.c       |   29 +-
 hw/usb-msd.c           |    9 +-
 hw/virtio-net.c        |    2 +-
 hw/virtio-serial-bus.c |    2 +-
 iov.c                  |   49 +-
 iov.h                  |   10 +-
 qemu-config.c          |    6 +
 qemu-img.c             |   31 +-
 qemu-io.c              | 2653 ++++++++++++++++++++++++------------------------
 qemu-options.hx        |    8 +
 23 files changed, 2462 insertions(+), 1846 deletions(-)

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 01/21] sheepdog: add full data preallocation support
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 02/21] qemu-io: Fix formatting Kevin Wolf
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>

This introduces qemu-img create option for sheepdog which allows the
data to be fully preallocated (note that sheepdog always preallocates
metadata).

The option is disabled by default and you need to enable it like the
following:

qemu-img create sheepdog:test -o preallocation=full 1G

Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/sheepdog.c |   71 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 80d106c..77a4de5 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -1286,6 +1286,49 @@ static int do_sd_create(char *filename, int64_t vdi_size,
     return 0;
 }
 
+static int sd_prealloc(const char *filename)
+{
+    BlockDriverState *bs = NULL;
+    uint32_t idx, max_idx;
+    int64_t vdi_size;
+    void *buf = qemu_mallocz(SD_DATA_OBJ_SIZE);
+    int ret;
+
+    ret = bdrv_file_open(&bs, filename, BDRV_O_RDWR);
+    if (ret < 0) {
+        goto out;
+    }
+
+    vdi_size = bdrv_getlength(bs);
+    if (vdi_size < 0) {
+        ret = vdi_size;
+        goto out;
+    }
+    max_idx = DIV_ROUND_UP(vdi_size, SD_DATA_OBJ_SIZE);
+
+    for (idx = 0; idx < max_idx; idx++) {
+        /*
+         * The created image can be a cloned image, so we need to read
+         * a data from the source image.
+         */
+        ret = bdrv_pread(bs, idx * SD_DATA_OBJ_SIZE, buf, SD_DATA_OBJ_SIZE);
+        if (ret < 0) {
+            goto out;
+        }
+        ret = bdrv_pwrite(bs, idx * SD_DATA_OBJ_SIZE, buf, SD_DATA_OBJ_SIZE);
+        if (ret < 0) {
+            goto out;
+        }
+    }
+out:
+    if (bs) {
+        bdrv_delete(bs);
+    }
+    qemu_free(buf);
+
+    return ret;
+}
+
 static int sd_create(const char *filename, QEMUOptionParameter *options)
 {
     int ret;
@@ -1295,13 +1338,15 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
     BDRVSheepdogState s;
     char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];
     uint32_t snapid;
+    int prealloc = 0;
+    const char *vdiname;
 
-    strstart(filename, "sheepdog:", (const char **)&filename);
+    strstart(filename, "sheepdog:", &vdiname);
 
     memset(&s, 0, sizeof(s));
     memset(vdi, 0, sizeof(vdi));
     memset(tag, 0, sizeof(tag));
-    if (parse_vdiname(&s, filename, vdi, &snapid, tag) < 0) {
+    if (parse_vdiname(&s, vdiname, vdi, &snapid, tag) < 0) {
         error_report("invalid filename");
         return -EINVAL;
     }
@@ -1311,6 +1356,16 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
             vdi_size = options->value.n;
         } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
             backing_file = options->value.s;
+        } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
+            if (!options->value.s || !strcmp(options->value.s, "off")) {
+                prealloc = 0;
+            } else if (!strcmp(options->value.s, "full")) {
+                prealloc = 1;
+            } else {
+                error_report("Invalid preallocation mode: '%s'",
+                             options->value.s);
+                return -EINVAL;
+            }
         }
         options++;
     }
@@ -1348,7 +1403,12 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
         bdrv_delete(bs);
     }
 
-    return do_sd_create((char *)vdi, vdi_size, base_vid, &vid, 0, s.addr, s.port);
+    ret = do_sd_create(vdi, vdi_size, base_vid, &vid, 0, s.addr, s.port);
+    if (!prealloc || ret) {
+        return ret;
+    }
+
+    return sd_prealloc(filename);
 }
 
 static void sd_close(BlockDriverState *bs)
@@ -1984,6 +2044,11 @@ static QEMUOptionParameter sd_create_options[] = {
         .type = OPT_STRING,
         .help = "File name of a base image"
     },
+    {
+        .name = BLOCK_OPT_PREALLOC,
+        .type = OPT_STRING,
+        .help = "Preallocation mode (allowed values: off, full)"
+    },
     { NULL }
 };
 
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 02/21] qemu-io: Fix formatting
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 01/21] sheepdog: add full data preallocation support Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 03/21] qemu-io: Fix if scoping bug Kevin Wolf
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Devin Nakamura <devin122@gmail.com>

Replaced tabs with spaces, 8 space indentations with 4 space
indentation, and other fixes to better adhere to CODING_STYLE

Signed-off-by: Devin Nakamura <devin122@gmail.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qemu-io.c | 2652 +++++++++++++++++++++++++++++++------------------------------
 1 files changed, 1330 insertions(+), 1322 deletions(-)

diff --git a/qemu-io.c b/qemu-io.c
index dd4ebf5..e3c825f 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -20,7 +20,7 @@
 
 #define VERSION	"0.0.1"
 
-#define CMD_NOFILE_OK	0x01
+#define CMD_NOFILE_OK   0x01
 
 char *progname;
 static BlockDriverState *bs;
@@ -35,16 +35,16 @@ static int misalign;
  */
 static int parse_pattern(const char *arg)
 {
-	char *endptr = NULL;
-	long pattern;
+    char *endptr = NULL;
+    long pattern;
 
-	pattern = strtol(arg, &endptr, 0);
-	if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') {
-		printf("%s is not a valid pattern byte\n", arg);
-		return -1;
-	}
+    pattern = strtol(arg, &endptr, 0);
+    if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') {
+        printf("%s is not a valid pattern byte\n", arg);
+        return -1;
+    }
 
-	return pattern;
+    return pattern;
 }
 
 /*
@@ -54,70 +54,73 @@ static int parse_pattern(const char *arg)
  * that is specified on the command line.
  */
 
-#define MISALIGN_OFFSET		16
+#define MISALIGN_OFFSET     16
 static void *qemu_io_alloc(size_t len, int pattern)
 {
-	void *buf;
-
-	if (misalign)
-		len += MISALIGN_OFFSET;
-	buf = qemu_blockalign(bs, len);
-	memset(buf, pattern, len);
-	if (misalign)
-		buf += MISALIGN_OFFSET;
-	return buf;
+    void *buf;
+
+    if (misalign) {
+        len += MISALIGN_OFFSET;
+    }
+    buf = qemu_blockalign(bs, len);
+    memset(buf, pattern, len);
+    if (misalign) {
+        buf += MISALIGN_OFFSET;
+    }
+    return buf;
 }
 
 static void qemu_io_free(void *p)
 {
-	if (misalign)
-		p -= MISALIGN_OFFSET;
-	qemu_vfree(p);
+    if (misalign) {
+        p -= MISALIGN_OFFSET;
+    }
+    qemu_vfree(p);
 }
 
-static void
-dump_buffer(const void *buffer, int64_t offset, int len)
+static void dump_buffer(const void *buffer, int64_t offset, int len)
 {
-	int i, j;
-	const uint8_t *p;
-
-	for (i = 0, p = buffer; i < len; i += 16) {
-		const uint8_t *s = p;
-
-                printf("%08" PRIx64 ":  ", offset + i);
-		for (j = 0; j < 16 && i + j < len; j++, p++)
-			printf("%02x ", *p);
-		printf(" ");
-		for (j = 0; j < 16 && i + j < len; j++, s++) {
-			if (isalnum(*s))
-				printf("%c", *s);
-			else
-				printf(".");
-		}
-		printf("\n");
-	}
+    int i, j;
+    const uint8_t *p;
+
+    for (i = 0, p = buffer; i < len; i += 16) {
+        const uint8_t *s = p;
+
+        printf("%08" PRIx64 ":  ", offset + i);
+        for (j = 0; j < 16 && i + j < len; j++, p++) {
+            printf("%02x ", *p);
+        }
+        printf(" ");
+        for (j = 0; j < 16 && i + j < len; j++, s++) {
+            if (isalnum(*s)) {
+                printf("%c", *s);
+            } else {
+                printf(".");
+            }
+        }
+        printf("\n");
+    }
 }
 
-static void
-print_report(const char *op, struct timeval *t, int64_t offset,
-		int count, int total, int cnt, int Cflag)
+static void print_report(const char *op, struct timeval *t, int64_t offset,
+                         int count, int total, int cnt, int Cflag)
 {
-	char s1[64], s2[64], ts[64];
-
-	timestr(t, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0);
-	if (!Cflag) {
-		cvtstr((double)total, s1, sizeof(s1));
-		cvtstr(tdiv((double)total, *t), s2, sizeof(s2));
-                printf("%s %d/%d bytes at offset %" PRId64 "\n",
-                       op, total, count, offset);
-		printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n",
-			s1, cnt, ts, s2, tdiv((double)cnt, *t));
-	} else {/* bytes,ops,time,bytes/sec,ops/sec */
-		printf("%d,%d,%s,%.3f,%.3f\n",
-			total, cnt, ts,
-			tdiv((double)total, *t),
-			tdiv((double)cnt, *t));
-	}
+    char s1[64], s2[64], ts[64];
+
+    timestr(t, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0);
+    if (!Cflag) {
+        cvtstr((double)total, s1, sizeof(s1));
+        cvtstr(tdiv((double)total, *t), s2, sizeof(s2));
+        printf("%s %d/%d bytes at offset %" PRId64 "\n",
+               op, total, count, offset);
+        printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n",
+               s1, cnt, ts, s2, tdiv((double)cnt, *t));
+    } else {/* bytes,ops,time,bytes/sec,ops/sec */
+        printf("%d,%d,%s,%.3f,%.3f\n",
+            total, cnt, ts,
+            tdiv((double)total, *t),
+            tdiv((double)cnt, *t));
+    }
 }
 
 /*
@@ -127,192 +130,200 @@ print_report(const char *op, struct timeval *t, int64_t offset,
 static void *
 create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
 {
-	size_t *sizes = calloc(nr_iov, sizeof(size_t));
-	size_t count = 0;
-	void *buf = NULL;
-	void *p;
-	int i;
-
-	for (i = 0; i < nr_iov; i++) {
-		char *arg = argv[i];
-                int64_t len;
-
-		len = cvtnum(arg);
-		if (len < 0) {
-			printf("non-numeric length argument -- %s\n", arg);
-			goto fail;
-		}
-
-		/* should be SIZE_T_MAX, but that doesn't exist */
-		if (len > INT_MAX) {
-			printf("too large length argument -- %s\n", arg);
-			goto fail;
-		}
-
-		if (len & 0x1ff) {
-                        printf("length argument %" PRId64
-                               " is not sector aligned\n", len);
-			goto fail;
-		}
-
-		sizes[i] = len;
-		count += len;
-	}
-
-	qemu_iovec_init(qiov, nr_iov);
-
-	buf = p = qemu_io_alloc(count, pattern);
-
-	for (i = 0; i < nr_iov; i++) {
-		qemu_iovec_add(qiov, p, sizes[i]);
-		p += sizes[i];
-	}
+    size_t *sizes = calloc(nr_iov, sizeof(size_t));
+    size_t count = 0;
+    void *buf = NULL;
+    void *p;
+    int i;
+
+    for (i = 0; i < nr_iov; i++) {
+        char *arg = argv[i];
+        int64_t len;
+
+        len = cvtnum(arg);
+        if (len < 0) {
+            printf("non-numeric length argument -- %s\n", arg);
+            goto fail;
+        }
+
+        /* should be SIZE_T_MAX, but that doesn't exist */
+        if (len > INT_MAX) {
+            printf("too large length argument -- %s\n", arg);
+            goto fail;
+        }
+
+        if (len & 0x1ff) {
+            printf("length argument %" PRId64
+                   " is not sector aligned\n", len);
+            goto fail;
+        }
+
+        sizes[i] = len;
+        count += len;
+    }
+
+    qemu_iovec_init(qiov, nr_iov);
+
+    buf = p = qemu_io_alloc(count, pattern);
+
+    for (i = 0; i < nr_iov; i++) {
+        qemu_iovec_add(qiov, p, sizes[i]);
+        p += sizes[i];
+    }
 
 fail:
-	free(sizes);
-	return buf;
+    free(sizes);
+    return buf;
 }
 
 static int do_read(char *buf, int64_t offset, int count, int *total)
 {
-	int ret;
+    int ret;
 
-	ret = bdrv_read(bs, offset >> 9, (uint8_t *)buf, count >> 9);
-	if (ret < 0)
-		return ret;
-	*total = count;
-	return 1;
+    ret = bdrv_read(bs, offset >> 9, (uint8_t *)buf, count >> 9);
+    if (ret < 0) {
+        return ret;
+    }
+    *total = count;
+    return 1;
 }
 
 static int do_write(char *buf, int64_t offset, int count, int *total)
 {
-	int ret;
+    int ret;
 
-	ret = bdrv_write(bs, offset >> 9, (uint8_t *)buf, count >> 9);
-	if (ret < 0)
-		return ret;
-	*total = count;
-	return 1;
+    ret = bdrv_write(bs, offset >> 9, (uint8_t *)buf, count >> 9);
+    if (ret < 0) {
+        return ret;
+    }
+    *total = count;
+    return 1;
 }
 
 static int do_pread(char *buf, int64_t offset, int count, int *total)
 {
-	*total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
-	if (*total < 0)
-		return *total;
-	return 1;
+    *total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
+    if (*total < 0) {
+        return *total;
+    }
+    return 1;
 }
 
 static int do_pwrite(char *buf, int64_t offset, int count, int *total)
 {
-	*total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count);
-	if (*total < 0)
-		return *total;
-	return 1;
+    *total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count);
+    if (*total < 0) {
+        return *total;
+    }
+    return 1;
 }
 
 static int do_load_vmstate(char *buf, int64_t offset, int count, int *total)
 {
-	*total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
-	if (*total < 0)
-		return *total;
-	return 1;
+    *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
+    if (*total < 0) {
+        return *total;
+    }
+    return 1;
 }
 
 static int do_save_vmstate(char *buf, int64_t offset, int count, int *total)
 {
-	*total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count);
-	if (*total < 0)
-		return *total;
-	return 1;
+    *total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count);
+    if (*total < 0) {
+        return *total;
+    }
+    return 1;
 }
 
 #define NOT_DONE 0x7fffffff
 static void aio_rw_done(void *opaque, int ret)
 {
-	*(int *)opaque = ret;
+    *(int *)opaque = ret;
 }
 
 static int do_aio_readv(QEMUIOVector *qiov, int64_t offset, int *total)
 {
-	BlockDriverAIOCB *acb;
-	int async_ret = NOT_DONE;
+    BlockDriverAIOCB *acb;
+    int async_ret = NOT_DONE;
 
-	acb = bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9,
-			     aio_rw_done, &async_ret);
-	if (!acb)
-		return -EIO;
-
-	while (async_ret == NOT_DONE)
-		qemu_aio_wait();
+    acb = bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9,
+                         aio_rw_done, &async_ret);
+    if (!acb) {
+        return -EIO;
+    }
+    while (async_ret == NOT_DONE) {
+        qemu_aio_wait();
+    }
 
-	*total = qiov->size;
-	return async_ret < 0 ? async_ret : 1;
+    *total = qiov->size;
+    return async_ret < 0 ? async_ret : 1;
 }
 
 static int do_aio_writev(QEMUIOVector *qiov, int64_t offset, int *total)
 {
-	BlockDriverAIOCB *acb;
-	int async_ret = NOT_DONE;
+    BlockDriverAIOCB *acb;
+    int async_ret = NOT_DONE;
 
-	acb = bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9,
-			      aio_rw_done, &async_ret);
-	if (!acb)
-		return -EIO;
+    acb = bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9,
+                          aio_rw_done, &async_ret);
+    if (!acb) {
+        return -EIO;
+    }
 
-	while (async_ret == NOT_DONE)
-		qemu_aio_wait();
+    while (async_ret == NOT_DONE) {
+        qemu_aio_wait();
+    }
 
-	*total = qiov->size;
-	return async_ret < 0 ? async_ret : 1;
+    *total = qiov->size;
+    return async_ret < 0 ? async_ret : 1;
 }
 
 struct multiwrite_async_ret {
-	int num_done;
-	int error;
+    int num_done;
+    int error;
 };
 
 static void multiwrite_cb(void *opaque, int ret)
 {
-	struct multiwrite_async_ret *async_ret = opaque;
+    struct multiwrite_async_ret *async_ret = opaque;
 
-	async_ret->num_done++;
-	if (ret < 0) {
-		async_ret->error = ret;
-	}
+    async_ret->num_done++;
+    if (ret < 0) {
+        async_ret->error = ret;
+    }
 }
 
 static int do_aio_multiwrite(BlockRequest* reqs, int num_reqs, int *total)
 {
-	int i, ret;
-	struct multiwrite_async_ret async_ret = {
-		.num_done = 0,
-		.error = 0,
-	};
-
-	*total = 0;
-	for (i = 0; i < num_reqs; i++) {
-		reqs[i].cb = multiwrite_cb;
-		reqs[i].opaque = &async_ret;
-		*total += reqs[i].qiov->size;
-	}
-
-	ret = bdrv_aio_multiwrite(bs, reqs, num_reqs);
-	if (ret < 0) {
-		return ret;
-	}
-
-	while (async_ret.num_done < num_reqs) {
-		qemu_aio_wait();
-	}
-
-	return async_ret.error < 0 ? async_ret.error : 1;
+    int i, ret;
+    struct multiwrite_async_ret async_ret = {
+        .num_done = 0,
+        .error = 0,
+    };
+
+    *total = 0;
+    for (i = 0; i < num_reqs; i++) {
+        reqs[i].cb = multiwrite_cb;
+        reqs[i].opaque = &async_ret;
+        *total += reqs[i].qiov->size;
+    }
+
+    ret = bdrv_aio_multiwrite(bs, reqs, num_reqs);
+    if (ret < 0) {
+        return ret;
+    }
+
+    while (async_ret.num_done < num_reqs) {
+        qemu_aio_wait();
+    }
+
+    return async_ret.error < 0 ? async_ret.error : 1;
 }
 
-static void
-read_help(void)
+static void read_help(void)
 {
-	printf(
+    printf(
 "\n"
 " reads a range of bytes from the given offset\n"
 "\n"
@@ -335,94 +346,95 @@ read_help(void)
 static int read_f(int argc, char **argv);
 
 static const cmdinfo_t read_cmd = {
-	.name		= "read",
-	.altname	= "r",
-	.cfunc		= read_f,
-	.argmin		= 2,
-	.argmax		= -1,
-	.args		= "[-abCpqv] [-P pattern [-s off] [-l len]] off len",
-	.oneline	= "reads a number of bytes at a specified offset",
-	.help		= read_help,
+    .name       = "read",
+    .altname    = "r",
+    .cfunc      = read_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-abCpqv] [-P pattern [-s off] [-l len]] off len",
+    .oneline    = "reads a number of bytes at a specified offset",
+    .help       = read_help,
 };
 
-static int
-read_f(int argc, char **argv)
+static int read_f(int argc, char **argv)
 {
-	struct timeval t1, t2;
-	int Cflag = 0, pflag = 0, qflag = 0, vflag = 0;
-	int Pflag = 0, sflag = 0, lflag = 0, bflag = 0;
-	int c, cnt;
-	char *buf;
-	int64_t offset;
-	int count;
-        /* Some compilers get confused and warn if this is not initialized.  */
-        int total = 0;
-	int pattern = 0, pattern_offset = 0, pattern_count = 0;
-
-	while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != EOF) {
-		switch (c) {
-		case 'b':
-			bflag = 1;
-			break;
-		case 'C':
-			Cflag = 1;
-			break;
-		case 'l':
-			lflag = 1;
-			pattern_count = cvtnum(optarg);
-			if (pattern_count < 0) {
-				printf("non-numeric length argument -- %s\n", optarg);
-				return 0;
-			}
-			break;
-		case 'p':
-			pflag = 1;
-			break;
-		case 'P':
-			Pflag = 1;
-			pattern = parse_pattern(optarg);
-			if (pattern < 0)
-				return 0;
-			break;
-		case 'q':
-			qflag = 1;
-			break;
-		case 's':
-			sflag = 1;
-			pattern_offset = cvtnum(optarg);
-			if (pattern_offset < 0) {
-				printf("non-numeric length argument -- %s\n", optarg);
-				return 0;
-			}
-			break;
-		case 'v':
-			vflag = 1;
-			break;
-		default:
-			return command_usage(&read_cmd);
-		}
-	}
-
-	if (optind != argc - 2)
-		return command_usage(&read_cmd);
-
-	if (bflag && pflag) {
-		printf("-b and -p cannot be specified at the same time\n");
-		return 0;
-	}
-
-	offset = cvtnum(argv[optind]);
-	if (offset < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		return 0;
-	}
-
-	optind++;
-	count = cvtnum(argv[optind]);
-	if (count < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		return 0;
-	}
+    struct timeval t1, t2;
+    int Cflag = 0, pflag = 0, qflag = 0, vflag = 0;
+    int Pflag = 0, sflag = 0, lflag = 0, bflag = 0;
+    int c, cnt;
+    char *buf;
+    int64_t offset;
+    int count;
+    /* Some compilers get confused and warn if this is not initialized.  */
+    int total = 0;
+    int pattern = 0, pattern_offset = 0, pattern_count = 0;
+
+    while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != EOF) {
+        switch (c) {
+        case 'b':
+            bflag = 1;
+            break;
+        case 'C':
+            Cflag = 1;
+            break;
+        case 'l':
+            lflag = 1;
+            pattern_count = cvtnum(optarg);
+            if (pattern_count < 0) {
+                printf("non-numeric length argument -- %s\n", optarg);
+                return 0;
+            }
+            break;
+        case 'p':
+            pflag = 1;
+            break;
+        case 'P':
+            Pflag = 1;
+            pattern = parse_pattern(optarg);
+            if (pattern < 0) {
+                return 0;
+            }
+            break;
+        case 'q':
+            qflag = 1;
+            break;
+        case 's':
+            sflag = 1;
+            pattern_offset = cvtnum(optarg);
+            if (pattern_offset < 0) {
+                printf("non-numeric length argument -- %s\n", optarg);
+                return 0;
+            }
+            break;
+        case 'v':
+            vflag = 1;
+            break;
+        default:
+            return command_usage(&read_cmd);
+        }
+    }
+
+    if (optind != argc - 2) {
+        return command_usage(&read_cmd);
+    }
+
+    if (bflag && pflag) {
+        printf("-b and -p cannot be specified at the same time\n");
+        return 0;
+    }
+
+    offset = cvtnum(argv[optind]);
+    if (offset < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        return 0;
+    }
+
+    optind++;
+    count = cvtnum(argv[optind]);
+    if (count < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        return 0;
+    }
 
     if (!Pflag && (lflag || sflag)) {
         return command_usage(&read_cmd);
@@ -437,66 +449,67 @@ read_f(int argc, char **argv)
         return 0;
     }
 
-	if (!pflag)
-		if (offset & 0x1ff) {
-                        printf("offset %" PRId64 " is not sector aligned\n",
-                               offset);
-			return 0;
-
-		if (count & 0x1ff) {
-			printf("count %d is not sector aligned\n",
-				count);
-			return 0;
-		}
-	}
-
-	buf = qemu_io_alloc(count, 0xab);
-
-	gettimeofday(&t1, NULL);
-	if (pflag)
-		cnt = do_pread(buf, offset, count, &total);
-	else if (bflag)
-		cnt = do_load_vmstate(buf, offset, count, &total);
-	else
-		cnt = do_read(buf, offset, count, &total);
-	gettimeofday(&t2, NULL);
-
-	if (cnt < 0) {
-		printf("read failed: %s\n", strerror(-cnt));
-		goto out;
-	}
-
-	if (Pflag) {
-		void* cmp_buf = malloc(pattern_count);
-		memset(cmp_buf, pattern, pattern_count);
-		if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
-			printf("Pattern verification failed at offset %"
-                               PRId64 ", %d bytes\n",
-                               offset + pattern_offset, pattern_count);
-		}
-		free(cmp_buf);
-	}
-
-	if (qflag)
-		goto out;
-
-        if (vflag)
-		dump_buffer(buf, offset, count);
-
-	/* Finally, report back -- -C gives a parsable format */
-	t2 = tsub(t2, t1);
-	print_report("read", &t2, offset, count, total, cnt, Cflag);
+    if (!pflag)
+        if (offset & 0x1ff) {
+            printf("offset %" PRId64 " is not sector aligned\n",
+                   offset);
+            return 0;
+        }
+        if (count & 0x1ff) {
+            printf("count %d is not sector aligned\n",
+                   count);
+            return 0;
+        }
+
+    buf = qemu_io_alloc(count, 0xab);
+
+    gettimeofday(&t1, NULL);
+    if (pflag) {
+        cnt = do_pread(buf, offset, count, &total);
+    } else if (bflag) {
+        cnt = do_load_vmstate(buf, offset, count, &total);
+    } else {
+        cnt = do_read(buf, offset, count, &total);
+    }
+    gettimeofday(&t2, NULL);
+
+    if (cnt < 0) {
+        printf("read failed: %s\n", strerror(-cnt));
+        goto out;
+    }
+
+    if (Pflag) {
+        void *cmp_buf = malloc(pattern_count);
+        memset(cmp_buf, pattern, pattern_count);
+        if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
+            printf("Pattern verification failed at offset %"
+                   PRId64 ", %d bytes\n",
+                   offset + pattern_offset, pattern_count);
+        }
+        free(cmp_buf);
+    }
+
+    if (qflag) {
+        goto out;
+    }
+
+    if (vflag) {
+        dump_buffer(buf, offset, count);
+    }
+
+    /* Finally, report back -- -C gives a parsable format */
+    t2 = tsub(t2, t1);
+    print_report("read", &t2, offset, count, total, cnt, Cflag);
 
 out:
-	qemu_io_free(buf);
+    qemu_io_free(buf);
 
-	return 0;
+    return 0;
 }
 
-static void
-readv_help(void)
+static void readv_help(void)
 {
-	printf(
+    printf(
 "\n"
 " reads a range of bytes from the given offset into multiple buffers\n"
 "\n"
@@ -516,111 +529,112 @@ readv_help(void)
 static int readv_f(int argc, char **argv);
 
 static const cmdinfo_t readv_cmd = {
-	.name		= "readv",
-	.cfunc		= readv_f,
-	.argmin		= 2,
-	.argmax		= -1,
-	.args		= "[-Cqv] [-P pattern ] off len [len..]",
-	.oneline	= "reads a number of bytes at a specified offset",
-	.help		= readv_help,
+    .name       = "readv",
+    .cfunc      = readv_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-Cqv] [-P pattern ] off len [len..]",
+    .oneline    = "reads a number of bytes at a specified offset",
+    .help       = readv_help,
 };
 
-static int
-readv_f(int argc, char **argv)
+static int readv_f(int argc, char **argv)
 {
-	struct timeval t1, t2;
-	int Cflag = 0, qflag = 0, vflag = 0;
-	int c, cnt;
-	char *buf;
-	int64_t offset;
-        /* Some compilers get confused and warn if this is not initialized.  */
-        int total = 0;
-	int nr_iov;
-	QEMUIOVector qiov;
-	int pattern = 0;
-	int Pflag = 0;
-
-	while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
-		switch (c) {
-		case 'C':
-			Cflag = 1;
-			break;
-		case 'P':
-			Pflag = 1;
-			pattern = parse_pattern(optarg);
-			if (pattern < 0)
-				return 0;
-			break;
-		case 'q':
-			qflag = 1;
-			break;
-		case 'v':
-			vflag = 1;
-			break;
-		default:
-			return command_usage(&readv_cmd);
-		}
-	}
-
-	if (optind > argc - 2)
-		return command_usage(&readv_cmd);
-
-
-	offset = cvtnum(argv[optind]);
-	if (offset < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		return 0;
-	}
-	optind++;
-
-	if (offset & 0x1ff) {
-                printf("offset %" PRId64 " is not sector aligned\n",
-                       offset);
-		return 0;
-	}
-
-	nr_iov = argc - optind;
-	buf = create_iovec(&qiov, &argv[optind], nr_iov, 0xab);
-
-	gettimeofday(&t1, NULL);
-	cnt = do_aio_readv(&qiov, offset, &total);
-	gettimeofday(&t2, NULL);
-
-	if (cnt < 0) {
-		printf("readv failed: %s\n", strerror(-cnt));
-		goto out;
-	}
-
-	if (Pflag) {
-		void* cmp_buf = malloc(qiov.size);
-		memset(cmp_buf, pattern, qiov.size);
-		if (memcmp(buf, cmp_buf, qiov.size)) {
-			printf("Pattern verification failed at offset %"
-                               PRId64 ", %zd bytes\n",
-                               offset, qiov.size);
-		}
-		free(cmp_buf);
-	}
-
-	if (qflag)
-		goto out;
-
-        if (vflag)
-		dump_buffer(buf, offset, qiov.size);
-
-	/* Finally, report back -- -C gives a parsable format */
-	t2 = tsub(t2, t1);
-	print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);
+    struct timeval t1, t2;
+    int Cflag = 0, qflag = 0, vflag = 0;
+    int c, cnt;
+    char *buf;
+    int64_t offset;
+    /* Some compilers get confused and warn if this is not initialized.  */
+    int total = 0;
+    int nr_iov;
+    QEMUIOVector qiov;
+    int pattern = 0;
+    int Pflag = 0;
+
+    while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
+        switch (c) {
+        case 'C':
+            Cflag = 1;
+            break;
+        case 'P':
+            Pflag = 1;
+            pattern = parse_pattern(optarg);
+            if (pattern < 0) {
+                return 0;
+            }
+            break;
+        case 'q':
+            qflag = 1;
+            break;
+        case 'v':
+            vflag = 1;
+            break;
+        default:
+            return command_usage(&readv_cmd);
+        }
+    }
+
+    if (optind > argc - 2) {
+        return command_usage(&readv_cmd);
+    }
+
+
+    offset = cvtnum(argv[optind]);
+    if (offset < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        return 0;
+    }
+    optind++;
+
+    if (offset & 0x1ff) {
+        printf("offset %" PRId64 " is not sector aligned\n",
+               offset);
+        return 0;
+    }
+
+    nr_iov = argc - optind;
+    buf = create_iovec(&qiov, &argv[optind], nr_iov, 0xab);
+
+    gettimeofday(&t1, NULL);
+    cnt = do_aio_readv(&qiov, offset, &total);
+    gettimeofday(&t2, NULL);
+
+    if (cnt < 0) {
+        printf("readv failed: %s\n", strerror(-cnt));
+        goto out;
+    }
+
+    if (Pflag) {
+        void *cmp_buf = malloc(qiov.size);
+        memset(cmp_buf, pattern, qiov.size);
+        if (memcmp(buf, cmp_buf, qiov.size)) {
+            printf("Pattern verification failed at offset %"
+                   PRId64 ", %zd bytes\n", offset, qiov.size);
+        }
+        free(cmp_buf);
+    }
+
+    if (qflag) {
+        goto out;
+    }
+
+    if (vflag) {
+        dump_buffer(buf, offset, qiov.size);
+    }
+
+    /* Finally, report back -- -C gives a parsable format */
+    t2 = tsub(t2, t1);
+    print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);
 
 out:
-	qemu_io_free(buf);
-	return 0;
+    qemu_io_free(buf);
+    return 0;
 }
 
-static void
-write_help(void)
+static void write_help(void)
 {
-	printf(
+    printf(
 "\n"
 " writes a range of bytes from the given offset\n"
 "\n"
@@ -640,121 +654,124 @@ write_help(void)
 static int write_f(int argc, char **argv);
 
 static const cmdinfo_t write_cmd = {
-	.name		= "write",
-	.altname	= "w",
-	.cfunc		= write_f,
-	.argmin		= 2,
-	.argmax		= -1,
-	.args		= "[-abCpq] [-P pattern ] off len",
-	.oneline	= "writes a number of bytes at a specified offset",
-	.help		= write_help,
+    .name       = "write",
+    .altname    = "w",
+    .cfunc      = write_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-abCpq] [-P pattern ] off len",
+    .oneline    = "writes a number of bytes at a specified offset",
+    .help       = write_help,
 };
 
-static int
-write_f(int argc, char **argv)
+static int write_f(int argc, char **argv)
 {
-	struct timeval t1, t2;
-	int Cflag = 0, pflag = 0, qflag = 0, bflag = 0;
-	int c, cnt;
-	char *buf;
-	int64_t offset;
-	int count;
-        /* Some compilers get confused and warn if this is not initialized.  */
-        int total = 0;
-	int pattern = 0xcd;
-
-	while ((c = getopt(argc, argv, "bCpP:q")) != EOF) {
-		switch (c) {
-		case 'b':
-			bflag = 1;
-			break;
-		case 'C':
-			Cflag = 1;
-			break;
-		case 'p':
-			pflag = 1;
-			break;
-		case 'P':
-			pattern = parse_pattern(optarg);
-			if (pattern < 0)
-				return 0;
-			break;
-		case 'q':
-			qflag = 1;
-			break;
-		default:
-			return command_usage(&write_cmd);
-		}
-	}
-
-	if (optind != argc - 2)
-		return command_usage(&write_cmd);
-
-	if (bflag && pflag) {
-		printf("-b and -p cannot be specified at the same time\n");
-		return 0;
-	}
-
-	offset = cvtnum(argv[optind]);
-	if (offset < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		return 0;
-	}
-
-	optind++;
-	count = cvtnum(argv[optind]);
-	if (count < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		return 0;
-	}
-
-	if (!pflag) {
-		if (offset & 0x1ff) {
-                        printf("offset %" PRId64 " is not sector aligned\n",
-                               offset);
-			return 0;
-		}
-
-		if (count & 0x1ff) {
-			printf("count %d is not sector aligned\n",
-				count);
-			return 0;
-		}
-	}
-
-	buf = qemu_io_alloc(count, pattern);
-
-	gettimeofday(&t1, NULL);
-	if (pflag)
-		cnt = do_pwrite(buf, offset, count, &total);
-	else if (bflag)
-		cnt = do_save_vmstate(buf, offset, count, &total);
-	else
-		cnt = do_write(buf, offset, count, &total);
-	gettimeofday(&t2, NULL);
-
-	if (cnt < 0) {
-		printf("write failed: %s\n", strerror(-cnt));
-		goto out;
-	}
-
-	if (qflag)
-		goto out;
-
-	/* Finally, report back -- -C gives a parsable format */
-	t2 = tsub(t2, t1);
-	print_report("wrote", &t2, offset, count, total, cnt, Cflag);
+    struct timeval t1, t2;
+    int Cflag = 0, pflag = 0, qflag = 0, bflag = 0;
+    int c, cnt;
+    char *buf;
+    int64_t offset;
+    int count;
+    /* Some compilers get confused and warn if this is not initialized.  */
+    int total = 0;
+    int pattern = 0xcd;
+
+    while ((c = getopt(argc, argv, "bCpP:q")) != EOF) {
+        switch (c) {
+        case 'b':
+            bflag = 1;
+            break;
+        case 'C':
+            Cflag = 1;
+            break;
+        case 'p':
+            pflag = 1;
+            break;
+        case 'P':
+            pattern = parse_pattern(optarg);
+            if (pattern < 0) {
+                return 0;
+            }
+            break;
+        case 'q':
+            qflag = 1;
+            break;
+        default:
+            return command_usage(&write_cmd);
+        }
+    }
+
+    if (optind != argc - 2) {
+        return command_usage(&write_cmd);
+    }
+
+    if (bflag && pflag) {
+        printf("-b and -p cannot be specified at the same time\n");
+        return 0;
+    }
+
+    offset = cvtnum(argv[optind]);
+    if (offset < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        return 0;
+    }
+
+    optind++;
+    count = cvtnum(argv[optind]);
+    if (count < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        return 0;
+    }
+
+    if (!pflag) {
+        if (offset & 0x1ff) {
+            printf("offset %" PRId64 " is not sector aligned\n",
+                   offset);
+            return 0;
+        }
+
+        if (count & 0x1ff) {
+            printf("count %d is not sector aligned\n",
+                   count);
+            return 0;
+        }
+    }
+
+    buf = qemu_io_alloc(count, pattern);
+
+    gettimeofday(&t1, NULL);
+    if (pflag) {
+        cnt = do_pwrite(buf, offset, count, &total);
+    } else if (bflag) {
+        cnt = do_save_vmstate(buf, offset, count, &total);
+    } else {
+        cnt = do_write(buf, offset, count, &total);
+    }
+    gettimeofday(&t2, NULL);
+
+    if (cnt < 0) {
+        printf("write failed: %s\n", strerror(-cnt));
+        goto out;
+    }
+
+    if (qflag) {
+        goto out;
+    }
+
+    /* Finally, report back -- -C gives a parsable format */
+    t2 = tsub(t2, t1);
+    print_report("wrote", &t2, offset, count, total, cnt, Cflag);
 
 out:
-	qemu_io_free(buf);
+    qemu_io_free(buf);
 
-	return 0;
+    return 0;
 }
 
 static void
 writev_help(void)
 {
-	printf(
+    printf(
 "\n"
 " writes a range of bytes from the given offset source from multiple buffers\n"
 "\n"
@@ -772,90 +789,91 @@ writev_help(void)
 static int writev_f(int argc, char **argv);
 
 static const cmdinfo_t writev_cmd = {
-	.name		= "writev",
-	.cfunc		= writev_f,
-	.argmin		= 2,
-	.argmax		= -1,
-	.args		= "[-Cq] [-P pattern ] off len [len..]",
-	.oneline	= "writes a number of bytes at a specified offset",
-	.help		= writev_help,
+    .name       = "writev",
+    .cfunc      = writev_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-Cq] [-P pattern ] off len [len..]",
+    .oneline    = "writes a number of bytes at a specified offset",
+    .help       = writev_help,
 };
 
-static int
-writev_f(int argc, char **argv)
+static int writev_f(int argc, char **argv)
 {
-	struct timeval t1, t2;
-	int Cflag = 0, qflag = 0;
-	int c, cnt;
-	char *buf;
-	int64_t offset;
-        /* Some compilers get confused and warn if this is not initialized.  */
-        int total = 0;
-	int nr_iov;
-	int pattern = 0xcd;
-	QEMUIOVector qiov;
-
-	while ((c = getopt(argc, argv, "CqP:")) != EOF) {
-		switch (c) {
-		case 'C':
-			Cflag = 1;
-			break;
-		case 'q':
-			qflag = 1;
-			break;
-		case 'P':
-			pattern = parse_pattern(optarg);
-			if (pattern < 0)
-				return 0;
-			break;
-		default:
-			return command_usage(&writev_cmd);
-		}
-	}
-
-	if (optind > argc - 2)
-		return command_usage(&writev_cmd);
-
-	offset = cvtnum(argv[optind]);
-	if (offset < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		return 0;
-	}
-	optind++;
-
-	if (offset & 0x1ff) {
-                printf("offset %" PRId64 " is not sector aligned\n",
-                       offset);
-		return 0;
-	}
-
-	nr_iov = argc - optind;
-	buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern);
-
-	gettimeofday(&t1, NULL);
-	cnt = do_aio_writev(&qiov, offset, &total);
-	gettimeofday(&t2, NULL);
-
-	if (cnt < 0) {
-		printf("writev failed: %s\n", strerror(-cnt));
-		goto out;
-	}
-
-	if (qflag)
-		goto out;
-
-	/* Finally, report back -- -C gives a parsable format */
-	t2 = tsub(t2, t1);
-	print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
+    struct timeval t1, t2;
+    int Cflag = 0, qflag = 0;
+    int c, cnt;
+    char *buf;
+    int64_t offset;
+    /* Some compilers get confused and warn if this is not initialized.  */
+    int total = 0;
+    int nr_iov;
+    int pattern = 0xcd;
+    QEMUIOVector qiov;
+
+    while ((c = getopt(argc, argv, "CqP:")) != EOF) {
+        switch (c) {
+        case 'C':
+            Cflag = 1;
+            break;
+        case 'q':
+            qflag = 1;
+            break;
+        case 'P':
+            pattern = parse_pattern(optarg);
+            if (pattern < 0) {
+                return 0;
+            }
+            break;
+        default:
+            return command_usage(&writev_cmd);
+        }
+    }
+
+    if (optind > argc - 2) {
+        return command_usage(&writev_cmd);
+    }
+
+    offset = cvtnum(argv[optind]);
+    if (offset < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        return 0;
+    }
+    optind++;
+
+    if (offset & 0x1ff) {
+        printf("offset %" PRId64 " is not sector aligned\n",
+               offset);
+        return 0;
+    }
+
+    nr_iov = argc - optind;
+    buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern);
+
+    gettimeofday(&t1, NULL);
+    cnt = do_aio_writev(&qiov, offset, &total);
+    gettimeofday(&t2, NULL);
+
+    if (cnt < 0) {
+        printf("writev failed: %s\n", strerror(-cnt));
+        goto out;
+    }
+
+    if (qflag) {
+        goto out;
+    }
+
+    /* Finally, report back -- -C gives a parsable format */
+    t2 = tsub(t2, t1);
+    print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
 out:
-	qemu_io_free(buf);
-	return 0;
+    qemu_io_free(buf);
+    return 0;
 }
 
-static void
-multiwrite_help(void)
+static void multiwrite_help(void)
 {
-	printf(
+    printf(
 "\n"
 " writes a range of bytes from the given offset source from multiple buffers,\n"
 " in a batch of requests that may be merged by qemu\n"
@@ -876,217 +894,215 @@ multiwrite_help(void)
 static int multiwrite_f(int argc, char **argv);
 
 static const cmdinfo_t multiwrite_cmd = {
-	.name		= "multiwrite",
-	.cfunc		= multiwrite_f,
-	.argmin		= 2,
-	.argmax		= -1,
-	.args		= "[-Cq] [-P pattern ] off len [len..] [; off len [len..]..]",
-	.oneline	= "issues multiple write requests at once",
-	.help		= multiwrite_help,
+    .name       = "multiwrite",
+    .cfunc      = multiwrite_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-Cq] [-P pattern ] off len [len..] [; off len [len..]..]",
+    .oneline    = "issues multiple write requests at once",
+    .help       = multiwrite_help,
 };
 
-static int
-multiwrite_f(int argc, char **argv)
+static int multiwrite_f(int argc, char **argv)
 {
-	struct timeval t1, t2;
-	int Cflag = 0, qflag = 0;
-	int c, cnt;
-	char **buf;
-	int64_t offset, first_offset = 0;
-	/* Some compilers get confused and warn if this is not initialized.  */
-	int total = 0;
-	int nr_iov;
-	int nr_reqs;
-	int pattern = 0xcd;
-	QEMUIOVector *qiovs;
-	int i;
-	BlockRequest *reqs;
-
-	while ((c = getopt(argc, argv, "CqP:")) != EOF) {
-		switch (c) {
-		case 'C':
-			Cflag = 1;
-			break;
-		case 'q':
-			qflag = 1;
-			break;
-		case 'P':
-			pattern = parse_pattern(optarg);
-			if (pattern < 0)
-				return 0;
-			break;
-		default:
-			return command_usage(&writev_cmd);
-		}
-	}
-
-	if (optind > argc - 2)
-		return command_usage(&writev_cmd);
-
-	nr_reqs = 1;
-	for (i = optind; i < argc; i++) {
-		if (!strcmp(argv[i], ";")) {
-			nr_reqs++;
-		}
-	}
-
-	reqs = qemu_malloc(nr_reqs * sizeof(*reqs));
-	buf = qemu_malloc(nr_reqs * sizeof(*buf));
-	qiovs = qemu_malloc(nr_reqs * sizeof(*qiovs));
-
-	for (i = 0; i < nr_reqs; i++) {
-		int j;
-
-		/* Read the offset of the request */
-		offset = cvtnum(argv[optind]);
-		if (offset < 0) {
-			printf("non-numeric offset argument -- %s\n", argv[optind]);
-			return 0;
-		}
-		optind++;
-
-		if (offset & 0x1ff) {
-			printf("offset %lld is not sector aligned\n",
-				(long long)offset);
-			return 0;
-		}
+    struct timeval t1, t2;
+    int Cflag = 0, qflag = 0;
+    int c, cnt;
+    char **buf;
+    int64_t offset, first_offset = 0;
+    /* Some compilers get confused and warn if this is not initialized.  */
+    int total = 0;
+    int nr_iov;
+    int nr_reqs;
+    int pattern = 0xcd;
+    QEMUIOVector *qiovs;
+    int i;
+    BlockRequest *reqs;
+
+    while ((c = getopt(argc, argv, "CqP:")) != EOF) {
+        switch (c) {
+        case 'C':
+            Cflag = 1;
+            break;
+        case 'q':
+            qflag = 1;
+            break;
+        case 'P':
+            pattern = parse_pattern(optarg);
+            if (pattern < 0) {
+                return 0;
+            }
+            break;
+        default:
+            return command_usage(&writev_cmd);
+        }
+    }
+
+    if (optind > argc - 2) {
+        return command_usage(&writev_cmd);
+    }
+
+    nr_reqs = 1;
+    for (i = optind; i < argc; i++) {
+        if (!strcmp(argv[i], ";")) {
+            nr_reqs++;
+        }
+    }
+
+    reqs = qemu_malloc(nr_reqs * sizeof(*reqs));
+    buf = qemu_malloc(nr_reqs * sizeof(*buf));
+    qiovs = qemu_malloc(nr_reqs * sizeof(*qiovs));
+
+    for (i = 0; i < nr_reqs; i++) {
+        int j;
+
+        /* Read the offset of the request */
+        offset = cvtnum(argv[optind]);
+        if (offset < 0) {
+            printf("non-numeric offset argument -- %s\n", argv[optind]);
+            return 0;
+        }
+        optind++;
+
+        if (offset & 0x1ff) {
+            printf("offset %lld is not sector aligned\n",
+                   (long long)offset);
+            return 0;
+        }
 
         if (i == 0) {
             first_offset = offset;
         }
 
-		/* Read lengths for qiov entries */
-		for (j = optind; j < argc; j++) {
-			if (!strcmp(argv[j], ";")) {
-				break;
-			}
-		}
+        /* Read lengths for qiov entries */
+        for (j = optind; j < argc; j++) {
+            if (!strcmp(argv[j], ";")) {
+                break;
+            }
+        }
 
-		nr_iov = j - optind;
+        nr_iov = j - optind;
 
-		/* Build request */
-		reqs[i].qiov = &qiovs[i];
-		buf[i] = create_iovec(reqs[i].qiov, &argv[optind], nr_iov, pattern);
-		reqs[i].sector = offset >> 9;
-		reqs[i].nb_sectors = reqs[i].qiov->size >> 9;
+        /* Build request */
+        reqs[i].qiov = &qiovs[i];
+        buf[i] = create_iovec(reqs[i].qiov, &argv[optind], nr_iov, pattern);
+        reqs[i].sector = offset >> 9;
+        reqs[i].nb_sectors = reqs[i].qiov->size >> 9;
 
-		optind = j + 1;
+        optind = j + 1;
 
-		offset += reqs[i].qiov->size;
-		pattern++;
-	}
+        offset += reqs[i].qiov->size;
+        pattern++;
+    }
 
-	gettimeofday(&t1, NULL);
-	cnt = do_aio_multiwrite(reqs, nr_reqs, &total);
-	gettimeofday(&t2, NULL);
+    gettimeofday(&t1, NULL);
+    cnt = do_aio_multiwrite(reqs, nr_reqs, &total);
+    gettimeofday(&t2, NULL);
 
-	if (cnt < 0) {
-		printf("aio_multiwrite failed: %s\n", strerror(-cnt));
-		goto out;
-	}
+    if (cnt < 0) {
+        printf("aio_multiwrite failed: %s\n", strerror(-cnt));
+        goto out;
+    }
 
-	if (qflag)
-		goto out;
+    if (qflag) {
+        goto out;
+    }
 
-	/* Finally, report back -- -C gives a parsable format */
-	t2 = tsub(t2, t1);
-	print_report("wrote", &t2, first_offset, total, total, cnt, Cflag);
+    /* Finally, report back -- -C gives a parsable format */
+    t2 = tsub(t2, t1);
+    print_report("wrote", &t2, first_offset, total, total, cnt, Cflag);
 out:
-	for (i = 0; i < nr_reqs; i++) {
-		qemu_io_free(buf[i]);
-		qemu_iovec_destroy(&qiovs[i]);
-	}
-	qemu_free(buf);
-	qemu_free(reqs);
-	qemu_free(qiovs);
-	return 0;
+    for (i = 0; i < nr_reqs; i++) {
+        qemu_io_free(buf[i]);
+        qemu_iovec_destroy(&qiovs[i]);
+    }
+    qemu_free(buf);
+    qemu_free(reqs);
+    qemu_free(qiovs);
+    return 0;
 }
 
 struct aio_ctx {
-	QEMUIOVector qiov;
-	int64_t offset;
-	char *buf;
-	int qflag;
-	int vflag;
-	int Cflag;
-	int Pflag;
-	int pattern;
-	struct timeval t1;
+    QEMUIOVector qiov;
+    int64_t offset;
+    char *buf;
+    int qflag;
+    int vflag;
+    int Cflag;
+    int Pflag;
+    int pattern;
+    struct timeval t1;
 };
 
-static void
-aio_write_done(void *opaque, int ret)
+static void aio_write_done(void *opaque, int ret)
 {
-	struct aio_ctx *ctx = opaque;
-	struct timeval t2;
+    struct aio_ctx *ctx = opaque;
+    struct timeval t2;
 
-	gettimeofday(&t2, NULL);
+    gettimeofday(&t2, NULL);
 
 
-	if (ret < 0) {
-		printf("aio_write failed: %s\n", strerror(-ret));
-		goto out;
-	}
+    if (ret < 0) {
+        printf("aio_write failed: %s\n", strerror(-ret));
+        goto out;
+    }
 
-	if (ctx->qflag) {
-		goto out;
-	}
+    if (ctx->qflag) {
+        goto out;
+    }
 
-	/* Finally, report back -- -C gives a parsable format */
-	t2 = tsub(t2, ctx->t1);
-	print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
-		     ctx->qiov.size, 1, ctx->Cflag);
+    /* Finally, report back -- -C gives a parsable format */
+    t2 = tsub(t2, ctx->t1);
+    print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
+                 ctx->qiov.size, 1, ctx->Cflag);
 out:
-	qemu_io_free(ctx->buf);
-	free(ctx);
+    qemu_io_free(ctx->buf);
+    free(ctx);
 }
 
-static void
-aio_read_done(void *opaque, int ret)
+static void aio_read_done(void *opaque, int ret)
 {
-	struct aio_ctx *ctx = opaque;
-	struct timeval t2;
-
-	gettimeofday(&t2, NULL);
-
-	if (ret < 0) {
-		printf("readv failed: %s\n", strerror(-ret));
-		goto out;
-	}
-
-	if (ctx->Pflag) {
-		void *cmp_buf = malloc(ctx->qiov.size);
-
-		memset(cmp_buf, ctx->pattern, ctx->qiov.size);
-		if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
-			printf("Pattern verification failed at offset %"
-                               PRId64 ", %zd bytes\n",
-                               ctx->offset, ctx->qiov.size);
-		}
-		free(cmp_buf);
-	}
-
-	if (ctx->qflag) {
-		goto out;
-	}
-
-	if (ctx->vflag) {
-		dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size);
-	}
-
-	/* Finally, report back -- -C gives a parsable format */
-	t2 = tsub(t2, ctx->t1);
-	print_report("read", &t2, ctx->offset, ctx->qiov.size,
-		     ctx->qiov.size, 1, ctx->Cflag);
+    struct aio_ctx *ctx = opaque;
+    struct timeval t2;
+
+    gettimeofday(&t2, NULL);
+
+    if (ret < 0) {
+        printf("readv failed: %s\n", strerror(-ret));
+        goto out;
+    }
+
+    if (ctx->Pflag) {
+        void *cmp_buf = malloc(ctx->qiov.size);
+
+        memset(cmp_buf, ctx->pattern, ctx->qiov.size);
+        if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
+            printf("Pattern verification failed at offset %"
+                   PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
+        }
+        free(cmp_buf);
+    }
+
+    if (ctx->qflag) {
+        goto out;
+    }
+
+    if (ctx->vflag) {
+        dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size);
+    }
+
+    /* Finally, report back -- -C gives a parsable format */
+    t2 = tsub(t2, ctx->t1);
+    print_report("read", &t2, ctx->offset, ctx->qiov.size,
+                 ctx->qiov.size, 1, ctx->Cflag);
 out:
-	qemu_io_free(ctx->buf);
-	free(ctx);
+    qemu_io_free(ctx->buf);
+    free(ctx);
 }
 
-static void
-aio_read_help(void)
+static void aio_read_help(void)
 {
-	printf(
+    printf(
 "\n"
 " asynchronously reads a range of bytes from the given offset\n"
 "\n"
@@ -1107,88 +1123,86 @@ aio_read_help(void)
 static int aio_read_f(int argc, char **argv);
 
 static const cmdinfo_t aio_read_cmd = {
-	.name		= "aio_read",
-	.cfunc		= aio_read_f,
-	.argmin		= 2,
-	.argmax		= -1,
-	.args		= "[-Cqv] [-P pattern ] off len [len..]",
-	.oneline	= "asynchronously reads a number of bytes",
-	.help		= aio_read_help,
+    .name       = "aio_read",
+    .cfunc      = aio_read_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-Cqv] [-P pattern ] off len [len..]",
+    .oneline    = "asynchronously reads a number of bytes",
+    .help       = aio_read_help,
 };
 
-static int
-aio_read_f(int argc, char **argv)
+static int aio_read_f(int argc, char **argv)
 {
-	int nr_iov, c;
-	struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));
-	BlockDriverAIOCB *acb;
-
-	while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
-		switch (c) {
-		case 'C':
-			ctx->Cflag = 1;
-			break;
-		case 'P':
-			ctx->Pflag = 1;
-			ctx->pattern = parse_pattern(optarg);
-			if (ctx->pattern < 0) {
-                                free(ctx);
-				return 0;
-                        }
-			break;
-		case 'q':
-			ctx->qflag = 1;
-			break;
-		case 'v':
-			ctx->vflag = 1;
-			break;
-		default:
-			free(ctx);
-			return command_usage(&aio_read_cmd);
-		}
-	}
-
-	if (optind > argc - 2) {
-		free(ctx);
-		return command_usage(&aio_read_cmd);
-	}
-
-	ctx->offset = cvtnum(argv[optind]);
-	if (ctx->offset < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		free(ctx);
-		return 0;
-	}
-	optind++;
-
-	if (ctx->offset & 0x1ff) {
-		printf("offset %" PRId64 " is not sector aligned\n",
-                       ctx->offset);
-		free(ctx);
-		return 0;
-	}
-
-	nr_iov = argc - optind;
-	ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab);
-
-	gettimeofday(&ctx->t1, NULL);
-	acb = bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
-			      ctx->qiov.size >> 9, aio_read_done, ctx);
-	if (!acb) {
-		free(ctx->buf);
-		free(ctx);
-		return -EIO;
-	}
-
-	return 0;
+    int nr_iov, c;
+    struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));
+    BlockDriverAIOCB *acb;
+
+    while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
+        switch (c) {
+        case 'C':
+            ctx->Cflag = 1;
+            break;
+        case 'P':
+            ctx->Pflag = 1;
+            ctx->pattern = parse_pattern(optarg);
+            if (ctx->pattern < 0) {
+                free(ctx);
+                return 0;
+            }
+            break;
+        case 'q':
+            ctx->qflag = 1;
+            break;
+        case 'v':
+            ctx->vflag = 1;
+            break;
+        default:
+            free(ctx);
+            return command_usage(&aio_read_cmd);
+        }
+    }
+
+    if (optind > argc - 2) {
+        free(ctx);
+        return command_usage(&aio_read_cmd);
+    }
+
+    ctx->offset = cvtnum(argv[optind]);
+    if (ctx->offset < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        free(ctx);
+        return 0;
+    }
+    optind++;
+
+    if (ctx->offset & 0x1ff) {
+        printf("offset %" PRId64 " is not sector aligned\n",
+               ctx->offset);
+        free(ctx);
+        return 0;
+    }
+
+    nr_iov = argc - optind;
+    ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab);
+
+    gettimeofday(&ctx->t1, NULL);
+    acb = bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
+                         ctx->qiov.size >> 9, aio_read_done, ctx);
+    if (!acb) {
+        free(ctx->buf);
+        free(ctx);
+        return -EIO;
+    }
+
+    return 0;
 }
 
-static void
-aio_write_help(void)
+static void aio_write_help(void)
 {
-	printf(
+    printf(
 "\n"
-" asynchronously writes a range of bytes from the given offset source \n"
+" asynchronously writes a range of bytes from the given offset source\n"
 " from multiple buffers\n"
 "\n"
 " Example:\n"
@@ -1207,199 +1221,196 @@ aio_write_help(void)
 static int aio_write_f(int argc, char **argv);
 
 static const cmdinfo_t aio_write_cmd = {
-	.name		= "aio_write",
-	.cfunc		= aio_write_f,
-	.argmin		= 2,
-	.argmax		= -1,
-	.args		= "[-Cq] [-P pattern ] off len [len..]",
-	.oneline	= "asynchronously writes a number of bytes",
-	.help		= aio_write_help,
+    .name       = "aio_write",
+    .cfunc      = aio_write_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-Cq] [-P pattern ] off len [len..]",
+    .oneline    = "asynchronously writes a number of bytes",
+    .help       = aio_write_help,
 };
 
-static int
-aio_write_f(int argc, char **argv)
+static int aio_write_f(int argc, char **argv)
 {
-	int nr_iov, c;
-	int pattern = 0xcd;
-	struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));
-	BlockDriverAIOCB *acb;
-
-	while ((c = getopt(argc, argv, "CqP:")) != EOF) {
-		switch (c) {
-		case 'C':
-			ctx->Cflag = 1;
-			break;
-		case 'q':
-			ctx->qflag = 1;
-			break;
-		case 'P':
-			pattern = parse_pattern(optarg);
-			if (pattern < 0)
-				return 0;
-			break;
-		default:
-			free(ctx);
-			return command_usage(&aio_write_cmd);
-		}
-	}
-
-	if (optind > argc - 2) {
-		free(ctx);
-		return command_usage(&aio_write_cmd);
-	}
-
-	ctx->offset = cvtnum(argv[optind]);
-	if (ctx->offset < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		free(ctx);
-		return 0;
-	}
-	optind++;
-
-	if (ctx->offset & 0x1ff) {
-		printf("offset %" PRId64 " is not sector aligned\n",
-                       ctx->offset);
-		free(ctx);
-		return 0;
-	}
-
-	nr_iov = argc - optind;
-	ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern);
-
-	gettimeofday(&ctx->t1, NULL);
-	acb = bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
-			      ctx->qiov.size >> 9, aio_write_done, ctx);
-	if (!acb) {
-		free(ctx->buf);
-		free(ctx);
-		return -EIO;
-	}
-
-	return 0;
+    int nr_iov, c;
+    int pattern = 0xcd;
+    struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));
+    BlockDriverAIOCB *acb;
+
+    while ((c = getopt(argc, argv, "CqP:")) != EOF) {
+        switch (c) {
+        case 'C':
+            ctx->Cflag = 1;
+            break;
+        case 'q':
+            ctx->qflag = 1;
+            break;
+        case 'P':
+            pattern = parse_pattern(optarg);
+            if (pattern < 0) {
+                return 0;
+            }
+            break;
+        default:
+            free(ctx);
+            return command_usage(&aio_write_cmd);
+        }
+    }
+
+    if (optind > argc - 2) {
+        free(ctx);
+        return command_usage(&aio_write_cmd);
+    }
+
+    ctx->offset = cvtnum(argv[optind]);
+    if (ctx->offset < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        free(ctx);
+        return 0;
+    }
+    optind++;
+
+    if (ctx->offset & 0x1ff) {
+        printf("offset %" PRId64 " is not sector aligned\n",
+               ctx->offset);
+        free(ctx);
+        return 0;
+    }
+
+    nr_iov = argc - optind;
+    ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern);
+
+    gettimeofday(&ctx->t1, NULL);
+    acb = bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
+                          ctx->qiov.size >> 9, aio_write_done, ctx);
+    if (!acb) {
+        free(ctx->buf);
+        free(ctx);
+        return -EIO;
+    }
+
+    return 0;
 }
 
-static int
-aio_flush_f(int argc, char **argv)
+static int aio_flush_f(int argc, char **argv)
 {
-	qemu_aio_flush();
-	return 0;
+    qemu_aio_flush();
+    return 0;
 }
 
 static const cmdinfo_t aio_flush_cmd = {
-	.name		= "aio_flush",
-	.cfunc		= aio_flush_f,
-	.oneline	= "completes all outstanding aio requests"
+    .name       = "aio_flush",
+    .cfunc      = aio_flush_f,
+    .oneline    = "completes all outstanding aio requests"
 };
 
-static int
-flush_f(int argc, char **argv)
+static int flush_f(int argc, char **argv)
 {
-	bdrv_flush(bs);
-	return 0;
+    bdrv_flush(bs);
+    return 0;
 }
 
 static const cmdinfo_t flush_cmd = {
-	.name		= "flush",
-	.altname	= "f",
-	.cfunc		= flush_f,
-	.oneline	= "flush all in-core file state to disk",
+    .name       = "flush",
+    .altname    = "f",
+    .cfunc      = flush_f,
+    .oneline    = "flush all in-core file state to disk",
 };
 
-static int
-truncate_f(int argc, char **argv)
+static int truncate_f(int argc, char **argv)
 {
-	int64_t offset;
-	int ret;
-
-	offset = cvtnum(argv[1]);
-	if (offset < 0) {
-		printf("non-numeric truncate argument -- %s\n", argv[1]);
-		return 0;
-	}
-
-	ret = bdrv_truncate(bs, offset);
-	if (ret < 0) {
-		printf("truncate: %s\n", strerror(-ret));
-		return 0;
-	}
-
-	return 0;
+    int64_t offset;
+    int ret;
+
+    offset = cvtnum(argv[1]);
+    if (offset < 0) {
+        printf("non-numeric truncate argument -- %s\n", argv[1]);
+        return 0;
+    }
+
+    ret = bdrv_truncate(bs, offset);
+    if (ret < 0) {
+        printf("truncate: %s\n", strerror(-ret));
+        return 0;
+    }
+
+    return 0;
 }
 
 static const cmdinfo_t truncate_cmd = {
-	.name		= "truncate",
-	.altname	= "t",
-	.cfunc		= truncate_f,
-	.argmin		= 1,
-	.argmax		= 1,
-	.args		= "off",
-	.oneline	= "truncates the current file at the given offset",
+    .name       = "truncate",
+    .altname    = "t",
+    .cfunc      = truncate_f,
+    .argmin     = 1,
+    .argmax     = 1,
+    .args       = "off",
+    .oneline    = "truncates the current file at the given offset",
 };
 
-static int
-length_f(int argc, char **argv)
+static int length_f(int argc, char **argv)
 {
-        int64_t size;
-	char s1[64];
-
-	size = bdrv_getlength(bs);
-	if (size < 0) {
-		printf("getlength: %s\n", strerror(-size));
-		return 0;
-	}
-
-	cvtstr(size, s1, sizeof(s1));
-	printf("%s\n", s1);
-	return 0;
+    int64_t size;
+    char s1[64];
+
+    size = bdrv_getlength(bs);
+    if (size < 0) {
+        printf("getlength: %s\n", strerror(-size));
+        return 0;
+    }
+
+    cvtstr(size, s1, sizeof(s1));
+    printf("%s\n", s1);
+    return 0;
 }
 
 
 static const cmdinfo_t length_cmd = {
-	.name		= "length",
-	.altname	= "l",
-	.cfunc		= length_f,
-	.oneline	= "gets the length of the current file",
+    .name   = "length",
+    .altname    = "l",
+    .cfunc      = length_f,
+    .oneline    = "gets the length of the current file",
 };
 
 
-static int
-info_f(int argc, char **argv)
+static int info_f(int argc, char **argv)
 {
-	BlockDriverInfo bdi;
-	char s1[64], s2[64];
-	int ret;
+    BlockDriverInfo bdi;
+    char s1[64], s2[64];
+    int ret;
 
-	if (bs->drv && bs->drv->format_name)
-		printf("format name: %s\n", bs->drv->format_name);
-	if (bs->drv && bs->drv->protocol_name)
-		printf("format name: %s\n", bs->drv->protocol_name);
+    if (bs->drv && bs->drv->format_name) {
+        printf("format name: %s\n", bs->drv->format_name);
+    }
+    if (bs->drv && bs->drv->protocol_name) {
+        printf("format name: %s\n", bs->drv->protocol_name);
+    }
 
-	ret = bdrv_get_info(bs, &bdi);
-	if (ret)
-		return 0;
+    ret = bdrv_get_info(bs, &bdi);
+    if (ret) {
+        return 0;
+    }
 
-	cvtstr(bdi.cluster_size, s1, sizeof(s1));
-	cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
+    cvtstr(bdi.cluster_size, s1, sizeof(s1));
+    cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
 
-	printf("cluster size: %s\n", s1);
-	printf("vm state offset: %s\n", s2);
+    printf("cluster size: %s\n", s1);
+    printf("vm state offset: %s\n", s2);
 
-	return 0;
+    return 0;
 }
 
 
 
 static const cmdinfo_t info_cmd = {
-	.name		= "info",
-	.altname	= "i",
-	.cfunc		= info_f,
-	.oneline	= "prints information about the current file",
+    .name       = "info",
+    .altname    = "i",
+    .cfunc      = info_f,
+    .oneline    = "prints information about the current file",
 };
 
-static void
-discard_help(void)
+static void discard_help(void)
 {
-	printf(
+    printf(
 "\n"
 " discards a range of bytes from the given offset\n"
 "\n"
@@ -1415,148 +1426,147 @@ discard_help(void)
 static int discard_f(int argc, char **argv);
 
 static const cmdinfo_t discard_cmd = {
-	.name		= "discard",
-	.altname	= "d",
-	.cfunc		= discard_f,
-	.argmin		= 2,
-	.argmax		= -1,
-	.args		= "[-Cq] off len",
-	.oneline	= "discards a number of bytes at a specified offset",
-	.help		= discard_help,
+    .name       = "discard",
+    .altname    = "d",
+    .cfunc      = discard_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-Cq] off len",
+    .oneline    = "discards a number of bytes at a specified offset",
+    .help       = discard_help,
 };
 
-static int
-discard_f(int argc, char **argv)
+static int discard_f(int argc, char **argv)
 {
-	struct timeval t1, t2;
-	int Cflag = 0, qflag = 0;
-	int c, ret;
-	int64_t offset;
-	int count;
-
-	while ((c = getopt(argc, argv, "Cq")) != EOF) {
-		switch (c) {
-		case 'C':
-			Cflag = 1;
-			break;
-		case 'q':
-			qflag = 1;
-			break;
-		default:
-			return command_usage(&discard_cmd);
-		}
-	}
-
-	if (optind != argc - 2) {
-		return command_usage(&discard_cmd);
-	}
-
-	offset = cvtnum(argv[optind]);
-	if (offset < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		return 0;
-	}
-
-	optind++;
-	count = cvtnum(argv[optind]);
-	if (count < 0) {
-		printf("non-numeric length argument -- %s\n", argv[optind]);
-		return 0;
-	}
-
-	gettimeofday(&t1, NULL);
-	ret = bdrv_discard(bs, offset >> BDRV_SECTOR_BITS, count >> BDRV_SECTOR_BITS);
-	gettimeofday(&t2, NULL);
-
-	if (ret < 0) {
-		printf("discard failed: %s\n", strerror(-ret));
-		goto out;
-	}
-
-	/* Finally, report back -- -C gives a parsable format */
-	if (!qflag) {
-		t2 = tsub(t2, t1);
-		print_report("discard", &t2, offset, count, count, 1, Cflag);
-	}
+    struct timeval t1, t2;
+    int Cflag = 0, qflag = 0;
+    int c, ret;
+    int64_t offset;
+    int count;
+
+    while ((c = getopt(argc, argv, "Cq")) != EOF) {
+        switch (c) {
+        case 'C':
+            Cflag = 1;
+            break;
+        case 'q':
+            qflag = 1;
+            break;
+        default:
+            return command_usage(&discard_cmd);
+        }
+    }
+
+    if (optind != argc - 2) {
+        return command_usage(&discard_cmd);
+    }
+
+    offset = cvtnum(argv[optind]);
+    if (offset < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        return 0;
+    }
+
+    optind++;
+    count = cvtnum(argv[optind]);
+    if (count < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        return 0;
+    }
+
+    gettimeofday(&t1, NULL);
+    ret = bdrv_discard(bs, offset >> BDRV_SECTOR_BITS,
+                       count >> BDRV_SECTOR_BITS);
+    gettimeofday(&t2, NULL);
+
+    if (ret < 0) {
+        printf("discard failed: %s\n", strerror(-ret));
+        goto out;
+    }
+
+    /* Finally, report back -- -C gives a parsable format */
+    if (!qflag) {
+        t2 = tsub(t2, t1);
+        print_report("discard", &t2, offset, count, count, 1, Cflag);
+    }
 
 out:
-	return 0;
+    return 0;
 }
 
-static int
-alloc_f(int argc, char **argv)
+static int alloc_f(int argc, char **argv)
 {
-	int64_t offset;
-	int nb_sectors, remaining;
-	char s1[64];
-	int num, sum_alloc;
-	int ret;
-
-	offset = cvtnum(argv[1]);
-	if (offset & 0x1ff) {
-                printf("offset %" PRId64 " is not sector aligned\n",
-                       offset);
-		return 0;
-	}
-
-	if (argc == 3)
-		nb_sectors = cvtnum(argv[2]);
-	else
-		nb_sectors = 1;
-
-	remaining = nb_sectors;
-	sum_alloc = 0;
-	while (remaining) {
-		ret = bdrv_is_allocated(bs, offset >> 9, nb_sectors, &num);
-		remaining -= num;
-		if (ret) {
-			sum_alloc += num;
-		}
-	}
-
-	cvtstr(offset, s1, sizeof(s1));
-
-	printf("%d/%d sectors allocated at offset %s\n",
-	       sum_alloc, nb_sectors, s1);
-	return 0;
+    int64_t offset;
+    int nb_sectors, remaining;
+    char s1[64];
+    int num, sum_alloc;
+    int ret;
+
+    offset = cvtnum(argv[1]);
+    if (offset & 0x1ff) {
+        printf("offset %" PRId64 " is not sector aligned\n",
+               offset);
+        return 0;
+    }
+
+    if (argc == 3) {
+        nb_sectors = cvtnum(argv[2]);
+    } else {
+        nb_sectors = 1;
+    }
+
+    remaining = nb_sectors;
+    sum_alloc = 0;
+    while (remaining) {
+        ret = bdrv_is_allocated(bs, offset >> 9, nb_sectors, &num);
+        remaining -= num;
+        if (ret) {
+            sum_alloc += num;
+        }
+    }
+
+    cvtstr(offset, s1, sizeof(s1));
+
+    printf("%d/%d sectors allocated at offset %s\n",
+           sum_alloc, nb_sectors, s1);
+    return 0;
 }
 
 static const cmdinfo_t alloc_cmd = {
-	.name		= "alloc",
-	.altname	= "a",
-	.argmin		= 1,
-	.argmax		= 2,
-	.cfunc		= alloc_f,
-	.args		= "off [sectors]",
-	.oneline	= "checks if a sector is present in the file",
+    .name       = "alloc",
+    .altname    = "a",
+    .argmin     = 1,
+    .argmax     = 2,
+    .cfunc      = alloc_f,
+    .args       = "off [sectors]",
+    .oneline    = "checks if a sector is present in the file",
 };
 
-static int
-map_f(int argc, char **argv)
+static int map_f(int argc, char **argv)
 {
-	int64_t offset;
-	int64_t nb_sectors;
-	char s1[64];
-	int num, num_checked;
-	int ret;
-	const char *retstr;
-
-	offset = 0;
-	nb_sectors = bs->total_sectors;
-
-	do {
-		num_checked = MIN(nb_sectors, INT_MAX);
-		ret = bdrv_is_allocated(bs, offset, num_checked, &num);
-		retstr = ret ? "    allocated" : "not allocated";
-		cvtstr(offset << 9ULL, s1, sizeof(s1));
-		printf("[% 24" PRId64 "] % 8d/% 8d sectors %s at offset %s (%d)\n",
-				offset << 9ULL, num, num_checked, retstr, s1, ret);
-
-		offset += num;
-		nb_sectors -= num;
-	} while(offset < bs->total_sectors);
-
-	return 0;
+    int64_t offset;
+    int64_t nb_sectors;
+    char s1[64];
+    int num, num_checked;
+    int ret;
+    const char *retstr;
+
+    offset = 0;
+    nb_sectors = bs->total_sectors;
+
+    do {
+        num_checked = MIN(nb_sectors, INT_MAX);
+        ret = bdrv_is_allocated(bs, offset, num_checked, &num);
+        retstr = ret ? "    allocated" : "not allocated";
+        cvtstr(offset << 9ULL, s1, sizeof(s1));
+        printf("[% 24" PRId64 "] % 8d/% 8d sectors %s at offset %s (%d)\n",
+               offset << 9ULL, num, num_checked, retstr, s1, ret);
+
+        offset += num;
+        nb_sectors -= num;
+    } while (offset < bs->total_sectors);
+
+    return 0;
 }
 
 static const cmdinfo_t map_cmd = {
@@ -1569,50 +1579,48 @@ static const cmdinfo_t map_cmd = {
 };
 
 
-static int
-close_f(int argc, char **argv)
+static int close_f(int argc, char **argv)
 {
-	bdrv_close(bs);
-	bs = NULL;
-	return 0;
+    bdrv_close(bs);
+    bs = NULL;
+    return 0;
 }
 
 static const cmdinfo_t close_cmd = {
-	.name		= "close",
-	.altname	= "c",
-	.cfunc		= close_f,
-	.oneline	= "close the current open file",
+    .name       = "close",
+    .altname    = "c",
+    .cfunc      = close_f,
+    .oneline    = "close the current open file",
 };
 
 static int openfile(char *name, int flags, int growable)
 {
-	if (bs) {
-		fprintf(stderr, "file open already, try 'help close'\n");
-		return 1;
-	}
-
-	if (growable) {
-		if (bdrv_file_open(&bs, name, flags)) {
-			fprintf(stderr, "%s: can't open device %s\n", progname, name);
-			return 1;
-		}
-	} else {
-		bs = bdrv_new("hda");
-
-		if (bdrv_open(bs, name, flags, NULL) < 0) {
-			fprintf(stderr, "%s: can't open device %s\n", progname, name);
-			bs = NULL;
-			return 1;
-		}
-	}
-
-	return 0;
+    if (bs) {
+        fprintf(stderr, "file open already, try 'help close'\n");
+        return 1;
+    }
+
+    if (growable) {
+        if (bdrv_file_open(&bs, name, flags)) {
+            fprintf(stderr, "%s: can't open device %s\n", progname, name);
+            return 1;
+        }
+    } else {
+        bs = bdrv_new("hda");
+
+        if (bdrv_open(bs, name, flags, NULL) < 0) {
+            fprintf(stderr, "%s: can't open device %s\n", progname, name);
+            bs = NULL;
+            return 1;
+        }
+    }
+
+    return 0;
 }
 
-static void
-open_help(void)
+static void open_help(void)
 {
-	printf(
+    printf(
 "\n"
 " opens a new file in the requested mode\n"
 "\n"
@@ -1630,80 +1638,78 @@ open_help(void)
 static int open_f(int argc, char **argv);
 
 static const cmdinfo_t open_cmd = {
-	.name		= "open",
-	.altname	= "o",
-	.cfunc		= open_f,
-	.argmin		= 1,
-	.argmax		= -1,
-	.flags		= CMD_NOFILE_OK,
-	.args		= "[-Crsn] [path]",
-	.oneline	= "open the file specified by path",
-	.help		= open_help,
+    .name       = "open",
+    .altname    = "o",
+    .cfunc      = open_f,
+    .argmin     = 1,
+    .argmax     = -1,
+    .flags      = CMD_NOFILE_OK,
+    .args       = "[-Crsn] [path]",
+    .oneline    = "open the file specified by path",
+    .help       = open_help,
 };
 
-static int
-open_f(int argc, char **argv)
+static int open_f(int argc, char **argv)
 {
-	int flags = 0;
-	int readonly = 0;
-	int growable = 0;
-	int c;
-
-	while ((c = getopt(argc, argv, "snrg")) != EOF) {
-		switch (c) {
-		case 's':
-			flags |= BDRV_O_SNAPSHOT;
-			break;
-		case 'n':
-			flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
-			break;
-		case 'r':
-			readonly = 1;
-			break;
-		case 'g':
-			growable = 1;
-			break;
-		default:
-			return command_usage(&open_cmd);
-		}
-	}
-
-	if (!readonly) {
-            flags |= BDRV_O_RDWR;
+    int flags = 0;
+    int readonly = 0;
+    int growable = 0;
+    int c;
+
+    while ((c = getopt(argc, argv, "snrg")) != EOF) {
+        switch (c) {
+        case 's':
+            flags |= BDRV_O_SNAPSHOT;
+            break;
+        case 'n':
+            flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
+            break;
+        case 'r':
+            readonly = 1;
+            break;
+        case 'g':
+            growable = 1;
+            break;
+        default:
+            return command_usage(&open_cmd);
         }
+    }
+
+    if (!readonly) {
+        flags |= BDRV_O_RDWR;
+    }
 
-	if (optind != argc - 1)
-		return command_usage(&open_cmd);
+    if (optind != argc - 1) {
+        return command_usage(&open_cmd);
+    }
 
-	return openfile(argv[optind], flags, growable);
+    return openfile(argv[optind], flags, growable);
 }
 
-static int
-init_args_command(
-        int     index)
+static int init_args_command(int index)
 {
-	/* only one device allowed so far */
-	if (index >= 1)
-		return 0;
-	return ++index;
+    /* only one device allowed so far */
+    if (index >= 1) {
+        return 0;
+    }
+    return ++index;
 }
 
-static int
-init_check_command(
-	const cmdinfo_t *ct)
+static int init_check_command(const cmdinfo_t *ct)
 {
-	if (ct->flags & CMD_FLAG_GLOBAL)
-		return 1;
-	if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
-		fprintf(stderr, "no file open, try 'help open'\n");
-		return 0;
-	}
-	return 1;
+    if (ct->flags & CMD_FLAG_GLOBAL) {
+        return 1;
+    }
+    if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
+        fprintf(stderr, "no file open, try 'help open'\n");
+        return 0;
+    }
+    return 1;
 }
 
 static void usage(const char *name)
 {
-	printf(
+    printf(
 "Usage: %s [-h] [-V] [-rsnm] [-c cmd] ... [file]\n"
 "QEMU Disk exerciser\n"
 "\n"
@@ -1717,115 +1723,117 @@ static void usage(const char *name)
 "  -h, --help           display this help and exit\n"
 "  -V, --version        output version information and exit\n"
 "\n",
-	name);
+    name);
 }
 
 
 int main(int argc, char **argv)
 {
-	int readonly = 0;
-	int growable = 0;
-	const char *sopt = "hVc:rsnmgk";
-        const struct option lopt[] = {
-		{ "help", 0, NULL, 'h' },
-		{ "version", 0, NULL, 'V' },
-		{ "offset", 1, NULL, 'o' },
-		{ "cmd", 1, NULL, 'c' },
-		{ "read-only", 0, NULL, 'r' },
-		{ "snapshot", 0, NULL, 's' },
-		{ "nocache", 0, NULL, 'n' },
-		{ "misalign", 0, NULL, 'm' },
-		{ "growable", 0, NULL, 'g' },
-		{ "native-aio", 0, NULL, 'k' },
-		{ NULL, 0, NULL, 0 }
-	};
-	int c;
-	int opt_index = 0;
-	int flags = 0;
-
-	progname = basename(argv[0]);
-
-	while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) {
-		switch (c) {
-		case 's':
-			flags |= BDRV_O_SNAPSHOT;
-			break;
-		case 'n':
-			flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
-			break;
-		case 'c':
-			add_user_command(optarg);
-			break;
-		case 'r':
-			readonly = 1;
-			break;
-		case 'm':
-			misalign = 1;
-			break;
-		case 'g':
-			growable = 1;
-			break;
-		case 'k':
-			flags |= BDRV_O_NATIVE_AIO;
-			break;
-		case 'V':
-			printf("%s version %s\n", progname, VERSION);
-			exit(0);
-		case 'h':
-			usage(progname);
-			exit(0);
-		default:
-			usage(progname);
-			exit(1);
-		}
-	}
-
-	if ((argc - optind) > 1) {
-		usage(progname);
-		exit(1);
-	}
-
-	bdrv_init();
-
-	/* initialize commands */
-	quit_init();
-	help_init();
-	add_command(&open_cmd);
-	add_command(&close_cmd);
-	add_command(&read_cmd);
-	add_command(&readv_cmd);
-	add_command(&write_cmd);
-	add_command(&writev_cmd);
-	add_command(&multiwrite_cmd);
-	add_command(&aio_read_cmd);
-	add_command(&aio_write_cmd);
-	add_command(&aio_flush_cmd);
-	add_command(&flush_cmd);
-	add_command(&truncate_cmd);
-	add_command(&length_cmd);
-	add_command(&info_cmd);
-	add_command(&discard_cmd);
-	add_command(&alloc_cmd);
-	add_command(&map_cmd);
-
-	add_args_command(init_args_command);
-	add_check_command(init_check_command);
-
-	/* open the device */
-	if (!readonly) {
-            flags |= BDRV_O_RDWR;
+    int readonly = 0;
+    int growable = 0;
+    const char *sopt = "hVc:rsnmgk";
+    const struct option lopt[] = {
+        { "help", 0, NULL, 'h' },
+        { "version", 0, NULL, 'V' },
+        { "offset", 1, NULL, 'o' },
+        { "cmd", 1, NULL, 'c' },
+        { "read-only", 0, NULL, 'r' },
+        { "snapshot", 0, NULL, 's' },
+        { "nocache", 0, NULL, 'n' },
+        { "misalign", 0, NULL, 'm' },
+        { "growable", 0, NULL, 'g' },
+        { "native-aio", 0, NULL, 'k' },
+        { NULL, 0, NULL, 0 }
+    };
+    int c;
+    int opt_index = 0;
+    int flags = 0;
+
+    progname = basename(argv[0]);
+
+    while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) {
+        switch (c) {
+        case 's':
+            flags |= BDRV_O_SNAPSHOT;
+            break;
+        case 'n':
+            flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
+            break;
+        case 'c':
+            add_user_command(optarg);
+            break;
+        case 'r':
+            readonly = 1;
+            break;
+        case 'm':
+            misalign = 1;
+            break;
+        case 'g':
+            growable = 1;
+            break;
+        case 'k':
+            flags |= BDRV_O_NATIVE_AIO;
+            break;
+        case 'V':
+            printf("%s version %s\n", progname, VERSION);
+            exit(0);
+        case 'h':
+            usage(progname);
+            exit(0);
+        default:
+            usage(progname);
+            exit(1);
         }
+    }
+
+    if ((argc - optind) > 1) {
+        usage(progname);
+        exit(1);
+    }
 
-	if ((argc - optind) == 1)
-		openfile(argv[optind], flags, growable);
-	command_loop();
+    bdrv_init();
+
+    /* initialize commands */
+    quit_init();
+    help_init();
+    add_command(&open_cmd);
+    add_command(&close_cmd);
+    add_command(&read_cmd);
+    add_command(&readv_cmd);
+    add_command(&write_cmd);
+    add_command(&writev_cmd);
+    add_command(&multiwrite_cmd);
+    add_command(&aio_read_cmd);
+    add_command(&aio_write_cmd);
+    add_command(&aio_flush_cmd);
+    add_command(&flush_cmd);
+    add_command(&truncate_cmd);
+    add_command(&length_cmd);
+    add_command(&info_cmd);
+    add_command(&discard_cmd);
+    add_command(&alloc_cmd);
+    add_command(&map_cmd);
+
+    add_args_command(init_args_command);
+    add_check_command(init_check_command);
+
+    /* open the device */
+    if (!readonly) {
+        flags |= BDRV_O_RDWR;
+    }
+
+    if ((argc - optind) == 1) {
+        openfile(argv[optind], flags, growable);
+    }
+    command_loop();
 
-	/*
-	 * Make sure all outstanding requests get flushed the program exits.
-	 */
-	qemu_aio_flush();
+    /*
+     * Make sure all outstanding requests get flushed the program exits.
+     */
+    qemu_aio_flush();
 
-	if (bs)
-		bdrv_close(bs);
-	return 0;
+    if (bs) {
+        bdrv_close(bs);
+    }
+    return 0;
 }
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 03/21] qemu-io: Fix if scoping bug
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 01/21] sheepdog: add full data preallocation support Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 02/21] qemu-io: Fix formatting Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 04/21] iov: Update parameter usage in iov_(to|from)_buf() Kevin Wolf
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Devin Nakamura <devin122@gmail.com>

Fix a bug caused by lack of braces in if statement

Lack of braces means that if(count & 0x1ff) is never reached

Signed-off-by: Devin Nakamura <devin122@gmail.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qemu-io.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/qemu-io.c b/qemu-io.c
index e3c825f..a553d0c 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -449,7 +449,7 @@ static int read_f(int argc, char **argv)
         return 0;
     }
 
-    if (!pflag)
+    if (!pflag) {
         if (offset & 0x1ff) {
             printf("offset %" PRId64 " is not sector aligned\n",
                    offset);
@@ -460,6 +460,7 @@ static int read_f(int argc, char **argv)
                    count);
             return 0;
         }
+    }
 
     buf = qemu_io_alloc(count, 0xab);
 
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 04/21] iov: Update parameter usage in iov_(to|from)_buf()
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (2 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 03/21] qemu-io: Fix if scoping bug Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 05/21] scsi: Add 'hba_private' to SCSIRequest Kevin Wolf
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Hannes Reinecke <hare@suse.de>

iov_to_buf() has an 'offset' parameter, iov_from_buf() hasn't.
This patch adds the missing parameter to iov_from_buf().
It also renames the 'offset' parameter to 'iov_off' to
emphasize it's the offset into the iovec and not the buffer.

Signed-off-by: Hannes Reinecke <hare@suse.de>
Acked-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/virtio-net.c        |    2 +-
 hw/virtio-serial-bus.c |    2 +-
 iov.c                  |   49 ++++++++++++++++++++++++++---------------------
 iov.h                  |   10 ++++----
 4 files changed, 34 insertions(+), 29 deletions(-)

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 6997e02..a32cc01 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -657,7 +657,7 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_
 
         /* copy in packet.  ugh */
         len = iov_from_buf(sg, elem.in_num,
-                           buf + offset, size - offset);
+                           buf + offset, 0, size - offset);
         total += len;
         offset += len;
         /* If buffers can't be merged, at this point we
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 7f6db7b..53c58d0 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -103,7 +103,7 @@ static size_t write_to_port(VirtIOSerialPort *port,
         }
 
         len = iov_from_buf(elem.in_sg, elem.in_num,
-                           buf + offset, size - offset);
+                           buf + offset, 0, size - offset);
         offset += len;
 
         virtqueue_push(vq, &elem, len);
diff --git a/iov.c b/iov.c
index 588cd04..1e02791 100644
--- a/iov.c
+++ b/iov.c
@@ -14,56 +14,61 @@
 
 #include "iov.h"
 
-size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt,
-                    const void *buf, size_t size)
+size_t iov_from_buf(struct iovec *iov, unsigned int iov_cnt,
+                    const void *buf, size_t iov_off, size_t size)
 {
-    size_t offset;
+    size_t iovec_off, buf_off;
     unsigned int i;
 
-    offset = 0;
-    for (i = 0; offset < size && i < iovcnt; i++) {
-        size_t len;
+    iovec_off = 0;
+    buf_off = 0;
+    for (i = 0; i < iov_cnt && size; i++) {
+        if (iov_off < (iovec_off + iov[i].iov_len)) {
+            size_t len = MIN((iovec_off + iov[i].iov_len) - iov_off, size);
 
-        len = MIN(iov[i].iov_len, size - offset);
+            memcpy(iov[i].iov_base + (iov_off - iovec_off), buf + buf_off, len);
 
-        memcpy(iov[i].iov_base, buf + offset, len);
-        offset += len;
+            buf_off += len;
+            iov_off += len;
+            size -= len;
+        }
+        iovec_off += iov[i].iov_len;
     }
-    return offset;
+    return buf_off;
 }
 
-size_t iov_to_buf(const struct iovec *iov, const unsigned int iovcnt,
-                  void *buf, size_t offset, size_t size)
+size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
+                  void *buf, size_t iov_off, size_t size)
 {
     uint8_t *ptr;
-    size_t iov_off, buf_off;
+    size_t iovec_off, buf_off;
     unsigned int i;
 
     ptr = buf;
-    iov_off = 0;
+    iovec_off = 0;
     buf_off = 0;
-    for (i = 0; i < iovcnt && size; i++) {
-        if (offset < (iov_off + iov[i].iov_len)) {
-            size_t len = MIN((iov_off + iov[i].iov_len) - offset , size);
+    for (i = 0; i < iov_cnt && size; i++) {
+        if (iov_off < (iovec_off + iov[i].iov_len)) {
+            size_t len = MIN((iovec_off + iov[i].iov_len) - iov_off , size);
 
-            memcpy(ptr + buf_off, iov[i].iov_base + (offset - iov_off), len);
+            memcpy(ptr + buf_off, iov[i].iov_base + (iov_off - iovec_off), len);
 
             buf_off += len;
-            offset += len;
+            iov_off += len;
             size -= len;
         }
-        iov_off += iov[i].iov_len;
+        iovec_off += iov[i].iov_len;
     }
     return buf_off;
 }
 
-size_t iov_size(const struct iovec *iov, const unsigned int iovcnt)
+size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt)
 {
     size_t len;
     unsigned int i;
 
     len = 0;
-    for (i = 0; i < iovcnt; i++) {
+    for (i = 0; i < iov_cnt; i++) {
         len += iov[i].iov_len;
     }
     return len;
diff --git a/iov.h b/iov.h
index 60a8547..110f67a 100644
--- a/iov.h
+++ b/iov.h
@@ -12,8 +12,8 @@
 
 #include "qemu-common.h"
 
-size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt,
-                    const void *buf, size_t size);
-size_t iov_to_buf(const struct iovec *iov, const unsigned int iovcnt,
-                  void *buf, size_t offset, size_t size);
-size_t iov_size(const struct iovec *iov, const unsigned int iovcnt);
+size_t iov_from_buf(struct iovec *iov, unsigned int iov_cnt,
+                    const void *buf, size_t iov_off, size_t size);
+size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
+                  void *buf, size_t iov_off, size_t size);
+size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt);
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 05/21] scsi: Add 'hba_private' to SCSIRequest
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (3 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 04/21] iov: Update parameter usage in iov_(to|from)_buf() Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 12:43   ` Anthony Liguori
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 06/21] scsi-disk: Fixup debugging statement Kevin Wolf
                   ` (15 subsequent siblings)
  20 siblings, 1 reply; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Hannes Reinecke <hare@suse.de>

'tag' is just an abstraction to identify the command
from the driver. So we should make that explicit by
replacing 'tag' with a driver-defined pointer 'hba_private'.
This saves the lookup for driver handling several commands
in parallel.
'tag' is still being kept for tracing purposes.

Signed-off-by: Hannes Reinecke <hare@suse.de>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/esp.c          |    2 +-
 hw/lsi53c895a.c   |   22 ++++++++--------------
 hw/scsi-bus.c     |    9 ++++++---
 hw/scsi-disk.c    |    4 ++--
 hw/scsi-generic.c |    5 +++--
 hw/scsi.h         |   10 +++++++---
 hw/spapr_vscsi.c  |   29 +++++++++--------------------
 hw/usb-msd.c      |    9 +--------
 8 files changed, 37 insertions(+), 53 deletions(-)

diff --git a/hw/esp.c b/hw/esp.c
index aa50800..9ddd637 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -244,7 +244,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
 
     DPRINTF("do_busid_cmd: busid 0x%x\n", busid);
     lun = busid & 7;
-    s->current_req = scsi_req_new(s->current_dev, 0, lun);
+    s->current_req = scsi_req_new(s->current_dev, 0, lun, NULL);
     datalen = scsi_req_enqueue(s->current_req, buf);
     s->ti_size = datalen;
     if (datalen != 0) {
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 940b43a..69eec1d 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -661,7 +661,7 @@ static lsi_request *lsi_find_by_tag(LSIState *s, uint32_t tag)
 static void lsi_request_cancelled(SCSIRequest *req)
 {
     LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
-    lsi_request *p;
+    lsi_request *p = req->hba_private;
 
     if (s->current && req == s->current->req) {
         scsi_req_unref(req);
@@ -670,7 +670,6 @@ static void lsi_request_cancelled(SCSIRequest *req)
         return;
     }
 
-    p = lsi_find_by_tag(s, req->tag);
     if (p) {
         QTAILQ_REMOVE(&s->queue, p, next);
         scsi_req_unref(req);
@@ -680,18 +679,12 @@ static void lsi_request_cancelled(SCSIRequest *req)
 
 /* Record that data is available for a queued command.  Returns zero if
    the device was reselected, nonzero if the IO is deferred.  */
-static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t len)
+static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len)
 {
-    lsi_request *p;
-
-    p = lsi_find_by_tag(s, tag);
-    if (!p) {
-        BADF("IO with unknown tag %d\n", tag);
-        return 1;
-    }
+    lsi_request *p = req->hba_private;
 
     if (p->pending) {
-        BADF("Multiple IO pending for tag %d\n", tag);
+        BADF("Multiple IO pending for request %p\n", p);
     }
     p->pending = len;
     /* Reselect if waiting for it, or if reselection triggers an IRQ
@@ -743,9 +736,9 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t len)
     LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
     int out;
 
-    if (s->waiting == 1 || !s->current || req->tag != s->current->tag ||
+    if (s->waiting == 1 || !s->current || req->hba_private != s->current ||
         (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) {
-        if (lsi_queue_tag(s, req->tag, len)) {
+        if (lsi_queue_req(s, req, len)) {
             return;
         }
     }
@@ -789,7 +782,8 @@ static void lsi_do_command(LSIState *s)
     assert(s->current == NULL);
     s->current = qemu_mallocz(sizeof(lsi_request));
     s->current->tag = s->select_tag;
-    s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun);
+    s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun,
+                                   s->current);
 
     n = scsi_req_enqueue(s->current->req, buf);
     if (n) {
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index ad6a730..8b1a412 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -131,7 +131,8 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
     return res;
 }
 
-SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun)
+SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
+                            uint32_t lun, void *hba_private)
 {
     SCSIRequest *req;
 
@@ -141,14 +142,16 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t l
     req->dev = d;
     req->tag = tag;
     req->lun = lun;
+    req->hba_private = hba_private;
     req->status = -1;
     trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
     return req;
 }
 
-SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun)
+SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
+                          void *hba_private)
 {
-    return d->info->alloc_req(d, tag, lun);
+    return d->info->alloc_req(d, tag, lun, hba_private);
 }
 
 uint8_t *scsi_req_get_buf(SCSIRequest *req)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index a8c7372..c2a99fe 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -81,13 +81,13 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
 static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf);
 
 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
-        uint32_t lun)
+                                     uint32_t lun, void *hba_private)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
     SCSIRequest *req;
     SCSIDiskReq *r;
 
-    req = scsi_req_alloc(sizeof(SCSIDiskReq), &s->qdev, tag, lun);
+    req = scsi_req_alloc(sizeof(SCSIDiskReq), &s->qdev, tag, lun, hba_private);
     r = DO_UPCAST(SCSIDiskReq, req, req);
     r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
     return req;
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 8e59c7e..90345a7 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -96,11 +96,12 @@ static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len)
     return size;
 }
 
-static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
+static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
+                                     void *hba_private)
 {
     SCSIRequest *req;
 
-    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
+    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun, hba_private);
     return req;
 }
 
diff --git a/hw/scsi.h b/hw/scsi.h
index c1dca35..6b15bbc 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -43,6 +43,7 @@ struct SCSIRequest {
     } cmd;
     BlockDriverAIOCB  *aiocb;
     bool enqueued;
+    void *hba_private;
     QTAILQ_ENTRY(SCSIRequest) next;
 };
 
@@ -67,7 +68,8 @@ struct SCSIDeviceInfo {
     DeviceInfo qdev;
     scsi_qdev_initfn init;
     void (*destroy)(SCSIDevice *s);
-    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun);
+    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
+                              void *hba_private);
     void (*free_req)(SCSIRequest *req);
     int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
     void (*read_data)(SCSIRequest *req);
@@ -138,8 +140,10 @@ extern const struct SCSISense sense_code_LUN_FAILURE;
 int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed);
 int scsi_sense_valid(SCSISense sense);
 
-SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun);
-SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun);
+SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
+                            uint32_t lun, void *hba_private);
+SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
+                          void *hba_private);
 int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf);
 void scsi_req_free(SCSIRequest *req);
 SCSIRequest *scsi_req_ref(SCSIRequest *req);
diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index 1c901ef..9e1cb2e 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -121,7 +121,7 @@ static struct vscsi_req *vscsi_get_req(VSCSIState *s)
     return NULL;
 }
 
-static void vscsi_put_req(VSCSIState *s, vscsi_req *req)
+static void vscsi_put_req(vscsi_req *req)
 {
     if (req->sreq != NULL) {
         scsi_req_unref(req->sreq);
@@ -130,15 +130,6 @@ static void vscsi_put_req(VSCSIState *s, vscsi_req *req)
     req->active = 0;
 }
 
-static vscsi_req *vscsi_find_req(VSCSIState *s, SCSIRequest *req)
-{
-    uint32_t tag = req->tag;
-    if (tag >= VSCSI_REQ_LIMIT || !s->reqs[tag].active) {
-        return NULL;
-    }
-    return &s->reqs[tag];
-}
-
 static void vscsi_decode_id_lun(uint64_t srp_lun, int *id, int *lun)
 {
     /* XXX Figure that one out properly ! This is crackpot */
@@ -454,7 +445,7 @@ static void vscsi_send_request_sense(VSCSIState *s, vscsi_req *req)
     if (n) {
         req->senselen = n;
         vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
-        vscsi_put_req(s, req);
+        vscsi_put_req(req);
         return;
     }
 
@@ -483,7 +474,7 @@ static void vscsi_send_request_sense(VSCSIState *s, vscsi_req *req)
 static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t len)
 {
     VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent);
-    vscsi_req *req = vscsi_find_req(s, sreq);
+    vscsi_req *req = sreq->hba_private;
     uint8_t *buf;
     int rc = 0;
 
@@ -530,8 +521,7 @@ static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t len)
 /* Callback to indicate that the SCSI layer has completed a transfer.  */
 static void vscsi_command_complete(SCSIRequest *sreq, uint32_t status)
 {
-    VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent);
-    vscsi_req *req = vscsi_find_req(s, sreq);
+    vscsi_req *req = sreq->hba_private;
     int32_t res_in = 0, res_out = 0;
 
     dprintf("VSCSI: SCSI cmd complete, r=0x%x tag=0x%x status=0x%x, req=%p\n",
@@ -563,15 +553,14 @@ static void vscsi_command_complete(SCSIRequest *sreq, uint32_t status)
         }
     }
     vscsi_send_rsp(s, req, 0, res_in, res_out);
-    vscsi_put_req(s, req);
+    vscsi_put_req(req);
 }
 
 static void vscsi_request_cancelled(SCSIRequest *sreq)
 {
-    VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent);
-    vscsi_req *req = vscsi_find_req(s, sreq);
+    vscsi_req *req = sreq->hba_private;
 
-    vscsi_put_req(s, req);
+    vscsi_put_req(req);
 }
 
 static void vscsi_process_login(VSCSIState *s, vscsi_req *req)
@@ -659,7 +648,7 @@ static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req)
     }
 
     req->lun = lun;
-    req->sreq = scsi_req_new(sdev, req->qtag, lun);
+    req->sreq = scsi_req_new(sdev, req->qtag, lun, req);
     n = scsi_req_enqueue(req->sreq, srp->cmd.cdb);
 
     dprintf("VSCSI: Queued command tag 0x%x CMD 0x%x ID %d LUN %d ret: %d\n",
@@ -858,7 +847,7 @@ static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq)
     }
 
     if (done) {
-        vscsi_put_req(s, req);
+        vscsi_put_req(req);
     }
 }
 
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index 86582cc..bfea096 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -216,10 +216,6 @@ static void usb_msd_transfer_data(SCSIRequest *req, uint32_t len)
     MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
     USBPacket *p = s->packet;
 
-    if (req->tag != s->tag) {
-        fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", req->tag);
-    }
-
     assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV));
     s->scsi_len = len;
     s->scsi_buf = scsi_req_get_buf(req);
@@ -241,9 +237,6 @@ static void usb_msd_command_complete(SCSIRequest *req, uint32_t status)
     MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
     USBPacket *p = s->packet;
 
-    if (req->tag != s->tag) {
-        fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", req->tag);
-    }
     DPRINTF("Command complete %d\n", status);
     s->residue = s->data_len;
     s->result = status != 0;
@@ -387,7 +380,7 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
                     s->tag, cbw.flags, cbw.cmd_len, s->data_len);
             s->residue = 0;
             s->scsi_len = 0;
-            s->req = scsi_req_new(s->scsi_dev, s->tag, 0);
+            s->req = scsi_req_new(s->scsi_dev, s->tag, 0, NULL);
             scsi_req_enqueue(s->req, cbw.cmd);
             /* ??? Should check that USB and SCSI data transfer
                directions match.  */
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 06/21] scsi-disk: Fixup debugging statement
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (4 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 05/21] scsi: Add 'hba_private' to SCSIRequest Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 07/21] scsi-disk: Mask out serial number EVPD Kevin Wolf
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Hannes Reinecke <hare@suse.de>

A debugging statement wasn't converted to the new interface.

Signed-off-by: Hannes Reinecke <hare@suse.de>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/scsi-disk.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index c2a99fe..5804662 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1007,7 +1007,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
 
     command = buf[0];
     outbuf = (uint8_t *)r->iov.iov_base;
-    DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
+    DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", req->lun, req->tag, buf[0]);
 
     if (scsi_req_parse(&r->req, buf) != 0) {
         BADF("Unsupported command length, command %x\n", command);
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 07/21] scsi-disk: Mask out serial number EVPD
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (5 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 06/21] scsi-disk: Fixup debugging statement Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 08/21] qemu-options.hx: Document missing -drive options Kevin Wolf
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Hannes Reinecke <hare@suse.de>

If the serial number is not set we should mask it out in the
list of supported VPD pages and mark it as not supported.

Signed-off-by: Hannes Reinecke <hare@suse.de>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/scsi-disk.c |   15 ++++++++++++---
 1 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 5804662..05d14ab 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -398,7 +398,8 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
                     "buffer size %zd\n", req->cmd.xfer);
             pages = buflen++;
             outbuf[buflen++] = 0x00; // list of supported pages (this page)
-            outbuf[buflen++] = 0x80; // unit serial number
+            if (s->serial)
+                outbuf[buflen++] = 0x80; // unit serial number
             outbuf[buflen++] = 0x83; // device identification
             if (s->drive_kind == SCSI_HD) {
                 outbuf[buflen++] = 0xb0; // block limits
@@ -409,8 +410,14 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
         }
         case 0x80: /* Device serial number, optional */
         {
-            int l = strlen(s->serial);
+            int l;
 
+            if (!s->serial) {
+                DPRINTF("Inquiry (EVPD[Serial number] not supported\n");
+                return -1;
+            }
+
+            l = strlen(s->serial);
             if (l > req->cmd.xfer)
                 l = req->cmd.xfer;
             if (l > 20)
@@ -1203,7 +1210,9 @@ static int scsi_initfn(SCSIDevice *dev, SCSIDriveKind kind)
     if (!s->serial) {
         /* try to fall back to value set with legacy -drive serial=... */
         dinfo = drive_get_by_blockdev(s->bs);
-        s->serial = qemu_strdup(*dinfo->serial ? dinfo->serial : "0");
+        if (*dinfo->serial) {
+            s->serial = qemu_strdup(dinfo->serial);
+        }
     }
 
     if (!s->version) {
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 08/21] qemu-options.hx: Document missing -drive options
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (6 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 07/21] scsi-disk: Mask out serial number EVPD Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 09/21] qemu-config: Document " Kevin Wolf
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Luiz Capitulino <lcapitulino@redhat.com>

They are 'werror', 'rerror' and 'readonly'.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qemu-options.hx |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index e6d7adc..64114dd 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -160,6 +160,14 @@ an untrusted format header.
 This option specifies the serial number to assign to the device.
 @item addr=@var{addr}
 Specify the controller's PCI address (if=virtio only).
+@item werror=@var{action},rerror=@var{action}
+Specify which @var{action} to take on write and read errors. Valid actions are:
+"ignore" (ignore the error and try to continue), "stop" (pause QEMU),
+"report" (report the error to the guest), "enospc" (pause QEMU only if the
+host disk is full; report the error to the guest otherwise).
+The default setting is @option{werror=enospc} and @option{rerror=report}.
+@item readonly
+Open drive @option{file} as read-only. Guest write attempts will fail.
 @end table
 
 By default, writethrough caching is used for all block device.  This means that
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 09/21] qemu-config: Document -drive options
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (7 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 08/21] qemu-options.hx: Document missing -drive options Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 10/21] VMDK: introduce VmdkExtent Kevin Wolf
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Luiz Capitulino <lcapitulino@gmail.com>

Signed-off-by: Luiz Capitulino <lcapitulino@gmail.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qemu-config.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/qemu-config.c b/qemu-config.c
index c63741c..93d20c6 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -23,6 +23,7 @@ static QemuOptsList qemu_drive_opts = {
         },{
             .name = "index",
             .type = QEMU_OPT_NUMBER,
+            .help = "index number",
         },{
             .name = "cyls",
             .type = QEMU_OPT_NUMBER,
@@ -46,6 +47,7 @@ static QemuOptsList qemu_drive_opts = {
         },{
             .name = "snapshot",
             .type = QEMU_OPT_BOOL,
+            .help = "enable/disable snapshot mode",
         },{
             .name = "file",
             .type = QEMU_OPT_STRING,
@@ -65,12 +67,15 @@ static QemuOptsList qemu_drive_opts = {
         },{
             .name = "serial",
             .type = QEMU_OPT_STRING,
+            .help = "disk serial number",
         },{
             .name = "rerror",
             .type = QEMU_OPT_STRING,
+            .help = "read error action",
         },{
             .name = "werror",
             .type = QEMU_OPT_STRING,
+            .help = "write error action",
         },{
             .name = "addr",
             .type = QEMU_OPT_STRING,
@@ -78,6 +83,7 @@ static QemuOptsList qemu_drive_opts = {
         },{
             .name = "readonly",
             .type = QEMU_OPT_BOOL,
+            .help = "open drive file as read-only",
         },
         { /* end of list */ }
     },
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 10/21] VMDK: introduce VmdkExtent
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (8 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 09/21] qemu-config: Document " Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 11/21] VMDK: bugfix, align offset to cluster in get_whole_cluster Kevin Wolf
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Fam Zheng <famcool@gmail.com>

Introduced VmdkExtent array into BDRVVmdkState, enable holding multiple
image extents for multiple file image support.

Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vmdk.c |  348 +++++++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 246 insertions(+), 102 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 922b23d..3b78583 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -60,7 +60,11 @@ typedef struct {
 
 #define L2_CACHE_SIZE 16
 
-typedef struct BDRVVmdkState {
+typedef struct VmdkExtent {
+    BlockDriverState *file;
+    bool flat;
+    int64_t sectors;
+    int64_t end_sector;
     int64_t l1_table_offset;
     int64_t l1_backup_table_offset;
     uint32_t *l1_table;
@@ -74,7 +78,13 @@ typedef struct BDRVVmdkState {
     uint32_t l2_cache_counts[L2_CACHE_SIZE];
 
     unsigned int cluster_sectors;
+} VmdkExtent;
+
+typedef struct BDRVVmdkState {
     uint32_t parent_cid;
+    int num_extents;
+    /* Extent array with num_extents entries, ascend ordered by address */
+    VmdkExtent *extents;
 } BDRVVmdkState;
 
 typedef struct VmdkMetaData {
@@ -105,6 +115,19 @@ static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
 #define DESC_SIZE 20*SECTOR_SIZE	// 20 sectors of 512 bytes each
 #define HEADER_SIZE 512   			// first sector of 512 bytes
 
+static void vmdk_free_extents(BlockDriverState *bs)
+{
+    int i;
+    BDRVVmdkState *s = bs->opaque;
+
+    for (i = 0; i < s->num_extents; i++) {
+        qemu_free(s->extents[i].l1_table);
+        qemu_free(s->extents[i].l2_cache);
+        qemu_free(s->extents[i].l1_backup_table);
+    }
+    qemu_free(s->extents);
+}
+
 static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
 {
     char desc[DESC_SIZE];
@@ -358,11 +381,50 @@ static int vmdk_parent_open(BlockDriverState *bs)
     return 0;
 }
 
+/* Create and append extent to the extent array. Return the added VmdkExtent
+ * address. return NULL if allocation failed. */
+static VmdkExtent *vmdk_add_extent(BlockDriverState *bs,
+                           BlockDriverState *file, bool flat, int64_t sectors,
+                           int64_t l1_offset, int64_t l1_backup_offset,
+                           uint32_t l1_size,
+                           int l2_size, unsigned int cluster_sectors)
+{
+    VmdkExtent *extent;
+    BDRVVmdkState *s = bs->opaque;
+
+    s->extents = qemu_realloc(s->extents,
+                              (s->num_extents + 1) * sizeof(VmdkExtent));
+    extent = &s->extents[s->num_extents];
+    s->num_extents++;
+
+    memset(extent, 0, sizeof(VmdkExtent));
+    extent->file = file;
+    extent->flat = flat;
+    extent->sectors = sectors;
+    extent->l1_table_offset = l1_offset;
+    extent->l1_backup_table_offset = l1_backup_offset;
+    extent->l1_size = l1_size;
+    extent->l1_entry_sectors = l2_size * cluster_sectors;
+    extent->l2_size = l2_size;
+    extent->cluster_sectors = cluster_sectors;
+
+    if (s->num_extents > 1) {
+        extent->end_sector = (*(extent - 1)).end_sector + extent->sectors;
+    } else {
+        extent->end_sector = extent->sectors;
+    }
+    bs->total_sectors = extent->end_sector;
+    return extent;
+}
+
+
 static int vmdk_open(BlockDriverState *bs, int flags)
 {
     BDRVVmdkState *s = bs->opaque;
     uint32_t magic;
-    int l1_size, i;
+    int i;
+    uint32_t l1_size, l1_entry_sectors;
+    VmdkExtent *extent = NULL;
 
     if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic))
         goto fail;
@@ -370,32 +432,34 @@ static int vmdk_open(BlockDriverState *bs, int flags)
     magic = be32_to_cpu(magic);
     if (magic == VMDK3_MAGIC) {
         VMDK3Header header;
-
-        if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)) != sizeof(header))
+        if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
+                != sizeof(header)) {
             goto fail;
-        s->cluster_sectors = le32_to_cpu(header.granularity);
-        s->l2_size = 1 << 9;
-        s->l1_size = 1 << 6;
-        bs->total_sectors = le32_to_cpu(header.disk_sectors);
-        s->l1_table_offset = le32_to_cpu(header.l1dir_offset) << 9;
-        s->l1_backup_table_offset = 0;
-        s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
+        }
+        extent = vmdk_add_extent(bs, bs->file, false,
+                              le32_to_cpu(header.disk_sectors),
+                              le32_to_cpu(header.l1dir_offset) << 9, 0,
+                              1 << 6, 1 << 9, le32_to_cpu(header.granularity));
     } else if (magic == VMDK4_MAGIC) {
         VMDK4Header header;
-
-        if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)) != sizeof(header))
+        if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
+                != sizeof(header)) {
             goto fail;
-        bs->total_sectors = le64_to_cpu(header.capacity);
-        s->cluster_sectors = le64_to_cpu(header.granularity);
-        s->l2_size = le32_to_cpu(header.num_gtes_per_gte);
-        s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
-        if (s->l1_entry_sectors <= 0)
+        }
+        l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
+                            * le64_to_cpu(header.granularity);
+        l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
+                    / l1_entry_sectors;
+        extent = vmdk_add_extent(bs, bs->file, false,
+                              le64_to_cpu(header.capacity),
+                              le64_to_cpu(header.gd_offset) << 9,
+                              le64_to_cpu(header.rgd_offset) << 9,
+                              l1_size,
+                              le32_to_cpu(header.num_gtes_per_gte),
+                              le64_to_cpu(header.granularity));
+        if (extent->l1_entry_sectors <= 0) {
             goto fail;
-        s->l1_size = (bs->total_sectors + s->l1_entry_sectors - 1)
-            / s->l1_entry_sectors;
-        s->l1_table_offset = le64_to_cpu(header.rgd_offset) << 9;
-        s->l1_backup_table_offset = le64_to_cpu(header.gd_offset) << 9;
-
+        }
         // try to open parent images, if exist
         if (vmdk_parent_open(bs) != 0)
             goto fail;
@@ -406,40 +470,49 @@ static int vmdk_open(BlockDriverState *bs, int flags)
     }
 
     /* read the L1 table */
-    l1_size = s->l1_size * sizeof(uint32_t);
-    s->l1_table = qemu_malloc(l1_size);
-    if (bdrv_pread(bs->file, s->l1_table_offset, s->l1_table, l1_size) != l1_size)
+    l1_size = extent->l1_size * sizeof(uint32_t);
+    extent->l1_table = qemu_malloc(l1_size);
+    if (bdrv_pread(bs->file,
+            extent->l1_table_offset,
+            extent->l1_table,
+            l1_size)
+        != l1_size) {
         goto fail;
-    for(i = 0; i < s->l1_size; i++) {
-        le32_to_cpus(&s->l1_table[i]);
+    }
+    for (i = 0; i < extent->l1_size; i++) {
+        le32_to_cpus(&extent->l1_table[i]);
     }
 
-    if (s->l1_backup_table_offset) {
-        s->l1_backup_table = qemu_malloc(l1_size);
-        if (bdrv_pread(bs->file, s->l1_backup_table_offset, s->l1_backup_table, l1_size) != l1_size)
+    if (extent->l1_backup_table_offset) {
+        extent->l1_backup_table = qemu_malloc(l1_size);
+        if (bdrv_pread(bs->file,
+                    extent->l1_backup_table_offset,
+                    extent->l1_backup_table,
+                    l1_size)
+                != l1_size) {
             goto fail;
-        for(i = 0; i < s->l1_size; i++) {
-            le32_to_cpus(&s->l1_backup_table[i]);
+        }
+        for (i = 0; i < extent->l1_size; i++) {
+            le32_to_cpus(&extent->l1_backup_table[i]);
         }
     }
 
-    s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
+    extent->l2_cache =
+        qemu_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
     return 0;
  fail:
-    qemu_free(s->l1_backup_table);
-    qemu_free(s->l1_table);
-    qemu_free(s->l2_cache);
+    vmdk_free_extents(bs);
     return -1;
 }
 
-static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
-                                   uint64_t offset, int allocate);
-
-static int get_whole_cluster(BlockDriverState *bs, uint64_t cluster_offset,
-                             uint64_t offset, int allocate)
+static int get_whole_cluster(BlockDriverState *bs,
+                VmdkExtent *extent,
+                uint64_t cluster_offset,
+                uint64_t offset,
+                bool allocate)
 {
-    BDRVVmdkState *s = bs->opaque;
-    uint8_t  whole_grain[s->cluster_sectors*512];        // 128 sectors * 512 bytes each = grain size 64KB
+    /* 128 sectors * 512 bytes each = grain size 64KB */
+    uint8_t  whole_grain[extent->cluster_sectors * 512];
 
     // we will be here if it's first write on non-exist grain(cluster).
     // try to read from parent image, if exist
@@ -450,14 +523,14 @@ static int get_whole_cluster(BlockDriverState *bs, uint64_t cluster_offset,
             return -1;
 
         ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain,
-            s->cluster_sectors);
+                extent->cluster_sectors);
         if (ret < 0) {
             return -1;
         }
 
         //Write grain only into the active image
-        ret = bdrv_write(bs->file, cluster_offset, whole_grain,
-            s->cluster_sectors);
+        ret = bdrv_write(extent->file, cluster_offset, whole_grain,
+                extent->cluster_sectors);
         if (ret < 0) {
             return -1;
         }
@@ -465,29 +538,39 @@ static int get_whole_cluster(BlockDriverState *bs, uint64_t cluster_offset,
     return 0;
 }
 
-static int vmdk_L2update(BlockDriverState *bs, VmdkMetaData *m_data)
+static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data)
 {
-    BDRVVmdkState *s = bs->opaque;
-
     /* update L2 table */
-    if (bdrv_pwrite_sync(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
-                    &(m_data->offset), sizeof(m_data->offset)) < 0)
+    if (bdrv_pwrite_sync(
+                extent->file,
+                ((int64_t)m_data->l2_offset * 512)
+                    + (m_data->l2_index * sizeof(m_data->offset)),
+                &(m_data->offset),
+                sizeof(m_data->offset)
+            ) < 0) {
         return -1;
+    }
     /* update backup L2 table */
-    if (s->l1_backup_table_offset != 0) {
-        m_data->l2_offset = s->l1_backup_table[m_data->l1_index];
-        if (bdrv_pwrite_sync(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
-                        &(m_data->offset), sizeof(m_data->offset)) < 0)
+    if (extent->l1_backup_table_offset != 0) {
+        m_data->l2_offset = extent->l1_backup_table[m_data->l1_index];
+        if (bdrv_pwrite_sync(
+                    extent->file,
+                    ((int64_t)m_data->l2_offset * 512)
+                        + (m_data->l2_index * sizeof(m_data->offset)),
+                    &(m_data->offset), sizeof(m_data->offset)
+                ) < 0) {
             return -1;
+        }
     }
 
     return 0;
 }
 
-static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
-                                   uint64_t offset, int allocate)
+static uint64_t get_cluster_offset(BlockDriverState *bs,
+                                    VmdkExtent *extent,
+                                    VmdkMetaData *m_data,
+                                    uint64_t offset, int allocate)
 {
-    BDRVVmdkState *s = bs->opaque;
     unsigned int l1_index, l2_offset, l2_index;
     int min_index, i, j;
     uint32_t min_count, *l2_table, tmp = 0;
@@ -496,21 +579,23 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
     if (m_data)
         m_data->valid = 0;
 
-    l1_index = (offset >> 9) / s->l1_entry_sectors;
-    if (l1_index >= s->l1_size)
+    l1_index = (offset >> 9) / extent->l1_entry_sectors;
+    if (l1_index >= extent->l1_size) {
         return 0;
-    l2_offset = s->l1_table[l1_index];
-    if (!l2_offset)
+    }
+    l2_offset = extent->l1_table[l1_index];
+    if (!l2_offset) {
         return 0;
+    }
     for(i = 0; i < L2_CACHE_SIZE; i++) {
-        if (l2_offset == s->l2_cache_offsets[i]) {
+        if (l2_offset == extent->l2_cache_offsets[i]) {
             /* increment the hit count */
-            if (++s->l2_cache_counts[i] == 0xffffffff) {
+            if (++extent->l2_cache_counts[i] == 0xffffffff) {
                 for(j = 0; j < L2_CACHE_SIZE; j++) {
-                    s->l2_cache_counts[j] >>= 1;
+                    extent->l2_cache_counts[j] >>= 1;
                 }
             }
-            l2_table = s->l2_cache + (i * s->l2_size);
+            l2_table = extent->l2_cache + (i * extent->l2_size);
             goto found;
         }
     }
@@ -518,20 +603,25 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
     min_index = 0;
     min_count = 0xffffffff;
     for(i = 0; i < L2_CACHE_SIZE; i++) {
-        if (s->l2_cache_counts[i] < min_count) {
-            min_count = s->l2_cache_counts[i];
+        if (extent->l2_cache_counts[i] < min_count) {
+            min_count = extent->l2_cache_counts[i];
             min_index = i;
         }
     }
-    l2_table = s->l2_cache + (min_index * s->l2_size);
-    if (bdrv_pread(bs->file, (int64_t)l2_offset * 512, l2_table, s->l2_size * sizeof(uint32_t)) !=
-                                                                        s->l2_size * sizeof(uint32_t))
+    l2_table = extent->l2_cache + (min_index * extent->l2_size);
+    if (bdrv_pread(
+                extent->file,
+                (int64_t)l2_offset * 512,
+                l2_table,
+                extent->l2_size * sizeof(uint32_t)
+            ) != extent->l2_size * sizeof(uint32_t)) {
         return 0;
+    }
 
-    s->l2_cache_offsets[min_index] = l2_offset;
-    s->l2_cache_counts[min_index] = 1;
+    extent->l2_cache_offsets[min_index] = l2_offset;
+    extent->l2_cache_counts[min_index] = 1;
  found:
-    l2_index = ((offset >> 9) / s->cluster_sectors) % s->l2_size;
+    l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
     cluster_offset = le32_to_cpu(l2_table[l2_index]);
 
     if (!cluster_offset) {
@@ -539,8 +629,11 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
             return 0;
 
         // Avoid the L2 tables update for the images that have snapshots.
-        cluster_offset = bdrv_getlength(bs->file);
-        bdrv_truncate(bs->file, cluster_offset + (s->cluster_sectors << 9));
+        cluster_offset = bdrv_getlength(extent->file);
+        bdrv_truncate(
+            extent->file,
+            cluster_offset + (extent->cluster_sectors << 9)
+        );
 
         cluster_offset >>= 9;
         tmp = cpu_to_le32(cluster_offset);
@@ -551,7 +644,8 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
          * This problem may occur because of insufficient space on host disk
          * or inappropriate VM shutdown.
          */
-        if (get_whole_cluster(bs, cluster_offset, offset, allocate) == -1)
+        if (get_whole_cluster(
+                bs, extent, cluster_offset, offset, allocate) == -1)
             return 0;
 
         if (m_data) {
@@ -566,33 +660,69 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
     return cluster_offset;
 }
 
+static VmdkExtent *find_extent(BDRVVmdkState *s,
+                                int64_t sector_num, VmdkExtent *start_hint)
+{
+    VmdkExtent *extent = start_hint;
+
+    if (!extent) {
+        extent = &s->extents[0];
+    }
+    while (extent < &s->extents[s->num_extents]) {
+        if (sector_num < extent->end_sector) {
+            return extent;
+        }
+        extent++;
+    }
+    return NULL;
+}
+
 static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num,
                              int nb_sectors, int *pnum)
 {
     BDRVVmdkState *s = bs->opaque;
-    int index_in_cluster, n;
-    uint64_t cluster_offset;
 
-    cluster_offset = get_cluster_offset(bs, NULL, sector_num << 9, 0);
-    index_in_cluster = sector_num % s->cluster_sectors;
-    n = s->cluster_sectors - index_in_cluster;
+    int64_t index_in_cluster, n, ret;
+    uint64_t offset;
+    VmdkExtent *extent;
+
+    extent = find_extent(s, sector_num, NULL);
+    if (!extent) {
+        return 0;
+    }
+    if (extent->flat) {
+        n = extent->end_sector - sector_num;
+        ret = 1;
+    } else {
+        offset = get_cluster_offset(bs, extent, NULL, sector_num * 512, 0);
+        index_in_cluster = sector_num % extent->cluster_sectors;
+        n = extent->cluster_sectors - index_in_cluster;
+        ret = offset ? 1 : 0;
+    }
     if (n > nb_sectors)
         n = nb_sectors;
     *pnum = n;
-    return (cluster_offset != 0);
+    return ret;
 }
 
 static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
                     uint8_t *buf, int nb_sectors)
 {
     BDRVVmdkState *s = bs->opaque;
-    int index_in_cluster, n, ret;
+    int ret;
+    uint64_t n, index_in_cluster;
+    VmdkExtent *extent = NULL;
     uint64_t cluster_offset;
 
     while (nb_sectors > 0) {
-        cluster_offset = get_cluster_offset(bs, NULL, sector_num << 9, 0);
-        index_in_cluster = sector_num % s->cluster_sectors;
-        n = s->cluster_sectors - index_in_cluster;
+        extent = find_extent(s, sector_num, extent);
+        if (!extent) {
+            return -EIO;
+        }
+        cluster_offset = get_cluster_offset(
+                            bs, extent, NULL, sector_num << 9, 0);
+        index_in_cluster = sector_num % extent->cluster_sectors;
+        n = extent->cluster_sectors - index_in_cluster;
         if (n > nb_sectors)
             n = nb_sectors;
         if (!cluster_offset) {
@@ -621,10 +751,12 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
                      const uint8_t *buf, int nb_sectors)
 {
     BDRVVmdkState *s = bs->opaque;
-    VmdkMetaData m_data;
-    int index_in_cluster, n;
+    VmdkExtent *extent = NULL;
+    int n;
+    int64_t index_in_cluster;
     uint64_t cluster_offset;
     static int cid_update = 0;
+    VmdkMetaData m_data;
 
     if (sector_num > bs->total_sectors) {
         fprintf(stderr,
@@ -635,20 +767,35 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
     }
 
     while (nb_sectors > 0) {
-        index_in_cluster = sector_num & (s->cluster_sectors - 1);
-        n = s->cluster_sectors - index_in_cluster;
-        if (n > nb_sectors)
-            n = nb_sectors;
-        cluster_offset = get_cluster_offset(bs, &m_data, sector_num << 9, 1);
-        if (!cluster_offset)
+        extent = find_extent(s, sector_num, extent);
+        if (!extent) {
+            return -EIO;
+        }
+        cluster_offset = get_cluster_offset(
+                                bs,
+                                extent,
+                                &m_data,
+                                sector_num << 9, 1);
+        if (!cluster_offset) {
             return -1;
+        }
+        index_in_cluster = sector_num % extent->cluster_sectors;
+        n = extent->cluster_sectors - index_in_cluster;
+        if (n > nb_sectors) {
+            n = nb_sectors;
+        }
 
-        if (bdrv_pwrite(bs->file, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512)
+        if (bdrv_pwrite(bs->file,
+                        cluster_offset + index_in_cluster * 512,
+                        buf, n * 512)
+                != n * 512) {
             return -1;
+        }
         if (m_data.valid) {
             /* update L2 tables */
-            if (vmdk_L2update(bs, &m_data) == -1)
+            if (vmdk_L2update(extent, &m_data) == -1) {
                 return -1;
+            }
         }
         nb_sectors -= n;
         sector_num += n;
@@ -822,10 +969,7 @@ exit:
 
 static void vmdk_close(BlockDriverState *bs)
 {
-    BDRVVmdkState *s = bs->opaque;
-
-    qemu_free(s->l1_table);
-    qemu_free(s->l2_cache);
+    vmdk_free_extents(bs);
 }
 
 static int vmdk_flush(BlockDriverState *bs)
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 11/21] VMDK: bugfix, align offset to cluster in get_whole_cluster
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (9 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 10/21] VMDK: introduce VmdkExtent Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 12/21] VMDK: probe for monolithicFlat images Kevin Wolf
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Fam Zheng <famcool@gmail.com>

In get_whole_cluster, the offset is not aligned to cluster when reading
from backing_hd. When the first write to child is not at the cluster
boundary, wrong address data from parent is copied to child.

Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vmdk.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 3b78583..03a4619 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -514,21 +514,23 @@ static int get_whole_cluster(BlockDriverState *bs,
     /* 128 sectors * 512 bytes each = grain size 64KB */
     uint8_t  whole_grain[extent->cluster_sectors * 512];
 
-    // we will be here if it's first write on non-exist grain(cluster).
-    // try to read from parent image, if exist
+    /* we will be here if it's first write on non-exist grain(cluster).
+     * try to read from parent image, if exist */
     if (bs->backing_hd) {
         int ret;
 
         if (!vmdk_is_cid_valid(bs))
             return -1;
 
+        /* floor offset to cluster */
+        offset -= offset % (extent->cluster_sectors * 512);
         ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain,
                 extent->cluster_sectors);
         if (ret < 0) {
             return -1;
         }
 
-        //Write grain only into the active image
+        /* Write grain only into the active image */
         ret = bdrv_write(extent->file, cluster_offset, whole_grain,
                 extent->cluster_sectors);
         if (ret < 0) {
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 12/21] VMDK: probe for monolithicFlat images
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (10 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 11/21] VMDK: bugfix, align offset to cluster in get_whole_cluster Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 13/21] VMDK: separate vmdk_open by format version Kevin Wolf
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Fam Zheng <famcool@gmail.com>

Probe as the same behavior as VMware does.
Recognize image as monolithicFlat descriptor file when the file is text
and the first effective line (not '#' leaded comment or space line) is
either 'version=1' or 'version=2'. No space or upper case charactors
accepted.

Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vmdk.c |   45 +++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 03a4619..f8a815c 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -103,10 +103,51 @@ static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
         return 0;
     magic = be32_to_cpu(*(uint32_t *)buf);
     if (magic == VMDK3_MAGIC ||
-        magic == VMDK4_MAGIC)
+        magic == VMDK4_MAGIC) {
         return 100;
-    else
+    } else {
+        const char *p = (const char *)buf;
+        const char *end = p + buf_size;
+        while (p < end) {
+            if (*p == '#') {
+                /* skip comment line */
+                while (p < end && *p != '\n') {
+                    p++;
+                }
+                p++;
+                continue;
+            }
+            if (*p == ' ') {
+                while (p < end && *p == ' ') {
+                    p++;
+                }
+                /* skip '\r' if windows line endings used. */
+                if (p < end && *p == '\r') {
+                    p++;
+                }
+                /* only accept blank lines before 'version=' line */
+                if (p == end || *p != '\n') {
+                    return 0;
+                }
+                p++;
+                continue;
+            }
+            if (end - p >= strlen("version=X\n")) {
+                if (strncmp("version=1\n", p, strlen("version=1\n")) == 0 ||
+                    strncmp("version=2\n", p, strlen("version=2\n")) == 0) {
+                    return 100;
+                }
+            }
+            if (end - p >= strlen("version=X\r\n")) {
+                if (strncmp("version=1\r\n", p, strlen("version=1\r\n")) == 0 ||
+                    strncmp("version=2\r\n", p, strlen("version=2\r\n")) == 0) {
+                    return 100;
+                }
+            }
+            return 0;
+        }
         return 0;
+    }
 }
 
 #define CHECK_CID 1
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 13/21] VMDK: separate vmdk_open by format version
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (11 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 12/21] VMDK: probe for monolithicFlat images Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 14/21] VMDK: add field BDRVVmdkState.desc_offset Kevin Wolf
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Fam Zheng <famcool@gmail.com>

Separate vmdk_open by subformats to:
* vmdk_open_vmdk3
* vmdk_open_vmdk4

Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vmdk.c |  178 ++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 112 insertions(+), 66 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index f8a815c..6d7b497 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -458,67 +458,20 @@ static VmdkExtent *vmdk_add_extent(BlockDriverState *bs,
     return extent;
 }
 
-
-static int vmdk_open(BlockDriverState *bs, int flags)
+static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
 {
-    BDRVVmdkState *s = bs->opaque;
-    uint32_t magic;
-    int i;
-    uint32_t l1_size, l1_entry_sectors;
-    VmdkExtent *extent = NULL;
-
-    if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic))
-        goto fail;
-
-    magic = be32_to_cpu(magic);
-    if (magic == VMDK3_MAGIC) {
-        VMDK3Header header;
-        if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
-                != sizeof(header)) {
-            goto fail;
-        }
-        extent = vmdk_add_extent(bs, bs->file, false,
-                              le32_to_cpu(header.disk_sectors),
-                              le32_to_cpu(header.l1dir_offset) << 9, 0,
-                              1 << 6, 1 << 9, le32_to_cpu(header.granularity));
-    } else if (magic == VMDK4_MAGIC) {
-        VMDK4Header header;
-        if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
-                != sizeof(header)) {
-            goto fail;
-        }
-        l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
-                            * le64_to_cpu(header.granularity);
-        l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
-                    / l1_entry_sectors;
-        extent = vmdk_add_extent(bs, bs->file, false,
-                              le64_to_cpu(header.capacity),
-                              le64_to_cpu(header.gd_offset) << 9,
-                              le64_to_cpu(header.rgd_offset) << 9,
-                              l1_size,
-                              le32_to_cpu(header.num_gtes_per_gte),
-                              le64_to_cpu(header.granularity));
-        if (extent->l1_entry_sectors <= 0) {
-            goto fail;
-        }
-        // try to open parent images, if exist
-        if (vmdk_parent_open(bs) != 0)
-            goto fail;
-        // write the CID once after the image creation
-        s->parent_cid = vmdk_read_cid(bs,1);
-    } else {
-        goto fail;
-    }
+    int ret;
+    int l1_size, i;
 
     /* read the L1 table */
     l1_size = extent->l1_size * sizeof(uint32_t);
     extent->l1_table = qemu_malloc(l1_size);
-    if (bdrv_pread(bs->file,
-            extent->l1_table_offset,
-            extent->l1_table,
-            l1_size)
-        != l1_size) {
-        goto fail;
+    ret = bdrv_pread(extent->file,
+                    extent->l1_table_offset,
+                    extent->l1_table,
+                    l1_size);
+    if (ret < 0) {
+        goto fail_l1;
     }
     for (i = 0; i < extent->l1_size; i++) {
         le32_to_cpus(&extent->l1_table[i]);
@@ -526,12 +479,12 @@ static int vmdk_open(BlockDriverState *bs, int flags)
 
     if (extent->l1_backup_table_offset) {
         extent->l1_backup_table = qemu_malloc(l1_size);
-        if (bdrv_pread(bs->file,
-                    extent->l1_backup_table_offset,
-                    extent->l1_backup_table,
-                    l1_size)
-                != l1_size) {
-            goto fail;
+        ret = bdrv_pread(extent->file,
+                        extent->l1_backup_table_offset,
+                        extent->l1_backup_table,
+                        l1_size);
+        if (ret < 0) {
+            goto fail_l1b;
         }
         for (i = 0; i < extent->l1_size; i++) {
             le32_to_cpus(&extent->l1_backup_table[i]);
@@ -541,9 +494,102 @@ static int vmdk_open(BlockDriverState *bs, int flags)
     extent->l2_cache =
         qemu_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
     return 0;
+ fail_l1b:
+    qemu_free(extent->l1_backup_table);
+ fail_l1:
+    qemu_free(extent->l1_table);
+    return ret;
+}
+
+static int vmdk_open_vmdk3(BlockDriverState *bs, int flags)
+{
+    int ret;
+    uint32_t magic;
+    VMDK3Header header;
+    VmdkExtent *extent;
+
+    ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
+    if (ret < 0) {
+        goto fail;
+    }
+    extent = vmdk_add_extent(bs,
+                             bs->file, false,
+                             le32_to_cpu(header.disk_sectors),
+                             le32_to_cpu(header.l1dir_offset) << 9,
+                             0, 1 << 6, 1 << 9,
+                             le32_to_cpu(header.granularity));
+    ret = vmdk_init_tables(bs, extent);
+    if (ret) {
+        /* vmdk_init_tables cleans up on fail, so only free allocation of
+         * vmdk_add_extent here. */
+        goto fail;
+    }
+    return 0;
  fail:
     vmdk_free_extents(bs);
-    return -1;
+    return ret;
+}
+
+static int vmdk_open_vmdk4(BlockDriverState *bs, int flags)
+{
+    int ret;
+    uint32_t magic;
+    uint32_t l1_size, l1_entry_sectors;
+    VMDK4Header header;
+    BDRVVmdkState *s = bs->opaque;
+    VmdkExtent *extent;
+
+    ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
+    if (ret < 0) {
+        goto fail;
+    }
+    l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
+                        * le64_to_cpu(header.granularity);
+    l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
+                / l1_entry_sectors;
+    extent = vmdk_add_extent(bs, bs->file, false,
+                          le64_to_cpu(header.capacity),
+                          le64_to_cpu(header.gd_offset) << 9,
+                          le64_to_cpu(header.rgd_offset) << 9,
+                          l1_size,
+                          le32_to_cpu(header.num_gtes_per_gte),
+                          le64_to_cpu(header.granularity));
+    if (extent->l1_entry_sectors <= 0) {
+        ret = -EINVAL;
+        goto fail;
+    }
+    /* try to open parent images, if exist */
+    ret = vmdk_parent_open(bs);
+    if (ret) {
+        goto fail;
+    }
+    s->parent_cid = vmdk_read_cid(bs, 1);
+    ret = vmdk_init_tables(bs, extent);
+    if (ret) {
+        goto fail;
+    }
+    return 0;
+ fail:
+    vmdk_free_extents(bs);
+    return ret;
+}
+
+static int vmdk_open(BlockDriverState *bs, int flags)
+{
+    uint32_t magic;
+
+    if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic)) {
+        return -EIO;
+    }
+
+    magic = be32_to_cpu(magic);
+    if (magic == VMDK3_MAGIC) {
+        return vmdk_open_vmdk3(bs, flags);
+    } else if (magic == VMDK4_MAGIC) {
+        return vmdk_open_vmdk4(bs, flags);
+    } else {
+        return -EINVAL;
+    }
 }
 
 static int get_whole_cluster(BlockDriverState *bs,
@@ -630,11 +676,11 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
     if (!l2_offset) {
         return 0;
     }
-    for(i = 0; i < L2_CACHE_SIZE; i++) {
+    for (i = 0; i < L2_CACHE_SIZE; i++) {
         if (l2_offset == extent->l2_cache_offsets[i]) {
             /* increment the hit count */
             if (++extent->l2_cache_counts[i] == 0xffffffff) {
-                for(j = 0; j < L2_CACHE_SIZE; j++) {
+                for (j = 0; j < L2_CACHE_SIZE; j++) {
                     extent->l2_cache_counts[j] >>= 1;
                 }
             }
@@ -645,7 +691,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
     /* not found: load a new entry in the least used one */
     min_index = 0;
     min_count = 0xffffffff;
-    for(i = 0; i < L2_CACHE_SIZE; i++) {
+    for (i = 0; i < L2_CACHE_SIZE; i++) {
         if (extent->l2_cache_counts[i] < min_count) {
             min_count = extent->l2_cache_counts[i];
             min_index = i;
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 14/21] VMDK: add field BDRVVmdkState.desc_offset
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (12 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 13/21] VMDK: separate vmdk_open by format version Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 15/21] VMDK: flush multiple extents Kevin Wolf
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Fam Zheng <famcool@gmail.com>

There are several occurrence of magic number 0x200 as the descriptor
offset within mono sparse image file. This is not the case for images
with separate descriptor file. So a field is added to BDRVVmdkState to
hold the correct value.

Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vmdk.c |   27 ++++++++++++++++++---------
 1 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 6d7b497..529ae90 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -81,6 +81,7 @@ typedef struct VmdkExtent {
 } VmdkExtent;
 
 typedef struct BDRVVmdkState {
+    int desc_offset;
     uint32_t parent_cid;
     int num_extents;
     /* Extent array with num_extents entries, ascend ordered by address */
@@ -175,10 +176,11 @@ static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
     uint32_t cid;
     const char *p_name, *cid_str;
     size_t cid_str_size;
+    BDRVVmdkState *s = bs->opaque;
 
-    /* the descriptor offset = 0x200 */
-    if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
+    if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
         return 0;
+    }
 
     if (parent) {
         cid_str = "parentCID";
@@ -200,10 +202,12 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
 {
     char desc[DESC_SIZE], tmp_desc[DESC_SIZE];
     char *p_name, *tmp_str;
+    BDRVVmdkState *s = bs->opaque;
 
-    /* the descriptor offset = 0x200 */
-    if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
-        return -1;
+    memset(desc, 0, sizeof(desc));
+    if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
+        return -EIO;
+    }
 
     tmp_str = strstr(desc,"parentCID");
     pstrcpy(tmp_desc, sizeof(tmp_desc), tmp_str);
@@ -213,8 +217,9 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
         pstrcat(desc, sizeof(desc), tmp_desc);
     }
 
-    if (bdrv_pwrite_sync(bs->file, 0x200, desc, DESC_SIZE) < 0)
-        return -1;
+    if (bdrv_pwrite_sync(bs->file, s->desc_offset, desc, DESC_SIZE) < 0) {
+        return -EIO;
+    }
     return 0;
 }
 
@@ -402,10 +407,11 @@ static int vmdk_parent_open(BlockDriverState *bs)
 {
     char *p_name;
     char desc[DESC_SIZE];
+    BDRVVmdkState *s = bs->opaque;
 
-    /* the descriptor offset = 0x200 */
-    if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
+    if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
         return -1;
+    }
 
     if ((p_name = strstr(desc,"parentFileNameHint")) != NULL) {
         char *end_name;
@@ -506,8 +512,10 @@ static int vmdk_open_vmdk3(BlockDriverState *bs, int flags)
     int ret;
     uint32_t magic;
     VMDK3Header header;
+    BDRVVmdkState *s = bs->opaque;
     VmdkExtent *extent;
 
+    s->desc_offset = 0x200;
     ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
     if (ret < 0) {
         goto fail;
@@ -539,6 +547,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs, int flags)
     BDRVVmdkState *s = bs->opaque;
     VmdkExtent *extent;
 
+    s->desc_offset = 0x200;
     ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
     if (ret < 0) {
         goto fail;
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 15/21] VMDK: flush multiple extents
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (13 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 14/21] VMDK: add field BDRVVmdkState.desc_offset Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 16/21] VMDK: move 'static' cid_update flag to bs field Kevin Wolf
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Fam Zheng <famcool@gmail.com>

Flush all the file that referenced by the image.

Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vmdk.c |   12 +++++++++++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 529ae90..f6d2986 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1072,7 +1072,17 @@ static void vmdk_close(BlockDriverState *bs)
 
 static int vmdk_flush(BlockDriverState *bs)
 {
-    return bdrv_flush(bs->file);
+    int i, ret, err;
+    BDRVVmdkState *s = bs->opaque;
+
+    ret = bdrv_flush(bs->file);
+    for (i = 0; i < s->num_extents; i++) {
+        err = bdrv_flush(s->extents[i].file);
+        if (err < 0) {
+            ret = err;
+        }
+    }
+    return ret;
 }
 
 
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 16/21] VMDK: move 'static' cid_update flag to bs field
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (14 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 15/21] VMDK: flush multiple extents Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 17/21] VMDK: change get_cluster_offset return type Kevin Wolf
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Fam Zheng <famcool@gmail.com>

Cid_update is the flag for updating CID on first write after opening the
image. This should be per image open rather than per program life cycle,
so change it from static var of vmdk_write to a field in BDRVVmdkState.

Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vmdk.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index f6d2986..8dc58a8 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -82,6 +82,7 @@ typedef struct VmdkExtent {
 
 typedef struct BDRVVmdkState {
     int desc_offset;
+    bool cid_updated;
     uint32_t parent_cid;
     int num_extents;
     /* Extent array with num_extents entries, ascend ordered by address */
@@ -853,7 +854,6 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
     int n;
     int64_t index_in_cluster;
     uint64_t cluster_offset;
-    static int cid_update = 0;
     VmdkMetaData m_data;
 
     if (sector_num > bs->total_sectors) {
@@ -900,9 +900,9 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
         buf += n * 512;
 
         // update CID on the first write every time the virtual disk is opened
-        if (!cid_update) {
+        if (!s->cid_updated) {
             vmdk_write_cid(bs, time(NULL));
-            cid_update++;
+            s->cid_updated = true;
         }
     }
     return 0;
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 17/21] VMDK: change get_cluster_offset return type
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (15 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 16/21] VMDK: move 'static' cid_update flag to bs field Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 18/21] VMDK: open/read/write for monolithicFlat image Kevin Wolf
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Fam Zheng <famcool@gmail.com>

The return type of get_cluster_offset was an offset that use 0 to denote
'not allocated', this will be no longer true for flat extents, as we see
flat extent file as a single huge cluster whose offset is 0 and length
is the whole file length.
So now we use int return value, 0 means success and otherwise offset
invalid.

Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vmdk.c |   79 ++++++++++++++++++++++++++++++---------------------------
 1 files changed, 42 insertions(+), 37 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 8dc58a8..f637d98 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -665,26 +665,31 @@ static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data)
     return 0;
 }
 
-static uint64_t get_cluster_offset(BlockDriverState *bs,
+static int get_cluster_offset(BlockDriverState *bs,
                                     VmdkExtent *extent,
                                     VmdkMetaData *m_data,
-                                    uint64_t offset, int allocate)
+                                    uint64_t offset,
+                                    int allocate,
+                                    uint64_t *cluster_offset)
 {
     unsigned int l1_index, l2_offset, l2_index;
     int min_index, i, j;
     uint32_t min_count, *l2_table, tmp = 0;
-    uint64_t cluster_offset;
 
     if (m_data)
         m_data->valid = 0;
+    if (extent->flat) {
+        *cluster_offset = 0;
+        return 0;
+    }
 
     l1_index = (offset >> 9) / extent->l1_entry_sectors;
     if (l1_index >= extent->l1_size) {
-        return 0;
+        return -1;
     }
     l2_offset = extent->l1_table[l1_index];
     if (!l2_offset) {
-        return 0;
+        return -1;
     }
     for (i = 0; i < L2_CACHE_SIZE; i++) {
         if (l2_offset == extent->l2_cache_offsets[i]) {
@@ -714,28 +719,29 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
                 l2_table,
                 extent->l2_size * sizeof(uint32_t)
             ) != extent->l2_size * sizeof(uint32_t)) {
-        return 0;
+        return -1;
     }
 
     extent->l2_cache_offsets[min_index] = l2_offset;
     extent->l2_cache_counts[min_index] = 1;
  found:
     l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
-    cluster_offset = le32_to_cpu(l2_table[l2_index]);
+    *cluster_offset = le32_to_cpu(l2_table[l2_index]);
 
-    if (!cluster_offset) {
-        if (!allocate)
-            return 0;
+    if (!*cluster_offset) {
+        if (!allocate) {
+            return -1;
+        }
 
         // Avoid the L2 tables update for the images that have snapshots.
-        cluster_offset = bdrv_getlength(extent->file);
+        *cluster_offset = bdrv_getlength(extent->file);
         bdrv_truncate(
             extent->file,
-            cluster_offset + (extent->cluster_sectors << 9)
+            *cluster_offset + (extent->cluster_sectors << 9)
         );
 
-        cluster_offset >>= 9;
-        tmp = cpu_to_le32(cluster_offset);
+        *cluster_offset >>= 9;
+        tmp = cpu_to_le32(*cluster_offset);
         l2_table[l2_index] = tmp;
 
         /* First of all we write grain itself, to avoid race condition
@@ -744,8 +750,8 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
          * or inappropriate VM shutdown.
          */
         if (get_whole_cluster(
-                bs, extent, cluster_offset, offset, allocate) == -1)
-            return 0;
+                bs, extent, *cluster_offset, offset, allocate) == -1)
+            return -1;
 
         if (m_data) {
             m_data->offset = tmp;
@@ -755,8 +761,8 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
             m_data->valid = 1;
         }
     }
-    cluster_offset <<= 9;
-    return cluster_offset;
+    *cluster_offset <<= 9;
+    return 0;
 }
 
 static VmdkExtent *find_extent(BDRVVmdkState *s,
@@ -780,7 +786,6 @@ static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num,
                              int nb_sectors, int *pnum)
 {
     BDRVVmdkState *s = bs->opaque;
-
     int64_t index_in_cluster, n, ret;
     uint64_t offset;
     VmdkExtent *extent;
@@ -789,15 +794,13 @@ static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num,
     if (!extent) {
         return 0;
     }
-    if (extent->flat) {
-        n = extent->end_sector - sector_num;
-        ret = 1;
-    } else {
-        offset = get_cluster_offset(bs, extent, NULL, sector_num * 512, 0);
-        index_in_cluster = sector_num % extent->cluster_sectors;
-        n = extent->cluster_sectors - index_in_cluster;
-        ret = offset ? 1 : 0;
-    }
+    ret = get_cluster_offset(bs, extent, NULL,
+                            sector_num * 512, 0, &offset);
+    /* get_cluster_offset returning 0 means success */
+    ret = !ret;
+
+    index_in_cluster = sector_num % extent->cluster_sectors;
+    n = extent->cluster_sectors - index_in_cluster;
     if (n > nb_sectors)
         n = nb_sectors;
     *pnum = n;
@@ -818,14 +821,15 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
         if (!extent) {
             return -EIO;
         }
-        cluster_offset = get_cluster_offset(
-                            bs, extent, NULL, sector_num << 9, 0);
+        ret = get_cluster_offset(
+                            bs, extent, NULL,
+                            sector_num << 9, 0, &cluster_offset);
         index_in_cluster = sector_num % extent->cluster_sectors;
         n = extent->cluster_sectors - index_in_cluster;
         if (n > nb_sectors)
             n = nb_sectors;
-        if (!cluster_offset) {
-            // try to read from parent image, if exist
+        if (ret) {
+            /* if not allocated, try to read from parent image, if exist */
             if (bs->backing_hd) {
                 if (!vmdk_is_cid_valid(bs))
                     return -1;
@@ -851,7 +855,7 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
 {
     BDRVVmdkState *s = bs->opaque;
     VmdkExtent *extent = NULL;
-    int n;
+    int n, ret;
     int64_t index_in_cluster;
     uint64_t cluster_offset;
     VmdkMetaData m_data;
@@ -869,13 +873,14 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
         if (!extent) {
             return -EIO;
         }
-        cluster_offset = get_cluster_offset(
+        ret = get_cluster_offset(
                                 bs,
                                 extent,
                                 &m_data,
-                                sector_num << 9, 1);
-        if (!cluster_offset) {
-            return -1;
+                                sector_num << 9, 1,
+                                &cluster_offset);
+        if (ret) {
+            return -EINVAL;
         }
         index_in_cluster = sector_num % extent->cluster_sectors;
         n = extent->cluster_sectors - index_in_cluster;
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 18/21] VMDK: open/read/write for monolithicFlat image
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (16 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 17/21] VMDK: change get_cluster_offset return type Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 19/21] VMDK: create different subformats Kevin Wolf
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Fam Zheng <famcool@gmail.com>

Parse vmdk decriptor file and open mono flat image.
Read/write the flat extent.

Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vmdk.c |  171 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 158 insertions(+), 13 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index f637d98..e1fb962 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -65,6 +65,7 @@ typedef struct VmdkExtent {
     bool flat;
     int64_t sectors;
     int64_t end_sector;
+    int64_t flat_start_offset;
     int64_t l1_table_offset;
     int64_t l1_backup_table_offset;
     uint32_t *l1_table;
@@ -407,9 +408,10 @@ fail:
 static int vmdk_parent_open(BlockDriverState *bs)
 {
     char *p_name;
-    char desc[DESC_SIZE];
+    char desc[DESC_SIZE + 1];
     BDRVVmdkState *s = bs->opaque;
 
+    desc[DESC_SIZE] = '\0';
     if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
         return -1;
     }
@@ -584,6 +586,144 @@ static int vmdk_open_vmdk4(BlockDriverState *bs, int flags)
     return ret;
 }
 
+/* find an option value out of descriptor file */
+static int vmdk_parse_description(const char *desc, const char *opt_name,
+        char *buf, int buf_size)
+{
+    char *opt_pos, *opt_end;
+    const char *end = desc + strlen(desc);
+
+    opt_pos = strstr(desc, opt_name);
+    if (!opt_pos) {
+        return -1;
+    }
+    /* Skip "=\"" following opt_name */
+    opt_pos += strlen(opt_name) + 2;
+    if (opt_pos >= end) {
+        return -1;
+    }
+    opt_end = opt_pos;
+    while (opt_end < end && *opt_end != '"') {
+        opt_end++;
+    }
+    if (opt_end == end || buf_size < opt_end - opt_pos + 1) {
+        return -1;
+    }
+    pstrcpy(buf, opt_end - opt_pos + 1, opt_pos);
+    return 0;
+}
+
+static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
+        const char *desc_file_path)
+{
+    int ret;
+    char access[11];
+    char type[11];
+    char fname[512];
+    const char *p = desc;
+    int64_t sectors = 0;
+    int64_t flat_offset;
+
+    while (*p) {
+        /* parse extent line:
+         * RW [size in sectors] FLAT "file-name.vmdk" OFFSET
+         * or
+         * RW [size in sectors] SPARSE "file-name.vmdk"
+         */
+        flat_offset = -1;
+        ret = sscanf(p, "%10s %" SCNd64 " %10s %511s %" SCNd64,
+                access, &sectors, type, fname, &flat_offset);
+        if (ret < 4 || strcmp(access, "RW")) {
+            goto next_line;
+        } else if (!strcmp(type, "FLAT")) {
+            if (ret != 5 || flat_offset < 0) {
+                return -EINVAL;
+            }
+        } else if (ret != 4) {
+            return -EINVAL;
+        }
+
+        /* trim the quotation marks around */
+        if (fname[0] == '"') {
+            memmove(fname, fname + 1, strlen(fname));
+            if (strlen(fname) <= 1 || fname[strlen(fname) - 1] != '"') {
+                return -EINVAL;
+            }
+            fname[strlen(fname) - 1] = '\0';
+        }
+        if (sectors <= 0 ||
+            (strcmp(type, "FLAT") && strcmp(type, "SPARSE")) ||
+            (strcmp(access, "RW"))) {
+            goto next_line;
+        }
+
+        /* save to extents array */
+        if (!strcmp(type, "FLAT")) {
+            /* FLAT extent */
+            char extent_path[PATH_MAX];
+            BlockDriverState *extent_file;
+            VmdkExtent *extent;
+
+            path_combine(extent_path, sizeof(extent_path),
+                    desc_file_path, fname);
+            ret = bdrv_file_open(&extent_file, extent_path, bs->open_flags);
+            if (ret) {
+                return ret;
+            }
+            extent = vmdk_add_extent(bs, extent_file, true, sectors,
+                            0, 0, 0, 0, sectors);
+            extent->flat_start_offset = flat_offset;
+        } else {
+            /* SPARSE extent, not supported for now */
+            fprintf(stderr,
+                "VMDK: Not supported extent type \"%s\""".\n", type);
+            return -ENOTSUP;
+        }
+next_line:
+        /* move to next line */
+        while (*p && *p != '\n') {
+            p++;
+        }
+        p++;
+    }
+    return 0;
+}
+
+static int vmdk_open_desc_file(BlockDriverState *bs, int flags)
+{
+    int ret;
+    char buf[2048];
+    char ct[128];
+    BDRVVmdkState *s = bs->opaque;
+
+    ret = bdrv_pread(bs->file, 0, buf, sizeof(buf));
+    if (ret < 0) {
+        return ret;
+    }
+    buf[2047] = '\0';
+    if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) {
+        return -EINVAL;
+    }
+    if (strcmp(ct, "monolithicFlat")) {
+        fprintf(stderr,
+                "VMDK: Not supported image type \"%s\""".\n", ct);
+        return -ENOTSUP;
+    }
+    s->desc_offset = 0;
+    ret = vmdk_parse_extents(buf, bs, bs->file->filename);
+    if (ret) {
+        return ret;
+    }
+
+    /* try to open parent images, if exist */
+    if (vmdk_parent_open(bs)) {
+        qemu_free(s->extents);
+        return -EINVAL;
+    }
+    s->parent_cid = vmdk_read_cid(bs, 1);
+    return 0;
+}
+
 static int vmdk_open(BlockDriverState *bs, int flags)
 {
     uint32_t magic;
@@ -598,7 +738,7 @@ static int vmdk_open(BlockDriverState *bs, int flags)
     } else if (magic == VMDK4_MAGIC) {
         return vmdk_open_vmdk4(bs, flags);
     } else {
-        return -EINVAL;
+        return vmdk_open_desc_file(bs, flags);
     }
 }
 
@@ -679,7 +819,7 @@ static int get_cluster_offset(BlockDriverState *bs,
     if (m_data)
         m_data->valid = 0;
     if (extent->flat) {
-        *cluster_offset = 0;
+        *cluster_offset = extent->flat_start_offset;
         return 0;
     }
 
@@ -832,16 +972,20 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
             /* if not allocated, try to read from parent image, if exist */
             if (bs->backing_hd) {
                 if (!vmdk_is_cid_valid(bs))
-                    return -1;
+                    return -EINVAL;
                 ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
                 if (ret < 0)
-                    return -1;
+                    return ret;
             } else {
                 memset(buf, 0, 512 * n);
             }
         } else {
-            if(bdrv_pread(bs->file, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512)
-                return -1;
+            ret = bdrv_pread(extent->file,
+                            cluster_offset + index_in_cluster * 512,
+                            buf, n * 512);
+            if (ret < 0) {
+                return ret;
+            }
         }
         nb_sectors -= n;
         sector_num += n;
@@ -865,7 +1009,7 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
                 "(VMDK) Wrong offset: sector_num=0x%" PRIx64
                 " total_sectors=0x%" PRIx64 "\n",
                 sector_num, bs->total_sectors);
-        return -1;
+        return -EIO;
     }
 
     while (nb_sectors > 0) {
@@ -888,16 +1032,17 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
             n = nb_sectors;
         }
 
-        if (bdrv_pwrite(bs->file,
+        ret = bdrv_pwrite(extent->file,
                         cluster_offset + index_in_cluster * 512,
-                        buf, n * 512)
-                != n * 512) {
-            return -1;
+                        buf,
+                        n * 512);
+        if (ret < 0) {
+            return ret;
         }
         if (m_data.valid) {
             /* update L2 tables */
             if (vmdk_L2update(extent, &m_data) == -1) {
-                return -1;
+                return -EIO;
             }
         }
         nb_sectors -= n;
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 19/21] VMDK: create different subformats
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (17 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 18/21] VMDK: open/read/write for monolithicFlat image Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 20/21] VMDK: fix coding style Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 21/21] block: add bdrv_get_allocated_file_size() operation Kevin Wolf
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Fam Zheng <famcool@gmail.com>

Add create option 'format', with enums:
    monolithicSparse
    monolithicFlat
    twoGbMaxExtentSparse
    twoGbMaxExtentFlat
Each creates a subformat image file. The default is monolithicSparse.

Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vmdk.c |  503 +++++++++++++++++++++++++++++++--------------------------
 block_int.h  |    1 +
 2 files changed, 275 insertions(+), 229 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index e1fb962..b53c5f5 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -156,8 +156,9 @@ static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
 #define CHECK_CID 1
 
 #define SECTOR_SIZE 512
-#define DESC_SIZE 20*SECTOR_SIZE	// 20 sectors of 512 bytes each
-#define HEADER_SIZE 512   			// first sector of 512 bytes
+#define DESC_SIZE (20 * SECTOR_SIZE)    /* 20 sectors of 512 bytes each */
+#define BUF_SIZE 4096
+#define HEADER_SIZE 512                 /* first sector of 512 bytes */
 
 static void vmdk_free_extents(BlockDriverState *bs)
 {
@@ -243,168 +244,6 @@ static int vmdk_is_cid_valid(BlockDriverState *bs)
     return 1;
 }
 
-static int vmdk_snapshot_create(const char *filename, const char *backing_file)
-{
-    int snp_fd, p_fd;
-    int ret;
-    uint32_t p_cid;
-    char *p_name, *gd_buf, *rgd_buf;
-    const char *real_filename, *temp_str;
-    VMDK4Header header;
-    uint32_t gde_entries, gd_size;
-    int64_t gd_offset, rgd_offset, capacity, gt_size;
-    char p_desc[DESC_SIZE], s_desc[DESC_SIZE], hdr[HEADER_SIZE];
-    static const char desc_template[] =
-    "# Disk DescriptorFile\n"
-    "version=1\n"
-    "CID=%x\n"
-    "parentCID=%x\n"
-    "createType=\"monolithicSparse\"\n"
-    "parentFileNameHint=\"%s\"\n"
-    "\n"
-    "# Extent description\n"
-    "RW %u SPARSE \"%s\"\n"
-    "\n"
-    "# The Disk Data Base \n"
-    "#DDB\n"
-    "\n";
-
-    snp_fd = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 0644);
-    if (snp_fd < 0)
-        return -errno;
-    p_fd = open(backing_file, O_RDONLY | O_BINARY | O_LARGEFILE);
-    if (p_fd < 0) {
-        close(snp_fd);
-        return -errno;
-    }
-
-    /* read the header */
-    if (lseek(p_fd, 0x0, SEEK_SET) == -1) {
-        ret = -errno;
-        goto fail;
-    }
-    if (read(p_fd, hdr, HEADER_SIZE) != HEADER_SIZE) {
-        ret = -errno;
-        goto fail;
-    }
-
-    /* write the header */
-    if (lseek(snp_fd, 0x0, SEEK_SET) == -1) {
-        ret = -errno;
-        goto fail;
-    }
-    if (write(snp_fd, hdr, HEADER_SIZE) == -1) {
-        ret = -errno;
-        goto fail;
-    }
-
-    memset(&header, 0, sizeof(header));
-    memcpy(&header,&hdr[4], sizeof(header)); // skip the VMDK4_MAGIC
-
-    if (ftruncate(snp_fd, header.grain_offset << 9)) {
-        ret = -errno;
-        goto fail;
-    }
-    /* the descriptor offset = 0x200 */
-    if (lseek(p_fd, 0x200, SEEK_SET) == -1) {
-        ret = -errno;
-        goto fail;
-    }
-    if (read(p_fd, p_desc, DESC_SIZE) != DESC_SIZE) {
-        ret = -errno;
-        goto fail;
-    }
-
-    if ((p_name = strstr(p_desc,"CID")) != NULL) {
-        p_name += sizeof("CID");
-        sscanf(p_name,"%x",&p_cid);
-    }
-
-    real_filename = filename;
-    if ((temp_str = strrchr(real_filename, '\\')) != NULL)
-        real_filename = temp_str + 1;
-    if ((temp_str = strrchr(real_filename, '/')) != NULL)
-        real_filename = temp_str + 1;
-    if ((temp_str = strrchr(real_filename, ':')) != NULL)
-        real_filename = temp_str + 1;
-
-    snprintf(s_desc, sizeof(s_desc), desc_template, p_cid, p_cid, backing_file,
-             (uint32_t)header.capacity, real_filename);
-
-    /* write the descriptor */
-    if (lseek(snp_fd, 0x200, SEEK_SET) == -1) {
-        ret = -errno;
-        goto fail;
-    }
-    if (write(snp_fd, s_desc, strlen(s_desc)) == -1) {
-        ret = -errno;
-        goto fail;
-    }
-
-    gd_offset = header.gd_offset * SECTOR_SIZE;     // offset of GD table
-    rgd_offset = header.rgd_offset * SECTOR_SIZE;   // offset of RGD table
-    capacity = header.capacity * SECTOR_SIZE;       // Extent size
-    /*
-     * Each GDE span 32M disk, means:
-     * 512 GTE per GT, each GTE points to grain
-     */
-    gt_size = (int64_t)header.num_gtes_per_gte * header.granularity * SECTOR_SIZE;
-    if (!gt_size) {
-        ret = -EINVAL;
-        goto fail;
-    }
-    gde_entries = (uint32_t)(capacity / gt_size);  // number of gde/rgde
-    gd_size = gde_entries * sizeof(uint32_t);
-
-    /* write RGD */
-    rgd_buf = qemu_malloc(gd_size);
-    if (lseek(p_fd, rgd_offset, SEEK_SET) == -1) {
-        ret = -errno;
-        goto fail_rgd;
-    }
-    if (read(p_fd, rgd_buf, gd_size) != gd_size) {
-        ret = -errno;
-        goto fail_rgd;
-    }
-    if (lseek(snp_fd, rgd_offset, SEEK_SET) == -1) {
-        ret = -errno;
-        goto fail_rgd;
-    }
-    if (write(snp_fd, rgd_buf, gd_size) == -1) {
-        ret = -errno;
-        goto fail_rgd;
-    }
-
-    /* write GD */
-    gd_buf = qemu_malloc(gd_size);
-    if (lseek(p_fd, gd_offset, SEEK_SET) == -1) {
-        ret = -errno;
-        goto fail_gd;
-    }
-    if (read(p_fd, gd_buf, gd_size) != gd_size) {
-        ret = -errno;
-        goto fail_gd;
-    }
-    if (lseek(snp_fd, gd_offset, SEEK_SET) == -1) {
-        ret = -errno;
-        goto fail_gd;
-    }
-    if (write(snp_fd, gd_buf, gd_size) == -1) {
-        ret = -errno;
-        goto fail_gd;
-    }
-    ret = 0;
-
-fail_gd:
-    qemu_free(gd_buf);
-fail_rgd:
-    qemu_free(rgd_buf);
-fail:
-    close(p_fd);
-    close(snp_fd);
-    return ret;
-}
-
 static int vmdk_parent_open(BlockDriverState *bs)
 {
     char *p_name;
@@ -1058,68 +897,40 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
-static int vmdk_create(const char *filename, QEMUOptionParameter *options)
+
+static int vmdk_create_extent(const char *filename, int64_t filesize, bool flat)
 {
-    int fd, i;
+    int ret, i;
+    int fd = 0;
     VMDK4Header header;
     uint32_t tmp, magic, grains, gd_size, gt_size, gt_count;
-    static const char desc_template[] =
-        "# Disk DescriptorFile\n"
-        "version=1\n"
-        "CID=%x\n"
-        "parentCID=ffffffff\n"
-        "createType=\"monolithicSparse\"\n"
-        "\n"
-        "# Extent description\n"
-        "RW %" PRId64 " SPARSE \"%s\"\n"
-        "\n"
-        "# The Disk Data Base \n"
-        "#DDB\n"
-        "\n"
-        "ddb.virtualHWVersion = \"%d\"\n"
-        "ddb.geometry.cylinders = \"%" PRId64 "\"\n"
-        "ddb.geometry.heads = \"16\"\n"
-        "ddb.geometry.sectors = \"63\"\n"
-        "ddb.adapterType = \"ide\"\n";
-    char desc[1024];
-    const char *real_filename, *temp_str;
-    int64_t total_size = 0;
-    const char *backing_file = NULL;
-    int flags = 0;
-    int ret;
 
-    // Read out options
-    while (options && options->name) {
-        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-            total_size = options->value.n / 512;
-        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
-            backing_file = options->value.s;
-        } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) {
-            flags |= options->value.n ? BLOCK_FLAG_COMPAT6: 0;
-        }
-        options++;
+    fd = open(
+        filename,
+        O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
+        0644);
+    if (fd < 0) {
+        return -errno;
     }
-
-    /* XXX: add support for backing file */
-    if (backing_file) {
-        return vmdk_snapshot_create(filename, backing_file);
+    if (flat) {
+        ret = ftruncate(fd, filesize);
+        if (ret < 0) {
+            ret = -errno;
+        }
+        goto exit;
     }
-
-    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
-              0644);
-    if (fd < 0)
-        return -errno;
     magic = cpu_to_be32(VMDK4_MAGIC);
     memset(&header, 0, sizeof(header));
     header.version = 1;
     header.flags = 3; /* ?? */
-    header.capacity = total_size;
+    header.capacity = filesize / 512;
     header.granularity = 128;
     header.num_gtes_per_gte = 512;
 
-    grains = (total_size + header.granularity - 1) / header.granularity;
+    grains = (filesize / 512 + header.granularity - 1) / header.granularity;
     gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9;
-    gt_count = (grains + header.num_gtes_per_gte - 1) / header.num_gtes_per_gte;
+    gt_count =
+        (grains + header.num_gtes_per_gte - 1) / header.num_gtes_per_gte;
     gd_size = (gt_count * sizeof(uint32_t) + 511) >> 9;
 
     header.desc_offset = 1;
@@ -1130,7 +941,6 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
        ((header.gd_offset + gd_size + (gt_size * gt_count) +
          header.granularity - 1) / header.granularity) *
         header.granularity;
-
     /* swap endianness for all header fields */
     header.version = cpu_to_le32(header.version);
     header.flags = cpu_to_le32(header.flags);
@@ -1188,27 +998,255 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
         }
     }
 
-    /* compose the descriptor */
-    real_filename = filename;
-    if ((temp_str = strrchr(real_filename, '\\')) != NULL)
-        real_filename = temp_str + 1;
-    if ((temp_str = strrchr(real_filename, '/')) != NULL)
-        real_filename = temp_str + 1;
-    if ((temp_str = strrchr(real_filename, ':')) != NULL)
-        real_filename = temp_str + 1;
-    snprintf(desc, sizeof(desc), desc_template, (unsigned int)time(NULL),
-             total_size, real_filename,
-             (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
-             total_size / (int64_t)(63 * 16));
-
-    /* write the descriptor */
-    lseek(fd, le64_to_cpu(header.desc_offset) << 9, SEEK_SET);
+    ret = 0;
+ exit:
+    close(fd);
+    return ret;
+}
+
+static int filename_decompose(const char *filename, char *path, char *prefix,
+        char *postfix, size_t buf_len)
+{
+    const char *p, *q;
+
+    if (filename == NULL || !strlen(filename)) {
+        fprintf(stderr, "Vmdk: no filename provided.\n");
+        return -1;
+    }
+    p = strrchr(filename, '/');
+    if (p == NULL) {
+        p = strrchr(filename, '\\');
+    }
+    if (p == NULL) {
+        p = strrchr(filename, ':');
+    }
+    if (p != NULL) {
+        p++;
+        if (p - filename >= buf_len) {
+            return -1;
+        }
+        pstrcpy(path, p - filename + 1, filename);
+    } else {
+        p = filename;
+        path[0] = '\0';
+    }
+    q = strrchr(p, '.');
+    if (q == NULL) {
+        pstrcpy(prefix, buf_len, p);
+        postfix[0] = '\0';
+    } else {
+        if (q - p >= buf_len) {
+            return -1;
+        }
+        pstrcpy(prefix, q - p + 1, p);
+        pstrcpy(postfix, buf_len, q);
+    }
+    return 0;
+}
+
+static int relative_path(char *dest, int dest_size,
+        const char *base, const char *target)
+{
+    int i = 0;
+    int n = 0;
+    const char *p, *q;
+#ifdef _WIN32
+    const char *sep = "\\";
+#else
+    const char *sep = "/";
+#endif
+
+    if (!(dest && base && target)) {
+        return -1;
+    }
+    if (path_is_absolute(target)) {
+        dest[dest_size - 1] = '\0';
+        strncpy(dest, target, dest_size - 1);
+        return 0;
+    }
+    while (base[i] == target[i]) {
+        i++;
+    }
+    p = &base[i];
+    q = &target[i];
+    while (*p) {
+        if (*p == *sep) {
+            n++;
+        }
+        p++;
+    }
+    dest[0] = '\0';
+    for (; n; n--) {
+        pstrcat(dest, dest_size, "..");
+        pstrcat(dest, dest_size, sep);
+    }
+    pstrcat(dest, dest_size, q);
+    return 0;
+}
+
+static int vmdk_create(const char *filename, QEMUOptionParameter *options)
+{
+    int fd, idx = 0;
+    char desc[BUF_SIZE];
+    int64_t total_size = 0, filesize;
+    const char *backing_file = NULL;
+    const char *fmt = NULL;
+    int flags = 0;
+    int ret = 0;
+    bool flat, split;
+    char ext_desc_lines[BUF_SIZE] = "";
+    char path[PATH_MAX], prefix[PATH_MAX], postfix[PATH_MAX];
+    const int64_t split_size = 0x80000000;  /* VMDK has constant split size */
+    const char *desc_extent_line;
+    char parent_desc_line[BUF_SIZE] = "";
+    uint32_t parent_cid = 0xffffffff;
+    const char desc_template[] =
+        "# Disk DescriptorFile\n"
+        "version=1\n"
+        "CID=%x\n"
+        "parentCID=%x\n"
+        "createType=\"%s\"\n"
+        "%s"
+        "\n"
+        "# Extent description\n"
+        "%s"
+        "\n"
+        "# The Disk Data Base\n"
+        "#DDB\n"
+        "\n"
+        "ddb.virtualHWVersion = \"%d\"\n"
+        "ddb.geometry.cylinders = \"%" PRId64 "\"\n"
+        "ddb.geometry.heads = \"16\"\n"
+        "ddb.geometry.sectors = \"63\"\n"
+        "ddb.adapterType = \"ide\"\n";
+
+    if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) {
+        return -EINVAL;
+    }
+    /* Read out options */
+    while (options && options->name) {
+        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
+            total_size = options->value.n;
+        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
+            backing_file = options->value.s;
+        } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) {
+            flags |= options->value.n ? BLOCK_FLAG_COMPAT6 : 0;
+        } else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) {
+            fmt = options->value.s;
+        }
+        options++;
+    }
+    if (!fmt) {
+        /* Default format to monolithicSparse */
+        fmt = "monolithicSparse";
+    } else if (strcmp(fmt, "monolithicFlat") &&
+               strcmp(fmt, "monolithicSparse") &&
+               strcmp(fmt, "twoGbMaxExtentSparse") &&
+               strcmp(fmt, "twoGbMaxExtentFlat")) {
+        fprintf(stderr, "VMDK: Unknown subformat: %s\n", fmt);
+        return -EINVAL;
+    }
+    split = !(strcmp(fmt, "twoGbMaxExtentFlat") &&
+              strcmp(fmt, "twoGbMaxExtentSparse"));
+    flat = !(strcmp(fmt, "monolithicFlat") &&
+             strcmp(fmt, "twoGbMaxExtentFlat"));
+    if (flat) {
+        desc_extent_line = "RW %lld FLAT \"%s\" 0\n";
+    } else {
+        desc_extent_line = "RW %lld SPARSE \"%s\"\n";
+    }
+    if (flat && backing_file) {
+        /* not supporting backing file for flat image */
+        return -ENOTSUP;
+    }
+    if (backing_file) {
+        char parent_filename[PATH_MAX];
+        BlockDriverState *bs = bdrv_new("");
+        ret = bdrv_open(bs, backing_file, 0, NULL);
+        if (ret != 0) {
+            bdrv_delete(bs);
+            return ret;
+        }
+        if (strcmp(bs->drv->format_name, "vmdk")) {
+            bdrv_delete(bs);
+            return -EINVAL;
+        }
+        filesize = bdrv_getlength(bs);
+        parent_cid = vmdk_read_cid(bs, 0);
+        bdrv_delete(bs);
+        relative_path(parent_filename, sizeof(parent_filename),
+                      filename, backing_file);
+        snprintf(parent_desc_line, sizeof(parent_desc_line),
+                "parentFileNameHint=\"%s\"", parent_filename);
+    }
+
+    /* Create extents */
+    filesize = total_size;
+    while (filesize > 0) {
+        char desc_line[BUF_SIZE];
+        char ext_filename[PATH_MAX];
+        char desc_filename[PATH_MAX];
+        int64_t size = filesize;
+
+        if (split && size > split_size) {
+            size = split_size;
+        }
+        if (split) {
+            snprintf(desc_filename, sizeof(desc_filename), "%s-%c%03d%s",
+                    prefix, flat ? 'f' : 's', ++idx, postfix);
+        } else if (flat) {
+            snprintf(desc_filename, sizeof(desc_filename), "%s-flat%s",
+                    prefix, postfix);
+        } else {
+            snprintf(desc_filename, sizeof(desc_filename), "%s%s",
+                    prefix, postfix);
+        }
+        snprintf(ext_filename, sizeof(ext_filename), "%s%s",
+                path, desc_filename);
+
+        if (vmdk_create_extent(ext_filename, size, flat)) {
+            return -EINVAL;
+        }
+        filesize -= size;
+
+        /* Format description line */
+        snprintf(desc_line, sizeof(desc_line),
+                    desc_extent_line, size / 512, desc_filename);
+        pstrcat(ext_desc_lines, sizeof(ext_desc_lines), desc_line);
+    }
+    /* generate descriptor file */
+    snprintf(desc, sizeof(desc), desc_template,
+            (unsigned int)time(NULL),
+            parent_cid,
+            fmt,
+            parent_desc_line,
+            ext_desc_lines,
+            (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
+            total_size / (int64_t)(63 * 16 * 512));
+    if (split || flat) {
+        fd = open(
+                filename,
+                O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
+                0644);
+    } else {
+        fd = open(
+                filename,
+                O_WRONLY | O_BINARY | O_LARGEFILE,
+                0644);
+    }
+    if (fd < 0) {
+        return -errno;
+    }
+    /* the descriptor offset = 0x200 */
+    if (!split && !flat && 0x200 != lseek(fd, 0x200, SEEK_SET)) {
+        ret = -errno;
+        goto exit;
+    }
     ret = qemu_write_full(fd, desc, strlen(desc));
     if (ret != strlen(desc)) {
         ret = -errno;
         goto exit;
     }
-
     ret = 0;
 exit:
     close(fd);
@@ -1252,6 +1290,13 @@ static QEMUOptionParameter vmdk_create_options[] = {
         .type = OPT_FLAG,
         .help = "VMDK version 6 image"
     },
+    {
+        .name = BLOCK_OPT_SUBFMT,
+        .type = OPT_STRING,
+        .help =
+            "VMDK flat extent format, can be one of "
+            "{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat} "
+    },
     { NULL }
 };
 
diff --git a/block_int.h b/block_int.h
index 1e265d2..8a7b6cb 100644
--- a/block_int.h
+++ b/block_int.h
@@ -39,6 +39,7 @@
 #define BLOCK_OPT_CLUSTER_SIZE  "cluster_size"
 #define BLOCK_OPT_TABLE_SIZE    "table_size"
 #define BLOCK_OPT_PREALLOC      "preallocation"
+#define BLOCK_OPT_SUBFMT        "subformat"
 
 typedef struct AIOPool {
     void (*cancel)(BlockDriverAIOCB *acb);
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 20/21] VMDK: fix coding style
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (18 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 19/21] VMDK: create different subformats Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 21/21] block: add bdrv_get_allocated_file_size() operation Kevin Wolf
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Fam Zheng <famcool@gmail.com>

Conform coding style in vmdk.c to pass scripts/checkpatch.pl checks.

Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vmdk.c |   76 +++++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 46 insertions(+), 30 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index b53c5f5..de08d0c 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -102,8 +102,9 @@ static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
 {
     uint32_t magic;
 
-    if (buf_size < 4)
+    if (buf_size < 4) {
         return 0;
+    }
     magic = be32_to_cpu(*(uint32_t *)buf);
     if (magic == VMDK3_MAGIC ||
         magic == VMDK4_MAGIC) {
@@ -193,9 +194,10 @@ static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
         cid_str_size = sizeof("CID");
     }
 
-    if ((p_name = strstr(desc,cid_str)) != NULL) {
+    p_name = strstr(desc, cid_str);
+    if (p_name != NULL) {
         p_name += cid_str_size;
-        sscanf(p_name,"%x",&cid);
+        sscanf(p_name, "%x", &cid);
     }
 
     return cid;
@@ -212,9 +214,10 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
         return -EIO;
     }
 
-    tmp_str = strstr(desc,"parentCID");
+    tmp_str = strstr(desc, "parentCID");
     pstrcpy(tmp_desc, sizeof(tmp_desc), tmp_str);
-    if ((p_name = strstr(desc,"CID")) != NULL) {
+    p_name = strstr(desc, "CID");
+    if (p_name != NULL) {
         p_name += sizeof("CID");
         snprintf(p_name, sizeof(desc) - (p_name - desc), "%x\n", cid);
         pstrcat(desc, sizeof(desc), tmp_desc);
@@ -234,13 +237,14 @@ static int vmdk_is_cid_valid(BlockDriverState *bs)
     uint32_t cur_pcid;
 
     if (p_bs) {
-        cur_pcid = vmdk_read_cid(p_bs,0);
-        if (s->parent_cid != cur_pcid)
-            // CID not valid
+        cur_pcid = vmdk_read_cid(p_bs, 0);
+        if (s->parent_cid != cur_pcid) {
+            /* CID not valid */
             return 0;
+        }
     }
 #endif
-    // CID valid
+    /* CID valid */
     return 1;
 }
 
@@ -255,14 +259,18 @@ static int vmdk_parent_open(BlockDriverState *bs)
         return -1;
     }
 
-    if ((p_name = strstr(desc,"parentFileNameHint")) != NULL) {
+    p_name = strstr(desc, "parentFileNameHint");
+    if (p_name != NULL) {
         char *end_name;
 
         p_name += sizeof("parentFileNameHint") + 1;
-        if ((end_name = strchr(p_name,'\"')) == NULL)
+        end_name = strchr(p_name, '\"');
+        if (end_name == NULL) {
             return -1;
-        if ((end_name - p_name) > sizeof (bs->backing_file) - 1)
+        }
+        if ((end_name - p_name) > sizeof(bs->backing_file) - 1) {
             return -1;
+        }
 
         pstrcpy(bs->backing_file, end_name - p_name + 1, p_name);
     }
@@ -595,8 +603,9 @@ static int get_whole_cluster(BlockDriverState *bs,
     if (bs->backing_hd) {
         int ret;
 
-        if (!vmdk_is_cid_valid(bs))
+        if (!vmdk_is_cid_valid(bs)) {
             return -1;
+        }
 
         /* floor offset to cluster */
         offset -= offset % (extent->cluster_sectors * 512);
@@ -655,8 +664,9 @@ static int get_cluster_offset(BlockDriverState *bs,
     int min_index, i, j;
     uint32_t min_count, *l2_table, tmp = 0;
 
-    if (m_data)
+    if (m_data) {
         m_data->valid = 0;
+    }
     if (extent->flat) {
         *cluster_offset = extent->flat_start_offset;
         return 0;
@@ -712,7 +722,7 @@ static int get_cluster_offset(BlockDriverState *bs,
             return -1;
         }
 
-        // Avoid the L2 tables update for the images that have snapshots.
+        /* Avoid the L2 tables update for the images that have snapshots. */
         *cluster_offset = bdrv_getlength(extent->file);
         bdrv_truncate(
             extent->file,
@@ -729,8 +739,9 @@ static int get_cluster_offset(BlockDriverState *bs,
          * or inappropriate VM shutdown.
          */
         if (get_whole_cluster(
-                bs, extent, *cluster_offset, offset, allocate) == -1)
+                bs, extent, *cluster_offset, offset, allocate) == -1) {
             return -1;
+        }
 
         if (m_data) {
             m_data->offset = tmp;
@@ -780,8 +791,9 @@ static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num,
 
     index_in_cluster = sector_num % extent->cluster_sectors;
     n = extent->cluster_sectors - index_in_cluster;
-    if (n > nb_sectors)
+    if (n > nb_sectors) {
         n = nb_sectors;
+    }
     *pnum = n;
     return ret;
 }
@@ -805,16 +817,19 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
                             sector_num << 9, 0, &cluster_offset);
         index_in_cluster = sector_num % extent->cluster_sectors;
         n = extent->cluster_sectors - index_in_cluster;
-        if (n > nb_sectors)
+        if (n > nb_sectors) {
             n = nb_sectors;
+        }
         if (ret) {
             /* if not allocated, try to read from parent image, if exist */
             if (bs->backing_hd) {
-                if (!vmdk_is_cid_valid(bs))
+                if (!vmdk_is_cid_valid(bs)) {
                     return -EINVAL;
+                }
                 ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
-                if (ret < 0)
+                if (ret < 0) {
                     return ret;
+                }
             } else {
                 memset(buf, 0, 512 * n);
             }
@@ -888,7 +903,8 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
         sector_num += n;
         buf += n * 512;
 
-        // update CID on the first write every time the virtual disk is opened
+        /* update CID on the first write every time the virtual disk is
+         * opened */
         if (!s->cid_updated) {
             vmdk_write_cid(bs, time(NULL));
             s->cid_updated = true;
@@ -1301,16 +1317,16 @@ static QEMUOptionParameter vmdk_create_options[] = {
 };
 
 static BlockDriver bdrv_vmdk = {
-    .format_name	= "vmdk",
-    .instance_size	= sizeof(BDRVVmdkState),
-    .bdrv_probe		= vmdk_probe,
+    .format_name    = "vmdk",
+    .instance_size  = sizeof(BDRVVmdkState),
+    .bdrv_probe     = vmdk_probe,
     .bdrv_open      = vmdk_open,
-    .bdrv_read		= vmdk_read,
-    .bdrv_write		= vmdk_write,
-    .bdrv_close		= vmdk_close,
-    .bdrv_create	= vmdk_create,
-    .bdrv_flush		= vmdk_flush,
-    .bdrv_is_allocated	= vmdk_is_allocated,
+    .bdrv_read      = vmdk_read,
+    .bdrv_write     = vmdk_write,
+    .bdrv_close     = vmdk_close,
+    .bdrv_create    = vmdk_create,
+    .bdrv_flush     = vmdk_flush,
+    .bdrv_is_allocated  = vmdk_is_allocated,
 
     .create_options = vmdk_create_options,
 };
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 21/21] block: add bdrv_get_allocated_file_size() operation
  2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
                   ` (19 preceding siblings ...)
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 20/21] VMDK: fix coding style Kevin Wolf
@ 2011-07-19 10:15 ` Kevin Wolf
  20 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 10:15 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Fam Zheng <famcool@gmail.com>

qemu-img.c wants to count allocated file size of image. Previously it
counts a single bs->file by 'stat' or Window API. As VMDK introduces
multiple file support, the operation becomes format specific with
platform specific meanwhile.

The functions are moved to block/raw-{posix,win32}.c and qemu-img.c calls
bdrv_get_allocated_file_size to count the bs. And also added VMDK code
to count his own extents.

Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c           |   19 +++++++++++++++++++
 block.h           |    1 +
 block/raw-posix.c |   21 +++++++++++++++++++++
 block/raw-win32.c |   29 +++++++++++++++++++++++++++++
 block/vmdk.c      |   24 ++++++++++++++++++++++++
 block_int.h       |    1 +
 qemu-img.c        |   31 +------------------------------
 7 files changed, 96 insertions(+), 30 deletions(-)

diff --git a/block.c b/block.c
index 24a25d5..9549b9e 100644
--- a/block.c
+++ b/block.c
@@ -1147,6 +1147,25 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset)
 }
 
 /**
+ * Length of a allocated file in bytes. Sparse files are counted by actual
+ * allocated space. Return < 0 if error or unknown.
+ */
+int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
+{
+    BlockDriver *drv = bs->drv;
+    if (!drv) {
+        return -ENOMEDIUM;
+    }
+    if (drv->bdrv_get_allocated_file_size) {
+        return drv->bdrv_get_allocated_file_size(bs);
+    }
+    if (bs->file) {
+        return bdrv_get_allocated_file_size(bs->file);
+    }
+    return -ENOTSUP;
+}
+
+/**
  * Length of a file in bytes. Return < 0 if error or unknown.
  */
 int64_t bdrv_getlength(BlockDriverState *bs)
diff --git a/block.h b/block.h
index 859d1d9..59cc410 100644
--- a/block.h
+++ b/block.h
@@ -89,6 +89,7 @@ int bdrv_write_sync(BlockDriverState *bs, int64_t sector_num,
     const uint8_t *buf, int nb_sectors);
 int bdrv_truncate(BlockDriverState *bs, int64_t offset);
 int64_t bdrv_getlength(BlockDriverState *bs);
+int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
 void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
 void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs);
 int bdrv_commit(BlockDriverState *bs);
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 34b64aa..cd89c83 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -793,6 +793,17 @@ static int64_t raw_getlength(BlockDriverState *bs)
 }
 #endif
 
+static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
+{
+    struct stat st;
+    BDRVRawState *s = bs->opaque;
+
+    if (fstat(s->fd, &st) < 0) {
+        return -errno;
+    }
+    return (int64_t)st.st_blocks * 512;
+}
+
 static int raw_create(const char *filename, QEMUOptionParameter *options)
 {
     int fd;
@@ -888,6 +899,8 @@ static BlockDriver bdrv_file = {
 
     .bdrv_truncate = raw_truncate,
     .bdrv_getlength = raw_getlength,
+    .bdrv_get_allocated_file_size
+                        = raw_get_allocated_file_size,
 
     .create_options = raw_create_options,
 };
@@ -1156,6 +1169,8 @@ static BlockDriver bdrv_host_device = {
     .bdrv_read          = raw_read,
     .bdrv_write         = raw_write,
     .bdrv_getlength	= raw_getlength,
+    .bdrv_get_allocated_file_size
+                        = raw_get_allocated_file_size,
 
     /* generic scsi device */
 #ifdef __linux__
@@ -1277,6 +1292,8 @@ static BlockDriver bdrv_host_floppy = {
     .bdrv_read          = raw_read,
     .bdrv_write         = raw_write,
     .bdrv_getlength	= raw_getlength,
+    .bdrv_get_allocated_file_size
+                        = raw_get_allocated_file_size,
 
     /* removable device support */
     .bdrv_is_inserted   = floppy_is_inserted,
@@ -1380,6 +1397,8 @@ static BlockDriver bdrv_host_cdrom = {
     .bdrv_read          = raw_read,
     .bdrv_write         = raw_write,
     .bdrv_getlength     = raw_getlength,
+    .bdrv_get_allocated_file_size
+                        = raw_get_allocated_file_size,
 
     /* removable device support */
     .bdrv_is_inserted   = cdrom_is_inserted,
@@ -1503,6 +1522,8 @@ static BlockDriver bdrv_host_cdrom = {
     .bdrv_read          = raw_read,
     .bdrv_write         = raw_write,
     .bdrv_getlength     = raw_getlength,
+    .bdrv_get_allocated_file_size
+                        = raw_get_allocated_file_size,
 
     /* removable device support */
     .bdrv_is_inserted   = cdrom_is_inserted,
diff --git a/block/raw-win32.c b/block/raw-win32.c
index 56bd719..91067e7 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -213,6 +213,31 @@ static int64_t raw_getlength(BlockDriverState *bs)
     return l.QuadPart;
 }
 
+static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
+{
+    typedef DWORD (WINAPI * get_compressed_t)(const char *filename,
+                                              DWORD * high);
+    get_compressed_t get_compressed;
+    struct _stati64 st;
+    const char *filename = bs->filename;
+    /* WinNT support GetCompressedFileSize to determine allocate size */
+    get_compressed =
+        (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"),
+                                            "GetCompressedFileSizeA");
+    if (get_compressed) {
+        DWORD high, low;
+        low = get_compressed(filename, &high);
+        if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR) {
+            return (((int64_t) high) << 32) + low;
+        }
+    }
+
+    if (_stati64(filename, &st) < 0) {
+        return -1;
+    }
+    return st.st_size;
+}
+
 static int raw_create(const char *filename, QEMUOptionParameter *options)
 {
     int fd;
@@ -257,6 +282,8 @@ static BlockDriver bdrv_file = {
     .bdrv_write		= raw_write,
     .bdrv_truncate	= raw_truncate,
     .bdrv_getlength	= raw_getlength,
+    .bdrv_get_allocated_file_size
+                        = raw_get_allocated_file_size,
 
     .create_options = raw_create_options,
 };
@@ -419,6 +446,8 @@ static BlockDriver bdrv_host_device = {
     .bdrv_read		= raw_read,
     .bdrv_write	        = raw_write,
     .bdrv_getlength	= raw_getlength,
+    .bdrv_get_allocated_file_size
+                        = raw_get_allocated_file_size,
 };
 
 static void bdrv_file_init(void)
diff --git a/block/vmdk.c b/block/vmdk.c
index de08d0c..37478d2 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1289,6 +1289,29 @@ static int vmdk_flush(BlockDriverState *bs)
     return ret;
 }
 
+static int64_t vmdk_get_allocated_file_size(BlockDriverState *bs)
+{
+    int i;
+    int64_t ret = 0;
+    int64_t r;
+    BDRVVmdkState *s = bs->opaque;
+
+    ret = bdrv_get_allocated_file_size(bs->file);
+    if (ret < 0) {
+        return ret;
+    }
+    for (i = 0; i < s->num_extents; i++) {
+        if (s->extents[i].file == bs->file) {
+            continue;
+        }
+        r = bdrv_get_allocated_file_size(s->extents[i].file);
+        if (r < 0) {
+            return r;
+        }
+        ret += r;
+    }
+    return ret;
+}
 
 static QEMUOptionParameter vmdk_create_options[] = {
     {
@@ -1327,6 +1350,7 @@ static BlockDriver bdrv_vmdk = {
     .bdrv_create    = vmdk_create,
     .bdrv_flush     = vmdk_flush,
     .bdrv_is_allocated  = vmdk_is_allocated,
+    .bdrv_get_allocated_file_size  = vmdk_get_allocated_file_size,
 
     .create_options = vmdk_create_options,
 };
diff --git a/block_int.h b/block_int.h
index 8a7b6cb..efb6803 100644
--- a/block_int.h
+++ b/block_int.h
@@ -86,6 +86,7 @@ struct BlockDriver {
     const char *protocol_name;
     int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset);
     int64_t (*bdrv_getlength)(BlockDriverState *bs);
+    int64_t (*bdrv_get_allocated_file_size)(BlockDriverState *bs);
     int (*bdrv_write_compressed)(BlockDriverState *bs, int64_t sector_num,
                                  const uint8_t *buf, int nb_sectors);
 
diff --git a/qemu-img.c b/qemu-img.c
index 54137a4..b205e98 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1024,35 +1024,6 @@ out:
     return 0;
 }
 
-#ifdef _WIN32
-static int64_t get_allocated_file_size(const char *filename)
-{
-    typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
-    get_compressed_t get_compressed;
-    struct _stati64 st;
-
-    /* WinNT support GetCompressedFileSize to determine allocate size */
-    get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
-    if (get_compressed) {
-    	DWORD high, low;
-    	low = get_compressed(filename, &high);
-    	if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
-	    return (((int64_t) high) << 32) + low;
-    }
-
-    if (_stati64(filename, &st) < 0)
-        return -1;
-    return st.st_size;
-}
-#else
-static int64_t get_allocated_file_size(const char *filename)
-{
-    struct stat st;
-    if (stat(filename, &st) < 0)
-        return -1;
-    return (int64_t)st.st_blocks * 512;
-}
-#endif
 
 static void dump_snapshots(BlockDriverState *bs)
 {
@@ -1112,7 +1083,7 @@ static int img_info(int argc, char **argv)
     bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
     bdrv_get_geometry(bs, &total_sectors);
     get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
-    allocated_size = get_allocated_file_size(filename);
+    allocated_size = bdrv_get_allocated_file_size(bs);
     if (allocated_size < 0) {
         snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
     } else {
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 05/21] scsi: Add 'hba_private' to SCSIRequest
  2011-07-19 10:15 ` [Qemu-devel] [PATCH 05/21] scsi: Add 'hba_private' to SCSIRequest Kevin Wolf
@ 2011-07-19 12:43   ` Anthony Liguori
  2011-07-19 13:06     ` Kevin Wolf
  2011-07-19 13:20     ` Benjamin Herrenschmidt
  0 siblings, 2 replies; 34+ messages in thread
From: Anthony Liguori @ 2011-07-19 12:43 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel, David Gibson

On 07/19/2011 05:15 AM, Kevin Wolf wrote:
> From: Hannes Reinecke<hare@suse.de>
>
> 'tag' is just an abstraction to identify the command
> from the driver. So we should make that explicit by
> replacing 'tag' with a driver-defined pointer 'hba_private'.
> This saves the lookup for driver handling several commands
> in parallel.
> 'tag' is still being kept for tracing purposes.
>
> Signed-off-by: Hannes Reinecke<hare@suse.de>
> Acked-by: Paolo Bonzini<pbonzini@redhat.com>
> Signed-off-by: Kevin Wolf<kwolf@redhat.com>
> ---
>   hw/esp.c          |    2 +-
>   hw/lsi53c895a.c   |   22 ++++++++--------------
>   hw/scsi-bus.c     |    9 ++++++---
>   hw/scsi-disk.c    |    4 ++--
>   hw/scsi-generic.c |    5 +++--
>   hw/scsi.h         |   10 +++++++---
>   hw/spapr_vscsi.c  |   29 +++++++++--------------------
>   hw/usb-msd.c      |    9 +--------
>   8 files changed, 37 insertions(+), 53 deletions(-)
>
> diff --git a/hw/esp.c b/hw/esp.c
> index aa50800..9ddd637 100644
> --- a/hw/esp.c
> +++ b/hw/esp.c
> @@ -244,7 +244,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
>
>       DPRINTF("do_busid_cmd: busid 0x%x\n", busid);
>       lun = busid&  7;
> -    s->current_req = scsi_req_new(s->current_dev, 0, lun);
> +    s->current_req = scsi_req_new(s->current_dev, 0, lun, NULL);
>       datalen = scsi_req_enqueue(s->current_req, buf);
>       s->ti_size = datalen;
>       if (datalen != 0) {
> diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
> index 940b43a..69eec1d 100644
> --- a/hw/lsi53c895a.c
> +++ b/hw/lsi53c895a.c
> @@ -661,7 +661,7 @@ static lsi_request *lsi_find_by_tag(LSIState *s, uint32_t tag)
>   static void lsi_request_cancelled(SCSIRequest *req)
>   {
>       LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
> -    lsi_request *p;
> +    lsi_request *p = req->hba_private;
>
>       if (s->current&&  req == s->current->req) {
>           scsi_req_unref(req);
> @@ -670,7 +670,6 @@ static void lsi_request_cancelled(SCSIRequest *req)
>           return;
>       }
>
> -    p = lsi_find_by_tag(s, req->tag);
>       if (p) {
>           QTAILQ_REMOVE(&s->queue, p, next);
>           scsi_req_unref(req);
> @@ -680,18 +679,12 @@ static void lsi_request_cancelled(SCSIRequest *req)
>
>   /* Record that data is available for a queued command.  Returns zero if
>      the device was reselected, nonzero if the IO is deferred.  */
> -static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t len)
> +static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len)
>   {
> -    lsi_request *p;
> -
> -    p = lsi_find_by_tag(s, tag);
> -    if (!p) {
> -        BADF("IO with unknown tag %d\n", tag);
> -        return 1;
> -    }
> +    lsi_request *p = req->hba_private;
>
>       if (p->pending) {
> -        BADF("Multiple IO pending for tag %d\n", tag);
> +        BADF("Multiple IO pending for request %p\n", p);
>       }
>       p->pending = len;
>       /* Reselect if waiting for it, or if reselection triggers an IRQ
> @@ -743,9 +736,9 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t len)
>       LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
>       int out;
>
> -    if (s->waiting == 1 || !s->current || req->tag != s->current->tag ||
> +    if (s->waiting == 1 || !s->current || req->hba_private != s->current ||
>           (lsi_irq_on_rsl(s)&&  !(s->scntl1&  LSI_SCNTL1_CON))) {
> -        if (lsi_queue_tag(s, req->tag, len)) {
> +        if (lsi_queue_req(s, req, len)) {
>               return;
>           }
>       }
> @@ -789,7 +782,8 @@ static void lsi_do_command(LSIState *s)
>       assert(s->current == NULL);
>       s->current = qemu_mallocz(sizeof(lsi_request));
>       s->current->tag = s->select_tag;
> -    s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun);
> +    s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun,
> +                                   s->current);
>
>       n = scsi_req_enqueue(s->current->req, buf);
>       if (n) {
> diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
> index ad6a730..8b1a412 100644
> --- a/hw/scsi-bus.c
> +++ b/hw/scsi-bus.c
> @@ -131,7 +131,8 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
>       return res;
>   }
>
> -SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun)
> +SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
> +                            uint32_t lun, void *hba_private)
>   {
>       SCSIRequest *req;
>
> @@ -141,14 +142,16 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t l
>       req->dev = d;
>       req->tag = tag;
>       req->lun = lun;
> +    req->hba_private = hba_private;
>       req->status = -1;
>       trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
>       return req;
>   }
>
> -SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun)
> +SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
> +                          void *hba_private)
>   {
> -    return d->info->alloc_req(d, tag, lun);
> +    return d->info->alloc_req(d, tag, lun, hba_private);
>   }
>
>   uint8_t *scsi_req_get_buf(SCSIRequest *req)
> diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
> index a8c7372..c2a99fe 100644
> --- a/hw/scsi-disk.c
> +++ b/hw/scsi-disk.c
> @@ -81,13 +81,13 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
>   static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf);
>
>   static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
> -        uint32_t lun)
> +                                     uint32_t lun, void *hba_private)
>   {
>       SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
>       SCSIRequest *req;
>       SCSIDiskReq *r;
>
> -    req = scsi_req_alloc(sizeof(SCSIDiskReq),&s->qdev, tag, lun);
> +    req = scsi_req_alloc(sizeof(SCSIDiskReq),&s->qdev, tag, lun, hba_private);
>       r = DO_UPCAST(SCSIDiskReq, req, req);
>       r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
>       return req;
> diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
> index 8e59c7e..90345a7 100644
> --- a/hw/scsi-generic.c
> +++ b/hw/scsi-generic.c
> @@ -96,11 +96,12 @@ static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len)
>       return size;
>   }
>
> -static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
> +static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
> +                                     void *hba_private)
>   {
>       SCSIRequest *req;
>
> -    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
> +    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun, hba_private);
>       return req;
>   }
>
> diff --git a/hw/scsi.h b/hw/scsi.h
> index c1dca35..6b15bbc 100644
> --- a/hw/scsi.h
> +++ b/hw/scsi.h
> @@ -43,6 +43,7 @@ struct SCSIRequest {
>       } cmd;
>       BlockDriverAIOCB  *aiocb;
>       bool enqueued;
> +    void *hba_private;
>       QTAILQ_ENTRY(SCSIRequest) next;
>   };
>
> @@ -67,7 +68,8 @@ struct SCSIDeviceInfo {
>       DeviceInfo qdev;
>       scsi_qdev_initfn init;
>       void (*destroy)(SCSIDevice *s);
> -    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun);
> +    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
> +                              void *hba_private);
>       void (*free_req)(SCSIRequest *req);
>       int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
>       void (*read_data)(SCSIRequest *req);
> @@ -138,8 +140,10 @@ extern const struct SCSISense sense_code_LUN_FAILURE;
>   int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed);
>   int scsi_sense_valid(SCSISense sense);
>
> -SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun);
> -SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun);
> +SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
> +                            uint32_t lun, void *hba_private);
> +SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
> +                          void *hba_private);
>   int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf);
>   void scsi_req_free(SCSIRequest *req);
>   SCSIRequest *scsi_req_ref(SCSIRequest *req);
> diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
> index 1c901ef..9e1cb2e 100644
> --- a/hw/spapr_vscsi.c
> +++ b/hw/spapr_vscsi.c
> @@ -121,7 +121,7 @@ static struct vscsi_req *vscsi_get_req(VSCSIState *s)
>       return NULL;
>   }
>
> -static void vscsi_put_req(VSCSIState *s, vscsi_req *req)
> +static void vscsi_put_req(vscsi_req *req)
>   {
>       if (req->sreq != NULL) {
>           scsi_req_unref(req->sreq);

This breaks the build:

make[1]: Nothing to be done for `all'.
   CC    ppc64-softmmu/spapr_vscsi.o
/home/anthony/git/qemu/hw/spapr_vscsi.c: In function 
‘vscsi_command_complete’:
/home/anthony/git/qemu/hw/spapr_vscsi.c:535:34: error: ‘s’ undeclared 
(first use in this function)
/home/anthony/git/qemu/hw/spapr_vscsi.c:535:34: note: each undeclared 
identifier is reported only once for each function it appears in

This file is only built when libfdt is installed which is probably why 
you didn't catch it.

Ben/David, is there a way we can still build most of this stuff without 
libfdt?  libfdt is still not commonly packaged by some distros.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 05/21] scsi: Add 'hba_private' to SCSIRequest
  2011-07-19 12:43   ` Anthony Liguori
@ 2011-07-19 13:06     ` Kevin Wolf
  2011-07-19 13:24       ` Benjamin Herrenschmidt
  2011-07-19 13:26       ` Hannes Reinecke
  2011-07-19 13:20     ` Benjamin Herrenschmidt
  1 sibling, 2 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 13:06 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Hannes Reinecke, qemu-devel, David Gibson

Am 19.07.2011 14:43, schrieb Anthony Liguori:
> On 07/19/2011 05:15 AM, Kevin Wolf wrote:
>> From: Hannes Reinecke<hare@suse.de>
>>
>> 'tag' is just an abstraction to identify the command
>> from the driver. So we should make that explicit by
>> replacing 'tag' with a driver-defined pointer 'hba_private'.
>> This saves the lookup for driver handling several commands
>> in parallel.
>> 'tag' is still being kept for tracing purposes.
>>
>> Signed-off-by: Hannes Reinecke<hare@suse.de>
>> Acked-by: Paolo Bonzini<pbonzini@redhat.com>
>> Signed-off-by: Kevin Wolf<kwolf@redhat.com>
>> ---
>>   hw/esp.c          |    2 +-
>>   hw/lsi53c895a.c   |   22 ++++++++--------------
>>   hw/scsi-bus.c     |    9 ++++++---
>>   hw/scsi-disk.c    |    4 ++--
>>   hw/scsi-generic.c |    5 +++--
>>   hw/scsi.h         |   10 +++++++---
>>   hw/spapr_vscsi.c  |   29 +++++++++--------------------
>>   hw/usb-msd.c      |    9 +--------
>>   8 files changed, 37 insertions(+), 53 deletions(-)
>>
>> diff --git a/hw/esp.c b/hw/esp.c
>> index aa50800..9ddd637 100644
>> --- a/hw/esp.c
>> +++ b/hw/esp.c
>> @@ -244,7 +244,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
>>
>>       DPRINTF("do_busid_cmd: busid 0x%x\n", busid);
>>       lun = busid&  7;
>> -    s->current_req = scsi_req_new(s->current_dev, 0, lun);
>> +    s->current_req = scsi_req_new(s->current_dev, 0, lun, NULL);
>>       datalen = scsi_req_enqueue(s->current_req, buf);
>>       s->ti_size = datalen;
>>       if (datalen != 0) {
>> diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
>> index 940b43a..69eec1d 100644
>> --- a/hw/lsi53c895a.c
>> +++ b/hw/lsi53c895a.c
>> @@ -661,7 +661,7 @@ static lsi_request *lsi_find_by_tag(LSIState *s, uint32_t tag)
>>   static void lsi_request_cancelled(SCSIRequest *req)
>>   {
>>       LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
>> -    lsi_request *p;
>> +    lsi_request *p = req->hba_private;
>>
>>       if (s->current&&  req == s->current->req) {
>>           scsi_req_unref(req);
>> @@ -670,7 +670,6 @@ static void lsi_request_cancelled(SCSIRequest *req)
>>           return;
>>       }
>>
>> -    p = lsi_find_by_tag(s, req->tag);
>>       if (p) {
>>           QTAILQ_REMOVE(&s->queue, p, next);
>>           scsi_req_unref(req);
>> @@ -680,18 +679,12 @@ static void lsi_request_cancelled(SCSIRequest *req)
>>
>>   /* Record that data is available for a queued command.  Returns zero if
>>      the device was reselected, nonzero if the IO is deferred.  */
>> -static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t len)
>> +static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len)
>>   {
>> -    lsi_request *p;
>> -
>> -    p = lsi_find_by_tag(s, tag);
>> -    if (!p) {
>> -        BADF("IO with unknown tag %d\n", tag);
>> -        return 1;
>> -    }
>> +    lsi_request *p = req->hba_private;
>>
>>       if (p->pending) {
>> -        BADF("Multiple IO pending for tag %d\n", tag);
>> +        BADF("Multiple IO pending for request %p\n", p);
>>       }
>>       p->pending = len;
>>       /* Reselect if waiting for it, or if reselection triggers an IRQ
>> @@ -743,9 +736,9 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t len)
>>       LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
>>       int out;
>>
>> -    if (s->waiting == 1 || !s->current || req->tag != s->current->tag ||
>> +    if (s->waiting == 1 || !s->current || req->hba_private != s->current ||
>>           (lsi_irq_on_rsl(s)&&  !(s->scntl1&  LSI_SCNTL1_CON))) {
>> -        if (lsi_queue_tag(s, req->tag, len)) {
>> +        if (lsi_queue_req(s, req, len)) {
>>               return;
>>           }
>>       }
>> @@ -789,7 +782,8 @@ static void lsi_do_command(LSIState *s)
>>       assert(s->current == NULL);
>>       s->current = qemu_mallocz(sizeof(lsi_request));
>>       s->current->tag = s->select_tag;
>> -    s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun);
>> +    s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun,
>> +                                   s->current);
>>
>>       n = scsi_req_enqueue(s->current->req, buf);
>>       if (n) {
>> diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
>> index ad6a730..8b1a412 100644
>> --- a/hw/scsi-bus.c
>> +++ b/hw/scsi-bus.c
>> @@ -131,7 +131,8 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
>>       return res;
>>   }
>>
>> -SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun)
>> +SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
>> +                            uint32_t lun, void *hba_private)
>>   {
>>       SCSIRequest *req;
>>
>> @@ -141,14 +142,16 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t l
>>       req->dev = d;
>>       req->tag = tag;
>>       req->lun = lun;
>> +    req->hba_private = hba_private;
>>       req->status = -1;
>>       trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
>>       return req;
>>   }
>>
>> -SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun)
>> +SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
>> +                          void *hba_private)
>>   {
>> -    return d->info->alloc_req(d, tag, lun);
>> +    return d->info->alloc_req(d, tag, lun, hba_private);
>>   }
>>
>>   uint8_t *scsi_req_get_buf(SCSIRequest *req)
>> diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
>> index a8c7372..c2a99fe 100644
>> --- a/hw/scsi-disk.c
>> +++ b/hw/scsi-disk.c
>> @@ -81,13 +81,13 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
>>   static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf);
>>
>>   static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
>> -        uint32_t lun)
>> +                                     uint32_t lun, void *hba_private)
>>   {
>>       SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
>>       SCSIRequest *req;
>>       SCSIDiskReq *r;
>>
>> -    req = scsi_req_alloc(sizeof(SCSIDiskReq),&s->qdev, tag, lun);
>> +    req = scsi_req_alloc(sizeof(SCSIDiskReq),&s->qdev, tag, lun, hba_private);
>>       r = DO_UPCAST(SCSIDiskReq, req, req);
>>       r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
>>       return req;
>> diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
>> index 8e59c7e..90345a7 100644
>> --- a/hw/scsi-generic.c
>> +++ b/hw/scsi-generic.c
>> @@ -96,11 +96,12 @@ static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len)
>>       return size;
>>   }
>>
>> -static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
>> +static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
>> +                                     void *hba_private)
>>   {
>>       SCSIRequest *req;
>>
>> -    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
>> +    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun, hba_private);
>>       return req;
>>   }
>>
>> diff --git a/hw/scsi.h b/hw/scsi.h
>> index c1dca35..6b15bbc 100644
>> --- a/hw/scsi.h
>> +++ b/hw/scsi.h
>> @@ -43,6 +43,7 @@ struct SCSIRequest {
>>       } cmd;
>>       BlockDriverAIOCB  *aiocb;
>>       bool enqueued;
>> +    void *hba_private;
>>       QTAILQ_ENTRY(SCSIRequest) next;
>>   };
>>
>> @@ -67,7 +68,8 @@ struct SCSIDeviceInfo {
>>       DeviceInfo qdev;
>>       scsi_qdev_initfn init;
>>       void (*destroy)(SCSIDevice *s);
>> -    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun);
>> +    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
>> +                              void *hba_private);
>>       void (*free_req)(SCSIRequest *req);
>>       int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
>>       void (*read_data)(SCSIRequest *req);
>> @@ -138,8 +140,10 @@ extern const struct SCSISense sense_code_LUN_FAILURE;
>>   int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed);
>>   int scsi_sense_valid(SCSISense sense);
>>
>> -SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun);
>> -SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun);
>> +SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
>> +                            uint32_t lun, void *hba_private);
>> +SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
>> +                          void *hba_private);
>>   int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf);
>>   void scsi_req_free(SCSIRequest *req);
>>   SCSIRequest *scsi_req_ref(SCSIRequest *req);
>> diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
>> index 1c901ef..9e1cb2e 100644
>> --- a/hw/spapr_vscsi.c
>> +++ b/hw/spapr_vscsi.c
>> @@ -121,7 +121,7 @@ static struct vscsi_req *vscsi_get_req(VSCSIState *s)
>>       return NULL;
>>   }
>>
>> -static void vscsi_put_req(VSCSIState *s, vscsi_req *req)
>> +static void vscsi_put_req(vscsi_req *req)
>>   {
>>       if (req->sreq != NULL) {
>>           scsi_req_unref(req->sreq);
> 
> This breaks the build:
> 
> make[1]: Nothing to be done for `all'.
>    CC    ppc64-softmmu/spapr_vscsi.o
> /home/anthony/git/qemu/hw/spapr_vscsi.c: In function 
> ‘vscsi_command_complete’:
> /home/anthony/git/qemu/hw/spapr_vscsi.c:535:34: error: ‘s’ undeclared 
> (first use in this function)
> /home/anthony/git/qemu/hw/spapr_vscsi.c:535:34: note: each undeclared 
> identifier is reported only once for each function it appears in

Adding Hannes to CC.

> This file is only built when libfdt is installed which is probably why 
> you didn't catch it.

Yes, I did build all targets, but probably don't have most optional
dependencies installed. I guess I should install some more libraries on
that machine.

But as you said, there is no libfdt package in RHEL, so it will not be
among them, and I'd like to avoid installing things from source.

Kevin

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 05/21] scsi: Add 'hba_private' to SCSIRequest
  2011-07-19 12:43   ` Anthony Liguori
  2011-07-19 13:06     ` Kevin Wolf
@ 2011-07-19 13:20     ` Benjamin Herrenschmidt
  2011-07-20  5:49       ` David Gibson
  1 sibling, 1 reply; 34+ messages in thread
From: Benjamin Herrenschmidt @ 2011-07-19 13:20 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Kevin Wolf, qemu-devel, David Gibson

On Tue, 2011-07-19 at 07:43 -0500, Anthony Liguori wrote:
> 
> This breaks the build:
> 
> make[1]: Nothing to be done for `all'.
>    CC    ppc64-softmmu/spapr_vscsi.o
> /home/anthony/git/qemu/hw/spapr_vscsi.c: In function 
> ‘vscsi_command_complete’:
> /home/anthony/git/qemu/hw/spapr_vscsi.c:535:34: error: ‘s’ undeclared 
> (first use in this function)
> /home/anthony/git/qemu/hw/spapr_vscsi.c:535:34: note: each undeclared 
> identifier is reported only once for each function it appears in
> 
> This file is only built when libfdt is installed which is probably
> why 
> you didn't catch it.
> 
> Ben/David, is there a way we can still build most of this stuff
> without 
> libfdt?  libfdt is still not commonly packaged by some distros.

That would be hard ... the DT stuff is pretty deeply involved. Might be
easier to try to fix the distro :-)

Which ones ?

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 05/21] scsi: Add 'hba_private' to SCSIRequest
  2011-07-19 13:06     ` Kevin Wolf
@ 2011-07-19 13:24       ` Benjamin Herrenschmidt
  2011-07-19 13:26       ` Hannes Reinecke
  1 sibling, 0 replies; 34+ messages in thread
From: Benjamin Herrenschmidt @ 2011-07-19 13:24 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: Hannes Reinecke, qemu-devel, David Gibson

On Tue, 2011-07-19 at 15:06 +0200, Kevin Wolf wrote:
> Am 19.07.2011 14:43, schrieb Anthony Liguori:
> > On 07/19/2011 05:15 AM, Kevin Wolf wrote:
> >> From: Hannes Reinecke<hare@suse.de>
> >>
> >> 'tag' is just an abstraction to identify the command
> >> from the driver. So we should make that explicit by
> >> replacing 'tag' with a driver-defined pointer 'hba_private'.
> >> This saves the lookup for driver handling several commands
> >> in parallel.
> >> 'tag' is still being kept for tracing purposes.
> >>
> >> Signed-off-by: Hannes Reinecke<hare@suse.de>
> >> Acked-by: Paolo Bonzini<pbonzini@redhat.com>
> >> Signed-off-by: Kevin Wolf<kwolf@redhat.com>
> >> ---
> >>   hw/esp.c          |    2 +-
> >>   hw/lsi53c895a.c   |   22 ++++++++--------------
> >>   hw/scsi-bus.c     |    9 ++++++---
> >>   hw/scsi-disk.c    |    4 ++--
> >>   hw/scsi-generic.c |    5 +++--
> >>   hw/scsi.h         |   10 +++++++---
> >>   hw/spapr_vscsi.c  |   29 +++++++++--------------------
> >>   hw/usb-msd.c      |    9 +--------
> >>   8 files changed, 37 insertions(+), 53 deletions(-)
> >>
> >> diff --git a/hw/esp.c b/hw/esp.c
> >> index aa50800..9ddd637 100644
> >> --- a/hw/esp.c
> >> +++ b/hw/esp.c
> >> @@ -244,7 +244,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
> >>
> >>       DPRINTF("do_busid_cmd: busid 0x%x\n", busid);
> >>       lun = busid&  7;
> >> -    s->current_req = scsi_req_new(s->current_dev, 0, lun);
> >> +    s->current_req = scsi_req_new(s->current_dev, 0, lun, NULL);
> >>       datalen = scsi_req_enqueue(s->current_req, buf);
> >>       s->ti_size = datalen;
> >>       if (datalen != 0) {
> >> diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
> >> index 940b43a..69eec1d 100644
> >> --- a/hw/lsi53c895a.c
> >> +++ b/hw/lsi53c895a.c
> >> @@ -661,7 +661,7 @@ static lsi_request *lsi_find_by_tag(LSIState *s, uint32_t tag)
> >>   static void lsi_request_cancelled(SCSIRequest *req)
> >>   {
> >>       LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
> >> -    lsi_request *p;
> >> +    lsi_request *p = req->hba_private;
> >>
> >>       if (s->current&&  req == s->current->req) {
> >>           scsi_req_unref(req);
> >> @@ -670,7 +670,6 @@ static void lsi_request_cancelled(SCSIRequest *req)
> >>           return;
> >>       }
> >>
> >> -    p = lsi_find_by_tag(s, req->tag);
> >>       if (p) {
> >>           QTAILQ_REMOVE(&s->queue, p, next);
> >>           scsi_req_unref(req);
> >> @@ -680,18 +679,12 @@ static void lsi_request_cancelled(SCSIRequest *req)
> >>
> >>   /* Record that data is available for a queued command.  Returns zero if
> >>      the device was reselected, nonzero if the IO is deferred.  */
> >> -static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t len)
> >> +static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len)
> >>   {
> >> -    lsi_request *p;
> >> -
> >> -    p = lsi_find_by_tag(s, tag);
> >> -    if (!p) {
> >> -        BADF("IO with unknown tag %d\n", tag);
> >> -        return 1;
> >> -    }
> >> +    lsi_request *p = req->hba_private;
> >>
> >>       if (p->pending) {
> >> -        BADF("Multiple IO pending for tag %d\n", tag);
> >> +        BADF("Multiple IO pending for request %p\n", p);
> >>       }
> >>       p->pending = len;
> >>       /* Reselect if waiting for it, or if reselection triggers an IRQ
> >> @@ -743,9 +736,9 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t len)
> >>       LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
> >>       int out;
> >>
> >> -    if (s->waiting == 1 || !s->current || req->tag != s->current->tag ||
> >> +    if (s->waiting == 1 || !s->current || req->hba_private != s->current ||
> >>           (lsi_irq_on_rsl(s)&&  !(s->scntl1&  LSI_SCNTL1_CON))) {
> >> -        if (lsi_queue_tag(s, req->tag, len)) {
> >> +        if (lsi_queue_req(s, req, len)) {
> >>               return;
> >>           }
> >>       }
> >> @@ -789,7 +782,8 @@ static void lsi_do_command(LSIState *s)
> >>       assert(s->current == NULL);
> >>       s->current = qemu_mallocz(sizeof(lsi_request));
> >>       s->current->tag = s->select_tag;
> >> -    s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun);
> >> +    s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun,
> >> +                                   s->current);
> >>
> >>       n = scsi_req_enqueue(s->current->req, buf);
> >>       if (n) {
> >> diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
> >> index ad6a730..8b1a412 100644
> >> --- a/hw/scsi-bus.c
> >> +++ b/hw/scsi-bus.c
> >> @@ -131,7 +131,8 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
> >>       return res;
> >>   }
> >>
> >> -SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun)
> >> +SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
> >> +                            uint32_t lun, void *hba_private)
> >>   {
> >>       SCSIRequest *req;
> >>
> >> @@ -141,14 +142,16 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t l
> >>       req->dev = d;
> >>       req->tag = tag;
> >>       req->lun = lun;
> >> +    req->hba_private = hba_private;
> >>       req->status = -1;
> >>       trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
> >>       return req;
> >>   }
> >>
> >> -SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun)
> >> +SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
> >> +                          void *hba_private)
> >>   {
> >> -    return d->info->alloc_req(d, tag, lun);
> >> +    return d->info->alloc_req(d, tag, lun, hba_private);
> >>   }
> >>
> >>   uint8_t *scsi_req_get_buf(SCSIRequest *req)
> >> diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
> >> index a8c7372..c2a99fe 100644
> >> --- a/hw/scsi-disk.c
> >> +++ b/hw/scsi-disk.c
> >> @@ -81,13 +81,13 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
> >>   static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf);
> >>
> >>   static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
> >> -        uint32_t lun)
> >> +                                     uint32_t lun, void *hba_private)
> >>   {
> >>       SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
> >>       SCSIRequest *req;
> >>       SCSIDiskReq *r;
> >>
> >> -    req = scsi_req_alloc(sizeof(SCSIDiskReq),&s->qdev, tag, lun);
> >> +    req = scsi_req_alloc(sizeof(SCSIDiskReq),&s->qdev, tag, lun, hba_private);
> >>       r = DO_UPCAST(SCSIDiskReq, req, req);
> >>       r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
> >>       return req;
> >> diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
> >> index 8e59c7e..90345a7 100644
> >> --- a/hw/scsi-generic.c
> >> +++ b/hw/scsi-generic.c
> >> @@ -96,11 +96,12 @@ static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len)
> >>       return size;
> >>   }
> >>
> >> -static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
> >> +static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
> >> +                                     void *hba_private)
> >>   {
> >>       SCSIRequest *req;
> >>
> >> -    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
> >> +    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun, hba_private);
> >>       return req;
> >>   }
> >>
> >> diff --git a/hw/scsi.h b/hw/scsi.h
> >> index c1dca35..6b15bbc 100644
> >> --- a/hw/scsi.h
> >> +++ b/hw/scsi.h
> >> @@ -43,6 +43,7 @@ struct SCSIRequest {
> >>       } cmd;
> >>       BlockDriverAIOCB  *aiocb;
> >>       bool enqueued;
> >> +    void *hba_private;
> >>       QTAILQ_ENTRY(SCSIRequest) next;
> >>   };
> >>
> >> @@ -67,7 +68,8 @@ struct SCSIDeviceInfo {
> >>       DeviceInfo qdev;
> >>       scsi_qdev_initfn init;
> >>       void (*destroy)(SCSIDevice *s);
> >> -    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun);
> >> +    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
> >> +                              void *hba_private);
> >>       void (*free_req)(SCSIRequest *req);
> >>       int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
> >>       void (*read_data)(SCSIRequest *req);
> >> @@ -138,8 +140,10 @@ extern const struct SCSISense sense_code_LUN_FAILURE;
> >>   int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed);
> >>   int scsi_sense_valid(SCSISense sense);
> >>
> >> -SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun);
> >> -SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun);
> >> +SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
> >> +                            uint32_t lun, void *hba_private);
> >> +SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
> >> +                          void *hba_private);
> >>   int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf);
> >>   void scsi_req_free(SCSIRequest *req);
> >>   SCSIRequest *scsi_req_ref(SCSIRequest *req);
> >> diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
> >> index 1c901ef..9e1cb2e 100644
> >> --- a/hw/spapr_vscsi.c
> >> +++ b/hw/spapr_vscsi.c
> >> @@ -121,7 +121,7 @@ static struct vscsi_req *vscsi_get_req(VSCSIState *s)
> >>       return NULL;
> >>   }
> >>
> >> -static void vscsi_put_req(VSCSIState *s, vscsi_req *req)
> >> +static void vscsi_put_req(vscsi_req *req)
> >>   {
> >>       if (req->sreq != NULL) {
> >>           scsi_req_unref(req->sreq);
> > 
> > This breaks the build:
> > 
> > make[1]: Nothing to be done for `all'.
> >    CC    ppc64-softmmu/spapr_vscsi.o
> > /home/anthony/git/qemu/hw/spapr_vscsi.c: In function 
> > ‘vscsi_command_complete’:
> > /home/anthony/git/qemu/hw/spapr_vscsi.c:535:34: error: ‘s’ undeclared 
> > (first use in this function)
> > /home/anthony/git/qemu/hw/spapr_vscsi.c:535:34: note: each undeclared 
> > identifier is reported only once for each function it appears in
> 
> Adding Hannes to CC.
> 
> > This file is only built when libfdt is installed which is probably why 
> > you didn't catch it.
> 
> Yes, I did build all targets, but probably don't have most optional
> dependencies installed. I guess I should install some more libraries on
> that machine.
> 
> But as you said, there is no libfdt package in RHEL, so it will not be
> among them, and I'd like to avoid installing things from source.

Well, there isn't much we can do, those targets are going to require
libfdt, and if the device-tree stuff spreads on other architectures
(which is somewhat happening in the kernel now), expect that requirement
to grow beyond powerpc soon in qemu too :-)

I've spotted an effort to do a fedora package there:

https://bugzilla.redhat.com/show_bug.cgi?id=443882

I don't know much about distro packaging (I stay carefully away from
it), but maybe that could provide a basis for a RHEL one ?

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 05/21] scsi: Add 'hba_private' to SCSIRequest
  2011-07-19 13:06     ` Kevin Wolf
  2011-07-19 13:24       ` Benjamin Herrenschmidt
@ 2011-07-19 13:26       ` Hannes Reinecke
  2011-07-19 13:41         ` Kevin Wolf
  1 sibling, 1 reply; 34+ messages in thread
From: Hannes Reinecke @ 2011-07-19 13:26 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel, David Gibson

[-- Attachment #1: Type: text/plain, Size: 10823 bytes --]

On 07/19/2011 03:06 PM, Kevin Wolf wrote:
> Am 19.07.2011 14:43, schrieb Anthony Liguori:
>> On 07/19/2011 05:15 AM, Kevin Wolf wrote:
>>> From: Hannes Reinecke<hare@suse.de>
>>>
>>> 'tag' is just an abstraction to identify the command
>>> from the driver. So we should make that explicit by
>>> replacing 'tag' with a driver-defined pointer 'hba_private'.
>>> This saves the lookup for driver handling several commands
>>> in parallel.
>>> 'tag' is still being kept for tracing purposes.
>>>
>>> Signed-off-by: Hannes Reinecke<hare@suse.de>
>>> Acked-by: Paolo Bonzini<pbonzini@redhat.com>
>>> Signed-off-by: Kevin Wolf<kwolf@redhat.com>
>>> ---
>>>    hw/esp.c          |    2 +-
>>>    hw/lsi53c895a.c   |   22 ++++++++--------------
>>>    hw/scsi-bus.c     |    9 ++++++---
>>>    hw/scsi-disk.c    |    4 ++--
>>>    hw/scsi-generic.c |    5 +++--
>>>    hw/scsi.h         |   10 +++++++---
>>>    hw/spapr_vscsi.c  |   29 +++++++++--------------------
>>>    hw/usb-msd.c      |    9 +--------
>>>    8 files changed, 37 insertions(+), 53 deletions(-)
>>>
>>> diff --git a/hw/esp.c b/hw/esp.c
>>> index aa50800..9ddd637 100644
>>> --- a/hw/esp.c
>>> +++ b/hw/esp.c
>>> @@ -244,7 +244,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
>>>
>>>        DPRINTF("do_busid_cmd: busid 0x%x\n", busid);
>>>        lun = busid&   7;
>>> -    s->current_req = scsi_req_new(s->current_dev, 0, lun);
>>> +    s->current_req = scsi_req_new(s->current_dev, 0, lun, NULL);
>>>        datalen = scsi_req_enqueue(s->current_req, buf);
>>>        s->ti_size = datalen;
>>>        if (datalen != 0) {
>>> diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
>>> index 940b43a..69eec1d 100644
>>> --- a/hw/lsi53c895a.c
>>> +++ b/hw/lsi53c895a.c
>>> @@ -661,7 +661,7 @@ static lsi_request *lsi_find_by_tag(LSIState *s, uint32_t tag)
>>>    static void lsi_request_cancelled(SCSIRequest *req)
>>>    {
>>>        LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
>>> -    lsi_request *p;
>>> +    lsi_request *p = req->hba_private;
>>>
>>>        if (s->current&&   req == s->current->req) {
>>>            scsi_req_unref(req);
>>> @@ -670,7 +670,6 @@ static void lsi_request_cancelled(SCSIRequest *req)
>>>            return;
>>>        }
>>>
>>> -    p = lsi_find_by_tag(s, req->tag);
>>>        if (p) {
>>>            QTAILQ_REMOVE(&s->queue, p, next);
>>>            scsi_req_unref(req);
>>> @@ -680,18 +679,12 @@ static void lsi_request_cancelled(SCSIRequest *req)
>>>
>>>    /* Record that data is available for a queued command.  Returns zero if
>>>       the device was reselected, nonzero if the IO is deferred.  */
>>> -static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t len)
>>> +static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len)
>>>    {
>>> -    lsi_request *p;
>>> -
>>> -    p = lsi_find_by_tag(s, tag);
>>> -    if (!p) {
>>> -        BADF("IO with unknown tag %d\n", tag);
>>> -        return 1;
>>> -    }
>>> +    lsi_request *p = req->hba_private;
>>>
>>>        if (p->pending) {
>>> -        BADF("Multiple IO pending for tag %d\n", tag);
>>> +        BADF("Multiple IO pending for request %p\n", p);
>>>        }
>>>        p->pending = len;
>>>        /* Reselect if waiting for it, or if reselection triggers an IRQ
>>> @@ -743,9 +736,9 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t len)
>>>        LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
>>>        int out;
>>>
>>> -    if (s->waiting == 1 || !s->current || req->tag != s->current->tag ||
>>> +    if (s->waiting == 1 || !s->current || req->hba_private != s->current ||
>>>            (lsi_irq_on_rsl(s)&&   !(s->scntl1&   LSI_SCNTL1_CON))) {
>>> -        if (lsi_queue_tag(s, req->tag, len)) {
>>> +        if (lsi_queue_req(s, req, len)) {
>>>                return;
>>>            }
>>>        }
>>> @@ -789,7 +782,8 @@ static void lsi_do_command(LSIState *s)
>>>        assert(s->current == NULL);
>>>        s->current = qemu_mallocz(sizeof(lsi_request));
>>>        s->current->tag = s->select_tag;
>>> -    s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun);
>>> +    s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun,
>>> +                                   s->current);
>>>
>>>        n = scsi_req_enqueue(s->current->req, buf);
>>>        if (n) {
>>> diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
>>> index ad6a730..8b1a412 100644
>>> --- a/hw/scsi-bus.c
>>> +++ b/hw/scsi-bus.c
>>> @@ -131,7 +131,8 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
>>>        return res;
>>>    }
>>>
>>> -SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun)
>>> +SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
>>> +                            uint32_t lun, void *hba_private)
>>>    {
>>>        SCSIRequest *req;
>>>
>>> @@ -141,14 +142,16 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t l
>>>        req->dev = d;
>>>        req->tag = tag;
>>>        req->lun = lun;
>>> +    req->hba_private = hba_private;
>>>        req->status = -1;
>>>        trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
>>>        return req;
>>>    }
>>>
>>> -SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun)
>>> +SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
>>> +                          void *hba_private)
>>>    {
>>> -    return d->info->alloc_req(d, tag, lun);
>>> +    return d->info->alloc_req(d, tag, lun, hba_private);
>>>    }
>>>
>>>    uint8_t *scsi_req_get_buf(SCSIRequest *req)
>>> diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
>>> index a8c7372..c2a99fe 100644
>>> --- a/hw/scsi-disk.c
>>> +++ b/hw/scsi-disk.c
>>> @@ -81,13 +81,13 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
>>>    static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf);
>>>
>>>    static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
>>> -        uint32_t lun)
>>> +                                     uint32_t lun, void *hba_private)
>>>    {
>>>        SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
>>>        SCSIRequest *req;
>>>        SCSIDiskReq *r;
>>>
>>> -    req = scsi_req_alloc(sizeof(SCSIDiskReq),&s->qdev, tag, lun);
>>> +    req = scsi_req_alloc(sizeof(SCSIDiskReq),&s->qdev, tag, lun, hba_private);
>>>        r = DO_UPCAST(SCSIDiskReq, req, req);
>>>        r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
>>>        return req;
>>> diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
>>> index 8e59c7e..90345a7 100644
>>> --- a/hw/scsi-generic.c
>>> +++ b/hw/scsi-generic.c
>>> @@ -96,11 +96,12 @@ static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len)
>>>        return size;
>>>    }
>>>
>>> -static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
>>> +static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
>>> +                                     void *hba_private)
>>>    {
>>>        SCSIRequest *req;
>>>
>>> -    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
>>> +    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun, hba_private);
>>>        return req;
>>>    }
>>>
>>> diff --git a/hw/scsi.h b/hw/scsi.h
>>> index c1dca35..6b15bbc 100644
>>> --- a/hw/scsi.h
>>> +++ b/hw/scsi.h
>>> @@ -43,6 +43,7 @@ struct SCSIRequest {
>>>        } cmd;
>>>        BlockDriverAIOCB  *aiocb;
>>>        bool enqueued;
>>> +    void *hba_private;
>>>        QTAILQ_ENTRY(SCSIRequest) next;
>>>    };
>>>
>>> @@ -67,7 +68,8 @@ struct SCSIDeviceInfo {
>>>        DeviceInfo qdev;
>>>        scsi_qdev_initfn init;
>>>        void (*destroy)(SCSIDevice *s);
>>> -    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun);
>>> +    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
>>> +                              void *hba_private);
>>>        void (*free_req)(SCSIRequest *req);
>>>        int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
>>>        void (*read_data)(SCSIRequest *req);
>>> @@ -138,8 +140,10 @@ extern const struct SCSISense sense_code_LUN_FAILURE;
>>>    int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed);
>>>    int scsi_sense_valid(SCSISense sense);
>>>
>>> -SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun);
>>> -SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun);
>>> +SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
>>> +                            uint32_t lun, void *hba_private);
>>> +SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
>>> +                          void *hba_private);
>>>    int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf);
>>>    void scsi_req_free(SCSIRequest *req);
>>>    SCSIRequest *scsi_req_ref(SCSIRequest *req);
>>> diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
>>> index 1c901ef..9e1cb2e 100644
>>> --- a/hw/spapr_vscsi.c
>>> +++ b/hw/spapr_vscsi.c
>>> @@ -121,7 +121,7 @@ static struct vscsi_req *vscsi_get_req(VSCSIState *s)
>>>        return NULL;
>>>    }
>>>
>>> -static void vscsi_put_req(VSCSIState *s, vscsi_req *req)
>>> +static void vscsi_put_req(vscsi_req *req)
>>>    {
>>>        if (req->sreq != NULL) {
>>>            scsi_req_unref(req->sreq);
>>
>> This breaks the build:
>>
>> make[1]: Nothing to be done for `all'.
>>     CC    ppc64-softmmu/spapr_vscsi.o
>> /home/anthony/git/qemu/hw/spapr_vscsi.c: In function
>> ‘vscsi_command_complete’:
>> /home/anthony/git/qemu/hw/spapr_vscsi.c:535:34: error: ‘s’ undeclared
>> (first use in this function)
>> /home/anthony/git/qemu/hw/spapr_vscsi.c:535:34: note: each undeclared
>> identifier is reported only once for each function it appears in
>
> Adding Hannes to CC.
>
>> This file is only built when libfdt is installed which is probably why
>> you didn't catch it.
>
> Yes, I did build all targets, but probably don't have most optional
> dependencies installed. I guess I should install some more libraries on
> that machine.
>
> But as you said, there is no libfdt package in RHEL, so it will not be
> among them, and I'd like to avoid installing things from source.
>
Fix is attached.

How to proceed? Do you require a new patch or can you fix it up 
yourself?

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		      zSeries & Storage
hare@suse.de			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)

[-- Attachment #2: spapr-vscsi-fixup --]
[-- Type: text/plain, Size: 520 bytes --]

diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index 9e1cb2e..646b1e3 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -521,6 +521,7 @@ static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t len)
 /* Callback to indicate that the SCSI layer has completed a transfer.  */
 static void vscsi_command_complete(SCSIRequest *sreq, uint32_t status)
 {
+    VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent);
     vscsi_req *req = sreq->hba_private;
     int32_t res_in = 0, res_out = 0;
 

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 05/21] scsi: Add 'hba_private' to SCSIRequest
  2011-07-19 13:26       ` Hannes Reinecke
@ 2011-07-19 13:41         ` Kevin Wolf
  0 siblings, 0 replies; 34+ messages in thread
From: Kevin Wolf @ 2011-07-19 13:41 UTC (permalink / raw)
  To: Hannes Reinecke; +Cc: qemu-devel, David Gibson

Am 19.07.2011 15:26, schrieb Hannes Reinecke:
> On 07/19/2011 03:06 PM, Kevin Wolf wrote:
>> Am 19.07.2011 14:43, schrieb Anthony Liguori:
>>> On 07/19/2011 05:15 AM, Kevin Wolf wrote:
>>>> From: Hannes Reinecke<hare@suse.de>
>>>>
>>>> 'tag' is just an abstraction to identify the command
>>>> from the driver. So we should make that explicit by
>>>> replacing 'tag' with a driver-defined pointer 'hba_private'.
>>>> This saves the lookup for driver handling several commands
>>>> in parallel.
>>>> 'tag' is still being kept for tracing purposes.
>>>>
>>>> Signed-off-by: Hannes Reinecke<hare@suse.de>
>>>> Acked-by: Paolo Bonzini<pbonzini@redhat.com>
>>>> Signed-off-by: Kevin Wolf<kwolf@redhat.com>
>>>> ---
>>>>    hw/esp.c          |    2 +-
>>>>    hw/lsi53c895a.c   |   22 ++++++++--------------
>>>>    hw/scsi-bus.c     |    9 ++++++---
>>>>    hw/scsi-disk.c    |    4 ++--
>>>>    hw/scsi-generic.c |    5 +++--
>>>>    hw/scsi.h         |   10 +++++++---
>>>>    hw/spapr_vscsi.c  |   29 +++++++++--------------------
>>>>    hw/usb-msd.c      |    9 +--------
>>>>    8 files changed, 37 insertions(+), 53 deletions(-)
>>>>
>>>> diff --git a/hw/esp.c b/hw/esp.c
>>>> index aa50800..9ddd637 100644
>>>> --- a/hw/esp.c
>>>> +++ b/hw/esp.c
>>>> @@ -244,7 +244,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
>>>>
>>>>        DPRINTF("do_busid_cmd: busid 0x%x\n", busid);
>>>>        lun = busid&   7;
>>>> -    s->current_req = scsi_req_new(s->current_dev, 0, lun);
>>>> +    s->current_req = scsi_req_new(s->current_dev, 0, lun, NULL);
>>>>        datalen = scsi_req_enqueue(s->current_req, buf);
>>>>        s->ti_size = datalen;
>>>>        if (datalen != 0) {
>>>> diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
>>>> index 940b43a..69eec1d 100644
>>>> --- a/hw/lsi53c895a.c
>>>> +++ b/hw/lsi53c895a.c
>>>> @@ -661,7 +661,7 @@ static lsi_request *lsi_find_by_tag(LSIState *s, uint32_t tag)
>>>>    static void lsi_request_cancelled(SCSIRequest *req)
>>>>    {
>>>>        LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
>>>> -    lsi_request *p;
>>>> +    lsi_request *p = req->hba_private;
>>>>
>>>>        if (s->current&&   req == s->current->req) {
>>>>            scsi_req_unref(req);
>>>> @@ -670,7 +670,6 @@ static void lsi_request_cancelled(SCSIRequest *req)
>>>>            return;
>>>>        }
>>>>
>>>> -    p = lsi_find_by_tag(s, req->tag);
>>>>        if (p) {
>>>>            QTAILQ_REMOVE(&s->queue, p, next);
>>>>            scsi_req_unref(req);
>>>> @@ -680,18 +679,12 @@ static void lsi_request_cancelled(SCSIRequest *req)
>>>>
>>>>    /* Record that data is available for a queued command.  Returns zero if
>>>>       the device was reselected, nonzero if the IO is deferred.  */
>>>> -static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t len)
>>>> +static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len)
>>>>    {
>>>> -    lsi_request *p;
>>>> -
>>>> -    p = lsi_find_by_tag(s, tag);
>>>> -    if (!p) {
>>>> -        BADF("IO with unknown tag %d\n", tag);
>>>> -        return 1;
>>>> -    }
>>>> +    lsi_request *p = req->hba_private;
>>>>
>>>>        if (p->pending) {
>>>> -        BADF("Multiple IO pending for tag %d\n", tag);
>>>> +        BADF("Multiple IO pending for request %p\n", p);
>>>>        }
>>>>        p->pending = len;
>>>>        /* Reselect if waiting for it, or if reselection triggers an IRQ
>>>> @@ -743,9 +736,9 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t len)
>>>>        LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
>>>>        int out;
>>>>
>>>> -    if (s->waiting == 1 || !s->current || req->tag != s->current->tag ||
>>>> +    if (s->waiting == 1 || !s->current || req->hba_private != s->current ||
>>>>            (lsi_irq_on_rsl(s)&&   !(s->scntl1&   LSI_SCNTL1_CON))) {
>>>> -        if (lsi_queue_tag(s, req->tag, len)) {
>>>> +        if (lsi_queue_req(s, req, len)) {
>>>>                return;
>>>>            }
>>>>        }
>>>> @@ -789,7 +782,8 @@ static void lsi_do_command(LSIState *s)
>>>>        assert(s->current == NULL);
>>>>        s->current = qemu_mallocz(sizeof(lsi_request));
>>>>        s->current->tag = s->select_tag;
>>>> -    s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun);
>>>> +    s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun,
>>>> +                                   s->current);
>>>>
>>>>        n = scsi_req_enqueue(s->current->req, buf);
>>>>        if (n) {
>>>> diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
>>>> index ad6a730..8b1a412 100644
>>>> --- a/hw/scsi-bus.c
>>>> +++ b/hw/scsi-bus.c
>>>> @@ -131,7 +131,8 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
>>>>        return res;
>>>>    }
>>>>
>>>> -SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun)
>>>> +SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
>>>> +                            uint32_t lun, void *hba_private)
>>>>    {
>>>>        SCSIRequest *req;
>>>>
>>>> @@ -141,14 +142,16 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t l
>>>>        req->dev = d;
>>>>        req->tag = tag;
>>>>        req->lun = lun;
>>>> +    req->hba_private = hba_private;
>>>>        req->status = -1;
>>>>        trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
>>>>        return req;
>>>>    }
>>>>
>>>> -SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun)
>>>> +SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
>>>> +                          void *hba_private)
>>>>    {
>>>> -    return d->info->alloc_req(d, tag, lun);
>>>> +    return d->info->alloc_req(d, tag, lun, hba_private);
>>>>    }
>>>>
>>>>    uint8_t *scsi_req_get_buf(SCSIRequest *req)
>>>> diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
>>>> index a8c7372..c2a99fe 100644
>>>> --- a/hw/scsi-disk.c
>>>> +++ b/hw/scsi-disk.c
>>>> @@ -81,13 +81,13 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
>>>>    static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf);
>>>>
>>>>    static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
>>>> -        uint32_t lun)
>>>> +                                     uint32_t lun, void *hba_private)
>>>>    {
>>>>        SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
>>>>        SCSIRequest *req;
>>>>        SCSIDiskReq *r;
>>>>
>>>> -    req = scsi_req_alloc(sizeof(SCSIDiskReq),&s->qdev, tag, lun);
>>>> +    req = scsi_req_alloc(sizeof(SCSIDiskReq),&s->qdev, tag, lun, hba_private);
>>>>        r = DO_UPCAST(SCSIDiskReq, req, req);
>>>>        r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
>>>>        return req;
>>>> diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
>>>> index 8e59c7e..90345a7 100644
>>>> --- a/hw/scsi-generic.c
>>>> +++ b/hw/scsi-generic.c
>>>> @@ -96,11 +96,12 @@ static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len)
>>>>        return size;
>>>>    }
>>>>
>>>> -static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
>>>> +static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
>>>> +                                     void *hba_private)
>>>>    {
>>>>        SCSIRequest *req;
>>>>
>>>> -    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
>>>> +    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun, hba_private);
>>>>        return req;
>>>>    }
>>>>
>>>> diff --git a/hw/scsi.h b/hw/scsi.h
>>>> index c1dca35..6b15bbc 100644
>>>> --- a/hw/scsi.h
>>>> +++ b/hw/scsi.h
>>>> @@ -43,6 +43,7 @@ struct SCSIRequest {
>>>>        } cmd;
>>>>        BlockDriverAIOCB  *aiocb;
>>>>        bool enqueued;
>>>> +    void *hba_private;
>>>>        QTAILQ_ENTRY(SCSIRequest) next;
>>>>    };
>>>>
>>>> @@ -67,7 +68,8 @@ struct SCSIDeviceInfo {
>>>>        DeviceInfo qdev;
>>>>        scsi_qdev_initfn init;
>>>>        void (*destroy)(SCSIDevice *s);
>>>> -    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun);
>>>> +    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
>>>> +                              void *hba_private);
>>>>        void (*free_req)(SCSIRequest *req);
>>>>        int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
>>>>        void (*read_data)(SCSIRequest *req);
>>>> @@ -138,8 +140,10 @@ extern const struct SCSISense sense_code_LUN_FAILURE;
>>>>    int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed);
>>>>    int scsi_sense_valid(SCSISense sense);
>>>>
>>>> -SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun);
>>>> -SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun);
>>>> +SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
>>>> +                            uint32_t lun, void *hba_private);
>>>> +SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
>>>> +                          void *hba_private);
>>>>    int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf);
>>>>    void scsi_req_free(SCSIRequest *req);
>>>>    SCSIRequest *scsi_req_ref(SCSIRequest *req);
>>>> diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
>>>> index 1c901ef..9e1cb2e 100644
>>>> --- a/hw/spapr_vscsi.c
>>>> +++ b/hw/spapr_vscsi.c
>>>> @@ -121,7 +121,7 @@ static struct vscsi_req *vscsi_get_req(VSCSIState *s)
>>>>        return NULL;
>>>>    }
>>>>
>>>> -static void vscsi_put_req(VSCSIState *s, vscsi_req *req)
>>>> +static void vscsi_put_req(vscsi_req *req)
>>>>    {
>>>>        if (req->sreq != NULL) {
>>>>            scsi_req_unref(req->sreq);
>>>
>>> This breaks the build:
>>>
>>> make[1]: Nothing to be done for `all'.
>>>     CC    ppc64-softmmu/spapr_vscsi.o
>>> /home/anthony/git/qemu/hw/spapr_vscsi.c: In function
>>> ‘vscsi_command_complete’:
>>> /home/anthony/git/qemu/hw/spapr_vscsi.c:535:34: error: ‘s’ undeclared
>>> (first use in this function)
>>> /home/anthony/git/qemu/hw/spapr_vscsi.c:535:34: note: each undeclared
>>> identifier is reported only once for each function it appears in
>>
>> Adding Hannes to CC.
>>
>>> This file is only built when libfdt is installed which is probably why
>>> you didn't catch it.
>>
>> Yes, I did build all targets, but probably don't have most optional
>> dependencies installed. I guess I should install some more libraries on
>> that machine.
>>
>> But as you said, there is no libfdt package in RHEL, so it will not be
>> among them, and I'd like to avoid installing things from source.
>>
> Fix is attached.
> 
> How to proceed? Do you require a new patch or can you fix it up 
> yourself?

This is good enough for me, I'll update the commit.

Kevin

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 05/21] scsi: Add 'hba_private' to SCSIRequest
  2011-07-19 13:20     ` Benjamin Herrenschmidt
@ 2011-07-20  5:49       ` David Gibson
  0 siblings, 0 replies; 34+ messages in thread
From: David Gibson @ 2011-07-20  5:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Kevin Wolf, qemu-devel

On Tue, Jul 19, 2011 at 11:20:22PM +1000, Benjamin Herrenschmidt wrote:
> On Tue, 2011-07-19 at 07:43 -0500, Anthony Liguori wrote:
> > 
> > This breaks the build:
> > 
> > make[1]: Nothing to be done for `all'.
> >    CC    ppc64-softmmu/spapr_vscsi.o
> > /home/anthony/git/qemu/hw/spapr_vscsi.c: In function 
> > ‘vscsi_command_complete’:
> > /home/anthony/git/qemu/hw/spapr_vscsi.c:535:34: error: ‘s’ undeclared 
> > (first use in this function)
> > /home/anthony/git/qemu/hw/spapr_vscsi.c:535:34: note: each undeclared 
> > identifier is reported only once for each function it appears in
> > 
> > This file is only built when libfdt is installed which is probably
> > why 
> > you didn't catch it.
> > 
> > Ben/David, is there a way we can still build most of this stuff
> > without 
> > libfdt?  libfdt is still not commonly packaged by some distros.
> 
> That would be hard ... the DT stuff is pretty deeply involved. Might be
> easier to try to fix the distro :-)

Actually, I think what we should do is embed libfdt into qemu.  It's
small, it will remove a bunch of irritating config dependencies, and
it's designed to embeddable in this way.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PULL 00/21] Block patches
@ 2017-02-12  1:34 Max Reitz
  2017-02-13 10:54 ` Peter Maydell
  0 siblings, 1 reply; 34+ messages in thread
From: Max Reitz @ 2017-02-12  1:34 UTC (permalink / raw)
  To: qemu-block; +Cc: qemu-devel, Max Reitz, Peter Maydell

The following changes since commit 98b2faeaee96ab084d0b1669918688d8895c155f:

  Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging (2017-02-10 18:07:02 +0000)

are available in the git repository at:

  git://github.com/XanClic/qemu.git tags/pull-block-2017-02-12

for you to fetch changes up to 10d6eda1926804a09aa0710ca62933087813de0b:

  qemu-img: Avoid setting ret to unused value in img_convert() (2017-02-12 00:56:32 +0100)

----------------------------------------------------------------
Block patches

----------------------------------------------------------------
Alberto Garcia (2):
      qcow2: Optimize the refcount-block overlap check
      qemu-io: don't allow I/O operations larger than BDRV_REQUEST_MAX_BYTES

Daniel P. Berrange (1):
      iotests: record separate timings per format,protocol pair

Dou Liyang (2):
      block/qapi: reduce the coupling between the bdrv_query_stats and bdrv_query_bds_stats
      block/qapi: reduce the execution time of qmp_query_blockstats

Fam Zheng (2):
      qapi: Tweak error message of bdrv_query_image_info
      iotests: Fix reference output for 059

Jeff Cody (3):
      block: check full backing filename when searching protocol filenames
      qemu-iotests: Don't create fifos / pidfiles with protocol paths
      qemu-iotest: test to lookup protocol-based image with relative backing

Max Reitz (1):
      qemu-img: Improve commit invalid base message

Nir Soffer (3):
      qemu-io: Return non-zero exit code on failure
      qemu-iotests: Add _unsupported_fmt helper
      qemu-io: Add failure regression tests

Peter Lieven (2):
      block/nfs: fix NULL pointer dereference in URI parsing
      block/nfs: fix naming of runtime opts

Peter Maydell (2):
      qemu-img: Use qemu_strtoul() rather than raw strtoul()
      qemu-img: Avoid setting ret to unused value in img_convert()

QingFeng Hao (2):
      iotests: Fix a problem in common.filter
      block/vmdk: Fix the endian problem of buf_len and lba

Vladimir Sementsov-Ogievskiy (1):
      block: bdrv_invalidate_cache: invalidate children first

 tests/qemu-iotests/Makefile      |  2 +-
 block/qcow2.h                    |  1 +
 block.c                          | 24 +++++++---
 block/nfs.c                      | 49 ++++++++++----------
 block/qapi.c                     | 99 +++++++++++++++++-----------------------
 block/qcow2-refcount.c           | 24 +++++++++-
 block/qcow2.c                    |  1 +
 block/vmdk.c                     |  4 +-
 qemu-img.c                       | 44 +++++++++---------
 qemu-io-cmds.c                   | 20 +++++---
 qemu-io.c                        |  8 +++-
 tests/qemu-iotests/.gitignore    |  2 +-
 tests/qemu-iotests/059.out       |  5 +-
 tests/qemu-iotests/070.out       |  1 -
 tests/qemu-iotests/075.out       |  7 ---
 tests/qemu-iotests/076.out       |  3 --
 tests/qemu-iotests/078.out       |  6 ---
 tests/qemu-iotests/080.out       | 18 --------
 tests/qemu-iotests/083.out       | 17 -------
 tests/qemu-iotests/088.out       |  6 ---
 tests/qemu-iotests/092.out       | 12 -----
 tests/qemu-iotests/116.out       |  7 ---
 tests/qemu-iotests/131.out       |  1 -
 tests/qemu-iotests/140.out       |  1 -
 tests/qemu-iotests/173           | 97 +++++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/173.out       | 12 +++++
 tests/qemu-iotests/174           | 59 ++++++++++++++++++++++++
 tests/qemu-iotests/174.out       |  7 +++
 tests/qemu-iotests/check         | 12 +++--
 tests/qemu-iotests/common.config |  6 ++-
 tests/qemu-iotests/common.filter |  2 +-
 tests/qemu-iotests/common.qemu   | 10 ++--
 tests/qemu-iotests/common.rc     | 17 +++++--
 tests/qemu-iotests/group         |  2 +
 34 files changed, 366 insertions(+), 220 deletions(-)
 create mode 100755 tests/qemu-iotests/173
 create mode 100644 tests/qemu-iotests/173.out
 create mode 100755 tests/qemu-iotests/174
 create mode 100644 tests/qemu-iotests/174.out

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PULL 00/21] Block patches
  2017-02-12  1:34 Max Reitz
@ 2017-02-13 10:54 ` Peter Maydell
  0 siblings, 0 replies; 34+ messages in thread
From: Peter Maydell @ 2017-02-13 10:54 UTC (permalink / raw)
  To: Max Reitz; +Cc: Qemu-block, QEMU Developers

On 12 February 2017 at 01:34, Max Reitz <mreitz@redhat.com> wrote:
> The following changes since commit 98b2faeaee96ab084d0b1669918688d8895c155f:
>
>   Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging (2017-02-10 18:07:02 +0000)
>
> are available in the git repository at:
>
>   git://github.com/XanClic/qemu.git tags/pull-block-2017-02-12
>
> for you to fetch changes up to 10d6eda1926804a09aa0710ca62933087813de0b:
>
>   qemu-img: Avoid setting ret to unused value in img_convert() (2017-02-12 00:56:32 +0100)
>
> ----------------------------------------------------------------
> Block patches
>

Applied, thanks.

-- PMM

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PULL 00/21] Block patches
@ 2019-05-28 19:28 Max Reitz
  2019-05-30 11:09 ` Peter Maydell
  0 siblings, 1 reply; 34+ messages in thread
From: Max Reitz @ 2019-05-28 19:28 UTC (permalink / raw)
  To: qemu-block; +Cc: Kevin Wolf, Peter Maydell, qemu-devel, Max Reitz

The following changes since commit 8c1ecb590497b0349c550607db923972b37f6963:

  Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-next-280519-2' into staging (2019-05-28 17:38:32 +0100)

are available in the Git repository at:

  https://github.com/XanClic/qemu.git tags/pull-block-2019-05-28

for you to fetch changes up to a2d665c1bc3624a8375e2f9a7d569f7565cc1358:

  blockdev: loosen restrictions on drive-backup source node (2019-05-28 20:30:55 +0200)

----------------------------------------------------------------
Block patches:
- qcow2: Use threads for encrypted I/O
- qemu-img rebase: Optimizations
- backup job: Allow any source node, and some refactoring
- Some general simplifications in the block layer

----------------------------------------------------------------
Alberto Garcia (2):
  block: Use bdrv_unref_child() for all children in bdrv_close()
  block: Make bdrv_root_attach_child() unref child_bs on failure

Andrey Shinkevich (1):
  qcow2-bitmap: initialize bitmap directory alignment

Anton Nefedov (1):
  qcow2: skip writing zero buffers to empty COW areas

John Snow (1):
  blockdev: loosen restrictions on drive-backup source node

Sam Eiderman (3):
  qemu-img: rebase: Reuse parent BlockDriverState
  qemu-img: rebase: Reduce reads on in-chain rebase
  qemu-img: rebase: Reuse in-chain BlockDriverState

Vladimir Sementsov-Ogievskiy (13):
  qcow2.h: add missing include
  qcow2: add separate file for threaded data processing functions
  qcow2-threads: use thread_pool_submit_co
  qcow2-threads: qcow2_co_do_compress: protect queuing by mutex
  qcow2-threads: split out generic path
  qcow2: qcow2_co_preadv: improve locking
  qcow2: bdrv_co_pwritev: move encryption code out of the lock
  qcow2: do encryption in threads
  block/backup: simplify backup_incremental_init_copy_bitmap
  block/backup: move to copy_bitmap with granularity
  block/backup: refactor and tolerate unallocated cluster skipping
  block/backup: unify different modes code path
  block/backup: refactor: split out backup_calculate_cluster_size

 block/Makefile.objs         |   2 +-
 qapi/block-core.json        |   4 +-
 block/qcow2.h               |  26 ++-
 block.c                     |  46 +++---
 block/backup.c              | 243 ++++++++++++---------------
 block/block-backend.c       |   3 +-
 block/qcow2-bitmap.c        |   3 +-
 block/qcow2-cache.c         |   1 -
 block/qcow2-cluster.c       |  10 +-
 block/qcow2-refcount.c      |   1 -
 block/qcow2-snapshot.c      |   1 -
 block/qcow2-threads.c       | 268 ++++++++++++++++++++++++++++++
 block/qcow2.c               | 320 +++++++++++++-----------------------
 block/quorum.c              |   1 -
 blockdev.c                  |   7 +-
 blockjob.c                  |   2 +-
 qemu-img.c                  |  85 ++++++----
 tests/test-bdrv-drain.c     |   6 -
 tests/test-bdrv-graph-mod.c |   1 -
 block/trace-events          |   1 +
 tests/qemu-iotests/056      |   2 +-
 tests/qemu-iotests/060      |   7 +-
 tests/qemu-iotests/060.out  |   5 +-
 23 files changed, 615 insertions(+), 430 deletions(-)
 create mode 100644 block/qcow2-threads.c

-- 
2.21.0



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PULL 00/21] Block patches
  2019-05-28 19:28 [Qemu-devel] [PULL 00/21] Block patches Max Reitz
@ 2019-05-30 11:09 ` Peter Maydell
  0 siblings, 0 replies; 34+ messages in thread
From: Peter Maydell @ 2019-05-30 11:09 UTC (permalink / raw)
  To: Max Reitz; +Cc: Kevin Wolf, QEMU Developers, Qemu-block

On Tue, 28 May 2019 at 20:28, Max Reitz <mreitz@redhat.com> wrote:
>
> The following changes since commit 8c1ecb590497b0349c550607db923972b37f6963:
>
>   Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-next-280519-2' into staging (2019-05-28 17:38:32 +0100)
>
> are available in the Git repository at:
>
>   https://github.com/XanClic/qemu.git tags/pull-block-2019-05-28
>
> for you to fetch changes up to a2d665c1bc3624a8375e2f9a7d569f7565cc1358:
>
>   blockdev: loosen restrictions on drive-backup source node (2019-05-28 20:30:55 +0200)
>
> ----------------------------------------------------------------
> Block patches:
> - qcow2: Use threads for encrypted I/O
> - qemu-img rebase: Optimizations
> - backup job: Allow any source node, and some refactoring
> - Some general simplifications in the block layer
>
> ----------------------------------------------------------------


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/4.1
for any user-visible changes.

-- PMM


^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2019-05-30 11:11 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-19 10:15 [Qemu-devel] [PULL 00/21] Block patches Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 01/21] sheepdog: add full data preallocation support Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 02/21] qemu-io: Fix formatting Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 03/21] qemu-io: Fix if scoping bug Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 04/21] iov: Update parameter usage in iov_(to|from)_buf() Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 05/21] scsi: Add 'hba_private' to SCSIRequest Kevin Wolf
2011-07-19 12:43   ` Anthony Liguori
2011-07-19 13:06     ` Kevin Wolf
2011-07-19 13:24       ` Benjamin Herrenschmidt
2011-07-19 13:26       ` Hannes Reinecke
2011-07-19 13:41         ` Kevin Wolf
2011-07-19 13:20     ` Benjamin Herrenschmidt
2011-07-20  5:49       ` David Gibson
2011-07-19 10:15 ` [Qemu-devel] [PATCH 06/21] scsi-disk: Fixup debugging statement Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 07/21] scsi-disk: Mask out serial number EVPD Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 08/21] qemu-options.hx: Document missing -drive options Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 09/21] qemu-config: Document " Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 10/21] VMDK: introduce VmdkExtent Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 11/21] VMDK: bugfix, align offset to cluster in get_whole_cluster Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 12/21] VMDK: probe for monolithicFlat images Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 13/21] VMDK: separate vmdk_open by format version Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 14/21] VMDK: add field BDRVVmdkState.desc_offset Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 15/21] VMDK: flush multiple extents Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 16/21] VMDK: move 'static' cid_update flag to bs field Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 17/21] VMDK: change get_cluster_offset return type Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 18/21] VMDK: open/read/write for monolithicFlat image Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 19/21] VMDK: create different subformats Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 20/21] VMDK: fix coding style Kevin Wolf
2011-07-19 10:15 ` [Qemu-devel] [PATCH 21/21] block: add bdrv_get_allocated_file_size() operation Kevin Wolf
  -- strict thread matches above, loose matches on Subject: below --
2019-05-28 19:28 [Qemu-devel] [PULL 00/21] Block patches Max Reitz
2019-05-30 11:09 ` Peter Maydell
2017-02-12  1:34 Max Reitz
2017-02-13 10:54 ` Peter Maydell
2010-05-14 17:10 Kevin Wolf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).