All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets
@ 2017-08-07 14:45 Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 01/56] qobject: Touch up comments to say @param instead of 'param' Markus Armbruster
                   ` (56 more replies)
  0 siblings, 57 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Byte sizes, offsets and the like should use QAPI type 'size'
(uint64_t).  This rule is more honored in the breach than in the
observance.  Fix the obvious offenders.

The series is RFC for at least two reasons:

1. It's only lightly tested.  Commit message claims like "FOO now
   works" haven't been verified, yet.

2. The block layer represents file offsets and sizes as int64_t in
   many places.  Must not be negative, except for function return
   values, where it means failure.

   If you pass negative values via QMP, things explode.  Rejecting
   them cleanly would be better, but we do that only haphazardly, as
   far as I can tell.

   Changing the QAPI schema from 'int' (C: int64_t) to 'size' (C:
   uint64_t) arguably makes things slightly worse: you can't
   reasonably expect negative offsets and sizes to work, but expecting
   offsets and sizes between 2^63 and 2^64-1 to work is less
   unreasonable.  The explosions stay the same.

   Perhaps we should have a dedicated QAPI type for file offsets, just
   like libc has off_t.  Which is also signed, by the way.

Based on "[PATCH v2 0/3] Proactive pow2floor() fix, and dead code
removal" and "[PATCH 0/3] Don't QAPI without need".

Markus Armbruster (56):
  qobject: Touch up comments to say @param instead of 'param'
  qdict: New helpers to put and get unsigned integers
  monitor: Rewrite comment describing HMP .args_type
  char: Make ringbuf-read size unsigned in QAPI/QMP
  char: Make ringbuf size unsigned in QAPI
  char: Don't truncate -chardev and HMP chardev-add ringbuf size
  cpus: Make memsave, pmemsave sizes, addresses unsigned in QAPI/QMP
  dump: Make sizes and addresses unsigned in QAPI/QMP
  balloon: Make balloon size unsigned in QAPI/QMP
  hmp: Make balloon's argument unsigned
  monitor: Drop unused HMP .args_type 'M'
  pc-dimm: Make size and address unsigned in QAPI/QMP
  pci: Make PCI addresses and sizes unsigned in QAPI/QMP
  migration: Fix migrate-set-cache-size error reporting
  migration: Make XBZRLE cache size unsigned in QAPI/QMP
  migration: Make XBZRLE transferred size unsigned in QAPI/QMP
  migration: Make MigrationStats sizes unsigned in QAPI/QMP
  migration: Make parameter max-bandwidth unsigned in QAPI/QMP
  block: Make snapshot VM state size unsigned in QAPI/QMP
  block: Make ImageInfo sizes unsigned in QAPI/QMP
  block: Clean up get_human_readable_size()
  block: Mix up signed and unsigned less in bdrv_img_create()
  option: Fix type of qemu_opt_set_number() parameter @val
  block/qcow2: Change align_offset() to operate on uint64_t
  block/qcow2: Change qcow2_calc_prealloc_size() to uint64_t
  block: Make BlockMeasureInfo sizes unsigned in QAPI
  block/dirty-bitmap: Clean up signed vs. unsigned dirty counts
  block: Widen dirty bitmap granularity to uint64_t for safety
  block: Make BlockDirtyInfo byte count unsigned in QAPI/QMP
  block: Make write thresholds unsigned in QAPI/QMP
  block: Make throttle byte rates and sizes unsigned in QAPI/QMP
  hmp: Make block_set_io_throttle's arguments unsigned
  block: Make block_resize size unsigned in QAPI/QMP
  block: Make BlockDeviceStats sizes, offsets unsigned in QAPI/QMP
  blockjob: Lift speed sign conversion into block_job_set_speed()
  blockjob: Drop unused parameter @errp of method set_speed()
  blockjob: Make BlockJobInfo and event speed unsigned in QAPI/QMP
  blockjob: Lift speed sign conversion out of block_job_set_speed()
  blockjob: Lift speed sign conversion out of block_job_create()
  blockjob: Lift speed sign conversion out of backup_job_create()
  blockjob: Lift speed sign conversion out of mirror_start_job()
  blockjob: Lift speed sign conversion out of stream_start()
  blockjob: Lift speed sign conversion out of mirror_start()
  blockjob: Lift speed sign conversion out of blockdev_mirror_common()
  blockjob: Lift speed sign conversion out of commit_start() etc.
  blockjob: Make job commands' speed parameter unsigned in QAPI/QMP
  blockjob: Make BlockJobInfo and event offsets unsigned in QAPI/QMP
  block: Make mirror buffer size unsigned in QAPI/QMP
  block: Make ImageCheck file offset unsigned in QAPI
  block: Make BLOCK_IMAGE_CORRUPTED offset, size unsigned in QAPI/QMP
  block/nfs: Fix for readahead-size, page-cache-size > INT64_MAX
  block/nfs: Reject negative readahead-size, page-cache-size
  block: Make blockdev-add byte counts unsigned in QAPI/QMP
  qemu-img: blk_getlength() can fail, fix img_map() to check
  block: Make MapEntry offsets and size unsigned in QAPI
  crypto: Make QCryptoBlockInfoLUKS offsets unsigned in QAPI/QMP

 balloon.c                       |   2 +-
 block.c                         |  19 ++++---
 block/backup.c                  |  10 +---
 block/commit.c                  |   9 +--
 block/dirty-bitmap.c            |  23 +++-----
 block/mirror.c                  |  27 +++------
 block/nfs.c                     |  15 ++---
 block/null.c                    |   2 +-
 block/qapi.c                    |  20 ++++---
 block/qcow2-bitmap.c            |  18 +++---
 block/qcow2.c                   |  12 ++--
 block/qcow2.h                   |   7 +--
 block/raw-format.c              |  10 ++--
 block/stream.c                  |   8 +--
 block/trace-events              |   8 +--
 block/write-threshold.c         |   2 +-
 blockdev.c                      |  32 ++++++-----
 blockjob.c                      |  12 +---
 chardev/char-ringbuf.c          |  19 ++-----
 cpus.c                          |   6 +-
 dump.c                          |  26 ++++-----
 hmp-commands.hx                 |   4 +-
 hmp.c                           |  40 +++++++-------
 include/block/block.h           |   2 +-
 include/block/block_int.h       |  13 +++--
 include/block/blockjob.h        |   4 +-
 include/block/blockjob_int.h    |   4 +-
 include/block/dirty-bitmap.h    |  11 ++--
 include/qapi/qmp/qdict.h        |   5 ++
 include/qemu/option.h           |   2 +-
 include/sysemu/dump.h           |   8 +--
 include/sysemu/memory_mapping.h |   4 +-
 memory_mapping.c                |   4 +-
 migration/block.c               |   4 +-
 migration/migration.c           |  23 ++++----
 migration/migration.h           |   4 +-
 migration/page_cache.c          |  20 +++----
 migration/page_cache.h          |   2 +-
 migration/ram.c                 |  15 +++--
 migration/ram.h                 |   2 +-
 monitor.c                       |  80 +++++++++++++++------------
 qapi-schema.json                |  43 +++++++-------
 qapi/block-core.json            | 120 ++++++++++++++++++++--------------------
 qapi/crypto.json                |   4 +-
 qapi/event.json                 |   2 +-
 qemu-img.c                      |  10 +++-
 qobject/qdict.c                 | 101 +++++++++++++++++++++------------
 qobject/qlist.c                 |   2 +-
 tests/qemu-iotests/030          |  16 ------
 tests/qemu-iotests/030.out      |   4 +-
 tests/qemu-iotests/041          |  18 ------
 tests/qemu-iotests/041.out      |   4 +-
 tests/qemu-iotests/055          |  26 ---------
 tests/qemu-iotests/055.out      |   4 +-
 tests/test-hbitmap.c            |  16 +++---
 util/qemu-option.c              |   2 +-
 56 files changed, 439 insertions(+), 471 deletions(-)

-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 01/56] qobject: Touch up comments to say @param instead of 'param'
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-09 14:39   ` Eric Blake
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 02/56] qdict: New helpers to put and get unsigned integers Markus Armbruster
                   ` (55 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 qobject/qdict.c | 68 ++++++++++++++++++++++++++++-----------------------------
 qobject/qlist.c |  2 +-
 2 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/qobject/qdict.c b/qobject/qdict.c
index 576018e..d795079 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -116,13 +116,13 @@ static QDictEntry *qdict_find(const QDict *qdict,
 /**
  * qdict_put_obj(): Put a new QObject into the dictionary
  *
- * Insert the pair 'key:value' into 'qdict', if 'key' already exists
- * its 'value' will be replaced.
+ * Insert the pair @key:@value into @qdict, if @key already exists
+ * its value will be replaced.
  *
  * This is done by freeing the reference to the stored QObject and
  * storing the new one in the same entry.
  *
- * NOTE: ownership of 'value' is transferred to the QDict
+ * NOTE: ownership of @value is transferred to the QDict
  */
 void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
 {
@@ -144,10 +144,10 @@ void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
 }
 
 /**
- * qdict_get(): Lookup for a given 'key'
+ * qdict_get(): Lookup for a given @key
  *
- * Return a weak reference to the QObject associated with 'key' if
- * 'key' is present in the dictionary, NULL otherwise.
+ * Return a weak reference to the QObject associated with @key if
+ * @key is present in the dictionary, NULL otherwise.
  */
 QObject *qdict_get(const QDict *qdict, const char *key)
 {
@@ -158,9 +158,9 @@ QObject *qdict_get(const QDict *qdict, const char *key)
 }
 
 /**
- * qdict_haskey(): Check if 'key' exists
+ * qdict_haskey(): Check if @key exists
  *
- * Return 1 if 'key' exists in the dict, 0 otherwise
+ * Return 1 if @key exists in the dict, 0 otherwise
  */
 int qdict_haskey(const QDict *qdict, const char *key)
 {
@@ -177,11 +177,11 @@ size_t qdict_size(const QDict *qdict)
 }
 
 /**
- * qdict_get_double(): Get an number mapped by 'key'
+ * qdict_get_double(): Get an number mapped by @key
  *
- * This function assumes that 'key' exists and it stores a QNum.
+ * This function assumes that @key exists and it stores a QNum.
  *
- * Return number mapped by 'key'.
+ * Return number mapped by @key.
  */
 double qdict_get_double(const QDict *qdict, const char *key)
 {
@@ -189,12 +189,12 @@ double qdict_get_double(const QDict *qdict, const char *key)
 }
 
 /**
- * qdict_get_int(): Get an integer mapped by 'key'
+ * qdict_get_int(): Get an integer mapped by @key
  *
- * This function assumes that 'key' exists and it stores a
+ * This function assumes that @key exists and it stores a
  * QNum representable as int.
  *
- * Return integer mapped by 'key'.
+ * Return integer mapped by @key.
  */
 int64_t qdict_get_int(const QDict *qdict, const char *key)
 {
@@ -202,12 +202,12 @@ int64_t qdict_get_int(const QDict *qdict, const char *key)
 }
 
 /**
- * qdict_get_bool(): Get a bool mapped by 'key'
+ * qdict_get_bool(): Get a bool mapped by @key
  *
- * This function assumes that 'key' exists and it stores a
+ * This function assumes that @key exists and it stores a
  * QBool object.
  *
- * Return bool mapped by 'key'.
+ * Return bool mapped by @key.
  */
 bool qdict_get_bool(const QDict *qdict, const char *key)
 {
@@ -232,12 +232,12 @@ QDict *qdict_get_qdict(const QDict *qdict, const char *key)
 
 /**
  * qdict_get_str(): Get a pointer to the stored string mapped
- * by 'key'
+ * by @key
  *
- * This function assumes that 'key' exists and it stores a
+ * This function assumes that @key exists and it stores a
  * QString object.
  *
- * Return pointer to the string mapped by 'key'.
+ * Return pointer to the string mapped by @key.
  */
 const char *qdict_get_str(const QDict *qdict, const char *key)
 {
@@ -245,11 +245,11 @@ const char *qdict_get_str(const QDict *qdict, const char *key)
 }
 
 /**
- * qdict_get_try_int(): Try to get integer mapped by 'key'
+ * qdict_get_try_int(): Try to get integer mapped by @key
  *
- * Return integer mapped by 'key', if it is not present in the
+ * Return integer mapped by @key, if it is not present in the
  * dictionary or if the stored object is not a QNum representing an
- * integer, 'def_value' will be returned.
+ * integer, @def_value will be returned.
  */
 int64_t qdict_get_try_int(const QDict *qdict, const char *key,
                           int64_t def_value)
@@ -265,11 +265,11 @@ int64_t qdict_get_try_int(const QDict *qdict, const char *key,
 }
 
 /**
- * qdict_get_try_bool(): Try to get a bool mapped by 'key'
+ * qdict_get_try_bool(): Try to get a bool mapped by @key
  *
- * Return bool mapped by 'key', if it is not present in the
+ * Return bool mapped by @key, if it is not present in the
  * dictionary or if the stored object is not of QBool type
- * 'def_value' will be returned.
+ * @def_value will be returned.
  */
 bool qdict_get_try_bool(const QDict *qdict, const char *key, bool def_value)
 {
@@ -280,9 +280,9 @@ bool qdict_get_try_bool(const QDict *qdict, const char *key, bool def_value)
 
 /**
  * qdict_get_try_str(): Try to get a pointer to the stored string
- * mapped by 'key'
+ * mapped by @key
  *
- * Return a pointer to the string mapped by 'key', if it is not present
+ * Return a pointer to the string mapped by @key, if it is not present
  * in the dictionary or if the stored object is not of QString type
  * NULL will be returned.
  */
@@ -427,8 +427,8 @@ void qdict_destroy_obj(QObject *obj)
 }
 
 /**
- * qdict_copy_default(): If no entry mapped by 'key' exists in 'dst' yet, the
- * value of 'key' in 'src' is copied there (and the refcount increased
+ * qdict_copy_default(): If no entry mapped by @key exists in @dst yet, the
+ * value of @key in @src is copied there (and the refcount increased
  * accordingly).
  */
 void qdict_copy_default(QDict *dst, QDict *src, const char *key)
@@ -447,8 +447,8 @@ void qdict_copy_default(QDict *dst, QDict *src, const char *key)
 }
 
 /**
- * qdict_set_default_str(): If no entry mapped by 'key' exists in 'dst' yet, a
- * new QString initialised by 'val' is put there.
+ * qdict_set_default_str(): If no entry mapped by @key exists in @dst yet, a
+ * new QString initialised by @val is put there.
  */
 void qdict_set_default_str(QDict *dst, const char *key, const char *val)
 {
@@ -667,8 +667,8 @@ void qdict_array_split(QDict *src, QList **dst)
  *    'foo.0.bar' -> prefix='foo' and suffix='0.bar'
  *    'foo..0.bar' -> prefix='foo.0' and suffix='bar'
  *
- * The '..' sequence will be unescaped in the returned 'prefix'
- * string. The 'suffix' string will be left in escaped format, so it
+ * The '..' sequence will be unescaped in the returned @prefix
+ * string. The @suffix string will be left in escaped format, so it
  * can be fed back into the qdict_split_flat_key() key as the input
  * later.
  *
diff --git a/qobject/qlist.c b/qobject/qlist.c
index 86b60cb..f11dc5b 100644
--- a/qobject/qlist.c
+++ b/qobject/qlist.c
@@ -52,7 +52,7 @@ QList *qlist_copy(QList *src)
 /**
  * qlist_append_obj(): Append an QObject into QList
  *
- * NOTE: ownership of 'value' is transferred to the QList
+ * NOTE: ownership of @value is transferred to the QList
  */
 void qlist_append_obj(QList *qlist, QObject *value)
 {
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 02/56] qdict: New helpers to put and get unsigned integers
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 01/56] qobject: Touch up comments to say @param instead of 'param' Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-22 11:27   ` Marc-André Lureau
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 03/56] monitor: Rewrite comment describing HMP .args_type Markus Armbruster
                   ` (54 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 include/qapi/qmp/qdict.h |  5 +++++
 qobject/qdict.c          | 43 ++++++++++++++++++++++++++++++++++++-------
 2 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
index 363e431..3b52481 100644
--- a/include/qapi/qmp/qdict.h
+++ b/include/qapi/qmp/qdict.h
@@ -56,6 +56,8 @@ void qdict_destroy_obj(QObject *obj);
 /* Helpers for int, bool, and string */
 #define qdict_put_int(qdict, key, value) \
         qdict_put(qdict, key, qnum_from_int(value))
+#define qdict_put_uint(qdict, key, value) \
+        qdict_put(qdict, key, qnum_from_uint(value))
 #define qdict_put_bool(qdict, key, value) \
         qdict_put(qdict, key, qbool_from_bool(value))
 #define qdict_put_str(qdict, key, value) \
@@ -64,12 +66,15 @@ void qdict_destroy_obj(QObject *obj);
 /* High level helpers */
 double qdict_get_double(const QDict *qdict, const char *key);
 int64_t qdict_get_int(const QDict *qdict, const char *key);
+uint64_t qdict_get_uint(const QDict *qdict, const char *key);
 bool qdict_get_bool(const QDict *qdict, const char *key);
 QList *qdict_get_qlist(const QDict *qdict, const char *key);
 QDict *qdict_get_qdict(const QDict *qdict, const char *key);
 const char *qdict_get_str(const QDict *qdict, const char *key);
 int64_t qdict_get_try_int(const QDict *qdict, const char *key,
                           int64_t def_value);
+uint64_t qdict_get_try_uint(const QDict *qdict, const char *key,
+                            uint64_t def_value);
 bool qdict_get_try_bool(const QDict *qdict, const char *key, bool def_value);
 const char *qdict_get_try_str(const QDict *qdict, const char *key);
 
diff --git a/qobject/qdict.c b/qobject/qdict.c
index d795079..be919b9 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -189,10 +189,9 @@ double qdict_get_double(const QDict *qdict, const char *key)
 }
 
 /**
- * qdict_get_int(): Get an integer mapped by @key
+ * qdict_get_int(): Get a signed integer mapped by @key
  *
- * This function assumes that @key exists and it stores a
- * QNum representable as int.
+ * @qdict must map @key to an integer QNum that fits into int64_t.
  *
  * Return integer mapped by @key.
  */
@@ -202,6 +201,18 @@ int64_t qdict_get_int(const QDict *qdict, const char *key)
 }
 
 /**
+ * qdict_get_uint(): Get an unsigned integer mapped by 'key'
+ *
+ * @qdict must map @key to an integer QNum that fits into uint64_t.
+ *
+ * Return integer mapped by 'key'.
+ */
+uint64_t qdict_get_uint(const QDict *qdict, const char *key)
+{
+    return qnum_get_uint(qobject_to_qnum(qdict_get(qdict, key)));
+}
+
+/**
  * qdict_get_bool(): Get a bool mapped by @key
  *
  * This function assumes that @key exists and it stores a
@@ -245,11 +256,10 @@ const char *qdict_get_str(const QDict *qdict, const char *key)
 }
 
 /**
- * qdict_get_try_int(): Try to get integer mapped by @key
+ * qdict_get_try_int(): Try to get signed integer mapped by @key
  *
- * Return integer mapped by @key, if it is not present in the
- * dictionary or if the stored object is not a QNum representing an
- * integer, @def_value will be returned.
+ * If @qdict maps @key to an integer QNum that fits into int64_t,
+ * return it.  Else return @def_value.
  */
 int64_t qdict_get_try_int(const QDict *qdict, const char *key,
                           int64_t def_value)
@@ -265,6 +275,25 @@ int64_t qdict_get_try_int(const QDict *qdict, const char *key,
 }
 
 /**
+ * qdict_get_try_uint(): Try to get unsigned integer mapped by 'key'
+ *
+ * If @qdict maps @key to an integer QNum that fits into uint64_t,
+ * return it.  Else return @def_value.
+ */
+uint64_t qdict_get_try_uint(const QDict *qdict, const char *key,
+                            uint64_t def_value)
+{
+    QNum *qnum = qobject_to_qnum(qdict_get(qdict, key));
+    uint64_t val;
+
+    if (!qnum || !qnum_get_try_uint(qnum, &val)) {
+        return def_value;
+    }
+
+    return val;
+}
+
+/**
  * qdict_get_try_bool(): Try to get a bool mapped by @key
  *
  * Return bool mapped by @key, if it is not present in the
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 03/56] monitor: Rewrite comment describing HMP .args_type
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 01/56] qobject: Touch up comments to say @param instead of 'param' Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 02/56] qdict: New helpers to put and get unsigned integers Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-08 11:20   ` Dr. David Alan Gilbert
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 04/56] char: Make ringbuf-read size unsigned in QAPI/QMP Markus Armbruster
                   ` (53 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 monitor.c | 75 +++++++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 47 insertions(+), 28 deletions(-)

diff --git a/monitor.c b/monitor.c
index e0f8801..8b54ba1 100644
--- a/monitor.c
+++ b/monitor.c
@@ -85,37 +85,56 @@
 #endif
 
 /*
- * Supported types:
+ * Command handlers (mon_cmd_t member @cmd) receive actual arguments
+ * in a QDict, which is built by the HMP core according to mon_cmd_t
+ * member @args_type.  It's a list of NAME:TYPE separated by comma.
  *
- * 'F'          filename
- * 'B'          block device name
- * 's'          string (accept optional quote)
- * 'S'          it just appends the rest of the string (accept optional quote)
- * 'O'          option string of the form NAME=VALUE,...
- *              parsed according to QemuOptsList given by its name
- *              Example: 'device:O' uses qemu_device_opts.
- *              Restriction: only lists with empty desc are supported
- *              TODO lift the restriction
- * 'i'          32 bit integer
- * 'l'          target long (32 or 64 bit)
- * 'M'          Non-negative target long (32 or 64 bit), in user mode the
- *              value is multiplied by 2^20 (think Mebibyte)
- * 'o'          octets (aka bytes)
- *              user mode accepts an optional E, e, P, p, T, t, G, g, M, m,
- *              K, k suffix, which multiplies the value by 2^60 for suffixes E
- *              and e, 2^50 for suffixes P and p, 2^40 for suffixes T and t,
- *              2^30 for suffixes G and g, 2^20 for M and m, 2^10 for K and k
- * 'T'          double
- *              user mode accepts an optional ms, us, ns suffix,
- *              which divides the value by 1e3, 1e6, 1e9, respectively
- * '/'          optional gdb-like print format (like "/10x")
+ * TYPEs that put a string value with key NAME into the QDict:
+ * 's'    Argument is enclosed in '"' or delimited by whitespace.  In
+ *        the former case, escapes \n \r \\ \' and \" are recognized.
+ * 'F'    File name, like 's' except for completion.
+ * 'B'    BlockBackend name, like 's' except for completion.
+ * 'S'    Argument is the remainder of the line, less leading
+ *        whitespace.
+
  *
- * '?'          optional type (for all types, except '/')
- * '.'          other form of optional type (for 'i' and 'l')
- * 'b'          boolean
- *              user mode accepts "on" or "off"
- * '-'          optional parameter (eg. '-f')
+ * TYPEs that put an int64_t value with key NAME:
+ * 'l'    Argument is an expression (QEMU pocket calculator).
+ * 'i'    Like 'l' except value must fit into 32 bit unsigned.
+ * 'M'    Like 'l' except value must not be negative and is multiplied
+ *        by 2^20 (think "mebibyte").
  *
+ * TYPEs that put an uint64_t value with key NAME:
+ * 'o'    Argument is a size (think "octets").  Without suffix the
+ *        value is multiplied by 2^20 (mebibytes), with suffix E or e
+ *        by 2^60 (exbibytes), with P or p by 2^50 (pebibytes), with T
+ *        or t by 2^40 (tebibytes), with G or g by 2^30 (gibibytes),
+ *        with M or m by 2^10 (mebibytes), with K or k by 2^10
+ *        (kibibytes).
+ *
+ * TYPEs that put a double value with key NAME:
+ * 'T'    Argument is a time in seconds.  With optional ms, us, ns
+ *        suffix, the value divided by 1e3, 1e6, 1e9 respectively.
+ *
+ * TYPEs that put a bool value with key NAME:
+ * 'b'    Argument is either "on" (true) or "off" (false).
+ * '-' CHAR
+ *        Argument is either "-CHAR" (true) or absent (false).
+ *
+ * TYPEs that put multiple values:
+ * 'O'    Option string of the form NAME=VALUE,... parsed according to
+ *        the QemuOptsList given by its name.
+ *        Example: 'device:O' uses qemu_device_opts.
+ *        Restriction: only lists with empty desc are supported.
+ *        Puts all the NAME=VALUE.
+ * '/'    Gdb-like print format (like "/10x"), always optional.
+ *        Puts keys "count", "format", "size", all int.
+ *
+ * Modifier character following the type string:
+ * '?'    Argument is optional, nothing is put when it is absent
+ *        (all types except 'O', '/', 'b').
+ * '.'    Argument is optional, must be preceded by '.' if present
+ *        (only types 'i', 'l', 'M')
  */
 
 typedef struct mon_cmd_t {
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 04/56] char: Make ringbuf-read size unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (2 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 03/56] monitor: Rewrite comment describing HMP .args_type Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-22 11:32   ` Marc-André Lureau
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 05/56] char: Make ringbuf size unsigned in QAPI Markus Armbruster
                   ` (52 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Sizes should use QAPI type 'size' (uint64_t).  ringbuf-read parameter
@size is 'int' (int64_t).  qmp_ringbuf_read() rejects negative values,
then implicitly converts to size_t.

Change the parameter to 'size' and drop the check for negative values.

ringbuf-read now accepts size values between 2^63 and 2^64-1.  It
accepts negative values as before, because that's how the QObject
input visitor works for backward compatibility.

The HMP command's size parameter remains uint32_t, as HMP args_type
strings can't do uint64_t byte counts: 'l' is signed, and 'o'
multiplies by 2^20.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 chardev/char-ringbuf.c | 11 +++--------
 qapi-schema.json       |  2 +-
 2 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/chardev/char-ringbuf.c b/chardev/char-ringbuf.c
index df52b04..a9205ea 100644
--- a/chardev/char-ringbuf.c
+++ b/chardev/char-ringbuf.c
@@ -65,10 +65,10 @@ static int ringbuf_chr_write(Chardev *chr, const uint8_t *buf, int len)
     return len;
 }
 
-static int ringbuf_chr_read(Chardev *chr, uint8_t *buf, int len)
+static int ringbuf_chr_read(Chardev *chr, uint8_t *buf, size_t len)
 {
     RingBufChardev *d = RINGBUF_CHARDEV(chr);
-    int i;
+    size_t i;
 
     qemu_mutex_lock(&chr->chr_write_lock);
     for (i = 0; i < len && d->cons != d->prod; i++) {
@@ -151,7 +151,7 @@ void qmp_ringbuf_write(const char *device, const char *data,
     }
 }
 
-char *qmp_ringbuf_read(const char *device, int64_t size,
+char *qmp_ringbuf_read(const char *device, uint64_t size,
                        bool has_format, enum DataFormat format,
                        Error **errp)
 {
@@ -171,11 +171,6 @@ char *qmp_ringbuf_read(const char *device, int64_t size,
         return NULL;
     }
 
-    if (size <= 0) {
-        error_setg(errp, "size must be greater than zero");
-        return NULL;
-    }
-
     count = ringbuf_count(chr);
     size = size > count ? count : size;
     read_data = g_malloc(size + 1);
diff --git a/qapi-schema.json b/qapi-schema.json
index febe70e..18ec301 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -543,7 +543,7 @@
 #
 ##
 { 'command': 'ringbuf-read',
-  'data': {'device': 'str', 'size': 'int', '*format': 'DataFormat'},
+  'data': {'device': 'str', 'size': 'size', '*format': 'DataFormat'},
   'returns': 'str' }
 
 ##
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 05/56] char: Make ringbuf size unsigned in QAPI
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (3 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 04/56] char: Make ringbuf-read size unsigned in QAPI/QMP Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 06/56] char: Don't truncate -chardev and HMP chardev-add ringbuf size Markus Armbruster
                   ` (51 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Sizes should use QAPI type 'size' (uint64_t).  ChardevRingbuf member
@size is 'int' (int64_t).  Doesn't really matter, as its users
chardev-add and chardev-change manually reject sizes that aren't
powers of two.

Change the ChardevRingbuf member to 'size' anyway.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 qapi-schema.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index 18ec301..f4a71df 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -5106,7 +5106,7 @@
 #
 # Since: 1.5
 ##
-{ 'struct': 'ChardevRingbuf', 'data': { '*size'  : 'int' },
+{ 'struct': 'ChardevRingbuf', 'data': { '*size'  : 'size' },
   'base': 'ChardevCommon' }
 
 ##
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 06/56] char: Don't truncate -chardev and HMP chardev-add ringbuf size
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (4 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 05/56] char: Make ringbuf size unsigned in QAPI Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 07/56] cpus: Make memsave, pmemsave sizes, addresses unsigned in QAPI/QMP Markus Armbruster
                   ` (50 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

qemu_chr_parse_ringbuf() initializes the new ChardevRingbuf's @size to
the value of qemu_opt_get_size().  Except it first truncates the value
from uint64_t to int.  Fix that, so you can waste your RAM on
multi-gigabyte ring buffers.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 chardev/char-ringbuf.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/chardev/char-ringbuf.c b/chardev/char-ringbuf.c
index a9205ea..9275ae9 100644
--- a/chardev/char-ringbuf.c
+++ b/chardev/char-ringbuf.c
@@ -198,18 +198,14 @@ char *qmp_ringbuf_read(const char *device, uint64_t size,
 static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend,
                                    Error **errp)
 {
-    int val;
     ChardevRingbuf *ringbuf;
 
     backend->type = CHARDEV_BACKEND_KIND_RINGBUF;
     ringbuf = backend->u.ringbuf.data = g_new0(ChardevRingbuf, 1);
     qemu_chr_parse_common(opts, qapi_ChardevRingbuf_base(ringbuf));
 
-    val = qemu_opt_get_size(opts, "size", 0);
-    if (val != 0) {
-        ringbuf->has_size = true;
-        ringbuf->size = val;
-    }
+    ringbuf->size = qemu_opt_get_size(opts, "size", 0);
+    ringbuf->has_size = ringbuf->size != 0;
 }
 
 static void char_ringbuf_class_init(ObjectClass *oc, void *data)
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 07/56] cpus: Make memsave, pmemsave sizes, addresses unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (5 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 06/56] char: Don't truncate -chardev and HMP chardev-add ringbuf size Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-08 14:31   ` Dr. David Alan Gilbert
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 08/56] dump: Make sizes and " Markus Armbruster
                   ` (49 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Sizes, virtual and physical addresses should use QAPI type 'size'
(uint64_t).  memsave, pmemsave parameters @val, @size are 'int'
(int64_t).  qmp_memsave() and qmp_pmemsave() implicitly convert to
target_ulong or hwaddr.

Change the parameters to 'size'.

Both commands now accept size and address values between 2^63 and
2^64-1.  They accept negative values as before, because that's how the
QObject input visitor works for backward compatibility.

The HMP commands' size parameters remain uint32_t, as HMP args_type
strings can't do uint64_t byte counts: 'l' is signed, and 'o'
multiplies by 2^20.  Their address parameters remain int64_t for the
same reason.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 cpus.c           | 6 +++---
 qapi-schema.json | 5 +++--
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/cpus.c b/cpus.c
index 9bed61e..8c5ee05 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1947,14 +1947,14 @@ CpuInfoList *qmp_query_cpus(Error **errp)
     return head;
 }
 
-void qmp_memsave(int64_t addr, int64_t size, const char *filename,
+void qmp_memsave(uint64_t addr, uint64_t size, const char *filename,
                  bool has_cpu, int64_t cpu_index, Error **errp)
 {
     FILE *f;
     uint32_t l;
     CPUState *cpu;
     uint8_t buf[1024];
-    int64_t orig_addr = addr, orig_size = size;
+    uint64_t orig_addr = addr, orig_size = size;
 
     if (!has_cpu) {
         cpu_index = 0;
@@ -1994,7 +1994,7 @@ exit:
     fclose(f);
 }
 
-void qmp_pmemsave(int64_t addr, int64_t size, const char *filename,
+void qmp_pmemsave(uint64_t addr, uint64_t size, const char *filename,
                   Error **errp)
 {
     FILE *f;
diff --git a/qapi-schema.json b/qapi-schema.json
index f4a71df..80458fa 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2460,7 +2460,8 @@
 #
 ##
 { 'command': 'memsave',
-  'data': {'val': 'int', 'size': 'int', 'filename': 'str', '*cpu-index': 'int'} }
+  'data': {'val': 'size', 'size': 'size', 'filename': 'str',
+           '*cpu-index': 'int'} }
 
 ##
 # @pmemsave:
@@ -2489,7 +2490,7 @@
 #
 ##
 { 'command': 'pmemsave',
-  'data': {'val': 'int', 'size': 'int', 'filename': 'str'} }
+  'data': {'val': 'size', 'size': 'size', 'filename': 'str'} }
 
 ##
 # @cont:
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 08/56] dump: Make sizes and addresses unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (6 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 07/56] cpus: Make memsave, pmemsave sizes, addresses unsigned in QAPI/QMP Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 09/56] balloon: Make balloon size " Markus Armbruster
                   ` (48 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Sizes, virtual and physical addresses should use QAPI type 'size'
(uint64_t).  dump-guest-memory parameters @begin, @length are 'int'
(int64_t).  They get implicitly converted to unsigned types somewhere
down in the bowels of the dump machinery.  DumpQueryResult members
@completed and @total are also 'int', and also implicitly converted.

Change these dump-guest-memory parameters and DumpQueryResult members
to 'size'.

dump-guest-memory now accepts size and address values between 2^63 and
2^64-1.  They accept negative values as before, because that's how the
QObject input visitor works for backward compatibility.

query-dump and DUMP_COMPLETED now report sizes above 2^63-1 correctly
instead of their (negative) two's complement.

So does HMP's "info dump".

Drop a few redundant initializers and an incorrect, disabled debug
print while there.

Parameters of HMP's dump-guest-memory remain uint32_t, as HMP
args_type strings can't do uint64_t byte counts: 'l' is signed, and
'o' multiplies by 2^20.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 dump.c                          | 26 ++++++++++++--------------
 hmp.c                           |  2 +-
 include/sysemu/dump.h           |  8 ++++----
 include/sysemu/memory_mapping.h |  4 ++--
 memory_mapping.c                |  4 ++--
 qapi-schema.json                |  6 +++---
 6 files changed, 24 insertions(+), 26 deletions(-)

diff --git a/dump.c b/dump.c
index d9090a2..452f20f 100644
--- a/dump.c
+++ b/dump.c
@@ -331,7 +331,7 @@ static void write_elf_section(DumpState *s, int type, Error **errp)
     }
 }
 
-static void write_data(DumpState *s, void *buf, int length, Error **errp)
+static void write_data(DumpState *s, void *buf, size_t length, Error **errp)
 {
     int ret;
 
@@ -345,9 +345,9 @@ static void write_data(DumpState *s, void *buf, int length, Error **errp)
 
 /* write the memory to vmcore. 1 page per I/O. */
 static void write_memory(DumpState *s, GuestPhysBlock *block, ram_addr_t start,
-                         int64_t size, Error **errp)
+                         uint64_t size, Error **errp)
 {
-    int64_t i;
+    uint64_t i;
     Error *local_err = NULL;
 
     for (i = 0; i < size / s->dump_info.page_size; i++) {
@@ -378,7 +378,7 @@ static void get_offset_range(hwaddr phys_addr,
 {
     GuestPhysBlock *block;
     hwaddr offset = s->memory_offset;
-    int64_t size_in_block, start;
+    uint64_t size_in_block, start;
 
     /* When the memory is not stored into vmcore, offset will be -1 */
     *p_offset = -1;
@@ -602,7 +602,7 @@ static int get_next_block(DumpState *s, GuestPhysBlock *block)
 static void dump_iterate(DumpState *s, Error **errp)
 {
     GuestPhysBlock *block;
-    int64_t size;
+    uint64_t size;
     Error *local_err = NULL;
 
     do {
@@ -1466,10 +1466,10 @@ bool dump_in_progress(void)
 
 /* calculate total size of memory to be dumped (taking filter into
  * acoount.) */
-static int64_t dump_calculate_size(DumpState *s)
+static uint64_t dump_calculate_size(DumpState *s)
 {
     GuestPhysBlock *block;
-    int64_t size = 0, total = 0, left = 0, right = 0;
+    uint64_t total = 0, size, left, right;
 
     QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
         if (s->has_filter) {
@@ -1490,7 +1490,7 @@ static int64_t dump_calculate_size(DumpState *s)
 
 static void dump_init(DumpState *s, int fd, bool has_format,
                       DumpGuestMemoryFormat format, bool paging, bool has_filter,
-                      int64_t begin, int64_t length, Error **errp)
+                      uint64_t begin, uint64_t length, Error **errp)
 {
     CPUState *cpu;
     int nr_cpus;
@@ -1532,9 +1532,6 @@ static void dump_init(DumpState *s, int fd, bool has_format,
     guest_phys_blocks_init(&s->guest_phys_blocks);
     guest_phys_blocks_append(&s->guest_phys_blocks);
     s->total_size = dump_calculate_size(s);
-#ifdef DEBUG_DUMP_GUEST_MEMORY
-    fprintf(stderr, "DUMP: total memory to dump: %lu\n", s->total_size);
-#endif
 
     s->start = get_start_block(s);
     if (s->start == -1) {
@@ -1667,7 +1664,7 @@ cleanup:
 static void dump_process(DumpState *s, Error **errp)
 {
     Error *local_err = NULL;
-    DumpQueryResult *result = NULL;
+    DumpQueryResult *result;
 
     if (s->has_format && s->format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
         create_kdump_vmcore(s, &local_err);
@@ -1706,6 +1703,7 @@ DumpQueryResult *qmp_query_dump(Error **errp)
 {
     DumpQueryResult *result = g_new(DumpQueryResult, 1);
     DumpState *state = &dump_state_global;
+
     result->status = atomic_read(&state->status);
     /* make sure we are reading status and written_size in order */
     smp_rmb();
@@ -1716,8 +1714,8 @@ DumpQueryResult *qmp_query_dump(Error **errp)
 
 void qmp_dump_guest_memory(bool paging, const char *file,
                            bool has_detach, bool detach,
-                           bool has_begin, int64_t begin, bool has_length,
-                           int64_t length, bool has_format,
+                           bool has_begin, uint64_t begin, bool has_length,
+                           uint64_t length, bool has_format,
                            DumpGuestMemoryFormat format, Error **errp)
 {
     const char *p;
diff --git a/hmp.c b/hmp.c
index fd80dce..8257dd0 100644
--- a/hmp.c
+++ b/hmp.c
@@ -2797,12 +2797,12 @@ void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict)
 void hmp_info_dump(Monitor *mon, const QDict *qdict)
 {
     DumpQueryResult *result = qmp_query_dump(NULL);
+    double percent;
 
     assert(result && result->status < DUMP_STATUS__MAX);
     monitor_printf(mon, "Status: %s\n", DumpStatus_lookup[result->status]);
 
     if (result->status == DUMP_STATUS_ACTIVE) {
-        float percent = 0;
         assert(result->total != 0);
         percent = 100.0 * result->completed / result->total;
         monitor_printf(mon, "Finished: %.2f %%\n", percent);
diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
index 2672a15..52024d6 100644
--- a/include/sysemu/dump.h
+++ b/include/sysemu/dump.h
@@ -165,8 +165,8 @@ typedef struct DumpState {
     GuestPhysBlock *next_block;
     ram_addr_t start;
     bool has_filter;
-    int64_t begin;
-    int64_t length;
+    uint64_t begin;
+    uint64_t length;
 
     uint8_t *note_buf;          /* buffer for notes */
     size_t note_buf_offset;     /* the writing place in note_buf */
@@ -184,11 +184,11 @@ typedef struct DumpState {
     DumpGuestMemoryFormat format; /* valid only if has_format == true */
     QemuThread dump_thread;       /* thread for detached dump */
 
-    int64_t total_size;          /* total memory size (in bytes) to
+    uint64_t total_size;         /* total memory size (in bytes) to
                                   * be dumped. When filter is
                                   * enabled, this will only count
                                   * those to be written. */
-    int64_t written_size;        /* written memory size (in bytes),
+    uint64_t written_size;       /* written memory size (in bytes),
                                   * this could be used to calculate
                                   * how much work we have
                                   * finished. */
diff --git a/include/sysemu/memory_mapping.h b/include/sysemu/memory_mapping.h
index 706152d..47d6252 100644
--- a/include/sysemu/memory_mapping.h
+++ b/include/sysemu/memory_mapping.h
@@ -79,7 +79,7 @@ void qemu_get_guest_memory_mapping(MemoryMappingList *list,
 void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list,
                                   const GuestPhysBlockList *guest_phys_blocks);
 
-void memory_mapping_filter(MemoryMappingList *list, int64_t begin,
-                           int64_t length);
+void memory_mapping_filter(MemoryMappingList *list, uint64_t begin,
+                           uint64_t length);
 
 #endif
diff --git a/memory_mapping.c b/memory_mapping.c
index a5d3855..a4fbdca 100644
--- a/memory_mapping.c
+++ b/memory_mapping.c
@@ -328,8 +328,8 @@ void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list,
     }
 }
 
-void memory_mapping_filter(MemoryMappingList *list, int64_t begin,
-                           int64_t length)
+void memory_mapping_filter(MemoryMappingList *list, uint64_t begin,
+                           uint64_t length)
 {
     MemoryMapping *cur, *next;
 
diff --git a/qapi-schema.json b/qapi-schema.json
index 80458fa..3ad2bc0 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3439,7 +3439,7 @@
 ##
 { 'command': 'dump-guest-memory',
   'data': { 'paging': 'bool', 'protocol': 'str', '*detach': 'bool',
-            '*begin': 'int', '*length': 'int',
+            '*begin': 'size', '*length': 'size',
             '*format': 'DumpGuestMemoryFormat'} }
 
 ##
@@ -3475,8 +3475,8 @@
 ##
 { 'struct': 'DumpQueryResult',
   'data': { 'status': 'DumpStatus',
-            'completed': 'int',
-            'total': 'int' } }
+            'completed': 'size',
+            'total': 'size' } }
 
 ##
 # @query-dump:
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 09/56] balloon: Make balloon size unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (7 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 08/56] dump: Make sizes and " Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-08 14:58   ` Dr. David Alan Gilbert
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 10/56] hmp: Make balloon's argument unsigned Markus Armbruster
                   ` (47 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Sizes should use QAPI type 'size' (uint64_t).  balloon parameter
@value is 'int' (int64_t).  qmp_balloon() implicitly converts to
ram_addr_t, i.e. uint64_t.  BALLOON_CHANGE parameter @actual and
BalloonInfo member @actual are also 'int'.
virtio_balloon_set_config() and virtio_balloon_stat() implicitly
convert from ram_addr_t.

Change all three to 'size', and adjust the code using them.

balloon now accepts size values between 2^63 and 2^64-1.  It accepts
negative values as before, because that's how the QObject input
visitor works for backward compatibility.

Doing the same for HMP's balloon deserves its own commit (the next
one).

BALLOON_CHANGE and query-balloon now report sizes above 2^63-1
correctly instead of their (negative) two's complement.

So does HMP's "info balloon".

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 balloon.c        | 2 +-
 hmp.c            | 2 +-
 qapi-schema.json | 4 ++--
 qapi/event.json  | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/balloon.c b/balloon.c
index 1d720ff..2ecca76 100644
--- a/balloon.c
+++ b/balloon.c
@@ -102,7 +102,7 @@ BalloonInfo *qmp_query_balloon(Error **errp)
     return info;
 }
 
-void qmp_balloon(int64_t target, Error **errp)
+void qmp_balloon(uint64_t target, Error **errp)
 {
     if (!have_balloon(errp)) {
         return;
diff --git a/hmp.c b/hmp.c
index 8257dd0..4556045 100644
--- a/hmp.c
+++ b/hmp.c
@@ -781,7 +781,7 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
         return;
     }
 
-    monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
+    monitor_printf(mon, "balloon: actual=%" PRIu64 "\n", info->actual >> 20);
 
     qapi_free_BalloonInfo(info);
 }
diff --git a/qapi-schema.json b/qapi-schema.json
index 3ad2bc0..23eb60d 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2003,7 +2003,7 @@
 # Since: 0.14.0
 #
 ##
-{ 'struct': 'BalloonInfo', 'data': {'actual': 'int' } }
+{ 'struct': 'BalloonInfo', 'data': {'actual': 'size' } }
 
 ##
 # @query-balloon:
@@ -2603,7 +2603,7 @@
 # <- { "return": {} }
 #
 ##
-{ 'command': 'balloon', 'data': {'value': 'int'} }
+{ 'command': 'balloon', 'data': {'value': 'size'} }
 
 ##
 # @Abort:
diff --git a/qapi/event.json b/qapi/event.json
index 6d22b02..9dfc70b 100644
--- a/qapi/event.json
+++ b/qapi/event.json
@@ -488,7 +488,7 @@
 #
 ##
 { 'event': 'BALLOON_CHANGE',
-  'data': { 'actual': 'int' } }
+  'data': { 'actual': 'size' } }
 
 ##
 # @GUEST_PANICKED:
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 10/56] hmp: Make balloon's argument unsigned
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (8 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 09/56] balloon: Make balloon size " Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-08 15:10   ` Dr. David Alan Gilbert
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 11/56] monitor: Drop unused HMP .args_type 'M' Markus Armbruster
                   ` (46 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

The previous commit made it unsigned in QMP.  Switch HMP's args_type
from 'M' to 'o'.  Loses support for expressions (QEMU pocket
calculator), gains support for units other than mebibytes.  Negative
values are no longer accepted and interpreted modulo 2^64.  Instead,
values between 2^63 and 2^64-1 are now accepted.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 hmp-commands.hx | 2 +-
 hmp.c           | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 1941e19..46ce79c 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1433,7 +1433,7 @@ ETEXI
 
     {
         .name       = "balloon",
-        .args_type  = "value:M",
+        .args_type  = "value:o",
         .params     = "target",
         .help       = "request VM to change its memory allocation (in MB)",
         .cmd        = hmp_balloon,
diff --git a/hmp.c b/hmp.c
index 4556045..1932a11 100644
--- a/hmp.c
+++ b/hmp.c
@@ -781,7 +781,7 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
         return;
     }
 
-    monitor_printf(mon, "balloon: actual=%" PRIu64 "\n", info->actual >> 20);
+    monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
 
     qapi_free_BalloonInfo(info);
 }
@@ -1178,7 +1178,7 @@ void hmp_block_passwd(Monitor *mon, const QDict *qdict)
 
 void hmp_balloon(Monitor *mon, const QDict *qdict)
 {
-    int64_t value = qdict_get_int(qdict, "value");
+    uint64_t value = qdict_get_uint(qdict, "value");
     Error *err = NULL;
 
     qmp_balloon(value, &err);
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 11/56] monitor: Drop unused HMP .args_type 'M'
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (9 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 10/56] hmp: Make balloon's argument unsigned Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-08 15:23   ` Dr. David Alan Gilbert
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 12/56] pc-dimm: Make size and address unsigned in QAPI/QMP Markus Armbruster
                   ` (45 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

The previous commit switched balloon from 'M' to 'o', rendering 'M'
unused.  It was never used for anything else.  Drop it.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 monitor.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/monitor.c b/monitor.c
index 8b54ba1..3b2757e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -101,8 +101,6 @@
  * TYPEs that put an int64_t value with key NAME:
  * 'l'    Argument is an expression (QEMU pocket calculator).
  * 'i'    Like 'l' except value must fit into 32 bit unsigned.
- * 'M'    Like 'l' except value must not be negative and is multiplied
- *        by 2^20 (think "mebibyte").
  *
  * TYPEs that put an uint64_t value with key NAME:
  * 'o'    Argument is a size (think "octets").  Without suffix the
@@ -134,7 +132,7 @@
  * '?'    Argument is optional, nothing is put when it is absent
  *        (all types except 'O', '/', 'b').
  * '.'    Argument is optional, must be preceded by '.' if present
- *        (only types 'i', 'l', 'M')
+ *        (only types 'i', 'l')
  */
 
 typedef struct mon_cmd_t {
@@ -2913,7 +2911,6 @@ static QDict *monitor_parse_arguments(Monitor *mon,
             break;
         case 'i':
         case 'l':
-        case 'M':
             {
                 int64_t val;
 
@@ -2944,12 +2941,6 @@ static QDict *monitor_parse_arguments(Monitor *mon,
                     monitor_printf(mon, "\'%s\' has failed: ", cmd->name);
                     monitor_printf(mon, "integer is for 32-bit values\n");
                     goto fail;
-                } else if (c == 'M') {
-                    if (val < 0) {
-                        monitor_printf(mon, "enter a positive value\n");
-                        goto fail;
-                    }
-                    val <<= 20;
                 }
                 qdict_put_int(qdict, key, val);
             }
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 12/56] pc-dimm: Make size and address unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (10 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 11/56] monitor: Drop unused HMP .args_type 'M' Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-22 12:55   ` Igor Mammedov
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 13/56] pci: Make PCI addresses and sizes " Markus Armbruster
                   ` (44 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Sizes and addresses should use QAPI type 'size' (uint64_t).
PCDIMMDeviceInfo members @addr and @size are 'int' (int64_t).
qmp_pc_dimm_device_list() implicitly converts from uint64_t.

Change these PCDIMMDeviceInfo members to 'size'.

query-memory-devices now reports sizes and addresses above 2^63-1
correctly instead of their (negative) two's complement.

HMP's "info memory-devices" already reported them correctly, because
it printed the signed integers with PRIx64 and PRIu32.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 qapi-schema.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index 23eb60d..6aa6be9 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -6057,8 +6057,8 @@
 ##
 { 'struct': 'PCDIMMDeviceInfo',
   'data': { '*id': 'str',
-            'addr': 'int',
-            'size': 'int',
+            'addr': 'size',
+            'size': 'size',
             'slot': 'int',
             'node': 'int',
             'memdev': 'str',
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 13/56] pci: Make PCI addresses and sizes unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (11 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 12/56] pc-dimm: Make size and address unsigned in QAPI/QMP Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-22 14:03   ` Marcel Apfelbaum
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 14/56] migration: Fix migrate-set-cache-size error reporting Markus Armbruster
                   ` (43 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Sizes and addresses should use QAPI type 'size' (uint64_t).
PciMemoryRegion members @address and @size are 'int' (int64_t).
qmp_query_pci_regions() implicitly converts from pcibus_t,
i.e. uint64_t.

Change these PciMemoryRegion members to 'size'.

query-pci now reports sizes and addresses above 2^63-1 correctly
instead of their (negative) two's complement.

HMP's "info pci" already reported them correctly, because it
implicitly converted back to uint64_t.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 qapi-schema.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index 6aa6be9..c8cceb9 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2062,7 +2062,7 @@
 # Since: 0.14.0
 ##
 { 'struct': 'PciMemoryRegion',
-  'data': {'bar': 'int', 'type': 'str', 'address': 'int', 'size': 'int',
+  'data': {'bar': 'int', 'type': 'str', 'address': 'size', 'size': 'size',
            '*prefetch': 'bool', '*mem_type_64': 'bool' } }
 
 ##
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 14/56] migration: Fix migrate-set-cache-size error reporting
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (12 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 13/56] pci: Make PCI addresses and sizes " Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 16:07   ` Juan Quintela
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 15/56] migration: Make XBZRLE cache size unsigned in QAPI/QMP Markus Armbruster
                   ` (42 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

qmp_migrate_set_cache_size() calls xbzrle_cache_resize() to do the
actual work, which in turn calls cache_init() to resize the cache.  If
cache_init() fails, xbzrle_cache_resize() reports that error with
error_report() and fails.  qmp_migrate_set_cache_size() detects the
failure and reports "Parameter 'cache size' expects is smaller than
page size" with error_setg().  The first error is accurate, the second
is bogus.  With HMP, we get both.  With QMP, we get the accurate one
on stderr, and the bogus one via QMP.

Fix by making xbzrle_cache_resize() use error_setg() instead of
error_report().

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 migration/migration.c | 4 +---
 migration/ram.c       | 9 +++++++--
 migration/ram.h       | 2 +-
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index c3fe0ed..3ce68f3 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1298,10 +1298,8 @@ void qmp_migrate_set_cache_size(int64_t value, Error **errp)
         return;
     }
 
-    new_size = xbzrle_cache_resize(value);
+    new_size = xbzrle_cache_resize(value, errp);
     if (new_size < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cache size",
-                   "is smaller than page size");
         return;
     }
 
diff --git a/migration/ram.c b/migration/ram.c
index e18b3e2..e9ab858 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -29,6 +29,7 @@
 #include "cpu.h"
 #include <zlib.h>
 #include "qapi-event.h"
+#include "qapi/qmp/qerror.h"
 #include "qemu/cutils.h"
 #include "qemu/bitops.h"
 #include "qemu/bitmap.h"
@@ -110,15 +111,19 @@ static void XBZRLE_cache_unlock(void)
  * hence changes to the cache are protected by XBZRLE.lock().
  *
  * Returns the new_size or negative in case of error.
+ * Returns the the new cache size on success, -1 on error.
  *
  * @new_size: new cache size
+ * @errp: return location for an Error
  */
-int64_t xbzrle_cache_resize(int64_t new_size)
+int64_t xbzrle_cache_resize(int64_t new_size, Error **errp)
 {
     PageCache *new_cache;
     int64_t ret;
 
     if (new_size < TARGET_PAGE_SIZE) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cache size",
+                   "is smaller than page size");
         return -1;
     }
 
@@ -131,7 +136,7 @@ int64_t xbzrle_cache_resize(int64_t new_size)
         new_cache = cache_init(new_size / TARGET_PAGE_SIZE,
                                         TARGET_PAGE_SIZE);
         if (!new_cache) {
-            error_report("Error creating cache");
+            error_setg(errp, "Error creating cache");
             ret = -1;
             goto out;
         }
diff --git a/migration/ram.h b/migration/ram.h
index c081fde..97842bf 100644
--- a/migration/ram.h
+++ b/migration/ram.h
@@ -35,7 +35,7 @@
 extern MigrationStats ram_counters;
 extern XBZRLECacheStats xbzrle_counters;
 
-int64_t xbzrle_cache_resize(int64_t new_size);
+int64_t xbzrle_cache_resize(int64_t new_size, Error **errp);
 uint64_t ram_bytes_remaining(void);
 uint64_t ram_bytes_total(void);
 
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 15/56] migration: Make XBZRLE cache size unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (13 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 14/56] migration: Fix migrate-set-cache-size error reporting Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 16:10   ` Juan Quintela
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 16/56] migration: Make XBZRLE transferred " Markus Armbruster
                   ` (41 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Sizes should use QAPI type 'size' (uint64_t).  migrate-set-cache-size
parameter @value is 'int' (int64_t).  qmp_migrate_set_cache_size()
ensures it fits into size_t.  page_cache.c implicitly converts the
signed size to unsigned types (it can't quite decide whether to use
uint64_t or size_t for cache offsets, but that's not something I can
tackle now).

XBZRLECacheStats member @cache-size and query-migrate-cache-size's
result are also 'int'.

Change the migrate-set-cache-size parameter and the XBZRLECacheStats
members to 'size', fix up hmp_migrate_set_cache_size(), and tweak a
few variable types to reduce implicit conversions.

migrate-set-cache-size now accepts size values between 2^63 and
2^64-1.  It accepts negative values as before, because that's how the
QObject input visitor works for backward compatibility.

So does HMP's migrate_set_cache_size.

query-migrate and query-migrate-cache-size now report cache sizes
above 2^63-1 correctly instead of their (negative) two's complement.

So does HMP's "info migrate_cache_size".  HMP's "info migrate" already
reported the cache size correctly, because it printed the signed
integer with PRIu32.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 hmp.c                  |  4 ++--
 migration/migration.c  | 10 +++++-----
 migration/migration.h  |  4 ++--
 migration/page_cache.c | 20 +++++++++-----------
 migration/page_cache.h |  2 +-
 migration/ram.c        |  5 ++---
 migration/ram.h        |  2 +-
 qapi-schema.json       |  6 +++---
 8 files changed, 25 insertions(+), 28 deletions(-)

diff --git a/hmp.c b/hmp.c
index 1932a11..184fb8b 100644
--- a/hmp.c
+++ b/hmp.c
@@ -344,7 +344,7 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
 
 void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict)
 {
-    monitor_printf(mon, "xbzrel cache size: %" PRId64 " kbytes\n",
+    monitor_printf(mon, "xbzrel cache size: %" PRIu64 " kbytes\n",
                    qmp_query_migrate_cache_size(NULL) >> 10);
 }
 
@@ -1504,7 +1504,7 @@ void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict)
 
 void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict)
 {
-    int64_t value = qdict_get_int(qdict, "value");
+    uint64_t value = qdict_get_uint(qdict, "value");
     Error *err = NULL;
 
     qmp_migrate_set_cache_size(value, &err);
diff --git a/migration/migration.c b/migration/migration.c
index 3ce68f3..2d7f3a2 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1279,13 +1279,13 @@ void qmp_migrate_cancel(Error **errp)
     migrate_fd_cancel(migrate_get_current());
 }
 
-void qmp_migrate_set_cache_size(int64_t value, Error **errp)
+void qmp_migrate_set_cache_size(uint64_t value, Error **errp)
 {
     MigrationState *s = migrate_get_current();
-    int64_t new_size;
+    ssize_t new_size;
 
     /* Check for truncation */
-    if (value != (size_t)value) {
+    if (value != (ssize_t)value) {
         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cache size",
                    "exceeding address space");
         return;
@@ -1306,7 +1306,7 @@ void qmp_migrate_set_cache_size(int64_t value, Error **errp)
     s->xbzrle_cache_size = new_size;
 }
 
-int64_t qmp_query_migrate_cache_size(Error **errp)
+uint64_t qmp_query_migrate_cache_size(Error **errp)
 {
     return migrate_xbzrle_cache_size();
 }
@@ -1431,7 +1431,7 @@ int migrate_use_xbzrle(void)
     return s->enabled_capabilities[MIGRATION_CAPABILITY_XBZRLE];
 }
 
-int64_t migrate_xbzrle_cache_size(void)
+size_t migrate_xbzrle_cache_size(void)
 {
     MigrationState *s;
 
diff --git a/migration/migration.h b/migration/migration.h
index 148c9fa..e4708e1 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -106,7 +106,7 @@ struct MigrationState
     int64_t downtime;
     int64_t expected_downtime;
     bool enabled_capabilities[MIGRATION_CAPABILITY__MAX];
-    int64_t xbzrle_cache_size;
+    size_t xbzrle_cache_size;
     int64_t setup_time;
 
     /* Flag set once the migration has been asked to enter postcopy */
@@ -172,7 +172,7 @@ bool migrate_zero_blocks(void);
 bool migrate_auto_converge(void);
 
 int migrate_use_xbzrle(void);
-int64_t migrate_xbzrle_cache_size(void);
+size_t migrate_xbzrle_cache_size(void);
 bool migrate_colo_enabled(void);
 
 bool migrate_use_block(void);
diff --git a/migration/page_cache.c b/migration/page_cache.c
index ba984c4..226ea72 100644
--- a/migration/page_cache.c
+++ b/migration/page_cache.c
@@ -40,18 +40,17 @@ struct CacheItem {
 struct PageCache {
     CacheItem *page_cache;
     unsigned int page_size;
-    int64_t max_num_items;
+    uint64_t max_num_items;
     uint64_t max_item_age;
-    int64_t num_items;
+    uint64_t num_items;
 };
 
-PageCache *cache_init(int64_t num_pages, unsigned int page_size)
+PageCache *cache_init(uint64_t num_pages, unsigned page_size)
 {
-    int64_t i;
-
+    uint64_t i;
     PageCache *cache;
 
-    if (num_pages <= 0) {
+    if (!num_pages) {
         DPRINTF("invalid number of pages\n");
         return NULL;
     }
@@ -65,18 +64,17 @@ PageCache *cache_init(int64_t num_pages, unsigned int page_size)
     /* round down to the nearest power of 2 */
     if (!is_power_of_2(num_pages)) {
         num_pages = pow2floor(num_pages);
-        DPRINTF("rounding down to %" PRId64 "\n", num_pages);
+        DPRINTF("rounding down to %zd\n", num_pages);
     }
     cache->page_size = page_size;
     cache->num_items = 0;
     cache->max_item_age = 0;
     cache->max_num_items = num_pages;
 
-    DPRINTF("Setting cache buckets to %" PRId64 "\n", cache->max_num_items);
+    DPRINTF("Setting cache buckets to %zd\n", cache->max_num_items);
 
     /* We prefer not to abort if there is no memory */
-    cache->page_cache = g_try_malloc((cache->max_num_items) *
-                                     sizeof(*cache->page_cache));
+    cache->page_cache = g_try_new(CacheItem, cache->max_num_items);
     if (!cache->page_cache) {
         DPRINTF("Failed to allocate cache->page_cache\n");
         g_free(cache);
@@ -94,7 +92,7 @@ PageCache *cache_init(int64_t num_pages, unsigned int page_size)
 
 void cache_fini(PageCache *cache)
 {
-    int64_t i;
+    uint64_t i;
 
     g_assert(cache);
     g_assert(cache->page_cache);
diff --git a/migration/page_cache.h b/migration/page_cache.h
index 4fadd0c..b9afce3 100644
--- a/migration/page_cache.h
+++ b/migration/page_cache.h
@@ -28,7 +28,7 @@ typedef struct PageCache PageCache;
  * @num_pages: cache maximal number of cached pages
  * @page_size: cache page size
  */
-PageCache *cache_init(int64_t num_pages, unsigned int page_size);
+PageCache *cache_init(uint64_t num_pages, unsigned page_size);
 
 /**
  * cache_fini: free all cache resources
diff --git a/migration/ram.c b/migration/ram.c
index e9ab858..ce38be4 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -110,16 +110,15 @@ static void XBZRLE_cache_unlock(void)
  * migration may be using the cache and might finish during this call,
  * hence changes to the cache are protected by XBZRLE.lock().
  *
- * Returns the new_size or negative in case of error.
  * Returns the the new cache size on success, -1 on error.
  *
  * @new_size: new cache size
  * @errp: return location for an Error
  */
-int64_t xbzrle_cache_resize(int64_t new_size, Error **errp)
+ssize_t xbzrle_cache_resize(size_t new_size, Error **errp)
 {
     PageCache *new_cache;
-    int64_t ret;
+    ssize_t ret;
 
     if (new_size < TARGET_PAGE_SIZE) {
         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cache size",
diff --git a/migration/ram.h b/migration/ram.h
index 97842bf..7c4187d 100644
--- a/migration/ram.h
+++ b/migration/ram.h
@@ -35,7 +35,7 @@
 extern MigrationStats ram_counters;
 extern XBZRLECacheStats xbzrle_counters;
 
-int64_t xbzrle_cache_resize(int64_t new_size, Error **errp);
+ssize_t xbzrle_cache_resize(size_t new_size, Error **errp);
 uint64_t ram_bytes_remaining(void);
 uint64_t ram_bytes_total(void);
 
diff --git a/qapi-schema.json b/qapi-schema.json
index c8cceb9..ecabff6 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -646,7 +646,7 @@
 # Since: 1.2
 ##
 { 'struct': 'XBZRLECacheStats',
-  'data': {'cache-size': 'int', 'bytes': 'int', 'pages': 'int',
+  'data': {'cache-size': 'size', 'bytes': 'int', 'pages': 'int',
            'cache-miss': 'int', 'cache-miss-rate': 'number',
            'overflow': 'int' } }
 
@@ -2875,7 +2875,7 @@
 # <- { "return": {} }
 #
 ##
-{ 'command': 'migrate-set-cache-size', 'data': {'value': 'int'} }
+{ 'command': 'migrate-set-cache-size', 'data': {'value': 'size'} }
 
 ##
 # @query-migrate-cache-size:
@@ -2892,7 +2892,7 @@
 # <- { "return": 67108864 }
 #
 ##
-{ 'command': 'query-migrate-cache-size', 'returns': 'int' }
+{ 'command': 'query-migrate-cache-size', 'returns': 'size' }
 
 ##
 # @ObjectPropertyInfo:
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 16/56] migration: Make XBZRLE transferred size unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (14 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 15/56] migration: Make XBZRLE cache size unsigned in QAPI/QMP Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 16:47   ` Juan Quintela
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 17/56] migration: Make MigrationStats sizes " Markus Armbruster
                   ` (40 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Sizes should use QAPI type 'size' (uint64_t).  XBZRLECacheStats member
@bytes is 'int' (int64_t).  save_xbzrle_page() computes the byte count
increment in size_t, implicitly converts it to int, then adds that to
@bytes.

Change the XBZRLECacheStats member to 'size' and clean up
save_xbzrle_page().

query-migrate now reports transferred sizes above 2^63-1 correctly
instead of their (negative) two's complement.

HMP's "info migrate" already reported them correctly, because it
printed the signed integer with PRIu64.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 migration/ram.c  | 3 ++-
 qapi-schema.json | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index ce38be4..5c247f8 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -461,7 +461,8 @@ static int save_xbzrle_page(RAMState *rs, uint8_t **current_data,
                             ram_addr_t current_addr, RAMBlock *block,
                             ram_addr_t offset, bool last_stage)
 {
-    int encoded_len = 0, bytes_xbzrle;
+    int encoded_len;
+    size_t bytes_xbzrle;
     uint8_t *prev_cached_page;
 
     if (!cache_is_cached(XBZRLE.cache, current_addr,
diff --git a/qapi-schema.json b/qapi-schema.json
index ecabff6..4a3d07e 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -646,7 +646,7 @@
 # Since: 1.2
 ##
 { 'struct': 'XBZRLECacheStats',
-  'data': {'cache-size': 'size', 'bytes': 'int', 'pages': 'int',
+  'data': {'cache-size': 'size', 'bytes': 'size', 'pages': 'int',
            'cache-miss': 'int', 'cache-miss-rate': 'number',
            'overflow': 'int' } }
 
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 17/56] migration: Make MigrationStats sizes unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (15 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 16/56] migration: Make XBZRLE transferred " Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 16:48   ` Juan Quintela
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 18/56] migration: Make parameter max-bandwidth " Markus Armbruster
                   ` (39 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Sizes should use QAPI type 'size' (uint64_t).  MigrationStats members
@transferred, @remaining, @total, @normal-bytes, @page-size are 'int'
(int64_t).  populate_ram_info(), populate_disk_info() and and many
places that update them in global variable @ram_counters implicitly
convert from unsigned types.

Change these MigrationStats members to 'size'.

query-migrate now reports them correctly above 2^63-1 instead of their
(negative) two's complement.

HMP's "info migrate" already reported them correctly, because it
printed the signed integer with PRIu64.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 qapi-schema.json | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index 4a3d07e..2eee676 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -620,11 +620,11 @@
 # Since: 0.14.0
 ##
 { 'struct': 'MigrationStats',
-  'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int' ,
+  'data': {'transferred': 'size', 'remaining': 'size', 'total': 'size' ,
            'duplicate': 'int', 'skipped': 'int', 'normal': 'int',
-           'normal-bytes': 'int', 'dirty-pages-rate' : 'int',
+           'normal-bytes': 'size', 'dirty-pages-rate' : 'int',
            'mbps' : 'number', 'dirty-sync-count' : 'int',
-           'postcopy-requests' : 'int', 'page-size' : 'int' } }
+           'postcopy-requests' : 'int', 'page-size' : 'size' } }
 
 ##
 # @XBZRLECacheStats:
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 18/56] migration: Make parameter max-bandwidth unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (16 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 17/56] migration: Make MigrationStats sizes " Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 16:50   ` Juan Quintela
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 19/56] block: Make snapshot VM state size " Markus Armbruster
                   ` (38 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Byte rates should use QAPI type 'size' (uint64_t).
migrate_set_speed's parameter @value and member @max-bandwidth of
MigrationParameters and MigrateSetParameters are 'int' (int64_t).

Change them all to 'size'.

migrate_set_speed and migrate-set-parameters now accept bandwidth
values between 2^63 and SIZE_MAX (commonly 2^64-1).  They accept
negative values as before, because that's how the QObject input
visitor works for backward compatibility.

So does HMP's migrate_set_speed, except it continues to reject
negative values.

query-migrate-parameters now reports bandwidth values above 2^63-1
correctly instead of their (negative) two's complement.

So does HMP's "info migrate_params".

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 hmp.c                 | 2 +-
 migration/migration.c | 9 ++++-----
 qapi-schema.json      | 6 +++---
 3 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/hmp.c b/hmp.c
index 184fb8b..9bcdcb3 100644
--- a/hmp.c
+++ b/hmp.c
@@ -322,7 +322,7 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
             MigrationParameter_lookup[MIGRATION_PARAMETER_TLS_HOSTNAME],
             params->tls_hostname);
         assert(params->has_max_bandwidth);
-        monitor_printf(mon, "%s: %" PRId64 " bytes/second\n",
+        monitor_printf(mon, "%s: %" PRIu64 " bytes/second\n",
             MigrationParameter_lookup[MIGRATION_PARAMETER_MAX_BANDWIDTH],
             params->max_bandwidth);
         assert(params->has_downtime_limit);
diff --git a/migration/migration.c b/migration/migration.c
index 2d7f3a2..0b47371 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -716,8 +716,7 @@ static bool migrate_params_check(MigrationParameters *params, Error **errp)
         return false;
     }
 
-    if (params->has_max_bandwidth &&
-        (params->max_bandwidth < 0 || params->max_bandwidth > SIZE_MAX)) {
+    if (params->has_max_bandwidth && params->max_bandwidth > SIZE_MAX) {
         error_setg(errp, "Parameter 'max_bandwidth' expects an integer in the"
                          " range of 0 to %zu bytes/second", SIZE_MAX);
         return false;
@@ -1311,7 +1310,7 @@ uint64_t qmp_query_migrate_cache_size(Error **errp)
     return migrate_xbzrle_cache_size();
 }
 
-void qmp_migrate_set_speed(int64_t value, Error **errp)
+void qmp_migrate_set_speed(uint64_t value, Error **errp)
 {
     MigrateSetParameters p = {
         .has_max_bandwidth = true,
@@ -2179,8 +2178,8 @@ static Property migration_properties[] = {
     DEFINE_PROP_INT64("x-cpu-throttle-increment", MigrationState,
                       parameters.cpu_throttle_increment,
                       DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT),
-    DEFINE_PROP_INT64("x-max-bandwidth", MigrationState,
-                      parameters.max_bandwidth, MAX_THROTTLE),
+    DEFINE_PROP_UINT64("x-max-bandwidth", MigrationState,
+                       parameters.max_bandwidth, MAX_THROTTLE),
     DEFINE_PROP_INT64("x-downtime-limit", MigrationState,
                       parameters.downtime_limit,
                       DEFAULT_MIGRATE_SET_DOWNTIME),
diff --git a/qapi-schema.json b/qapi-schema.json
index 2eee676..c18e574 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1116,7 +1116,7 @@
             '*cpu-throttle-increment': 'int',
             '*tls-creds': 'StrOrNull',
             '*tls-hostname': 'StrOrNull',
-            '*max-bandwidth': 'int',
+            '*max-bandwidth': 'size',
             '*downtime-limit': 'int',
             '*x-checkpoint-delay': 'int',
             '*block-incremental': 'bool' } }
@@ -1200,7 +1200,7 @@
             '*cpu-throttle-increment': 'int',
             '*tls-creds': 'str',
             '*tls-hostname': 'str',
-            '*max-bandwidth': 'int',
+            '*max-bandwidth': 'size',
             '*downtime-limit': 'int',
             '*x-checkpoint-delay': 'int',
             '*block-incremental': 'bool' } }
@@ -2852,7 +2852,7 @@
 # <- { "return": {} }
 #
 ##
-{ 'command': 'migrate_set_speed', 'data': {'value': 'int'} }
+{ 'command': 'migrate_set_speed', 'data': {'value': 'size'} }
 
 ##
 # @migrate-set-cache-size:
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 19/56] block: Make snapshot VM state size unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (17 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 18/56] migration: Make parameter max-bandwidth " Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 20/56] block: Make ImageInfo sizes " Markus Armbruster
                   ` (37 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Sizes should use QAPI type 'size' (uint64_t).  SnapshotInfo member
@vm-state-size is 'int' (int64_t).  QEMUSnapshotInfo member
@vm_state_size is uint64_t.  bdrv_query_snapshot_info_list(),
bdrv_image_info_dump(), qmp_blockdev_snapshot_delete_internal_sync()
convert implicitly between the two.

Change the SnapshotInfo member to 'size'.

query-named-block-nodes, query-block and
blockdev-snapshot-delete-internal-sync now report VM state sizes above
2^63-1 correctly instead of their (negative) two's complement.

HMP's "info snapshots" and "info block" still report negative values,
because bdrv_snapshot_dump() passes the size to
get_human_readable_size(), which is still signed.  To be fixed soon.

Same for "qemu-img snapshot -l" and "qemu-img info".

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 qapi/block-core.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 27790f3..ecfeecd 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -28,7 +28,7 @@
 #
 ##
 { 'struct': 'SnapshotInfo',
-  'data': { 'id': 'str', 'name': 'str', 'vm-state-size': 'int',
+  'data': { 'id': 'str', 'name': 'str', 'vm-state-size': 'size',
             'date-sec': 'int', 'date-nsec': 'int',
             'vm-clock-sec': 'int', 'vm-clock-nsec': 'int' } }
 
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 20/56] block: Make ImageInfo sizes unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (18 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 19/56] block: Make snapshot VM state size " Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 21/56] block: Clean up get_human_readable_size() Markus Armbruster
                   ` (36 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Sizes should use QAPI type 'size' (uint64_t).  ImageInfo members
@virtual-size, @actual-size, @cluster-size are 'int' (int64_t).
bdrv_query_image_info() gets their values from bdrv_getlength(),
bdrv_get_allocated_file_size(), bdrv_get_info(), all signed.  It
ensures the former two are non-negative, but doesn't bother with
cluster-size.  vmdk_get_extent_info() initializes virtual-size and
cluster-size from signed #sectors * BDRV_SECTOR_SIZE without checking
for overflow.  Perhaps we should be more careful with sizes
overflowing into signs, but that's not something I can tackle now.

Change these ImageInfo members to 'size'.

query-named-block-nodes and query-block would now report image sizes
above 2^63-1 correctly instead of their (negative) two's complement,
if such values were possible (they aren't; the block layer uses
int64_t internally).

So would HMP's "info block", except for the ones it formats with
get_human_readable_size(), which is still signed.  To be fixed next.

Same for "qemu-img info".

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/qapi.c         | 15 ++++++++++-----
 qapi/block-core.json |  5 +++--
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/block/qapi.c b/block/qapi.c
index 5f1a71f..1c6123c 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -235,7 +235,7 @@ void bdrv_query_image_info(BlockDriverState *bs,
                            ImageInfo **p_info,
                            Error **errp)
 {
-    int64_t size;
+    int64_t size, allocated_size;
     const char *backing_filename;
     BlockDriverInfo bdi;
     int ret;
@@ -251,12 +251,16 @@ void bdrv_query_image_info(BlockDriverState *bs,
         goto out;
     }
 
+    allocated_size = bdrv_get_allocated_file_size(bs);
+
     info = g_new0(ImageInfo, 1);
     info->filename        = g_strdup(bs->filename);
     info->format          = g_strdup(bdrv_get_format_name(bs));
     info->virtual_size    = size;
-    info->actual_size     = bdrv_get_allocated_file_size(bs);
-    info->has_actual_size = info->actual_size >= 0;
+    if (allocated_size >= 0) {
+        info->actual_size = allocated_size;
+        info->has_actual_size = true;
+    }
     if (bdrv_is_encrypted(bs)) {
         info->encrypted = true;
         info->has_encrypted = true;
@@ -727,6 +731,7 @@ void bdrv_image_info_dump(fprintf_function func_fprintf, void *f,
                           ImageInfo *info)
 {
     char size_buf[128], dsize_buf[128];
+
     if (!info->has_actual_size) {
         snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
     } else {
@@ -737,7 +742,7 @@ void bdrv_image_info_dump(fprintf_function func_fprintf, void *f,
     func_fprintf(f,
                  "image: %s\n"
                  "file format: %s\n"
-                 "virtual size: %s (%" PRId64 " bytes)\n"
+                 "virtual size: %s (%" PRIu64 " bytes)\n"
                  "disk size: %s\n",
                  info->filename, info->format, size_buf,
                  info->virtual_size,
@@ -748,7 +753,7 @@ void bdrv_image_info_dump(fprintf_function func_fprintf, void *f,
     }
 
     if (info->has_cluster_size) {
-        func_fprintf(f, "cluster_size: %" PRId64 "\n",
+        func_fprintf(f, "cluster_size: %" PRIu64 "\n",
                        info->cluster_size);
     }
 
diff --git a/qapi/block-core.json b/qapi/block-core.json
index ecfeecd..02e12f7 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -156,8 +156,9 @@
 ##
 { 'struct': 'ImageInfo',
   'data': {'filename': 'str', 'format': 'str', '*dirty-flag': 'bool',
-           '*actual-size': 'int', 'virtual-size': 'int',
-           '*cluster-size': 'int', '*encrypted': 'bool', '*compressed': 'bool',
+           '*actual-size': 'size', 'virtual-size': 'size',
+           '*cluster-size': 'size',
+           '*encrypted': 'bool', '*compressed': 'bool',
            '*backing-filename': 'str', '*full-backing-filename': 'str',
            '*backing-filename-format': 'str', '*snapshots': ['SnapshotInfo'],
            '*backing-image': 'ImageInfo',
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 21/56] block: Clean up get_human_readable_size()
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (19 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 20/56] block: Make ImageInfo sizes " Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 22/56] block: Mix up signed and unsigned less in bdrv_img_create() Markus Armbruster
                   ` (35 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

get_human_readable_size() formats all negative numbers as if they were
small.

The previous two commits changed all callers to pass unsigned
arguments.  Change the parameter type to from int64_t to uint64_t.

Also change the buffer size parameter from int (ahem!) to size_t.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/qapi.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/block/qapi.c b/block/qapi.c
index 1c6123c..0f6620e 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -566,10 +566,11 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
 
 #define NB_SUFFIXES 4
 
-static char *get_human_readable_size(char *buf, int buf_size, int64_t size)
+static char *get_human_readable_size(char *buf, size_t buf_size,
+                                     uint64_t size)
 {
     static const char suffixes[NB_SUFFIXES] = {'K', 'M', 'G', 'T'};
-    int64_t base;
+    uint64_t base;
     int i;
 
     if (size <= 999) {
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 22/56] block: Mix up signed and unsigned less in bdrv_img_create()
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (20 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 21/56] block: Clean up get_human_readable_size() Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 23/56] option: Fix type of qemu_opt_set_number() parameter @val Markus Armbruster
                   ` (34 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

@size is declared int64_t.  It's set in two places.

The second one assigns the (signed) value of bdrv_getlength(), then
errors out if its negative.

The first one assigns qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 0),
i.e. an uint64_t value.  What if it exceeds INT64_MAX?  Is that even
possible?  Turns out it is:

    $ qemu-img create -o size=9223372036854775808 foo.img

On closer examination, the code still works as long as converting from
uint64_t to int64_t and back doesn't change the value.
Implementation-defined behavior, but sane implementations behave.
Things actually break elsewhere for such sizes, e.g. file-posix.c's
raw_create().

Clean this up.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/block.c b/block.c
index ce9cce7..04cce0d 100644
--- a/block.c
+++ b/block.c
@@ -4309,7 +4309,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
     QemuOptsList *create_opts = NULL;
     QemuOpts *opts = NULL;
     const char *backing_fmt, *backing_file;
-    int64_t size;
+    uint64_t size;
+    int64_t backing_size;
     BlockDriver *drv, *proto_drv;
     Error *local_err = NULL;
     int ret = 0;
@@ -4414,7 +4415,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
         bs = bdrv_open(full_backing, NULL, backing_options, back_flags,
                        &local_err);
         g_free(full_backing);
-        if (!bs && size != -1) {
+        if (!bs && size != UINT64_MAX) {
             /* Couldn't open BS, but we have a size, so it's nonfatal */
             warn_reportf_err(local_err,
                             "Could not verify backing image. "
@@ -4426,22 +4427,24 @@ void bdrv_img_create(const char *filename, const char *fmt,
                               "Could not open backing image to determine size.\n");
             goto out;
         } else {
-            if (size == -1) {
+            if (size == UINT64_MAX) {
                 /* Opened BS, have no size */
-                size = bdrv_getlength(bs);
-                if (size < 0) {
-                    error_setg_errno(errp, -size, "Could not get size of '%s'",
+                backing_size = bdrv_getlength(bs);
+                if (backing_size < 0) {
+                    error_setg_errno(errp, -backing_size,
+                                     "Could not get size of '%s'",
                                      backing_file);
                     bdrv_unref(bs);
                     goto out;
                 }
+                size = backing_size;
                 qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size, &error_abort);
             }
             bdrv_unref(bs);
         }
     } /* (backing_file && !(flags & BDRV_O_NO_BACKING)) */
 
-    if (size == -1) {
+    if (size == UINT64_MAX) {
         error_setg(errp, "Image creation needs a size parameter");
         goto out;
     }
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 23/56] option: Fix type of qemu_opt_set_number() parameter @val
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (21 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 22/56] block: Mix up signed and unsigned less in bdrv_img_create() Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 24/56] block/qcow2: Change align_offset() to operate on uint64_t Markus Armbruster
                   ` (33 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Parameter @val is int64_t.  It's assigned to opt->value.uint, which is
uint64_t, because that's what QemuOpts integers are.  Screwed up when
the function was added in commit b83c18e.  Change @val to uint64_t.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 include/qemu/option.h | 2 +-
 util/qemu-option.c    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/qemu/option.h b/include/qemu/option.h
index f7338db..d812da4 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -92,7 +92,7 @@ void qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
                   Error **errp);
 void qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
                        Error **errp);
-void qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val,
+void qemu_opt_set_number(QemuOpts *opts, const char *name, uint64_t val,
                          Error **errp);
 typedef int (*qemu_opt_loopfunc)(void *opaque,
                                  const char *name, const char *value,
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 9b1dc80..ca4f737 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -579,7 +579,7 @@ void qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
     QTAILQ_INSERT_TAIL(&opts->head, opt, next);
 }
 
-void qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val,
+void qemu_opt_set_number(QemuOpts *opts, const char *name, uint64_t val,
                          Error **errp)
 {
     QemuOpt *opt;
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 24/56] block/qcow2: Change align_offset() to operate on uint64_t
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (22 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 23/56] option: Fix type of qemu_opt_set_number() parameter @val Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 25/56] block/qcow2: Change qcow2_calc_prealloc_size() to uint64_t Markus Armbruster
                   ` (32 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

align_offset() mixes different widths, and its callers pass both
signed and unsigned values.  It's best to stick to unsigned when
twiddling bits.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/qcow2.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/block/qcow2.h b/block/qcow2.h
index 96a8d43..0d7043e 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -468,10 +468,9 @@ static inline int offset_to_l2_index(BDRVQcow2State *s, int64_t offset)
     return (offset >> s->cluster_bits) & (s->l2_size - 1);
 }
 
-static inline int64_t align_offset(int64_t offset, int n)
+static inline uint64_t align_offset(uint64_t offset, uint64_t n)
 {
-    offset = (offset + n - 1) & ~(n - 1);
-    return offset;
+    return (offset + n - 1) & ~(n - 1);
 }
 
 static inline int64_t qcow2_vm_state_offset(BDRVQcow2State *s)
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 25/56] block/qcow2: Change qcow2_calc_prealloc_size() to uint64_t
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (23 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 24/56] block/qcow2: Change align_offset() to operate on uint64_t Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 26/56] block: Make BlockMeasureInfo sizes unsigned in QAPI Markus Armbruster
                   ` (31 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Change parameter @total_size and return value to uint64_t.  Callers
mix uint64_t and int64_t.  Thus, the commit reduces, but does not
eliminate implicit conversions.

qcow2_create2() passes a (presumably non-negative) int64_t argument,
then passes the result through a local variable to
qemu_opt_set_number().  Change the local variable to uint64_t to avoid
pointless conversions.

qcow2_measure() passes a uint64_t argument, then assigns the result to
int64_t (which the next commit will change to uint64_t).

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/qcow2.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index d7c600b..d96d1f6 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2613,13 +2613,13 @@ int64_t qcow2_refcount_metadata_size(int64_t clusters, size_t cluster_size,
  * Returns: Total number of bytes required for the fully allocated image
  * (including metadata).
  */
-static int64_t qcow2_calc_prealloc_size(int64_t total_size,
-                                        size_t cluster_size,
-                                        int refcount_order)
+static uint64_t qcow2_calc_prealloc_size(uint64_t total_size,
+                                         size_t cluster_size,
+                                         int refcount_order)
 {
-    int64_t meta_size = 0;
+    uint64_t meta_size = 0;
     uint64_t nl1e, nl2e;
-    int64_t aligned_total_size = align_offset(total_size, cluster_size);
+    uint64_t aligned_total_size = align_offset(total_size, cluster_size);
 
     /* header: 1 cluster */
     meta_size += cluster_size;
@@ -2729,7 +2729,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
     int ret;
 
     if (prealloc == PREALLOC_MODE_FULL || prealloc == PREALLOC_MODE_FALLOC) {
-        int64_t prealloc_size =
+        uint64_t prealloc_size =
             qcow2_calc_prealloc_size(total_size, cluster_size, refcount_order);
         qemu_opt_set_number(opts, BLOCK_OPT_SIZE, prealloc_size, &error_abort);
         qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_lookup[prealloc],
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 26/56] block: Make BlockMeasureInfo sizes unsigned in QAPI
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (24 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 25/56] block/qcow2: Change qcow2_calc_prealloc_size() to uint64_t Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 27/56] block/dirty-bitmap: Clean up signed vs. unsigned dirty counts Markus Armbruster
                   ` (30 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Sizes should use QAPI type 'size' (uint64_t).  BlockMeasureInfo
members @required and @fully-allocated are 'int' (int64_t).

qcow2_measure() computes their values from qcow2_calc_prealloc_size(),
@virtual_size and @required, all uint64_t (the former only since the
previous commit).

raw_measure() computes them either from bdrv_getlength() or from
qemu_opt_get_size_del().  The former is int64_t, but we error out if
it's negative.  The latter is uint64_t.

Change these BlockMeasureInfo members to 'size'.

qemu-img now reports them correctly above 2^63-1 instead of their
(negative) two's complement.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/raw-format.c   | 10 ++++++----
 qapi/block-core.json |  2 +-
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/block/raw-format.c b/block/raw-format.c
index 142649e..6b73d5b 100644
--- a/block/raw-format.c
+++ b/block/raw-format.c
@@ -316,14 +316,16 @@ static BlockMeasureInfo *raw_measure(QemuOpts *opts, BlockDriverState *in_bs,
                                      Error **errp)
 {
     BlockMeasureInfo *info;
-    int64_t required;
+    int64_t size;
+    uint64_t required;
 
     if (in_bs) {
-        required = bdrv_getlength(in_bs);
-        if (required < 0) {
-            error_setg_errno(errp, -required, "Unable to get image size");
+        size = bdrv_getlength(in_bs);
+        if (size < 0) {
+            error_setg_errno(errp, -size, "Unable to get image size");
             return NULL;
         }
+        required = size;
     } else {
         required = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
                             BDRV_SECTOR_SIZE);
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 02e12f7..bc8e5b6 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -485,7 +485,7 @@
 # Since: 2.10
 ##
 { 'struct': 'BlockMeasureInfo',
-  'data': {'required': 'int', 'fully-allocated': 'int'} }
+  'data': {'required': 'size', 'fully-allocated': 'size'} }
 
 ##
 # @query-block:
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 27/56] block/dirty-bitmap: Clean up signed vs. unsigned dirty counts
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (25 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 26/56] block: Make BlockMeasureInfo sizes unsigned in QAPI Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-08  1:50   ` John Snow
  2017-08-08 14:53   ` Eric Blake
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 28/56] block: Widen dirty bitmap granularity to uint64_t for safety Markus Armbruster
                   ` (29 subsequent siblings)
  56 siblings, 2 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

hbitmap_count() returns uint64_t.

Clean up test-hbitmap.c to check its value with g_assert_cmpuint()
instead of g_assert_cmpint().

bdrv_get_dirty_count() and bdrv_get_meta_dirty_count() return its
value converted to int64_t.  Clean them up to return it unadulterated.

This moves the implicit conversion to some callers, so clean them up,
too.

mirror_run() assigns the value of bdrv_get_meta_dirty_count() to a
local int64_t variable.  Change it to uint64_t.  Signedness still gets
mixed up in the computation of s->common.len, but messing with that is
more than I can handle right now.

get_remaining_dirty() tallies bdrv_get_dirty_count() values in
int64_t.  Its caller block_save_pending() converts it back to
uint64_t.  Change get_remaining_dirty() to uint64_t.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/dirty-bitmap.c         |  4 ++--
 block/mirror.c               |  4 ++--
 block/trace-events           |  8 ++++----
 include/block/dirty-bitmap.h |  4 ++--
 migration/block.c            |  4 ++--
 tests/test-hbitmap.c         | 16 +++++++++-------
 6 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index 30462d4..5b1699c 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -681,12 +681,12 @@ void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t sector_num)
     hbitmap_iter_init(&iter->hbi, iter->hbi.hb, sector_num);
 }
 
-int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
+uint64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
 {
     return hbitmap_count(bitmap->bitmap);
 }
 
-int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
+uint64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
 {
     return hbitmap_count(bitmap->meta);
 }
diff --git a/block/mirror.c b/block/mirror.c
index c9a6a3c..14c34e9 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -798,8 +798,8 @@ static void coroutine_fn mirror_run(void *opaque)
     assert(!s->dbi);
     s->dbi = bdrv_dirty_iter_new(s->dirty_bitmap, 0);
     for (;;) {
-        uint64_t delay_ns = 0;
-        int64_t cnt, delta;
+        uint64_t cnt, delay_ns = 0;
+        int64_t delta;
         bool should_complete;
 
         if (s->ret < 0) {
diff --git a/block/trace-events b/block/trace-events
index 071a8d7..464a11f 100644
--- a/block/trace-events
+++ b/block/trace-events
@@ -24,13 +24,13 @@ commit_start(void *bs, void *base, void *top, void *s) "bs %p base %p top %p s %
 
 # block/mirror.c
 mirror_start(void *bs, void *s, void *opaque) "bs %p s %p opaque %p"
-mirror_restart_iter(void *s, int64_t cnt) "s %p dirty count %"PRId64
+mirror_restart_iter(void *s, uint64_t cnt) "s %p dirty count %" PRIu64
 mirror_before_flush(void *s) "s %p"
-mirror_before_drain(void *s, int64_t cnt) "s %p dirty count %"PRId64
-mirror_before_sleep(void *s, int64_t cnt, int synced, uint64_t delay_ns) "s %p dirty count %"PRId64" synced %d delay %"PRIu64"ns"
+mirror_before_drain(void *s, uint64_t cnt) "s %p dirty count %" PRIu64
+mirror_before_sleep(void *s, uint64_t cnt, int synced, uint64_t delay_ns) "s %p dirty count %" PRIu64 " synced %d delay %" PRIu64 "ns"
 mirror_one_iteration(void *s, int64_t offset, uint64_t bytes) "s %p offset %" PRId64 " bytes %" PRIu64
 mirror_iteration_done(void *s, int64_t offset, uint64_t bytes, int ret) "s %p offset %" PRId64 " bytes %" PRIu64 " ret %d"
-mirror_yield(void *s, int64_t cnt, int buf_free_count, int in_flight) "s %p dirty count %"PRId64" free buffers %d in_flight %d"
+mirror_yield(void *s, uint64_t cnt, int buf_free_count, int in_flight) "s %p dirty count %" PRIu64 " free buffers %d in_flight %d"
 mirror_yield_in_flight(void *s, int64_t offset, int in_flight) "s %p offset %" PRId64 " in_flight %d"
 
 # block/backup.c
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
index a79a58d..d7e0f61 100644
--- a/include/block/dirty-bitmap.h
+++ b/include/block/dirty-bitmap.h
@@ -91,8 +91,8 @@ void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
                                     int64_t cur_sector, int64_t nr_sectors);
 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter);
 void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t sector_num);
-int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
-int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap);
+uint64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
+uint64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap);
 void bdrv_dirty_bitmap_truncate(BlockDriverState *bs);
 bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap);
 bool bdrv_has_readonly_bitmaps(BlockDriverState *bs);
diff --git a/migration/block.c b/migration/block.c
index 9171f60..59b7551 100644
--- a/migration/block.c
+++ b/migration/block.c
@@ -656,10 +656,10 @@ static int flush_blks(QEMUFile *f)
 
 /* Called with iothread lock taken.  */
 
-static int64_t get_remaining_dirty(void)
+static uint64_t get_remaining_dirty(void)
 {
     BlkMigDevState *bmds;
-    int64_t dirty = 0;
+    uint64_t dirty = 0;
 
     QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
         aio_context_acquire(blk_get_aio_context(bmds->blk));
diff --git a/tests/test-hbitmap.c b/tests/test-hbitmap.c
index 1acb353..f816827 100644
--- a/tests/test-hbitmap.c
+++ b/tests/test-hbitmap.c
@@ -70,7 +70,8 @@ static void hbitmap_test_check(TestHBitmapData *data,
     }
 
     if (first == 0) {
-        g_assert_cmpint(count << data->granularity, ==, hbitmap_count(data->hb));
+        g_assert_cmpuint(count << data->granularity,
+                         ==, hbitmap_count(data->hb));
     }
 }
 
@@ -222,7 +223,7 @@ static void hbitmap_test_check_get(TestHBitmapData *data)
         count += hbitmap_get(data->hb, i);
         g_assert_cmpint(hbitmap_get(data->hb, i), ==, val != 0);
     }
-    g_assert_cmpint(count, ==, hbitmap_count(data->hb));
+    g_assert_cmpuint(count, ==, hbitmap_count(data->hb));
 }
 
 static void test_hbitmap_zero(TestHBitmapData *data,
@@ -416,15 +417,15 @@ static void test_hbitmap_granularity(TestHBitmapData *data,
     /* Note that hbitmap_test_check has to be invoked manually in this test.  */
     hbitmap_test_init(data, L1, 1);
     hbitmap_test_set(data, 0, 1);
-    g_assert_cmpint(hbitmap_count(data->hb), ==, 2);
+    g_assert_cmpuint(hbitmap_count(data->hb), ==, 2);
     hbitmap_test_check(data, 0);
     hbitmap_test_set(data, 2, 1);
-    g_assert_cmpint(hbitmap_count(data->hb), ==, 4);
+    g_assert_cmpuint(hbitmap_count(data->hb), ==, 4);
     hbitmap_test_check(data, 0);
     hbitmap_test_set(data, 0, 3);
-    g_assert_cmpint(hbitmap_count(data->hb), ==, 4);
+    g_assert_cmpuint(hbitmap_count(data->hb), ==, 4);
     hbitmap_test_reset(data, 0, 1);
-    g_assert_cmpint(hbitmap_count(data->hb), ==, 2);
+    g_assert_cmpuint(hbitmap_count(data->hb), ==, 2);
 }
 
 static void test_hbitmap_iter_granularity(TestHBitmapData *data,
@@ -494,7 +495,8 @@ static void hbitmap_test_check_boundary_bits(TestHBitmapData *data)
          */
         g_assert(hbitmap_get(data->hb, 0));
         g_assert(hbitmap_get(data->hb, size - 1));
-        g_assert_cmpint(2 << data->granularity, ==, hbitmap_count(data->hb));
+        g_assert_cmpuint(2ull << data->granularity,
+                         ==, hbitmap_count(data->hb));
     }
 }
 
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 28/56] block: Widen dirty bitmap granularity to uint64_t for safety
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (26 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 27/56] block/dirty-bitmap: Clean up signed vs. unsigned dirty counts Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-08  1:55   ` John Snow
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 29/56] block: Make BlockDirtyInfo byte count unsigned in QAPI/QMP Markus Armbruster
                   ` (28 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Block dirty bitmaps represent granularity in bytes as uint32_t.  It
must be a power of two and a multiple of BDRV_SECTOR_SIZE.

The trouble with uint32_t is computations like this one in
mirror_do_read():

    uint64_t max_bytes;

    max_bytes = s->granularity * s->max_iov;

The operands of * are uint32_t and int, so the product is computed in
uint32_t (assuming 32 bit int), then zero-extended to uint64_t.

Since granularity is generally combined with 64 bit file offsets, it's
best to make it 64 bits, too.  Less opportunity to screw up.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block.c                      |  2 +-
 block/backup.c               |  2 +-
 block/dirty-bitmap.c         | 19 +++++++------------
 block/mirror.c               |  6 +++---
 block/qcow2-bitmap.c         | 18 +++++++++---------
 block/qcow2.h                |  2 +-
 blockdev.c                   |  6 +++---
 include/block/block.h        |  2 +-
 include/block/block_int.h    |  4 ++--
 include/block/dirty-bitmap.h |  7 +++----
 qapi/block-core.json         |  8 ++++----
 11 files changed, 35 insertions(+), 41 deletions(-)

diff --git a/block.c b/block.c
index 04cce0d..fe4b089 100644
--- a/block.c
+++ b/block.c
@@ -4922,7 +4922,7 @@ void bdrv_del_child(BlockDriverState *parent_bs, BdrvChild *child, Error **errp)
 }
 
 bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
-                                     uint32_t granularity, Error **errp)
+                                     uint64_t granularity, Error **errp)
 {
     BlockDriver *drv = bs->drv;
 
diff --git a/block/backup.c b/block/backup.c
index 504a089..a37c944 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -363,7 +363,7 @@ static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
     bool error_is_read;
     int ret = 0;
     int clusters_per_iter;
-    uint32_t granularity;
+    uint64_t granularity;
     int64_t offset;
     int64_t cluster;
     int64_t end;
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index 5b1699c..c0b5952 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -109,13 +109,13 @@ void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap)
 
 /* Called with BQL taken.  */
 BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
-                                          uint32_t granularity,
+                                          uint64_t granularity,
                                           const char *name,
                                           Error **errp)
 {
     int64_t bitmap_size;
     BdrvDirtyBitmap *bitmap;
-    uint32_t sector_granularity;
+    uint64_t sector_granularity;
 
     assert((granularity & (granularity - 1)) == 0);
 
@@ -133,7 +133,7 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
     }
     bitmap = g_new0(BdrvDirtyBitmap, 1);
     bitmap->mutex = &bs->dirty_bitmap_mutex;
-    bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(sector_granularity));
+    bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz64(sector_granularity));
     bitmap->size = bitmap_size;
     bitmap->name = g_strdup(name);
     bitmap->disabled = false;
@@ -178,7 +178,7 @@ int bdrv_dirty_bitmap_get_meta_locked(BlockDriverState *bs,
                                       int nb_sectors)
 {
     uint64_t i;
-    int sectors_per_bit = 1 << hbitmap_granularity(bitmap->meta);
+    uint64_t sectors_per_bit = 1ull << hbitmap_granularity(bitmap->meta);
 
     /* To optimize: we can make hbitmap to internally check the range in a
      * coarse level, or at least do it word by word. */
@@ -491,10 +491,10 @@ int bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
  * but clamped between [4K, 64K]. Defaults to 64K in the case that there
  * is no cluster size information available.
  */
-uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
+uint64_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
 {
     BlockDriverInfo bdi;
-    uint32_t granularity;
+    uint64_t granularity;
 
     if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) {
         granularity = MAX(4096, bdi.cluster_size);
@@ -506,16 +506,11 @@ uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
     return granularity;
 }
 
-uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
+uint64_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
 {
     return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap);
 }
 
-uint32_t bdrv_dirty_bitmap_meta_granularity(BdrvDirtyBitmap *bitmap)
-{
-    return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->meta);
-}
-
 BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
                                          uint64_t first_sector)
 {
diff --git a/block/mirror.c b/block/mirror.c
index 14c34e9..37a8744 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -53,7 +53,7 @@ typedef struct MirrorBlockJob {
     BlockdevOnError on_source_error, on_target_error;
     bool synced;
     bool should_complete;
-    int64_t granularity;
+    uint64_t granularity;
     size_t buf_size;
     int64_t bdev_length;
     unsigned long *cow_bitmap;
@@ -1124,7 +1124,7 @@ static BlockDriver bdrv_mirror_top = {
 static void mirror_start_job(const char *job_id, BlockDriverState *bs,
                              int creation_flags, BlockDriverState *target,
                              const char *replaces, int64_t speed,
-                             uint32_t granularity, int64_t buf_size,
+                             uint64_t granularity, int64_t buf_size,
                              BlockMirrorBackingMode backing_mode,
                              BlockdevOnError on_source_error,
                              BlockdevOnError on_target_error,
@@ -1287,7 +1287,7 @@ fail:
 
 void mirror_start(const char *job_id, BlockDriverState *bs,
                   BlockDriverState *target, const char *replaces,
-                  int64_t speed, uint32_t granularity, int64_t buf_size,
+                  int64_t speed, uint64_t granularity, int64_t buf_size,
                   MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
                   BlockdevOnError on_source_error,
                   BlockdevOnError on_target_error,
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index e8d3bdb..356772c 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -147,11 +147,11 @@ static int check_table_entry(uint64_t entry, int cluster_size)
 
 static int check_constraints_on_bitmap(BlockDriverState *bs,
                                        const char *name,
-                                       uint32_t granularity,
+                                       uint64_t granularity,
                                        Error **errp)
 {
     BDRVQcow2State *s = bs->opaque;
-    int granularity_bits = ctz32(granularity);
+    int granularity_bits = ctz64(granularity);
     int64_t len = bdrv_getlength(bs);
 
     assert(granularity > 0);
@@ -274,10 +274,10 @@ static int free_bitmap_clusters(BlockDriverState *bs, Qcow2BitmapTable *tb)
 static uint64_t sectors_covered_by_bitmap_cluster(const BDRVQcow2State *s,
                                                   const BdrvDirtyBitmap *bitmap)
 {
-    uint32_t sector_granularity =
+    uint64_t sector_granularity =
             bdrv_dirty_bitmap_granularity(bitmap) >> BDRV_SECTOR_BITS;
 
-    return (uint64_t)sector_granularity * (s->cluster_size << 3);
+    return sector_granularity * (s->cluster_size << 3);
 }
 
 /* load_bitmap_data
@@ -342,7 +342,7 @@ static BdrvDirtyBitmap *load_bitmap(BlockDriverState *bs,
 {
     int ret;
     uint64_t *bitmap_table = NULL;
-    uint32_t granularity;
+    uint64_t granularity;
     BdrvDirtyBitmap *bitmap = NULL;
 
     if (bm->flags & BME_FLAG_IN_USE) {
@@ -358,7 +358,7 @@ static BdrvDirtyBitmap *load_bitmap(BlockDriverState *bs,
         goto fail;
     }
 
-    granularity = 1U << bm->granularity_bits;
+    granularity = 1ULL << bm->granularity_bits;
     bitmap = bdrv_create_dirty_bitmap(bs, granularity, bm->name, errp);
     if (bitmap == NULL) {
         goto fail;
@@ -1321,7 +1321,7 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp)
          bitmap = bdrv_dirty_bitmap_next(bs, bitmap))
     {
         const char *name = bdrv_dirty_bitmap_name(bitmap);
-        uint32_t granularity = bdrv_dirty_bitmap_granularity(bitmap);
+        uint64_t granularity = bdrv_dirty_bitmap_granularity(bitmap);
         Qcow2Bitmap *bm;
 
         if (!bdrv_dirty_bitmap_get_persistance(bitmap) ||
@@ -1364,7 +1364,7 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp)
             QSIMPLEQ_INSERT_TAIL(&drop_tables, tb, entry);
         }
         bm->flags = bdrv_dirty_bitmap_get_autoload(bitmap) ? BME_FLAG_AUTO : 0;
-        bm->granularity_bits = ctz32(bdrv_dirty_bitmap_granularity(bitmap));
+        bm->granularity_bits = ctz64(bdrv_dirty_bitmap_granularity(bitmap));
         bm->dirty_bitmap = bitmap;
     }
 
@@ -1436,7 +1436,7 @@ int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp)
 
 bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs,
                                       const char *name,
-                                      uint32_t granularity,
+                                      uint64_t granularity,
                                       Error **errp)
 {
     BDRVQcow2State *s = bs->opaque;
diff --git a/block/qcow2.h b/block/qcow2.h
index 0d7043e..6a7ca09 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -659,7 +659,7 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp);
 int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp);
 bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs,
                                       const char *name,
-                                      uint32_t granularity,
+                                      uint64_t granularity,
                                       Error **errp);
 void qcow2_remove_persistent_dirty_bitmap(BlockDriverState *bs,
                                           const char *name,
diff --git a/blockdev.c b/blockdev.c
index 02cd69b..960c5be 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2708,7 +2708,7 @@ out:
 }
 
 void qmp_block_dirty_bitmap_add(const char *node, const char *name,
-                                bool has_granularity, uint32_t granularity,
+                                bool has_granularity, uint64_t granularity,
                                 bool has_persistent, bool persistent,
                                 bool has_autoload, bool autoload,
                                 Error **errp)
@@ -3401,7 +3401,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
                                    enum MirrorSyncMode sync,
                                    BlockMirrorBackingMode backing_mode,
                                    bool has_speed, int64_t speed,
-                                   bool has_granularity, uint32_t granularity,
+                                   bool has_granularity, uint64_t granularity,
                                    bool has_buf_size, int64_t buf_size,
                                    bool has_on_source_error,
                                    BlockdevOnError on_source_error,
@@ -3617,7 +3617,7 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
                          bool has_replaces, const char *replaces,
                          MirrorSyncMode sync,
                          bool has_speed, int64_t speed,
-                         bool has_granularity, uint32_t granularity,
+                         bool has_granularity, uint64_t granularity,
                          bool has_buf_size, int64_t buf_size,
                          bool has_on_source_error,
                          BlockdevOnError on_source_error,
diff --git a/include/block/block.h b/include/block/block.h
index 34770bb..3a4e980 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -620,6 +620,6 @@ void bdrv_add_child(BlockDriverState *parent, BlockDriverState *child,
 void bdrv_del_child(BlockDriverState *parent, BdrvChild *child, Error **errp);
 
 bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
-                                     uint32_t granularity, Error **errp);
+                                     uint64_t granularity, Error **errp);
 
 #endif
diff --git a/include/block/block_int.h b/include/block/block_int.h
index d4f4ea7..c09076e 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -392,7 +392,7 @@ struct BlockDriver {
     int (*bdrv_reopen_bitmaps_rw)(BlockDriverState *bs, Error **errp);
     bool (*bdrv_can_store_new_dirty_bitmap)(BlockDriverState *bs,
                                             const char *name,
-                                            uint32_t granularity,
+                                            uint64_t granularity,
                                             Error **errp);
     void (*bdrv_remove_persistent_dirty_bitmap)(BlockDriverState *bs,
                                                 const char *name,
@@ -896,7 +896,7 @@ void commit_active_start(const char *job_id, BlockDriverState *bs,
  */
 void mirror_start(const char *job_id, BlockDriverState *bs,
                   BlockDriverState *target, const char *replaces,
-                  int64_t speed, uint32_t granularity, int64_t buf_size,
+                  int64_t speed, uint64_t granularity, int64_t buf_size,
                   MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
                   BlockdevOnError on_source_error,
                   BlockdevOnError on_target_error,
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
index d7e0f61..9058cef 100644
--- a/include/block/dirty-bitmap.h
+++ b/include/block/dirty-bitmap.h
@@ -5,7 +5,7 @@
 #include "qemu/hbitmap.h"
 
 BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
-                                          uint32_t granularity,
+                                          uint64_t granularity,
                                           const char *name,
                                           Error **errp);
 void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
@@ -32,9 +32,8 @@ void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
 void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap);
 void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap);
 BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs);
-uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs);
-uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap);
-uint32_t bdrv_dirty_bitmap_meta_granularity(BdrvDirtyBitmap *bitmap);
+uint64_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs);
+uint64_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap);
 bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap);
 bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap);
 const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap);
diff --git a/qapi/block-core.json b/qapi/block-core.json
index bc8e5b6..1c4a08d 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -418,7 +418,7 @@
 # Since: 1.3
 ##
 { 'struct': 'BlockDirtyInfo',
-  'data': {'*name': 'str', 'count': 'int', 'granularity': 'uint32',
+  'data': {'*name': 'str', 'count': 'int', 'granularity': 'size',
            'status': 'DirtyBitmapStatus'} }
 
 ##
@@ -1532,7 +1532,7 @@
   'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
             '*format': 'str', '*node-name': 'str', '*replaces': 'str',
             'sync': 'MirrorSyncMode', '*mode': 'NewImageMode',
-            '*speed': 'int', '*granularity': 'uint32',
+            '*speed': 'int', '*granularity': 'size',
             '*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
             '*on-target-error': 'BlockdevOnError',
             '*unmap': 'bool' } }
@@ -1571,7 +1571,7 @@
 # Since: 2.4
 ##
 { 'struct': 'BlockDirtyBitmapAdd',
-  'data': { 'node': 'str', 'name': 'str', '*granularity': 'uint32',
+  'data': { 'node': 'str', 'name': 'str', '*granularity': 'size',
             '*persistent': 'bool', '*autoload': 'bool' } }
 
 ##
@@ -1731,7 +1731,7 @@
   'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
             '*replaces': 'str',
             'sync': 'MirrorSyncMode',
-            '*speed': 'int', '*granularity': 'uint32',
+            '*speed': 'int', '*granularity': 'size',
             '*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
             '*on-target-error': 'BlockdevOnError',
             '*filter-node-name': 'str' } }
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 29/56] block: Make BlockDirtyInfo byte count unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (27 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 28/56] block: Widen dirty bitmap granularity to uint64_t for safety Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-08  1:56   ` John Snow
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 30/56] block: Make write thresholds " Markus Armbruster
                   ` (27 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Byte counts should use QAPI type 'size' (uint64_t).  BlockDirtyInfo
member @count is 'int' (int64_t).  bdrv_query_dirty_bitmaps() computes
@count from bdrv_get_dirty_count() in uint64_t, then implicitly
converts to int64_t.  Before the commit before previous, the
conversion was in bdrv_get_dirty_count() instead.

Change member @count to 'size'.

query-block now reports @count values above 2^63-1 correctly instead
of their (negative) two's complement.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 qapi/block-core.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 1c4a08d..60e1b6f 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -418,7 +418,7 @@
 # Since: 1.3
 ##
 { 'struct': 'BlockDirtyInfo',
-  'data': {'*name': 'str', 'count': 'int', 'granularity': 'size',
+  'data': {'*name': 'str', 'count': 'size', 'granularity': 'size',
            'status': 'DirtyBitmapStatus'} }
 
 ##
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 30/56] block: Make write thresholds unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (28 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 29/56] block: Make BlockDirtyInfo byte count unsigned in QAPI/QMP Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 31/56] block: Make throttle byte rates and sizes " Markus Armbruster
                   ` (26 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

File offsets should use QAPI type 'size' (uint64_t).
block-set-write-threshold parameter @write-threshold is 'int'
(int64_t).  qmp_block_set_write_threshold() passes it on to
bdrv_write_threshold_set(), implicitly converting to uint64_t.
BLOCK_WRITE_THRESHOLD parameters @write-threshold, @amount-exceeded
are 'int'.  before_write_notify() gets them from BlockDriverState
member write_threshold_offset and bdrv_write_threshold_exceeded(),
implicitly converting from uint64_t.  BlockDeviceInfo members
@write_threshold is 'int'.  bdrv_block_device_info() gets it from
bdrv_write_threshold_get(), implicitly converting from uint64_t.

Change them all to 'size'.  Drop a redundant initializer while there.

block-set-write-threshold now accepts file offsets between 2^63 and
2^64-1.  It accepts negative values as before, because that's how the
QObject input visitor works for backward compatibility.

There is no matching HMP command.

BLOCK_WRITE_THRESHOLD, query-block and query-named-block-nodes now
report write threshold values above 2^63-1 correctly instead of their
(negative) two's complement.

HMP's info block does not report write thresholds.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/write-threshold.c | 2 +-
 qapi/block-core.json    | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/block/write-threshold.c b/block/write-threshold.c
index 0bd1a01..c4572d9 100644
--- a/block/write-threshold.c
+++ b/block/write-threshold.c
@@ -56,7 +56,7 @@ static int coroutine_fn before_write_notify(NotifierWithReturn *notifier,
 {
     BdrvTrackedRequest *req = opaque;
     BlockDriverState *bs = req->bs;
-    uint64_t amount = 0;
+    uint64_t amount;
 
     amount = bdrv_write_threshold_exceeded(bs, req);
     if (amount > 0) {
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 60e1b6f..9e96590 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -366,7 +366,7 @@
             '*bps_wr_max_length': 'int', '*iops_max_length': 'int',
             '*iops_rd_max_length': 'int', '*iops_wr_max_length': 'int',
             '*iops_size': 'int', '*group': 'str', 'cache': 'BlockdevCacheInfo',
-            'write_threshold': 'int' } }
+            'write_threshold': 'size' } }
 
 ##
 # @BlockDeviceIoStatus:
@@ -3748,8 +3748,8 @@
 ##
 { 'event': 'BLOCK_WRITE_THRESHOLD',
   'data': { 'node-name': 'str',
-            'amount-exceeded': 'uint64',
-            'write-threshold': 'uint64' } }
+            'amount-exceeded': 'size',
+            'write-threshold': 'size' } }
 
 ##
 # @block-set-write-threshold:
@@ -3779,7 +3779,7 @@
 #
 ##
 { 'command': 'block-set-write-threshold',
-  'data': { 'node-name': 'str', 'write-threshold': 'uint64' } }
+  'data': { 'node-name': 'str', 'write-threshold': 'size' } }
 
 ##
 # @x-blockdev-change:
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 31/56] block: Make throttle byte rates and sizes unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (29 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 30/56] block: Make write thresholds " Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-23 13:42   ` [Qemu-devel] [Qemu-block] " Alberto Garcia
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 32/56] hmp: Make block_set_io_throttle's arguments unsigned Markus Armbruster
                   ` (25 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Sizes and byte rates should use QAPI type 'size' (uint64_t).
BlockIOThrottle and BlockDeviceInfo members @bps, @bps_rd, @bps_wr,
@bps_max, @bps_rd_max, @bps_wr_max, @iops_size are 'int' (int64_t).
qmp_block_set_io_throttle() and bdrv_block_device_info() copy @bps,
@bps_rd, @bps_wr to / from LeakyBucket member @avg (implicit
conversion to / from double), @bps_max, @bps_rd_max, @bps_wr_max to /
from LeakyBucket member @max (implicit conversion to / from double),
and @iops_size to / from ThrottleConfig member op_size (implicit
conversion to / from uint64_t).

Change these BlockIOThrottle and BlockDeviceInfo members to 'size'.

block_set_io_throttle now accepts sizes and rates between 2^63 and
2^64-1.  It accepts negative values as before, because that's how the
QObject input visitor works for backward compatibility.

Doing the same for HMP's block_set_io_throttle deserves its own commit
(the next one).

query-block and query-named-block-nodes now report sizes and rates
above 2^63-1 correctly instead of their (negative) two's complement.

So does HMP's "info block".

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 hmp.c                | 12 ++++++------
 qapi/block-core.json | 20 ++++++++++----------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/hmp.c b/hmp.c
index 9bcdcb3..3253674 100644
--- a/hmp.c
+++ b/hmp.c
@@ -468,17 +468,17 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
     if (inserted->bps  || inserted->bps_rd  || inserted->bps_wr  ||
         inserted->iops || inserted->iops_rd || inserted->iops_wr)
     {
-        monitor_printf(mon, "    I/O throttling:   bps=%" PRId64
-                        " bps_rd=%" PRId64  " bps_wr=%" PRId64
-                        " bps_max=%" PRId64
-                        " bps_rd_max=%" PRId64
-                        " bps_wr_max=%" PRId64
+        monitor_printf(mon, "    I/O throttling:   bps=%" PRIu64
+                        " bps_rd=%" PRIu64  " bps_wr=%" PRIu64
+                        " bps_max=%" PRIu64
+                        " bps_rd_max=%" PRIu64
+                        " bps_wr_max=%" PRIu64
                         " iops=%" PRId64 " iops_rd=%" PRId64
                         " iops_wr=%" PRId64
                         " iops_max=%" PRId64
                         " iops_rd_max=%" PRId64
                         " iops_wr_max=%" PRId64
-                        " iops_size=%" PRId64
+                        " iops_size=%" PRIu64
                         " group=%s\n",
                         inserted->bps,
                         inserted->bps_rd,
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 9e96590..1e26cb0 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -356,16 +356,16 @@
             '*backing_file': 'str', 'backing_file_depth': 'int',
             'encrypted': 'bool', 'encryption_key_missing': 'bool',
             'detect_zeroes': 'BlockdevDetectZeroesOptions',
-            'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
+            'bps': 'size', 'bps_rd': 'size', 'bps_wr': 'size',
             'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int',
             'image': 'ImageInfo',
-            '*bps_max': 'int', '*bps_rd_max': 'int',
-            '*bps_wr_max': 'int', '*iops_max': 'int',
+            '*bps_max': 'size', '*bps_rd_max': 'size',
+            '*bps_wr_max': 'size', '*iops_max': 'int',
             '*iops_rd_max': 'int', '*iops_wr_max': 'int',
             '*bps_max_length': 'int', '*bps_rd_max_length': 'int',
             '*bps_wr_max_length': 'int', '*iops_max_length': 'int',
             '*iops_rd_max_length': 'int', '*iops_wr_max_length': 'int',
-            '*iops_size': 'int', '*group': 'str', 'cache': 'BlockdevCacheInfo',
+            '*iops_size': 'size', '*group': 'str', 'cache': 'BlockdevCacheInfo',
             'write_threshold': 'size' } }
 
 ##
@@ -1866,15 +1866,15 @@
 # Since: 1.1
 ##
 { 'struct': 'BlockIOThrottle',
-  'data': { '*device': 'str', '*id': 'str', 'bps': 'int', 'bps_rd': 'int',
-            'bps_wr': 'int', 'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int',
-            '*bps_max': 'int', '*bps_rd_max': 'int',
-            '*bps_wr_max': 'int', '*iops_max': 'int',
-            '*iops_rd_max': 'int', '*iops_wr_max': 'int',
+  'data': { '*device': 'str', '*id': 'str',
+            'bps': 'size', 'bps_rd': 'size', 'bps_wr': 'size',
+            'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int',
+            '*bps_max': 'size', '*bps_rd_max': 'size', '*bps_wr_max': 'size',
+            '*iops_max': 'int', '*iops_rd_max': 'int', '*iops_wr_max': 'int',
             '*bps_max_length': 'int', '*bps_rd_max_length': 'int',
             '*bps_wr_max_length': 'int', '*iops_max_length': 'int',
             '*iops_rd_max_length': 'int', '*iops_wr_max_length': 'int',
-            '*iops_size': 'int', '*group': 'str' } }
+            '*iops_size': 'size', '*group': 'str' } }
 
 ##
 # @block-stream:
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 32/56] hmp: Make block_set_io_throttle's arguments unsigned
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (30 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 31/56] block: Make throttle byte rates and sizes " Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-08 15:34   ` Dr. David Alan Gilbert
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 33/56] block: Make block_resize size unsigned in QAPI/QMP Markus Armbruster
                   ` (24 subsequent siblings)
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

The previous commit made them unsigned in QMP.  Switch HMP's args_type
from 'l' to 'o'.  Loses support for expressions (QEMU pocket
calculator), gains support for unit suffixes.  Negative values are no
longer accepted and interpreted modulo 2^64.  Instead, values between
2^63 and 2^64-1 are now accepted.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 hmp-commands.hx | 2 +-
 hmp.c           | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 46ce79c..bc3c066 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1668,7 +1668,7 @@ ETEXI
 
     {
         .name       = "block_set_io_throttle",
-        .args_type  = "device:B,bps:l,bps_rd:l,bps_wr:l,iops:l,iops_rd:l,iops_wr:l",
+        .args_type  = "device:B,bps:o,bps_rd:o,bps_wr:o,iops:l,iops_rd:l,iops_wr:l",
         .params     = "device bps bps_rd bps_wr iops iops_rd iops_wr",
         .help       = "change I/O throttle limits for a block drive",
         .cmd        = hmp_block_set_io_throttle,
diff --git a/hmp.c b/hmp.c
index 3253674..599e816 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1764,9 +1764,9 @@ void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
     BlockIOThrottle throttle = {
         .has_device = true,
         .device = (char *) qdict_get_str(qdict, "device"),
-        .bps = qdict_get_int(qdict, "bps"),
-        .bps_rd = qdict_get_int(qdict, "bps_rd"),
-        .bps_wr = qdict_get_int(qdict, "bps_wr"),
+        .bps = qdict_get_uint(qdict, "bps"),
+        .bps_rd = qdict_get_uint(qdict, "bps_rd"),
+        .bps_wr = qdict_get_uint(qdict, "bps_wr"),
         .iops = qdict_get_int(qdict, "iops"),
         .iops_rd = qdict_get_int(qdict, "iops_rd"),
         .iops_wr = qdict_get_int(qdict, "iops_wr"),
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 33/56] block: Make block_resize size unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (31 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 32/56] hmp: Make block_set_io_throttle's arguments unsigned Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 34/56] block: Make BlockDeviceStats sizes, offsets " Markus Armbruster
                   ` (23 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Sizes should use QAPI type 'size' (uint64_t).  block_resize parameter
@size is 'int' (int64_t).  qmp_block_resize() ensures it's
non-negative before it passes it on to blk_truncate().

Change parameter @size to 'size', and update the range check
accordingly.  Just cleanup; block_resize accepts the same size values
as before.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 blockdev.c           | 7 ++++---
 qapi/block-core.json | 2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 960c5be..98dbe51 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2916,7 +2916,7 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict)
 
 void qmp_block_resize(bool has_device, const char *device,
                       bool has_node_name, const char *node_name,
-                      int64_t size, Error **errp)
+                      uint64_t size, Error **errp)
 {
     Error *local_err = NULL;
     BlockBackend *blk = NULL;
@@ -2940,8 +2940,9 @@ void qmp_block_resize(bool has_device, const char *device,
         goto out;
     }
 
-    if (size < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "size", "a >0 size");
+    if (size > INT64_MAX) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "size",
+                   "a size less than 8EiB");
         goto out;
     }
 
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 1e26cb0..2e0d53c 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1009,7 +1009,7 @@
 ##
 { 'command': 'block_resize', 'data': { '*device': 'str',
                                        '*node-name': 'str',
-                                       'size': 'int' }}
+                                       'size': 'size' }}
 
 ##
 # @NewImageMode:
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 34/56] block: Make BlockDeviceStats sizes, offsets unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (32 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 33/56] block: Make block_resize size unsigned in QAPI/QMP Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 35/56] blockjob: Lift speed sign conversion into block_job_set_speed() Markus Armbruster
                   ` (22 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Byte counts and file offsets should use QAPI type 'size' (uint64_t).
BlockDeviceStats members @rd_bytes, @wr_bytes and @wr_highest_offset
are 'int' (int64_t).  bdrv_query_blk_stats() gets them from
BlockAcctStats member nr_bytes[] and stat64_get(), implicitly
converting from uint64_t.

Change all three to 'size'.

query-blockstats now report byte counts and file offsets above 2^63-1
correctly instead of their (negative) two's complement.

So does HMP's "info blockstats".

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 hmp.c                | 4 ++--
 qapi/block-core.json | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hmp.c b/hmp.c
index 599e816..ecacb7f 100644
--- a/hmp.c
+++ b/hmp.c
@@ -577,8 +577,8 @@ void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
         }
 
         monitor_printf(mon, "%s:", stats->value->device);
-        monitor_printf(mon, " rd_bytes=%" PRId64
-                       " wr_bytes=%" PRId64
+        monitor_printf(mon, " rd_bytes=%" PRIu64
+                       " wr_bytes=%" PRIu64
                        " rd_operations=%" PRId64
                        " wr_operations=%" PRId64
                        " flush_operations=%" PRId64
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 2e0d53c..1d68669 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -704,10 +704,10 @@
 # Since: 0.14.0
 ##
 { 'struct': 'BlockDeviceStats',
-  'data': {'rd_bytes': 'int', 'wr_bytes': 'int', 'rd_operations': 'int',
+  'data': {'rd_bytes': 'size', 'wr_bytes': 'size', 'rd_operations': 'int',
            'wr_operations': 'int', 'flush_operations': 'int',
            'flush_total_time_ns': 'int', 'wr_total_time_ns': 'int',
-           'rd_total_time_ns': 'int', 'wr_highest_offset': 'int',
+           'rd_total_time_ns': 'int', 'wr_highest_offset': 'size',
            'rd_merged': 'int', 'wr_merged': 'int', '*idle_time_ns': 'int',
            'failed_rd_operations': 'int', 'failed_wr_operations': 'int',
            'failed_flush_operations': 'int', 'invalid_rd_operations': 'int',
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 35/56] blockjob: Lift speed sign conversion into block_job_set_speed()
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (33 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 34/56] block: Make BlockDeviceStats sizes, offsets " Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 36/56] blockjob: Drop unused parameter @errp of method set_speed() Markus Armbruster
                   ` (21 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

The BlockJob abstraction takes int64_t speed.  The underlying
RateLimit abstraction takes uint64_t.  We convert from int64_t to
uint64_t in the BlockJobDriver speed_set() methods.  They all reject
negative speed.

Lift this check and conversion up into the method's caller
block_job_set_speed().  I'm going to lift it further until it falls
off the top.

Improve the error message while there.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/backup.c               | 6 +-----
 block/commit.c               | 6 +-----
 block/mirror.c               | 6 +-----
 block/stream.c               | 6 +-----
 blockjob.c                   | 7 +++++++
 include/block/blockjob.h     | 2 +-
 include/block/blockjob_int.h | 2 +-
 7 files changed, 13 insertions(+), 22 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index a37c944..b76143d 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -188,14 +188,10 @@ static int coroutine_fn backup_before_write_notify(
     return backup_do_cow(job, req->offset, req->bytes, NULL, true);
 }
 
-static void backup_set_speed(BlockJob *job, int64_t speed, Error **errp)
+static void backup_set_speed(BlockJob *job, uint64_t speed, Error **errp)
 {
     BackupBlockJob *s = container_of(job, BackupBlockJob, common);
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER, "speed");
-        return;
-    }
     ratelimit_set_speed(&s->limit, speed, SLICE_TIME);
 }
 
diff --git a/block/commit.c b/block/commit.c
index c7857c3..5dc1c73 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -220,14 +220,10 @@ out:
     block_job_defer_to_main_loop(&s->common, commit_complete, data);
 }
 
-static void commit_set_speed(BlockJob *job, int64_t speed, Error **errp)
+static void commit_set_speed(BlockJob *job, uint64_t speed, Error **errp)
 {
     CommitBlockJob *s = container_of(job, CommitBlockJob, common);
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER, "speed");
-        return;
-    }
     ratelimit_set_speed(&s->limit, speed, SLICE_TIME);
 }
 
diff --git a/block/mirror.c b/block/mirror.c
index 37a8744..7959a7f 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -928,14 +928,10 @@ immediate_exit:
     block_job_defer_to_main_loop(&s->common, mirror_exit, data);
 }
 
-static void mirror_set_speed(BlockJob *job, int64_t speed, Error **errp)
+static void mirror_set_speed(BlockJob *job, uint64_t speed, Error **errp)
 {
     MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER, "speed");
-        return;
-    }
     ratelimit_set_speed(&s->limit, speed, SLICE_TIME);
 }
 
diff --git a/block/stream.c b/block/stream.c
index e6f7234..11b6673 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -207,14 +207,10 @@ out:
     block_job_defer_to_main_loop(&s->common, stream_complete, data);
 }
 
-static void stream_set_speed(BlockJob *job, int64_t speed, Error **errp)
+static void stream_set_speed(BlockJob *job, uint64_t speed, Error **errp)
 {
     StreamBlockJob *s = container_of(job, StreamBlockJob, common);
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER, "speed");
-        return;
-    }
     ratelimit_set_speed(&s->limit, speed, SLICE_TIME);
 }
 
diff --git a/blockjob.c b/blockjob.c
index 70a7818..7f77b7e 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -460,6 +460,13 @@ void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
         error_setg(errp, QERR_UNSUPPORTED);
         return;
     }
+
+    if (speed < 0) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
+                   "a non-negative rate limit");
+        return;
+    }
+
     job->driver->set_speed(job, speed, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index 67c0968..bf5314b 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -110,7 +110,7 @@ typedef struct BlockJob {
     int64_t len;
 
     /** Speed that was set with @block_job_set_speed.  */
-    int64_t speed;
+    uint64_t speed;
 
     /** The completion function that will be called when the job completes.  */
     BlockCompletionFunc *cb;
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
index f13ad05..2d10794 100644
--- a/include/block/blockjob_int.h
+++ b/include/block/blockjob_int.h
@@ -42,7 +42,7 @@ struct BlockJobDriver {
     BlockJobType job_type;
 
     /** Optional callback for job types that support setting a speed limit */
-    void (*set_speed)(BlockJob *job, int64_t speed, Error **errp);
+    void (*set_speed)(BlockJob *job, uint64_t speed, Error **errp);
 
     /** Mandatory: Entrypoint for the Coroutine. */
     CoroutineEntry *start;
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 36/56] blockjob: Drop unused parameter @errp of method set_speed()
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (34 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 35/56] blockjob: Lift speed sign conversion into block_job_set_speed() Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 37/56] blockjob: Make BlockJobInfo and event speed unsigned in QAPI/QMP Markus Armbruster
                   ` (20 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/backup.c               | 2 +-
 block/commit.c               | 2 +-
 block/mirror.c               | 2 +-
 block/stream.c               | 2 +-
 blockjob.c                   | 9 +--------
 include/block/blockjob_int.h | 2 +-
 6 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index b76143d..359e526 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -188,7 +188,7 @@ static int coroutine_fn backup_before_write_notify(
     return backup_do_cow(job, req->offset, req->bytes, NULL, true);
 }
 
-static void backup_set_speed(BlockJob *job, uint64_t speed, Error **errp)
+static void backup_set_speed(BlockJob *job, uint64_t speed)
 {
     BackupBlockJob *s = container_of(job, BackupBlockJob, common);
 
diff --git a/block/commit.c b/block/commit.c
index 5dc1c73..ae9191d 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -220,7 +220,7 @@ out:
     block_job_defer_to_main_loop(&s->common, commit_complete, data);
 }
 
-static void commit_set_speed(BlockJob *job, uint64_t speed, Error **errp)
+static void commit_set_speed(BlockJob *job, uint64_t speed)
 {
     CommitBlockJob *s = container_of(job, CommitBlockJob, common);
 
diff --git a/block/mirror.c b/block/mirror.c
index 7959a7f..6c3b446 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -928,7 +928,7 @@ immediate_exit:
     block_job_defer_to_main_loop(&s->common, mirror_exit, data);
 }
 
-static void mirror_set_speed(BlockJob *job, uint64_t speed, Error **errp)
+static void mirror_set_speed(BlockJob *job, uint64_t speed)
 {
     MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
 
diff --git a/block/stream.c b/block/stream.c
index 11b6673..9a145f2 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -207,7 +207,7 @@ out:
     block_job_defer_to_main_loop(&s->common, stream_complete, data);
 }
 
-static void stream_set_speed(BlockJob *job, uint64_t speed, Error **errp)
+static void stream_set_speed(BlockJob *job, uint64_t speed)
 {
     StreamBlockJob *s = container_of(job, StreamBlockJob, common);
 
diff --git a/blockjob.c b/blockjob.c
index 7f77b7e..e653eef 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -454,8 +454,6 @@ static void block_job_completed_txn_success(BlockJob *job)
 
 void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
 {
-    Error *local_err = NULL;
-
     if (!job->driver->set_speed) {
         error_setg(errp, QERR_UNSUPPORTED);
         return;
@@ -467,12 +465,7 @@ void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
         return;
     }
 
-    job->driver->set_speed(job, speed, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
+    job->driver->set_speed(job, speed);
     job->speed = speed;
 }
 
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
index 2d10794..dadfd8c 100644
--- a/include/block/blockjob_int.h
+++ b/include/block/blockjob_int.h
@@ -42,7 +42,7 @@ struct BlockJobDriver {
     BlockJobType job_type;
 
     /** Optional callback for job types that support setting a speed limit */
-    void (*set_speed)(BlockJob *job, uint64_t speed, Error **errp);
+    void (*set_speed)(BlockJob *job, uint64_t speed);
 
     /** Mandatory: Entrypoint for the Coroutine. */
     CoroutineEntry *start;
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 37/56] blockjob: Make BlockJobInfo and event speed unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (35 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 36/56] blockjob: Drop unused parameter @errp of method set_speed() Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 38/56] blockjob: Lift speed sign conversion out of block_job_set_speed() Markus Armbruster
                   ` (19 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Byte rates should use QAPI type 'size' (uint64_t).  BlockJobInfo
member @speed and parameter @speed of events BLOCK_JOB_COMPLETED,
BLOCK_JOB_CANCELLED, BLOCK_JOB_READY are 'int' (int64_t).

block_job_query(), block_job_event_completed(),
block_job_event_cancelled(), block_job_event_ready() all get it from
BlockJob member @speed, implicitly converting from uint64_t (since the
commit before previous).  The conversion is safe, because
block_job_set_speed() won't set speeds above INT_MAX.

Change the BlockJobInfo member and the event parameters to 'size', for
QAPI/QMP consistency.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 hmp.c                | 4 ++--
 qapi/block-core.json | 9 +++++----
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/hmp.c b/hmp.c
index ecacb7f..fae974e 100644
--- a/hmp.c
+++ b/hmp.c
@@ -967,7 +967,7 @@ void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
     while (list) {
         if (strcmp(list->value->type, "stream") == 0) {
             monitor_printf(mon, "Streaming device %s: Completed %" PRId64
-                           " of %" PRId64 " bytes, speed limit %" PRId64
+                           " of %" PRId64 " bytes, speed limit %" PRIu64
                            " bytes/s\n",
                            list->value->device,
                            list->value->offset,
@@ -975,7 +975,7 @@ void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
                            list->value->speed);
         } else {
             monitor_printf(mon, "Type %s, device %s: Completed %" PRId64
-                           " of %" PRId64 " bytes, speed limit %" PRId64
+                           " of %" PRId64 " bytes, speed limit %" PRIu64
                            " bytes/s\n",
                            list->value->type,
                            list->value->device,
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 1d68669..ceaab43 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -956,7 +956,8 @@
 ##
 { 'struct': 'BlockJobInfo',
   'data': {'type': 'str', 'device': 'str', 'len': 'int',
-           'offset': 'int', 'busy': 'bool', 'paused': 'bool', 'speed': 'int',
+           'offset': 'int', 'busy': 'bool', 'paused': 'bool',
+           'speed': 'size',
            'io-status': 'BlockDeviceIoStatus', 'ready': 'bool'} }
 
 ##
@@ -3607,7 +3608,7 @@
             'device': 'str',
             'len'   : 'int',
             'offset': 'int',
-            'speed' : 'int',
+            'speed' : 'size',
             '*error': 'str' } }
 
 ##
@@ -3643,7 +3644,7 @@
             'device': 'str',
             'len'   : 'int',
             'offset': 'int',
-            'speed' : 'int' } }
+            'speed' : 'size' } }
 
 ##
 # @BLOCK_JOB_ERROR:
@@ -3708,7 +3709,7 @@
             'device': 'str',
             'len'   : 'int',
             'offset': 'int',
-            'speed' : 'int' } }
+            'speed' : 'size' } }
 
 ##
 # @PreallocMode:
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 38/56] blockjob: Lift speed sign conversion out of block_job_set_speed()
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (36 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 37/56] blockjob: Make BlockJobInfo and event speed unsigned in QAPI/QMP Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 39/56] blockjob: Lift speed sign conversion out of block_job_create() Markus Armbruster
                   ` (18 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

The BlockJob abstraction takes int64_t speed.  The underlying
RateLimit abstraction takes uint64_t.  We convert from int64_t to
uint64_t in block_job_set_speed().  It rejects negative speed.

Lift this check and conversion up into its callers
qmp_block_job_set_speed() and block_job_create().  I'm going to lift
it further until it falls off the top.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 blockdev.c               |  6 ++++++
 blockjob.c               | 14 +++++++-------
 include/block/blockjob.h |  2 +-
 3 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 98dbe51..f9afc32 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3697,6 +3697,12 @@ void qmp_block_job_set_speed(const char *device, int64_t speed, Error **errp)
         return;
     }
 
+    if (speed < 0) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
+                   "a non-negative rate limit");
+        return;
+    }
+
     block_job_set_speed(job, speed, errp);
     aio_context_release(aio_context);
 }
diff --git a/blockjob.c b/blockjob.c
index e653eef..998ffef 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -452,19 +452,13 @@ static void block_job_completed_txn_success(BlockJob *job)
     }
 }
 
-void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
+void block_job_set_speed(BlockJob *job, uint64_t speed, Error **errp)
 {
     if (!job->driver->set_speed) {
         error_setg(errp, QERR_UNSUPPORTED);
         return;
     }
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
-                   "a non-negative rate limit");
-        return;
-    }
-
     job->driver->set_speed(job, speed);
     job->speed = speed;
 }
@@ -647,6 +641,12 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
         }
     }
 
+    if (speed < 0) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
+                   "a non-negative rate limit");
+        return NULL;
+    }
+
     blk = blk_new(perm, shared_perm);
     ret = blk_insert_bs(blk, bs, errp);
     if (ret < 0) {
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index bf5314b..5eb1537 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -198,7 +198,7 @@ void block_job_remove_all_bdrv(BlockJob *job);
  * Set a rate-limiting parameter for the job; the actual meaning may
  * vary depending on the job type.
  */
-void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp);
+void block_job_set_speed(BlockJob *job, uint64_t speed, Error **errp);
 
 /**
  * block_job_start:
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 39/56] blockjob: Lift speed sign conversion out of block_job_create()
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (37 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 38/56] blockjob: Lift speed sign conversion out of block_job_set_speed() Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 40/56] blockjob: Lift speed sign conversion out of backup_job_create() Markus Armbruster
                   ` (17 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

block_job_create() takes int64_t speed.  The underlying RateLimit
abstraction takes uint64_t.  block_job_create() converts from int64_t
to uint64_t, rejecting negative speed.

Lift this check and conversion out of block_job_create() into its
callers.  I'm going to lift it further until it falls off the top.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/backup.c               | 5 +++++
 block/commit.c               | 6 ++++++
 block/mirror.c               | 6 ++++++
 block/stream.c               | 6 ++++++
 blockjob.c                   | 8 +-------
 include/block/blockjob_int.h | 2 +-
 6 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index 359e526..3a97836 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -577,6 +577,11 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
         return NULL;
     }
 
+    if (speed < 0) {
+        error_setg(errp, QERR_INVALID_PARAMETER, "speed");
+        return NULL;
+    }
+
     if (sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
         if (!sync_bitmap) {
             error_setg(errp, "must provide a valid bitmap name for "
diff --git a/block/commit.c b/block/commit.c
index ae9191d..86d780e 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -309,6 +309,12 @@ void commit_start(const char *job_id, BlockDriverState *bs,
         return;
     }
 
+    if (speed < 0) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
+                   "a non-negative rate limit");
+        return;
+    }
+
     s = block_job_create(job_id, &commit_job_driver, bs, 0, BLK_PERM_ALL,
                          speed, BLOCK_JOB_DEFAULT, NULL, NULL, errp);
     if (!s) {
diff --git a/block/mirror.c b/block/mirror.c
index 6c3b446..af54163 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1139,6 +1139,12 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
     Error *local_err = NULL;
     int ret;
 
+    if (speed < 0) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
+                   "a non-negative rate limit");
+        return;
+    }
+
     if (granularity == 0) {
         granularity = bdrv_get_default_bitmap_granularity(target);
     }
diff --git a/block/stream.c b/block/stream.c
index 9a145f2..fefcdb9 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -237,6 +237,12 @@ void stream_start(const char *job_id, BlockDriverState *bs,
         }
     }
 
+    if (speed < 0) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
+                   "a non-negative rate limit");
+        return;
+    }
+
     /* Prevent concurrent jobs trying to modify the graph structure here, we
      * already have our own plans. Also don't allow resize as the image size is
      * queried only at the job start and then cached. */
diff --git a/blockjob.c b/blockjob.c
index 998ffef..335099e 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -604,7 +604,7 @@ static void block_job_event_completed(BlockJob *job, const char *msg)
 
 void *block_job_create(const char *job_id, const BlockJobDriver *driver,
                        BlockDriverState *bs, uint64_t perm,
-                       uint64_t shared_perm, int64_t speed, int flags,
+                       uint64_t shared_perm, uint64_t speed, int flags,
                        BlockCompletionFunc *cb, void *opaque, Error **errp)
 {
     BlockBackend *blk;
@@ -641,12 +641,6 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
         }
     }
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
-                   "a non-negative rate limit");
-        return NULL;
-    }
-
     blk = blk_new(perm, shared_perm);
     ret = blk_insert_bs(blk, bs, errp);
     if (ret < 0) {
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
index dadfd8c..33472ba 100644
--- a/include/block/blockjob_int.h
+++ b/include/block/blockjob_int.h
@@ -133,7 +133,7 @@ struct BlockJobDriver {
  */
 void *block_job_create(const char *job_id, const BlockJobDriver *driver,
                        BlockDriverState *bs, uint64_t perm,
-                       uint64_t shared_perm, int64_t speed, int flags,
+                       uint64_t shared_perm, uint64_t speed, int flags,
                        BlockCompletionFunc *cb, void *opaque, Error **errp);
 
 /**
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 40/56] blockjob: Lift speed sign conversion out of backup_job_create()
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (38 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 39/56] blockjob: Lift speed sign conversion out of block_job_create() Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 41/56] blockjob: Lift speed sign conversion out of mirror_start_job() Markus Armbruster
                   ` (16 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

backup_job_create() takes int64_t speed.  The underlying BlockJob
abstraction takes uint64_t.  backup_job_create() converts from int64_t
to uint64_t, rejecting negative speed.

Lift this check and conversion out of backup_job_create() into its
callers.  I'm going to lift it further until it falls off the top.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/backup.c            |  7 +------
 blockdev.c                | 12 ++++++++++++
 include/block/block_int.h |  2 +-
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index 3a97836..eddc17a 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -529,7 +529,7 @@ static const BlockJobDriver backup_job_driver = {
 };
 
 BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
-                  BlockDriverState *target, int64_t speed,
+                  BlockDriverState *target, uint64_t speed,
                   MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
                   bool compress,
                   BlockdevOnError on_source_error,
@@ -577,11 +577,6 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
         return NULL;
     }
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER, "speed");
-        return NULL;
-    }
-
     if (sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
         if (!sync_bitmap) {
             error_setg(errp, "must provide a valid bitmap name for "
diff --git a/blockdev.c b/blockdev.c
index f9afc32..1deea49 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3210,6 +3210,12 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
         return NULL;
     }
 
+    if (backup->speed < 0) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
+                   "a non-negative rate limit");
+        return NULL;
+    }
+
     aio_context = bdrv_get_aio_context(bs);
     aio_context_acquire(aio_context);
 
@@ -3353,6 +3359,12 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
         return NULL;
     }
 
+    if (backup->speed < 0) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
+                   "a non-negative rate limit");
+        return NULL;
+    }
+
     aio_context = bdrv_get_aio_context(bs);
     aio_context_acquire(aio_context);
 
diff --git a/include/block/block_int.h b/include/block/block_int.h
index c09076e..19639c0 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -923,7 +923,7 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
  * until the job is cancelled or manually completed.
  */
 BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
-                            BlockDriverState *target, int64_t speed,
+                            BlockDriverState *target, uint64_t speed,
                             MirrorSyncMode sync_mode,
                             BdrvDirtyBitmap *sync_bitmap,
                             bool compress,
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 41/56] blockjob: Lift speed sign conversion out of mirror_start_job()
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (39 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 40/56] blockjob: Lift speed sign conversion out of backup_job_create() Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 42/56] blockjob: Lift speed sign conversion out of stream_start() Markus Armbruster
                   ` (15 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

mirror_start_job() takes int64_t speed.  The underlying BlockJob
abstraction takes uint64_t.  mirror_start_job() converts from int64_t
to uint64_t, rejecting negative speed.

Lift this check and conversion out of mirror_start_job() into its
callers.  I'm going to lift it further until it falls off the top.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/mirror.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/block/mirror.c b/block/mirror.c
index af54163..27b4c7f 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1119,7 +1119,7 @@ static BlockDriver bdrv_mirror_top = {
 
 static void mirror_start_job(const char *job_id, BlockDriverState *bs,
                              int creation_flags, BlockDriverState *target,
-                             const char *replaces, int64_t speed,
+                             const char *replaces, uint64_t speed,
                              uint64_t granularity, int64_t buf_size,
                              BlockMirrorBackingMode backing_mode,
                              BlockdevOnError on_source_error,
@@ -1139,12 +1139,6 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
     Error *local_err = NULL;
     int ret;
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
-                   "a non-negative rate limit");
-        return;
-    }
-
     if (granularity == 0) {
         granularity = bdrv_get_default_bitmap_granularity(target);
     }
@@ -1298,6 +1292,11 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
     bool is_none_mode;
     BlockDriverState *base;
 
+    if (speed < 0) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
+                   "a non-negative rate limit");
+        return;
+    }
     if (mode == MIRROR_SYNC_MODE_INCREMENTAL) {
         error_setg(errp, "Sync mode 'incremental' not supported");
         return;
@@ -1323,6 +1322,12 @@ void commit_active_start(const char *job_id, BlockDriverState *bs,
 
     orig_base_flags = bdrv_get_flags(base);
 
+    if (speed < 0) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
+                   "a non-negative rate limit");
+        return;
+    }
+
     if (bdrv_reopen(base, bs->open_flags, errp)) {
         return;
     }
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 42/56] blockjob: Lift speed sign conversion out of stream_start()
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (40 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 41/56] blockjob: Lift speed sign conversion out of mirror_start_job() Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 43/56] blockjob: Lift speed sign conversion out of mirror_start() Markus Armbruster
                   ` (14 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

stream_start() takes int64_t speed.  The underlying BlockJob
abstraction takes uint64_t.  stream_start() converts from int64_t to
uint64_t, rejecting negative speed.

Lift this check and conversion out of stream_start() into its caller.
I'm going to lift it further until it falls off the top.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/stream.c            | 8 +-------
 blockdev.c                | 6 ++++++
 include/block/block_int.h | 2 +-
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/block/stream.c b/block/stream.c
index fefcdb9..16acb1e 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -223,7 +223,7 @@ static const BlockJobDriver stream_job_driver = {
 
 void stream_start(const char *job_id, BlockDriverState *bs,
                   BlockDriverState *base, const char *backing_file_str,
-                  int64_t speed, BlockdevOnError on_error, Error **errp)
+                  uint64_t speed, BlockdevOnError on_error, Error **errp)
 {
     StreamBlockJob *s;
     BlockDriverState *iter;
@@ -237,12 +237,6 @@ void stream_start(const char *job_id, BlockDriverState *bs,
         }
     }
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
-                   "a non-negative rate limit");
-        return;
-    }
-
     /* Prevent concurrent jobs trying to modify the graph structure here, we
      * already have our own plans. Also don't allow resize as the image size is
      * queried only at the job start and then cached. */
diff --git a/blockdev.c b/blockdev.c
index 1deea49..4d9a665 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2989,6 +2989,12 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device,
         return;
     }
 
+    if (speed < 0) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
+                   "a non-negative rate limit");
+        return;
+    }
+
     aio_context = bdrv_get_aio_context(bs);
     aio_context_acquire(aio_context);
 
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 19639c0..695d7b3 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -821,7 +821,7 @@ int is_windows_drive(const char *filename);
  */
 void stream_start(const char *job_id, BlockDriverState *bs,
                   BlockDriverState *base, const char *backing_file_str,
-                  int64_t speed, BlockdevOnError on_error, Error **errp);
+                  uint64_t speed, BlockdevOnError on_error, Error **errp);
 
 /**
  * commit_start:
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 43/56] blockjob: Lift speed sign conversion out of mirror_start()
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (41 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 42/56] blockjob: Lift speed sign conversion out of stream_start() Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 44/56] blockjob: Lift speed sign conversion out of blockdev_mirror_common() Markus Armbruster
                   ` (13 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

mirror_start() takes int64_t speed.  The underlying BlockJob
abstraction takes uint64_t.  mirror_start() converts from int64_t to
uint64_t, rejecting negative speed.

Lift this check and conversion out of mirror_start() into its caller.
I'm going to lift it further until it falls off the top.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/mirror.c            | 7 +------
 blockdev.c                | 5 +++++
 include/block/block_int.h | 2 +-
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/block/mirror.c b/block/mirror.c
index 27b4c7f..af0c989 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1283,7 +1283,7 @@ fail:
 
 void mirror_start(const char *job_id, BlockDriverState *bs,
                   BlockDriverState *target, const char *replaces,
-                  int64_t speed, uint64_t granularity, int64_t buf_size,
+                  uint64_t speed, uint64_t granularity, int64_t buf_size,
                   MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
                   BlockdevOnError on_source_error,
                   BlockdevOnError on_target_error,
@@ -1292,11 +1292,6 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
     bool is_none_mode;
     BlockDriverState *base;
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
-                   "a non-negative rate limit");
-        return;
-    }
     if (mode == MIRROR_SYNC_MODE_INCREMENTAL) {
         error_setg(errp, "Sync mode 'incremental' not supported");
         return;
diff --git a/blockdev.c b/blockdev.c
index 4d9a665..06f87e3 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3454,6 +3454,11 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
         filter_node_name = NULL;
     }
 
+    if (speed < 0) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
+                   "a non-negative rate limit");
+        return;
+    }
     if (granularity != 0 && (granularity < 512 || granularity > 1048576 * 64)) {
         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "granularity",
                    "a value in range [512B, 64MB]");
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 695d7b3..3ff5536 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -896,7 +896,7 @@ void commit_active_start(const char *job_id, BlockDriverState *bs,
  */
 void mirror_start(const char *job_id, BlockDriverState *bs,
                   BlockDriverState *target, const char *replaces,
-                  int64_t speed, uint64_t granularity, int64_t buf_size,
+                  uint64_t speed, uint64_t granularity, int64_t buf_size,
                   MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
                   BlockdevOnError on_source_error,
                   BlockdevOnError on_target_error,
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 44/56] blockjob: Lift speed sign conversion out of blockdev_mirror_common()
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (42 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 43/56] blockjob: Lift speed sign conversion out of mirror_start() Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 45/56] blockjob: Lift speed sign conversion out of commit_start() etc Markus Armbruster
                   ` (12 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

blockdev_mirror_common() takes int64_t speed.  The underlying BlockJob
abstraction takes uint64_t.  blockdev_mirror_common() converts from
int64_t to uint64_t, rejecting negative speed.

Lift this check and conversion out of blockdev_mirror_common() into
its callers.  I'm going to lift it further until it falls off the top.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 blockdev.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 06f87e3..13df88b 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3419,7 +3419,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
                                    bool has_replaces, const char *replaces,
                                    enum MirrorSyncMode sync,
                                    BlockMirrorBackingMode backing_mode,
-                                   bool has_speed, int64_t speed,
+                                   bool has_speed, uint64_t speed,
                                    bool has_granularity, uint64_t granularity,
                                    bool has_buf_size, int64_t buf_size,
                                    bool has_on_source_error,
@@ -3454,11 +3454,6 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
         filter_node_name = NULL;
     }
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
-                   "a non-negative rate limit");
-        return;
-    }
     if (granularity != 0 && (granularity < 512 || granularity > 1048576 * 64)) {
         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "granularity",
                    "a value in range [512B, 64MB]");
@@ -3508,6 +3503,12 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
         return;
     }
 
+    if (arg->speed < 0) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
+                   "a non-negative rate limit");
+        return;
+    }
+
     aio_context = bdrv_get_aio_context(bs);
     aio_context_acquire(aio_context);
 
@@ -3667,6 +3668,12 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
         return;
     }
 
+    if (speed < 0) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
+                   "a non-negative rate limit");
+        return;
+    }
+
     aio_context = bdrv_get_aio_context(bs);
     aio_context_acquire(aio_context);
 
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 45/56] blockjob: Lift speed sign conversion out of commit_start() etc.
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (43 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 44/56] blockjob: Lift speed sign conversion out of blockdev_mirror_common() Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 46/56] blockjob: Make job commands' speed parameter unsigned in QAPI/QMP Markus Armbruster
                   ` (11 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

commit_start() takes int64_t speed.  The underlying BlockJob
abstraction takes uint64_t.  commit_start() converts from int64_t to
uint64_t, rejecting negative speed.

Lift this check and conversion out of commit_start() and
commit_active_start() into their caller qmp_block_commit().  I'm going
to lift it further until it falls off the top.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/commit.c            | 9 ++-------
 block/mirror.c            | 8 +-------
 blockdev.c                | 6 ++++++
 include/block/block_int.h | 5 +++--
 4 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/block/commit.c b/block/commit.c
index 86d780e..f61421f 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -282,7 +282,8 @@ static BlockDriver bdrv_commit_top = {
 };
 
 void commit_start(const char *job_id, BlockDriverState *bs,
-                  BlockDriverState *base, BlockDriverState *top, int64_t speed,
+                  BlockDriverState *base, BlockDriverState *top,
+                  uint64_t speed,
                   BlockdevOnError on_error, const char *backing_file_str,
                   const char *filter_node_name, Error **errp)
 {
@@ -309,12 +310,6 @@ void commit_start(const char *job_id, BlockDriverState *bs,
         return;
     }
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
-                   "a non-negative rate limit");
-        return;
-    }
-
     s = block_job_create(job_id, &commit_job_driver, bs, 0, BLK_PERM_ALL,
                          speed, BLOCK_JOB_DEFAULT, NULL, NULL, errp);
     if (!s) {
diff --git a/block/mirror.c b/block/mirror.c
index af0c989..f1adda5 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1307,7 +1307,7 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
 
 void commit_active_start(const char *job_id, BlockDriverState *bs,
                          BlockDriverState *base, int creation_flags,
-                         int64_t speed, BlockdevOnError on_error,
+                         uint64_t speed, BlockdevOnError on_error,
                          const char *filter_node_name,
                          BlockCompletionFunc *cb, void *opaque,
                          bool auto_complete, Error **errp)
@@ -1317,12 +1317,6 @@ void commit_active_start(const char *job_id, BlockDriverState *bs,
 
     orig_base_flags = bdrv_get_flags(base);
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
-                   "a non-negative rate limit");
-        return;
-    }
-
     if (bdrv_reopen(base, bs->open_flags, errp)) {
         return;
     }
diff --git a/blockdev.c b/blockdev.c
index 13df88b..e679f5d 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3102,6 +3102,12 @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device,
         return;
     }
 
+    if (speed < 0) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
+                   "a non-negative rate limit");
+        goto out;
+    }
+
     aio_context = bdrv_get_aio_context(bs);
     aio_context_acquire(aio_context);
 
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 3ff5536..75116e5 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -840,7 +840,8 @@ void stream_start(const char *job_id, BlockDriverState *bs,
  *
  */
 void commit_start(const char *job_id, BlockDriverState *bs,
-                  BlockDriverState *base, BlockDriverState *top, int64_t speed,
+                  BlockDriverState *base, BlockDriverState *top,
+                  uint64_t speed,
                   BlockdevOnError on_error, const char *backing_file_str,
                   const char *filter_node_name, Error **errp);
 /**
@@ -864,7 +865,7 @@ void commit_start(const char *job_id, BlockDriverState *bs,
  */
 void commit_active_start(const char *job_id, BlockDriverState *bs,
                          BlockDriverState *base, int creation_flags,
-                         int64_t speed, BlockdevOnError on_error,
+                         uint64_t speed, BlockdevOnError on_error,
                          const char *filter_node_name,
                          BlockCompletionFunc *cb, void *opaque,
                          bool auto_complete, Error **errp);
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 46/56] blockjob: Make job commands' speed parameter unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (44 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 45/56] blockjob: Lift speed sign conversion out of commit_start() etc Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 47/56] blockjob: Make BlockJobInfo and event offsets " Markus Armbruster
                   ` (10 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Byte rates should use QAPI type 'size' (uint64_t).  drive-backup,
blockdev-backup, block-commit, drive-mirror, blockdev-mirror,
block-stream and block-job-set-speed parameter @size is 'int'
(int64_t).  Their QMP command handlers all ensure it's non-negative
before they pass it on to the next lower layer, which expects
uint64_t.

Change these @speed parameters to 'size', and drop the range checks.
You can now set rate limits between 2^63 and 2^64-1.  Good luck
finding hardware where that actually limits.

Negative values are accepted and interpreted modulo 2^64, because
that's how the QObject input visitor works for backward compatibility.
Drop the tests for negative size.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 blockdev.c                 | 50 ++++------------------------------------------
 qapi/block-core.json       | 14 ++++++-------
 tests/qemu-iotests/030     | 16 ---------------
 tests/qemu-iotests/030.out |  4 ++--
 tests/qemu-iotests/041     | 18 -----------------
 tests/qemu-iotests/041.out |  4 ++--
 tests/qemu-iotests/055     | 26 ------------------------
 tests/qemu-iotests/055.out |  4 ++--
 8 files changed, 17 insertions(+), 119 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index e679f5d..7feed7a 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2970,7 +2970,7 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device,
                       bool has_base, const char *base,
                       bool has_base_node, const char *base_node,
                       bool has_backing_file, const char *backing_file,
-                      bool has_speed, int64_t speed,
+                      bool has_speed, uint64_t speed,
                       bool has_on_error, BlockdevOnError on_error,
                       Error **errp)
 {
@@ -2989,12 +2989,6 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device,
         return;
     }
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
-                   "a non-negative rate limit");
-        return;
-    }
-
     aio_context = bdrv_get_aio_context(bs);
     aio_context_acquire(aio_context);
 
@@ -3063,7 +3057,7 @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device,
                       bool has_base, const char *base,
                       bool has_top, const char *top,
                       bool has_backing_file, const char *backing_file,
-                      bool has_speed, int64_t speed,
+                      bool has_speed, uint64_t speed,
                       bool has_filter_node_name, const char *filter_node_name,
                       Error **errp)
 {
@@ -3102,12 +3096,6 @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device,
         return;
     }
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
-                   "a non-negative rate limit");
-        goto out;
-    }
-
     aio_context = bdrv_get_aio_context(bs);
     aio_context_acquire(aio_context);
 
@@ -3222,12 +3210,6 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
         return NULL;
     }
 
-    if (backup->speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
-                   "a non-negative rate limit");
-        return NULL;
-    }
-
     aio_context = bdrv_get_aio_context(bs);
     aio_context_acquire(aio_context);
 
@@ -3371,12 +3353,6 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
         return NULL;
     }
 
-    if (backup->speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
-                   "a non-negative rate limit");
-        return NULL;
-    }
-
     aio_context = bdrv_get_aio_context(bs);
     aio_context_acquire(aio_context);
 
@@ -3509,12 +3485,6 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
         return;
     }
 
-    if (arg->speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
-                   "a non-negative rate limit");
-        return;
-    }
-
     aio_context = bdrv_get_aio_context(bs);
     aio_context_acquire(aio_context);
 
@@ -3647,7 +3617,7 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
                          const char *device, const char *target,
                          bool has_replaces, const char *replaces,
                          MirrorSyncMode sync,
-                         bool has_speed, int64_t speed,
+                         bool has_speed, uint64_t speed,
                          bool has_granularity, uint64_t granularity,
                          bool has_buf_size, int64_t buf_size,
                          bool has_on_source_error,
@@ -3674,12 +3644,6 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
         return;
     }
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
-                   "a non-negative rate limit");
-        return;
-    }
-
     aio_context = bdrv_get_aio_context(bs);
     aio_context_acquire(aio_context);
 
@@ -3724,7 +3688,7 @@ static BlockJob *find_block_job(const char *id, AioContext **aio_context,
     return job;
 }
 
-void qmp_block_job_set_speed(const char *device, int64_t speed, Error **errp)
+void qmp_block_job_set_speed(const char *device, uint64_t speed, Error **errp)
 {
     AioContext *aio_context;
     BlockJob *job = find_block_job(device, &aio_context, errp);
@@ -3733,12 +3697,6 @@ void qmp_block_job_set_speed(const char *device, int64_t speed, Error **errp)
         return;
     }
 
-    if (speed < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
-                   "a non-negative rate limit");
-        return;
-    }
-
     block_job_set_speed(job, speed, errp);
     aio_context_release(aio_context);
 }
diff --git a/qapi/block-core.json b/qapi/block-core.json
index ceaab43..9e9f2d8 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1117,7 +1117,7 @@
 { 'struct': 'DriveBackup',
   'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
             '*format': 'str', 'sync': 'MirrorSyncMode', '*mode': 'NewImageMode',
-            '*speed': 'int', '*bitmap': 'str', '*compress': 'bool',
+            '*speed': 'size', '*bitmap': 'str', '*compress': 'bool',
             '*on-source-error': 'BlockdevOnError',
             '*on-target-error': 'BlockdevOnError' } }
 
@@ -1158,7 +1158,7 @@
 { 'struct': 'BlockdevBackup',
   'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
             'sync': 'MirrorSyncMode',
-            '*speed': 'int',
+            '*speed': 'size',
             '*compress': 'bool',
             '*on-source-error': 'BlockdevOnError',
             '*on-target-error': 'BlockdevOnError' } }
@@ -1329,7 +1329,7 @@
 ##
 { 'command': 'block-commit',
   'data': { '*job-id': 'str', 'device': 'str', '*base': 'str', '*top': 'str',
-            '*backing-file': 'str', '*speed': 'int',
+            '*backing-file': 'str', '*speed': 'size',
             '*filter-node-name': 'str' } }
 
 ##
@@ -1533,7 +1533,7 @@
   'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
             '*format': 'str', '*node-name': 'str', '*replaces': 'str',
             'sync': 'MirrorSyncMode', '*mode': 'NewImageMode',
-            '*speed': 'int', '*granularity': 'size',
+            '*speed': 'size', '*granularity': 'size',
             '*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
             '*on-target-error': 'BlockdevOnError',
             '*unmap': 'bool' } }
@@ -1732,7 +1732,7 @@
   'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
             '*replaces': 'str',
             'sync': 'MirrorSyncMode',
-            '*speed': 'int', '*granularity': 'size',
+            '*speed': 'size', '*granularity': 'size',
             '*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
             '*on-target-error': 'BlockdevOnError',
             '*filter-node-name': 'str' } }
@@ -1949,7 +1949,7 @@
 ##
 { 'command': 'block-stream',
   'data': { '*job-id': 'str', 'device': 'str', '*base': 'str',
-            '*base-node': 'str', '*backing-file': 'str', '*speed': 'int',
+            '*base-node': 'str', '*backing-file': 'str', '*speed': 'size',
             '*on-error': 'BlockdevOnError' } }
 
 ##
@@ -1974,7 +1974,7 @@
 # Since: 1.1
 ##
 { 'command': 'block-job-set-speed',
-  'data': { 'device': 'str', 'speed': 'int' } }
+  'data': { 'device': 'str', 'speed': 'size' } }
 
 ##
 # @block-job-cancel:
diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
index d745cb4..7fc365b 100755
--- a/tests/qemu-iotests/030
+++ b/tests/qemu-iotests/030
@@ -788,21 +788,5 @@ class TestSetSpeed(iotests.QMPTestCase):
 
         self.cancel_and_wait(resume=True)
 
-    def test_set_speed_invalid(self):
-        self.assert_no_active_block_jobs()
-
-        result = self.vm.qmp('block-stream', device='drive0', speed=-1)
-        self.assert_qmp(result, 'error/class', 'GenericError')
-
-        self.assert_no_active_block_jobs()
-
-        result = self.vm.qmp('block-stream', device='drive0')
-        self.assert_qmp(result, 'return', {})
-
-        result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
-        self.assert_qmp(result, 'error/class', 'GenericError')
-
-        self.cancel_and_wait()
-
 if __name__ == '__main__':
     iotests.main(supported_fmts=['qcow2', 'qed'])
diff --git a/tests/qemu-iotests/030.out b/tests/qemu-iotests/030.out
index 391c857..84bfd63 100644
--- a/tests/qemu-iotests/030.out
+++ b/tests/qemu-iotests/030.out
@@ -1,5 +1,5 @@
-.......................
+......................
 ----------------------------------------------------------------------
-Ran 23 tests
+Ran 22 tests
 
 OK
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
index a860a31..6c2dd50 100755
--- a/tests/qemu-iotests/041
+++ b/tests/qemu-iotests/041
@@ -701,24 +701,6 @@ class TestSetSpeed(iotests.QMPTestCase):
 
         self.wait_ready_and_cancel()
 
-    def test_set_speed_invalid(self):
-        self.assert_no_active_block_jobs()
-
-        result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             target=target_img, speed=-1)
-        self.assert_qmp(result, 'error/class', 'GenericError')
-
-        self.assert_no_active_block_jobs()
-
-        result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             target=target_img)
-        self.assert_qmp(result, 'return', {})
-
-        result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
-        self.assert_qmp(result, 'error/class', 'GenericError')
-
-        self.wait_ready_and_cancel()
-
 class TestUnbackedSource(iotests.QMPTestCase):
     image_len = 2 * 1024 * 1024 # MB
 
diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out
index c28b392..1eb95f3 100644
--- a/tests/qemu-iotests/041.out
+++ b/tests/qemu-iotests/041.out
@@ -1,5 +1,5 @@
-.....................................................................................
+....................................................................................
 ----------------------------------------------------------------------
-Ran 85 tests
+Ran 84 tests
 
 OK
diff --git a/tests/qemu-iotests/055 b/tests/qemu-iotests/055
index e1206ca..c703fbb 100755
--- a/tests/qemu-iotests/055
+++ b/tests/qemu-iotests/055
@@ -220,32 +220,6 @@ class TestSetSpeed(iotests.QMPTestCase):
     def test_set_speed_blockdev_backup(self):
         self.do_test_set_speed('blockdev-backup', 'drive1')
 
-    def do_test_set_speed_invalid(self, cmd, target):
-        self.assert_no_active_block_jobs()
-
-        result = self.vm.qmp(cmd, device='drive0',
-                             target=target, sync='full', speed=-1)
-        self.assert_qmp(result, 'error/class', 'GenericError')
-
-        self.assert_no_active_block_jobs()
-
-        self.vm.pause_drive('drive0')
-        result = self.vm.qmp(cmd, device='drive0',
-                             target=target, sync='full')
-        self.assert_qmp(result, 'return', {})
-
-        result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
-        self.assert_qmp(result, 'error/class', 'GenericError')
-
-        event = self.cancel_and_wait(resume=True)
-        self.assert_qmp(event, 'data/type', 'backup')
-
-    def test_set_speed_invalid_drive_backup(self):
-        self.do_test_set_speed_invalid('drive-backup', target_img)
-
-    def test_set_speed_invalid_blockdev_backup(self):
-        self.do_test_set_speed_invalid('blockdev-backup',  'drive1')
-
 class TestSingleTransaction(iotests.QMPTestCase):
     def setUp(self):
         qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(image_len))
diff --git a/tests/qemu-iotests/055.out b/tests/qemu-iotests/055.out
index 5ce2f9a..af8dac1 100644
--- a/tests/qemu-iotests/055.out
+++ b/tests/qemu-iotests/055.out
@@ -1,5 +1,5 @@
-..............................
+............................
 ----------------------------------------------------------------------
-Ran 30 tests
+Ran 28 tests
 
 OK
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 47/56] blockjob: Make BlockJobInfo and event offsets unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (45 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 46/56] blockjob: Make job commands' speed parameter unsigned in QAPI/QMP Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 48/56] block: Make mirror buffer size " Markus Armbruster
                   ` (9 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

File offsets should use QAPI type 'size' (uint64_t).  BlockJobInfo
members @len, offset and parameters @len, @offset of events
BLOCK_JOB_COMPLETED, BLOCK_JOB_CANCELLED, BLOCK_JOB_READY are 'int'
(int64_t).  block_job_query(), block_job_event_completed(),
block_job_event_cancelled(), block_job_event_ready() get them from
BlockJob members @len and @offset, which are int64_t, but should never
be negative.

Change the BlockJobInfo members and the event parameters to 'size',
for QAPI/QMP consistency.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 hmp.c                |  8 ++++----
 qapi/block-core.json | 16 ++++++++--------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/hmp.c b/hmp.c
index fae974e..867c50b 100644
--- a/hmp.c
+++ b/hmp.c
@@ -966,16 +966,16 @@ void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
 
     while (list) {
         if (strcmp(list->value->type, "stream") == 0) {
-            monitor_printf(mon, "Streaming device %s: Completed %" PRId64
-                           " of %" PRId64 " bytes, speed limit %" PRIu64
+            monitor_printf(mon, "Streaming device %s: Completed %" PRIu64
+                           " of %" PRIu64 " bytes, speed limit %" PRIu64
                            " bytes/s\n",
                            list->value->device,
                            list->value->offset,
                            list->value->len,
                            list->value->speed);
         } else {
-            monitor_printf(mon, "Type %s, device %s: Completed %" PRId64
-                           " of %" PRId64 " bytes, speed limit %" PRIu64
+            monitor_printf(mon, "Type %s, device %s: Completed %" PRIu64
+                           " of %" PRIu64 " bytes, speed limit %" PRIu64
                            " bytes/s\n",
                            list->value->type,
                            list->value->device,
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 9e9f2d8..b8442f3 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -955,8 +955,8 @@
 # Since: 1.1
 ##
 { 'struct': 'BlockJobInfo',
-  'data': {'type': 'str', 'device': 'str', 'len': 'int',
-           'offset': 'int', 'busy': 'bool', 'paused': 'bool',
+  'data': {'type': 'str', 'device': 'str', 'len': 'size',
+           'offset': 'size', 'busy': 'bool', 'paused': 'bool',
            'speed': 'size',
            'io-status': 'BlockDeviceIoStatus', 'ready': 'bool'} }
 
@@ -3606,8 +3606,8 @@
 { 'event': 'BLOCK_JOB_COMPLETED',
   'data': { 'type'  : 'BlockJobType',
             'device': 'str',
-            'len'   : 'int',
-            'offset': 'int',
+            'len'   : 'size',
+            'offset': 'size',
             'speed' : 'size',
             '*error': 'str' } }
 
@@ -3642,8 +3642,8 @@
 { 'event': 'BLOCK_JOB_CANCELLED',
   'data': { 'type'  : 'BlockJobType',
             'device': 'str',
-            'len'   : 'int',
-            'offset': 'int',
+            'len'   : 'size',
+            'offset': 'size',
             'speed' : 'size' } }
 
 ##
@@ -3707,8 +3707,8 @@
 { 'event': 'BLOCK_JOB_READY',
   'data': { 'type'  : 'BlockJobType',
             'device': 'str',
-            'len'   : 'int',
-            'offset': 'int',
+            'len'   : 'size',
+            'offset': 'size',
             'speed' : 'size' } }
 
 ##
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 48/56] block: Make mirror buffer size unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (46 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 47/56] blockjob: Make BlockJobInfo and event offsets " Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 49/56] block: Make ImageCheck file offset unsigned in QAPI Markus Armbruster
                   ` (8 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Byte counts should use QAPI type 'size' (uint64_t).  Parameter
@buf-size of drive-mirror and blockdev-mirror is 'int' (int64_t).  The
underlying MirrorBlockJob abstraction takes size_t.
mirror_start_job() converts from int64_t to size_t, rejecting negative
sizes (but not values exceeding SIZE_MAX).

Change the two parameters to 'size', and lift the (fixed) check and
the conversion into blockdev_mirror_common().

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/mirror.c            | 11 +++--------
 blockdev.c                |  9 +++++++--
 include/block/block_int.h |  2 +-
 qapi/block-core.json      |  4 ++--
 4 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/block/mirror.c b/block/mirror.c
index f1adda5..f9a5416 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -333,7 +333,7 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
     int nb_chunks = 1;
     int sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
     bool write_zeroes_ok = bdrv_can_write_zeroes_with_unmap(blk_bs(s->target));
-    int max_io_bytes = MAX(s->buf_size / MAX_IN_FLIGHT, MAX_IO_BYTES);
+    unsigned max_io_bytes = MAX(s->buf_size / MAX_IN_FLIGHT, MAX_IO_BYTES);
 
     bdrv_dirty_bitmap_lock(s->dirty_bitmap);
     offset = bdrv_dirty_iter_next(s->dbi) * BDRV_SECTOR_SIZE;
@@ -1120,7 +1120,7 @@ static BlockDriver bdrv_mirror_top = {
 static void mirror_start_job(const char *job_id, BlockDriverState *bs,
                              int creation_flags, BlockDriverState *target,
                              const char *replaces, uint64_t speed,
-                             uint64_t granularity, int64_t buf_size,
+                             uint64_t granularity, size_t buf_size,
                              BlockMirrorBackingMode backing_mode,
                              BlockdevOnError on_source_error,
                              BlockdevOnError on_target_error,
@@ -1147,11 +1147,6 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
     /* Granularity must be large enough for sector-based dirty bitmap */
     assert(granularity >= BDRV_SECTOR_SIZE);
 
-    if (buf_size < 0) {
-        error_setg(errp, "Invalid parameter 'buf-size'");
-        return;
-    }
-
     if (buf_size == 0) {
         buf_size = DEFAULT_MIRROR_BUF_SIZE;
     }
@@ -1283,7 +1278,7 @@ fail:
 
 void mirror_start(const char *job_id, BlockDriverState *bs,
                   BlockDriverState *target, const char *replaces,
-                  uint64_t speed, uint64_t granularity, int64_t buf_size,
+                  uint64_t speed, uint64_t granularity, size_t buf_size,
                   MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
                   BlockdevOnError on_source_error,
                   BlockdevOnError on_target_error,
diff --git a/blockdev.c b/blockdev.c
index 7feed7a..ba1a960 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3403,7 +3403,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
                                    BlockMirrorBackingMode backing_mode,
                                    bool has_speed, uint64_t speed,
                                    bool has_granularity, uint64_t granularity,
-                                   bool has_buf_size, int64_t buf_size,
+                                   bool has_buf_size, uint64_t buf_size,
                                    bool has_on_source_error,
                                    BlockdevOnError on_source_error,
                                    bool has_on_target_error,
@@ -3447,6 +3447,11 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
         return;
     }
 
+    if (buf_size > SIZE_MAX) {
+        error_setg(errp, "Parameter 'buf-size' is too large");
+        return;
+    }
+
     if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_MIRROR_SOURCE, errp)) {
         return;
     }
@@ -3619,7 +3624,7 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
                          MirrorSyncMode sync,
                          bool has_speed, uint64_t speed,
                          bool has_granularity, uint64_t granularity,
-                         bool has_buf_size, int64_t buf_size,
+                         bool has_buf_size, uint64_t buf_size,
                          bool has_on_source_error,
                          BlockdevOnError on_source_error,
                          bool has_on_target_error,
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 75116e5..8bde408 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -897,7 +897,7 @@ void commit_active_start(const char *job_id, BlockDriverState *bs,
  */
 void mirror_start(const char *job_id, BlockDriverState *bs,
                   BlockDriverState *target, const char *replaces,
-                  uint64_t speed, uint64_t granularity, int64_t buf_size,
+                  uint64_t speed, uint64_t granularity, size_t buf_size,
                   MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
                   BlockdevOnError on_source_error,
                   BlockdevOnError on_target_error,
diff --git a/qapi/block-core.json b/qapi/block-core.json
index b8442f3..51caee9 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1534,7 +1534,7 @@
             '*format': 'str', '*node-name': 'str', '*replaces': 'str',
             'sync': 'MirrorSyncMode', '*mode': 'NewImageMode',
             '*speed': 'size', '*granularity': 'size',
-            '*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
+            '*buf-size': 'size', '*on-source-error': 'BlockdevOnError',
             '*on-target-error': 'BlockdevOnError',
             '*unmap': 'bool' } }
 
@@ -1733,7 +1733,7 @@
             '*replaces': 'str',
             'sync': 'MirrorSyncMode',
             '*speed': 'size', '*granularity': 'size',
-            '*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
+            '*buf-size': 'size', '*on-source-error': 'BlockdevOnError',
             '*on-target-error': 'BlockdevOnError',
             '*filter-node-name': 'str' } }
 
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 49/56] block: Make ImageCheck file offset unsigned in QAPI
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (47 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 48/56] block: Make mirror buffer size " Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 50/56] block: Make BLOCK_IMAGE_CORRUPTED offset, size unsigned in QAPI/QMP Markus Armbruster
                   ` (7 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

File offsets should use QAPI type 'size' (uint64_t).  ImageCheck
member @image-end-offset is 'int' (int64_t).  collect_image_check()
gets it from BdrvCheckResult member @image_end_offset (also int64_t,
should never be negative).

Change the ImageCheck member to 'size', for QAPI/QMP consistency.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 qapi/block-core.json | 2 +-
 qemu-img.c           | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 51caee9..3c6d448 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -208,7 +208,7 @@
 ##
 { 'struct': 'ImageCheck',
   'data': {'filename': 'str', 'format': 'str', 'check-errors': 'int',
-           '*image-end-offset': 'int', '*corruptions': 'int', '*leaks': 'int',
+           '*image-end-offset': 'size', '*corruptions': 'int', '*leaks': 'int',
            '*corruptions-fixed': 'int', '*leaks-fixed': 'int',
            '*total-clusters': 'int', '*allocated-clusters': 'int',
            '*fragmented-clusters': 'int', '*compressed-clusters': 'int' } }
diff --git a/qemu-img.c b/qemu-img.c
index f4d5f0d..3ae5fe3 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -604,7 +604,7 @@ static void dump_human_image_check(ImageCheck *check, bool quiet)
 
     if (check->image_end_offset) {
         qprintf(quiet,
-                "Image end offset: %" PRId64 "\n", check->image_end_offset);
+                "Image end offset: %" PRIu64 "\n", check->image_end_offset);
     }
 }
 
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 50/56] block: Make BLOCK_IMAGE_CORRUPTED offset, size unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (48 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 49/56] block: Make ImageCheck file offset unsigned in QAPI Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 51/56] block/nfs: Fix for readahead-size, page-cache-size > INT64_MAX Markus Armbruster
                   ` (6 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

File offsets should use QAPI type 'size' (uint64_t).
BLOCK_IMAGE_CORRUPTED parameters @offset and @size are 'int'
(int64_t).  qcow2_signal_corruption() passes non-negative int64_t
values.

Change the event parameters to 'size', for QAPI/QMP consistency.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 qapi/block-core.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 3c6d448..64b84a5 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3520,8 +3520,8 @@
   'data': { 'device'     : 'str',
             '*node-name' : 'str',
             'msg'        : 'str',
-            '*offset'    : 'int',
-            '*size'      : 'int',
+            '*offset'    : 'size',
+            '*size'      : 'size',
             'fatal'      : 'bool' } }
 
 ##
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 51/56] block/nfs: Fix for readahead-size, page-cache-size > INT64_MAX
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (49 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 50/56] block: Make BLOCK_IMAGE_CORRUPTED offset, size unsigned in QAPI/QMP Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 52/56] block/nfs: Reject negative readahead-size, page-cache-size Markus Armbruster
                   ` (5 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

nfs_client_open() implicitly converts the uint64_t value of
qemu_opt_get_number() to int64_t, then clamps it to range.  The
clamping is broken for negative values.

Fix by making NFSClient members @readahead and @pagecache uint64_t.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/nfs.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/block/nfs.c b/block/nfs.c
index d8db419..2776788 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -58,7 +58,8 @@ typedef struct NFSClient {
     bool cache_used;
     NFSServer *server;
     char *path;
-    int64_t uid, gid, tcp_syncnt, readahead, pagecache, debug;
+    int64_t uid, gid, tcp_syncnt, debug;
+    uint64_t readahead, pagecache;
 } NFSClient;
 
 typedef struct NFSRPC {
@@ -856,10 +857,10 @@ static void nfs_refresh_filename(BlockDriverState *bs, QDict *options)
         qdict_put_int(opts, "tcp-syn-cnt", client->tcp_syncnt);
     }
     if (client->readahead) {
-        qdict_put_int(opts, "readahead-size", client->readahead);
+        qdict_put_uint(opts, "readahead-size", client->readahead);
     }
     if (client->pagecache) {
-        qdict_put_int(opts, "page-cache-size", client->pagecache);
+        qdict_put_uint(opts, "page-cache-size", client->pagecache);
     }
     if (client->debug) {
         qdict_put_int(opts, "debug", client->debug);
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 52/56] block/nfs: Reject negative readahead-size, page-cache-size
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (50 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 51/56] block/nfs: Fix for readahead-size, page-cache-size > INT64_MAX Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 53/56] block: Make blockdev-add byte counts unsigned in QAPI/QMP Markus Armbruster
                   ` (4 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

The nfs block driver uses QEMU_OPT_NUMBER for these sizes.  All other
block drivers use QEMU_OPT_SIZE.  Both are uint64_t, but QEMU_OPT_SIZE
rejects negative numbers, while QEMU_OPT_NUMBER interprets them modulo
2^64.  Switch the nfs block driver to QEMU_OPT_SIZE.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/nfs.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/block/nfs.c b/block/nfs.c
index 2776788..0ed3e7c 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -394,12 +394,12 @@ static QemuOptsList runtime_opts = {
         },
         {
             .name = "readahead-size",
-            .type = QEMU_OPT_NUMBER,
+            .type = QEMU_OPT_SIZE,
             .help = "Set the readahead size in bytes",
         },
         {
             .name = "page-cache-size",
-            .type = QEMU_OPT_NUMBER,
+            .type = QEMU_OPT_SIZE,
             .help = "Set the pagecache size in bytes",
         },
         {
@@ -557,7 +557,7 @@ static int64_t nfs_client_open(NFSClient *client, QDict *options,
                              "if cache.direct = on");
             goto fail;
         }
-        client->readahead = qemu_opt_get_number(opts, "readahead-size", 0);
+        client->readahead = qemu_opt_get_size(opts, "readahead-size", 0);
         if (client->readahead > QEMU_NFS_MAX_READAHEAD_SIZE) {
             warn_report("Truncating NFS readahead size to %d",
                         QEMU_NFS_MAX_READAHEAD_SIZE);
@@ -578,7 +578,7 @@ static int64_t nfs_client_open(NFSClient *client, QDict *options,
                              "if cache.direct = on");
             goto fail;
         }
-        client->pagecache = qemu_opt_get_number(opts, "page-cache-size", 0);
+        client->pagecache = qemu_opt_get_size(opts, "page-cache-size", 0);
         if (client->pagecache > QEMU_NFS_MAX_PAGECACHE_SIZE) {
             warn_report("Truncating NFS pagecache size to %d pages",
                         QEMU_NFS_MAX_PAGECACHE_SIZE);
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 53/56] block: Make blockdev-add byte counts unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (51 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 52/56] block/nfs: Reject negative readahead-size, page-cache-size Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 54/56] qemu-img: blk_getlength() can fail, fix img_map() to check Markus Armbruster
                   ` (3 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

File offsets, sizes and alignments should use QAPI type 'size'
(uint64_t).  blockdev-add parameters are 'int' (int64_t):
BlockdevOptionsNull member @size; BlockdevOptionsQcow2 members
@cache-size, @l2-cache-size, @refcount-cache-size; BlockdevOptionsNfs
members @readahead-size, @page-cache-size; BlockdevOptionsCurlBase
member @readahead; BlockdevOptionsRaw members @offset, @size.

The block drivers get their values with qemu_opt_get_size(), which
returns uint64_t.  They store them in uint64_t variables, except for
the null driver, which stores in BDRVNullState member int64_t length.

Change these BlockdevOptionsFOO members to 'size'.

Change BDRVNullState member length to uint64_t.  This moves the
implicit conversion to int64_t from null_file_open() to
null_getlength().  No worse than before.

blockdev-add and -blockdev now accept values between 2^63 and 2^64-1.
They accept negative values as before, because that's how the QObject
input visitor works for backward compatibility.

Values above 2^63 are unlikely to actually work; the block subsystem
isn't prepared for them.  Again, no worse than before.

Aside: we call the same thing @readahead-size in one place, and
@readahead in another place.  Sad.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/null.c         |  2 +-
 qapi/block-core.json | 22 +++++++++++-----------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/block/null.c b/block/null.c
index 876f909..2ab0e70 100644
--- a/block/null.c
+++ b/block/null.c
@@ -20,7 +20,7 @@
 #define NULL_OPT_ZEROES  "read-zeroes"
 
 typedef struct {
-    int64_t length;
+    uint64_t length;
     int64_t latency_ns;
     bool read_zeroes;
 } BDRVNullState;
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 64b84a5..3482f8c 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2189,7 +2189,7 @@
 # Since: 2.9
 ##
 { 'struct': 'BlockdevOptionsNull',
-  'data': { '*size': 'int', '*latency-ns': 'uint64' } }
+  'data': { '*size': 'size', '*latency-ns': 'uint64' } }
 
 ##
 # @BlockdevOptionsVVFAT:
@@ -2421,9 +2421,9 @@
             '*pass-discard-snapshot': 'bool',
             '*pass-discard-other': 'bool',
             '*overlap-check': 'Qcow2OverlapChecks',
-            '*cache-size': 'int',
-            '*l2-cache-size': 'int',
-            '*refcount-cache-size': 'int',
+            '*cache-size': 'size',
+            '*l2-cache-size': 'size',
+            '*refcount-cache-size': 'size',
             '*cache-clean-interval': 'int',
             '*encrypt': 'BlockdevQcow2Encryption' } }
 
@@ -2568,9 +2568,9 @@
 { 'struct': 'BlockdevOptionsBlkdebug',
   'data': { 'image': 'BlockdevRef',
             '*config': 'str',
-            '*align': 'int', '*max-transfer': 'int32',
-            '*opt-write-zero': 'int32', '*max-write-zero': 'int32',
-            '*opt-discard': 'int32', '*max-discard': 'int32',
+            '*align': 'size', '*max-transfer': 'size',
+            '*opt-write-zero': 'size', '*max-write-zero': 'size',
+            '*opt-discard': 'size', '*max-discard': 'size',
             '*inject-error': ['BlkdebugInjectErrorOptions'],
             '*set-state': ['BlkdebugSetStateOptions'] } }
 
@@ -2862,8 +2862,8 @@
             '*user': 'int',
             '*group': 'int',
             '*tcp-syn-count': 'int',
-            '*readahead-size': 'int',
-            '*page-cache-size': 'int',
+            '*readahead-size': 'size',
+            '*page-cache-size': 'size',
             '*debug': 'int' } }
 
 ##
@@ -2893,7 +2893,7 @@
 ##
 { 'struct': 'BlockdevOptionsCurlBase',
   'data': { 'url': 'str',
-            '*readahead': 'int',
+            '*readahead': 'size',
             '*timeout': 'int',
             '*username': 'str',
             '*password-secret': 'str',
@@ -3001,7 +3001,7 @@
 ##
 { 'struct': 'BlockdevOptionsRaw',
   'base': 'BlockdevOptionsGenericFormat',
-  'data': { '*offset': 'int', '*size': 'int' } }
+  'data': { '*offset': 'size', '*size': 'size' } }
 
 ##
 # @BlockdevOptionsVxHS:
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 54/56] qemu-img: blk_getlength() can fail, fix img_map() to check
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (52 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 53/56] block: Make blockdev-add byte counts unsigned in QAPI/QMP Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 55/56] block: Make MapEntry offsets and size unsigned in QAPI Markus Armbruster
                   ` (2 subsequent siblings)
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 qemu-img.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/qemu-img.c b/qemu-img.c
index 3ae5fe3..cf3ef3e 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -2838,6 +2838,10 @@ static int img_map(int argc, char **argv)
     }
 
     length = blk_getlength(blk);
+    if (length < 0) {
+        error_report("Couldn't get length of image '%s': %s",
+                     filename, strerror(-length));
+    }
     while (curr.start + curr.length < length) {
         int64_t nsectors_left;
         int64_t sector_num;
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 55/56] block: Make MapEntry offsets and size unsigned in QAPI
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (53 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 54/56] qemu-img: blk_getlength() can fail, fix img_map() to check Markus Armbruster
@ 2017-08-07 14:45 ` Markus Armbruster
  2017-08-07 14:46 ` [Qemu-devel] [RFC PATCH 56/56] crypto: Make QCryptoBlockInfoLUKS offsets unsigned in QAPI/QMP Markus Armbruster
  2017-09-06 15:32 ` [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Kevin Wolf
  56 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

File offsets and sizes use QAPI type 'size' (uint64_t).  MapEntry
members @start, @length and @offset are 'int' (int64_t).
get_block_status() sets @start and @length to unsigned long long
values, and @offset to a non-negative int64_t value.

Change these MapEntry members to 'size'.

"qemu-img map" now reports them correctly above 2^63-1 instead of
their (negative) two's complement.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 qapi/block-core.json | 4 ++--
 qemu-img.c           | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 3482f8c..6f62723 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -236,8 +236,8 @@
 #
 ##
 { 'struct': 'MapEntry',
-  'data': {'start': 'int', 'length': 'int', 'data': 'bool',
-           'zero': 'bool', 'depth': 'int', '*offset': 'int',
+  'data': {'start': 'size', 'length': 'size', 'data': 'bool',
+           'zero': 'bool', 'depth': 'int', '*offset': 'size',
            '*filename': 'str' } }
 
 ##
diff --git a/qemu-img.c b/qemu-img.c
index cf3ef3e..1c783c7 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -2655,14 +2655,14 @@ static void dump_map_entry(OutputFormat output_format, MapEntry *e,
         }
         break;
     case OFORMAT_JSON:
-        printf("%s{ \"start\": %"PRId64", \"length\": %"PRId64","
+        printf("%s{ \"start\": %" PRIu64 ", \"length\": %" PRIu64 ","
                " \"depth\": %"PRId64", \"zero\": %s, \"data\": %s",
                (e->start == 0 ? "[" : ",\n"),
                e->start, e->length, e->depth,
                e->zero ? "true" : "false",
                e->data ? "true" : "false");
         if (e->has_offset) {
-            printf(", \"offset\": %"PRId64"", e->offset);
+            printf(", \"offset\": %" PRIu64, e->offset);
         }
         putchar('}');
 
-- 
2.7.5

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

* [Qemu-devel] [RFC PATCH 56/56] crypto: Make QCryptoBlockInfoLUKS offsets unsigned in QAPI/QMP
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (54 preceding siblings ...)
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 55/56] block: Make MapEntry offsets and size unsigned in QAPI Markus Armbruster
@ 2017-08-07 14:46 ` Markus Armbruster
  2017-08-07 15:10   ` Daniel P. Berrange
  2017-09-06 15:32 ` [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Kevin Wolf
  56 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-07 14:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Byte offsets should use QAPI type 'size' (uint64_t).
QCryptoBlockInfoLUKS member @payload-offset and
QCryptoBlockInfoLUKSSlot member @key-offset are 'int' (int64_t).
qcrypto_block_luks_get_info() gets the former QCryptoBlock member
@payload_offset, implicitly converting from uint64_t, and computes the
latter from QCryptoBlockLUKSKeySlot member @key_offset, implicitly
converting from long long.

Change both offsets to 'size'.

query-block and query-named-block-nodes now report @payload-offset
values above 2^63-1 correctly instead of their (negative) two's
complement.  Should never occur in practice.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 qapi/crypto.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/qapi/crypto.json b/qapi/crypto.json
index 6b6fde3..57a10cb 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -266,7 +266,7 @@
   'data': {'active': 'bool',
            '*iters': 'int',
            '*stripes': 'int',
-           'key-offset': 'int' } }
+           'key-offset': 'size' } }
 
 
 ##
@@ -292,7 +292,7 @@
            'ivgen-alg': 'QCryptoIVGenAlgorithm',
            '*ivgen-hash-alg': 'QCryptoHashAlgorithm',
            'hash-alg': 'QCryptoHashAlgorithm',
-           'payload-offset': 'int',
+           'payload-offset': 'size',
            'master-key-iters': 'int',
            'uuid': 'str',
            'slots': [ 'QCryptoBlockInfoLUKSSlot' ] }}
-- 
2.7.5

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

* Re: [Qemu-devel] [RFC PATCH 56/56] crypto: Make QCryptoBlockInfoLUKS offsets unsigned in QAPI/QMP
  2017-08-07 14:46 ` [Qemu-devel] [RFC PATCH 56/56] crypto: Make QCryptoBlockInfoLUKS offsets unsigned in QAPI/QMP Markus Armbruster
@ 2017-08-07 15:10   ` Daniel P. Berrange
  0 siblings, 0 replies; 105+ messages in thread
From: Daniel P. Berrange @ 2017-08-07 15:10 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, qemu-block

On Mon, Aug 07, 2017 at 04:46:00PM +0200, Markus Armbruster wrote:
> Byte offsets should use QAPI type 'size' (uint64_t).
> QCryptoBlockInfoLUKS member @payload-offset and
> QCryptoBlockInfoLUKSSlot member @key-offset are 'int' (int64_t).
> qcrypto_block_luks_get_info() gets the former QCryptoBlock member
> @payload_offset, implicitly converting from uint64_t, and computes the
> latter from QCryptoBlockLUKSKeySlot member @key_offset, implicitly
> converting from long long.
> 
> Change both offsets to 'size'.
> 
> query-block and query-named-block-nodes now report @payload-offset
> values above 2^63-1 correctly instead of their (negative) two's
> complement.  Should never occur in practice.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>

Reviewed-by: Daniel P. Berrange <berrange@redhat.com>

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

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

* Re: [Qemu-devel] [RFC PATCH 14/56] migration: Fix migrate-set-cache-size error reporting
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 14/56] migration: Fix migrate-set-cache-size error reporting Markus Armbruster
@ 2017-08-07 16:07   ` Juan Quintela
  0 siblings, 0 replies; 105+ messages in thread
From: Juan Quintela @ 2017-08-07 16:07 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, berrange, qemu-block

Markus Armbruster <armbru@redhat.com> wrote:
> qmp_migrate_set_cache_size() calls xbzrle_cache_resize() to do the
> actual work, which in turn calls cache_init() to resize the cache.  If
> cache_init() fails, xbzrle_cache_resize() reports that error with
> error_report() and fails.  qmp_migrate_set_cache_size() detects the
> failure and reports "Parameter 'cache size' expects is smaller than
> page size" with error_setg().  The first error is accurate, the second
> is bogus.  With HMP, we get both.  With QMP, we get the accurate one
> on stderr, and the bogus one via QMP.
>
> Fix by making xbzrle_cache_resize() use error_setg() instead of
> error_report().
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>

Reviewed-by: Juan Quintela <quintela@redhat.com>

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

* Re: [Qemu-devel] [RFC PATCH 15/56] migration: Make XBZRLE cache size unsigned in QAPI/QMP
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 15/56] migration: Make XBZRLE cache size unsigned in QAPI/QMP Markus Armbruster
@ 2017-08-07 16:10   ` Juan Quintela
  2017-08-08 15:57     ` Markus Armbruster
  0 siblings, 1 reply; 105+ messages in thread
From: Juan Quintela @ 2017-08-07 16:10 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, berrange, qemu-block

Markus Armbruster <armbru@redhat.com> wrote:
> Sizes should use QAPI type 'size' (uint64_t).  migrate-set-cache-size
> parameter @value is 'int' (int64_t).  qmp_migrate_set_cache_size()
> ensures it fits into size_t.  page_cache.c implicitly converts the
> signed size to unsigned types (it can't quite decide whether to use
> uint64_t or size_t for cache offsets, but that's not something I can
> tackle now).
>
> XBZRLECacheStats member @cache-size and query-migrate-cache-size's
> result are also 'int'.
>
> Change the migrate-set-cache-size parameter and the XBZRLECacheStats
> members to 'size', fix up hmp_migrate_set_cache_size(), and tweak a
> few variable types to reduce implicit conversions.
>
> migrate-set-cache-size now accepts size values between 2^63 and
> 2^64-1.  It accepts negative values as before, because that's how the
> QObject input visitor works for backward compatibility.
>
> So does HMP's migrate_set_cache_size.
>
> query-migrate and query-migrate-cache-size now report cache sizes
> above 2^63-1 correctly instead of their (negative) two's complement.
>
> So does HMP's "info migrate_cache_size".  HMP's "info migrate" already
> reported the cache size correctly, because it printed the signed
> integer with PRIu32.
>

Reviewed-by: Juan Quintela <quintela@redhat.com>


> diff --git a/qapi-schema.json b/qapi-schema.json
> index c8cceb9..ecabff6 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -646,7 +646,7 @@
>  # Since: 1.2
>  ##
>  { 'struct': 'XBZRLECacheStats',
> -  'data': {'cache-size': 'int', 'bytes': 'int', 'pages': 'int',
> +  'data': {'cache-size': 'size', 'bytes': 'int', 'pages': 'int',
>             'cache-miss': 'int', 'cache-miss-rate': 'number',
>             'overflow': 'int' } }
>  
> @@ -2875,7 +2875,7 @@
>  # <- { "return": {} }
>  #
>  ##
> -{ 'command': 'migrate-set-cache-size', 'data': {'value': 'int'} }
> +{ 'command': 'migrate-set-cache-size', 'data': {'value': 'size'} }
>  
>  ##
>  # @query-migrate-cache-size:
> @@ -2892,7 +2892,7 @@
>  # <- { "return": 67108864 }
>  #
>  ##
> -{ 'command': 'query-migrate-cache-size', 'returns': 'int' }
> +{ 'command': 'query-migrate-cache-size', 'returns': 'size' }
>  
>  ##
>  # @ObjectPropertyInfo:

I am ussming this bits are backward compatible (I don't understand QMP
to assure this)

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

* Re: [Qemu-devel] [RFC PATCH 16/56] migration: Make XBZRLE transferred size unsigned in QAPI/QMP
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 16/56] migration: Make XBZRLE transferred " Markus Armbruster
@ 2017-08-07 16:47   ` Juan Quintela
  0 siblings, 0 replies; 105+ messages in thread
From: Juan Quintela @ 2017-08-07 16:47 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, berrange, qemu-block

Markus Armbruster <armbru@redhat.com> wrote:
> Sizes should use QAPI type 'size' (uint64_t).  XBZRLECacheStats member
> @bytes is 'int' (int64_t).  save_xbzrle_page() computes the byte count
> increment in size_t, implicitly converts it to int, then adds that to
> @bytes.
>
> Change the XBZRLECacheStats member to 'size' and clean up
> save_xbzrle_page().
>
> query-migrate now reports transferred sizes above 2^63-1 correctly
> instead of their (negative) two's complement.
>
> HMP's "info migrate" already reported them correctly, because it
> printed the signed integer with PRIu64.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>

Reviewed-by: Juan Quintela <quintela@redhat.com>

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

* Re: [Qemu-devel] [RFC PATCH 17/56] migration: Make MigrationStats sizes unsigned in QAPI/QMP
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 17/56] migration: Make MigrationStats sizes " Markus Armbruster
@ 2017-08-07 16:48   ` Juan Quintela
  0 siblings, 0 replies; 105+ messages in thread
From: Juan Quintela @ 2017-08-07 16:48 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, berrange, qemu-block

Markus Armbruster <armbru@redhat.com> wrote:
> Sizes should use QAPI type 'size' (uint64_t).  MigrationStats members
> @transferred, @remaining, @total, @normal-bytes, @page-size are 'int'
> (int64_t).  populate_ram_info(), populate_disk_info() and and many
> places that update them in global variable @ram_counters implicitly
> convert from unsigned types.
>
> Change these MigrationStats members to 'size'.
>
> query-migrate now reports them correctly above 2^63-1 instead of their
> (negative) two's complement.
>
> HMP's "info migrate" already reported them correctly, because it
> printed the signed integer with PRIu64.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>

Reviewed-by: Juan Quintela <quintela@redhat.com>


> ---
>  qapi-schema.json | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 4a3d07e..2eee676 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -620,11 +620,11 @@
>  # Since: 0.14.0
>  ##
>  { 'struct': 'MigrationStats',
> -  'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int' ,
> +  'data': {'transferred': 'size', 'remaining': 'size', 'total': 'size' ,
>             'duplicate': 'int', 'skipped': 'int', 'normal': 'int',
> -           'normal-bytes': 'int', 'dirty-pages-rate' : 'int',
> +           'normal-bytes': 'size', 'dirty-pages-rate' : 'int',
>             'mbps' : 'number', 'dirty-sync-count' : 'int',
> -           'postcopy-requests' : 'int', 'page-size' : 'int' } }
> +           'postcopy-requests' : 'int', 'page-size' : 'size' } }

I would expect page-size to not be so big, but who knows O:-)


>  
>  ##
>  # @XBZRLECacheStats:

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

* Re: [Qemu-devel] [RFC PATCH 18/56] migration: Make parameter max-bandwidth unsigned in QAPI/QMP
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 18/56] migration: Make parameter max-bandwidth " Markus Armbruster
@ 2017-08-07 16:50   ` Juan Quintela
  0 siblings, 0 replies; 105+ messages in thread
From: Juan Quintela @ 2017-08-07 16:50 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, berrange, qemu-block

Markus Armbruster <armbru@redhat.com> wrote:
> Byte rates should use QAPI type 'size' (uint64_t).
> migrate_set_speed's parameter @value and member @max-bandwidth of
> MigrationParameters and MigrateSetParameters are 'int' (int64_t).
>
> Change them all to 'size'.
>
> migrate_set_speed and migrate-set-parameters now accept bandwidth
> values between 2^63 and SIZE_MAX (commonly 2^64-1).  They accept
> negative values as before, because that's how the QObject input
> visitor works for backward compatibility.
>
> So does HMP's migrate_set_speed, except it continues to reject
> negative values.
>
> query-migrate-parameters now reports bandwidth values above 2^63-1
> correctly instead of their (negative) two's complement.
>
> So does HMP's "info migrate_params".
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>

Reviewed-by: Juan Quintela <quintela@redhat.com>

> -    if (params->has_max_bandwidth &&
> -        (params->max_bandwidth < 0 || params->max_bandwidth > SIZE_MAX)) {
> +    if (params->has_max_bandwidth && params->max_bandwidth > SIZE_MAX) {


Much nicer for something that we know can't be negative O:-)

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

* Re: [Qemu-devel] [RFC PATCH 27/56] block/dirty-bitmap: Clean up signed vs. unsigned dirty counts
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 27/56] block/dirty-bitmap: Clean up signed vs. unsigned dirty counts Markus Armbruster
@ 2017-08-08  1:50   ` John Snow
  2017-08-08 14:53   ` Eric Blake
  1 sibling, 0 replies; 105+ messages in thread
From: John Snow @ 2017-08-08  1:50 UTC (permalink / raw)
  To: Markus Armbruster, qemu-devel
  Cc: kwolf, famz, qemu-block, quintela, jcody, dgilbert, mreitz,
	marcandre.lureau, pbonzini



On 08/07/2017 10:45 AM, Markus Armbruster wrote:
> hbitmap_count() returns uint64_t.
> 
> Clean up test-hbitmap.c to check its value with g_assert_cmpuint()
> instead of g_assert_cmpint().
> 
> bdrv_get_dirty_count() and bdrv_get_meta_dirty_count() return its
> value converted to int64_t.  Clean them up to return it unadulterated.
> 
> This moves the implicit conversion to some callers, so clean them up,
> too.
> 
> mirror_run() assigns the value of bdrv_get_meta_dirty_count() to a
> local int64_t variable.  Change it to uint64_t.  Signedness still gets
> mixed up in the computation of s->common.len, but messing with that is
> more than I can handle right now.
> 
> get_remaining_dirty() tallies bdrv_get_dirty_count() values in
> int64_t.  Its caller block_save_pending() converts it back to
> uint64_t.  Change get_remaining_dirty() to uint64_t.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>

So these functions can't fail, so there's no reason to keep the int64_t
type around, OK.

Reviewed-by: John Snow <jsnow@redhat.com>

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

* Re: [Qemu-devel] [RFC PATCH 28/56] block: Widen dirty bitmap granularity to uint64_t for safety
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 28/56] block: Widen dirty bitmap granularity to uint64_t for safety Markus Armbruster
@ 2017-08-08  1:55   ` John Snow
  2017-08-08 14:55     ` Eric Blake
  2017-08-08 15:58     ` Markus Armbruster
  0 siblings, 2 replies; 105+ messages in thread
From: John Snow @ 2017-08-08  1:55 UTC (permalink / raw)
  To: Markus Armbruster, qemu-devel
  Cc: kwolf, famz, qemu-block, quintela, jcody, dgilbert, mreitz,
	marcandre.lureau, pbonzini



On 08/07/2017 10:45 AM, Markus Armbruster wrote:
> Block dirty bitmaps represent granularity in bytes as uint32_t.  It
> must be a power of two and a multiple of BDRV_SECTOR_SIZE.
> 
> The trouble with uint32_t is computations like this one in
> mirror_do_read():
> 
>     uint64_t max_bytes;
> 
>     max_bytes = s->granularity * s->max_iov;
> 
> The operands of * are uint32_t and int, so the product is computed in
> uint32_t (assuming 32 bit int), then zero-extended to uint64_t.
> 
> Since granularity is generally combined with 64 bit file offsets, it's
> best to make it 64 bits, too.  Less opportunity to screw up.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>

[bweeooop]

> --- a/block/dirty-bitmap.c
> +++ b/block/dirty-bitmap.c

[buuuuweeeep]

> @@ -506,16 +506,11 @@ uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
>      return granularity;
>  }
>  
> -uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
> +uint64_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
>  {
>      return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap);
>  }
>  
> -uint32_t bdrv_dirty_bitmap_meta_granularity(BdrvDirtyBitmap *bitmap)
> -{
> -    return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->meta);
> -}

Why? Unused? Not cool enough to mention?

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

* Re: [Qemu-devel] [RFC PATCH 29/56] block: Make BlockDirtyInfo byte count unsigned in QAPI/QMP
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 29/56] block: Make BlockDirtyInfo byte count unsigned in QAPI/QMP Markus Armbruster
@ 2017-08-08  1:56   ` John Snow
  2017-08-08 15:58     ` Markus Armbruster
  0 siblings, 1 reply; 105+ messages in thread
From: John Snow @ 2017-08-08  1:56 UTC (permalink / raw)
  To: Markus Armbruster, qemu-devel
  Cc: kwolf, famz, qemu-block, quintela, jcody, dgilbert, mreitz,
	marcandre.lureau, pbonzini



On 08/07/2017 10:45 AM, Markus Armbruster wrote:
> Byte counts should use QAPI type 'size' (uint64_t).  BlockDirtyInfo
> member @count is 'int' (int64_t).  bdrv_query_dirty_bitmaps() computes
> @count from bdrv_get_dirty_count() in uint64_t, then implicitly
> converts to int64_t.  Before the commit before previous, the
> conversion was in bdrv_get_dirty_count() instead.
> 
> Change member @count to 'size'.
> 
> query-block now reports @count values above 2^63-1 correctly instead
> of their (negative) two's complement.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>

Assuming there's no "gotcha" here introduced by changing the QAPI, then
ACK; but you're the expert there, so I trust you!

Reviewed-by: John Snow <jsnow@redhat.com>

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

* Re: [Qemu-devel] [RFC PATCH 03/56] monitor: Rewrite comment describing HMP .args_type
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 03/56] monitor: Rewrite comment describing HMP .args_type Markus Armbruster
@ 2017-08-08 11:20   ` Dr. David Alan Gilbert
  2017-08-08 14:22     ` Paolo Bonzini
  2017-08-08 15:36     ` Markus Armbruster
  0 siblings, 2 replies; 105+ messages in thread
From: Dr. David Alan Gilbert @ 2017-08-08 11:20 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, quintela, berrange, qemu-block

* Markus Armbruster (armbru@redhat.com) wrote:
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  monitor.c | 75 +++++++++++++++++++++++++++++++++++++++------------------------
>  1 file changed, 47 insertions(+), 28 deletions(-)
> 
> diff --git a/monitor.c b/monitor.c
> index e0f8801..8b54ba1 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -85,37 +85,56 @@
>  #endif
>  
>  /*
> - * Supported types:
> + * Command handlers (mon_cmd_t member @cmd) receive actual arguments
> + * in a QDict, which is built by the HMP core according to mon_cmd_t
> + * member @args_type.  It's a list of NAME:TYPE separated by comma.
>   *
> - * 'F'          filename
> - * 'B'          block device name
> - * 's'          string (accept optional quote)
> - * 'S'          it just appends the rest of the string (accept optional quote)
> - * 'O'          option string of the form NAME=VALUE,...
> - *              parsed according to QemuOptsList given by its name
> - *              Example: 'device:O' uses qemu_device_opts.
> - *              Restriction: only lists with empty desc are supported
> - *              TODO lift the restriction
> - * 'i'          32 bit integer
> - * 'l'          target long (32 or 64 bit)
> - * 'M'          Non-negative target long (32 or 64 bit), in user mode the
> - *              value is multiplied by 2^20 (think Mebibyte)
> - * 'o'          octets (aka bytes)
> - *              user mode accepts an optional E, e, P, p, T, t, G, g, M, m,
> - *              K, k suffix, which multiplies the value by 2^60 for suffixes E
> - *              and e, 2^50 for suffixes P and p, 2^40 for suffixes T and t,
> - *              2^30 for suffixes G and g, 2^20 for M and m, 2^10 for K and k
> - * 'T'          double
> - *              user mode accepts an optional ms, us, ns suffix,
> - *              which divides the value by 1e3, 1e6, 1e9, respectively
> - * '/'          optional gdb-like print format (like "/10x")
> + * TYPEs that put a string value with key NAME into the QDict:
> + * 's'    Argument is enclosed in '"' or delimited by whitespace.  In
> + *        the former case, escapes \n \r \\ \' and \" are recognized.
> + * 'F'    File name, like 's' except for completion.
> + * 'B'    BlockBackend name, like 's' except for completion.
> + * 'S'    Argument is the remainder of the line, less leading
> + *        whitespace.
> +
>   *
> - * '?'          optional type (for all types, except '/')
> - * '.'          other form of optional type (for 'i' and 'l')
> - * 'b'          boolean
> - *              user mode accepts "on" or "off"
> - * '-'          optional parameter (eg. '-f')
> + * TYPEs that put an int64_t value with key NAME:
> + * 'l'    Argument is an expression (QEMU pocket calculator).
> + * 'i'    Like 'l' except value must fit into 32 bit unsigned.
> + * 'M'    Like 'l' except value must not be negative and is multiplied
> + *        by 2^20 (think "mebibyte").
>   *
> + * TYPEs that put an uint64_t value with key NAME:
> + * 'o'    Argument is a size (think "octets").  Without suffix the
> + *        value is multiplied by 2^20 (mebibytes), with suffix E or e
> + *        by 2^60 (exbibytes), with P or p by 2^50 (pebibytes), with T
> + *        or t by 2^40 (tebibytes), with G or g by 2^30 (gibibytes),
> + *        with M or m by 2^10 (mebibytes), with K or k by 2^10
> + *        (kibibytes).

'o' is messy.  It using qemu_strtosz_MiB which uses a 'double' intermediate
so I fear it can round.  It also has a note it can't take all f's due to
an overflow from the conversion.   Two things not mentioned are that
it also takes hex (as explicit 0x) and that it also does 'b' as a suffix
to multiply by 1.  Those two combine in bad ways - i.e. 0x1b is 27MB,
1b is 1 byte (same for 'e').  These are probably OK except if you were
to start replacing 'l' by 'o' because you really wanted 64bit addresses
say.
(I also wouldn't bother expanding the size names and powers).

> + *
> + * TYPEs that put a double value with key NAME:
> + * 'T'    Argument is a time in seconds.  With optional ms, us, ns
> + *        suffix, the value divided by 1e3, 1e6, 1e9 respectively.
> + *
> + * TYPEs that put a bool value with key NAME:
> + * 'b'    Argument is either "on" (true) or "off" (false).
> + * '-' CHAR
> + *        Argument is either "-CHAR" (true) or absent (false).

I found the previous description clearer.

> + * TYPEs that put multiple values:
> + * 'O'    Option string of the form NAME=VALUE,... parsed according to
> + *        the QemuOptsList given by its name.
> + *        Example: 'device:O' uses qemu_device_opts.
> + *        Restriction: only lists with empty desc are supported.
> + *        Puts all the NAME=VALUE.
> + * '/'    Gdb-like print format (like "/10x"), always optional.
> + *        Puts keys "count", "format", "size", all int.
> + *
> + * Modifier character following the type string:
> + * '?'    Argument is optional, nothing is put when it is absent
> + *        (all types except 'O', '/', 'b').
> + * '.'    Argument is optional, must be preceded by '.' if present
> + *        (only types 'i', 'l', 'M')

That's obscure; I can only see one use of it in ioport_read and that's
extra-special!

Dave

>   */
>  
>  typedef struct mon_cmd_t {
> -- 
> 2.7.5
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

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

* Re: [Qemu-devel] [RFC PATCH 03/56] monitor: Rewrite comment describing HMP .args_type
  2017-08-08 11:20   ` Dr. David Alan Gilbert
@ 2017-08-08 14:22     ` Paolo Bonzini
  2017-08-08 14:46       ` Dr. David Alan Gilbert
  2017-08-08 15:36     ` Markus Armbruster
  1 sibling, 1 reply; 105+ messages in thread
From: Paolo Bonzini @ 2017-08-08 14:22 UTC (permalink / raw)
  To: Dr. David Alan Gilbert, Markus Armbruster
  Cc: qemu-devel, eblake, kwolf, mreitz, jcody, famz, jsnow,
	marcandre.lureau, quintela, berrange, qemu-block

On 08/08/2017 13:20, Dr. David Alan Gilbert wrote:
> * Markus Armbruster (armbru@redhat.com) wrote:
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>>  monitor.c | 75 +++++++++++++++++++++++++++++++++++++++------------------------
>>  1 file changed, 47 insertions(+), 28 deletions(-)
>>
>> diff --git a/monitor.c b/monitor.c
>> index e0f8801..8b54ba1 100644
>> --- a/monitor.c
>> +++ b/monitor.c
>> @@ -85,37 +85,56 @@
>>  #endif
>>  
>>  /*
>> - * Supported types:
>> + * Command handlers (mon_cmd_t member @cmd) receive actual arguments
>> + * in a QDict, which is built by the HMP core according to mon_cmd_t
>> + * member @args_type.  It's a list of NAME:TYPE separated by comma.
>>   *
>> - * 'F'          filename
>> - * 'B'          block device name
>> - * 's'          string (accept optional quote)
>> - * 'S'          it just appends the rest of the string (accept optional quote)
>> - * 'O'          option string of the form NAME=VALUE,...
>> - *              parsed according to QemuOptsList given by its name
>> - *              Example: 'device:O' uses qemu_device_opts.
>> - *              Restriction: only lists with empty desc are supported
>> - *              TODO lift the restriction
>> - * 'i'          32 bit integer
>> - * 'l'          target long (32 or 64 bit)
>> - * 'M'          Non-negative target long (32 or 64 bit), in user mode the
>> - *              value is multiplied by 2^20 (think Mebibyte)
>> - * 'o'          octets (aka bytes)
>> - *              user mode accepts an optional E, e, P, p, T, t, G, g, M, m,
>> - *              K, k suffix, which multiplies the value by 2^60 for suffixes E
>> - *              and e, 2^50 for suffixes P and p, 2^40 for suffixes T and t,
>> - *              2^30 for suffixes G and g, 2^20 for M and m, 2^10 for K and k
>> - * 'T'          double
>> - *              user mode accepts an optional ms, us, ns suffix,
>> - *              which divides the value by 1e3, 1e6, 1e9, respectively
>> - * '/'          optional gdb-like print format (like "/10x")
>> + * TYPEs that put a string value with key NAME into the QDict:
>> + * 's'    Argument is enclosed in '"' or delimited by whitespace.  In
>> + *        the former case, escapes \n \r \\ \' and \" are recognized.
>> + * 'F'    File name, like 's' except for completion.
>> + * 'B'    BlockBackend name, like 's' except for completion.
>> + * 'S'    Argument is the remainder of the line, less leading
>> + *        whitespace.
>> +
>>   *
>> - * '?'          optional type (for all types, except '/')
>> - * '.'          other form of optional type (for 'i' and 'l')
>> - * 'b'          boolean
>> - *              user mode accepts "on" or "off"
>> - * '-'          optional parameter (eg. '-f')
>> + * TYPEs that put an int64_t value with key NAME:
>> + * 'l'    Argument is an expression (QEMU pocket calculator).
>> + * 'i'    Like 'l' except value must fit into 32 bit unsigned.
>> + * 'M'    Like 'l' except value must not be negative and is multiplied
>> + *        by 2^20 (think "mebibyte").
>>   *
>> + * TYPEs that put an uint64_t value with key NAME:
>> + * 'o'    Argument is a size (think "octets").  Without suffix the
>> + *        value is multiplied by 2^20 (mebibytes), with suffix E or e
>> + *        by 2^60 (exbibytes), with P or p by 2^50 (pebibytes), with T
>> + *        or t by 2^40 (tebibytes), with G or g by 2^30 (gibibytes),
>> + *        with M or m by 2^10 (mebibytes), with K or k by 2^10
>> + *        (kibibytes).
> 
> 'o' is messy.  It using qemu_strtosz_MiB which uses a 'double' intermediate
> so I fear it can round.  It also has a note it can't take all f's due to
> an overflow from the conversion.   Two things not mentioned are that
> it also takes hex (as explicit 0x) and that it also does 'b' as a suffix
> to multiply by 1.  Those two combine in bad ways - i.e. 0x1b is 27MB,
> 1b is 1 byte (same for 'e').  These are probably OK except if you were
> to start replacing 'l' by 'o' because you really wanted 64bit addresses
> say.
> (I also wouldn't bother expanding the size names and powers).
> 
>> + *
>> + * TYPEs that put a double value with key NAME:
>> + * 'T'    Argument is a time in seconds.  With optional ms, us, ns
>> + *        suffix, the value divided by 1e3, 1e6, 1e9 respectively.
>> + *
>> + * TYPEs that put a bool value with key NAME:
>> + * 'b'    Argument is either "on" (true) or "off" (false).
>> + * '-' CHAR
>> + *        Argument is either "-CHAR" (true) or absent (false).
> 
> I found the previous description clearer.
> 
>> + * TYPEs that put multiple values:
>> + * 'O'    Option string of the form NAME=VALUE,... parsed according to
>> + *        the QemuOptsList given by its name.
>> + *        Example: 'device:O' uses qemu_device_opts.
>> + *        Restriction: only lists with empty desc are supported.
>> + *        Puts all the NAME=VALUE.
>> + * '/'    Gdb-like print format (like "/10x"), always optional.
>> + *        Puts keys "count", "format", "size", all int.
>> + *
>> + * Modifier character following the type string:
>> + * '?'    Argument is optional, nothing is put when it is absent
>> + *        (all types except 'O', '/', 'b').
>> + * '.'    Argument is optional, must be preceded by '.' if present
>> + *        (only types 'i', 'l', 'M')
> 
> That's obscure; I can only see one use of it in ioport_read and that's
> extra-special!

It seems like the idea is that

    ioport_read 0x70.0xc

is expanded to

    write 0xc to 0x70
    read from 0x71

I can see how it can be useful for both RTC and VGA I/O ports, but on
the other hand ioport_write doesn't support it and as you said it's
really obscure.  I guess it can be removed or changed to not use "?",
though it's such a nice little nugget. :)

Paolo

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

* Re: [Qemu-devel] [RFC PATCH 07/56] cpus: Make memsave, pmemsave sizes, addresses unsigned in QAPI/QMP
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 07/56] cpus: Make memsave, pmemsave sizes, addresses unsigned in QAPI/QMP Markus Armbruster
@ 2017-08-08 14:31   ` Dr. David Alan Gilbert
  2017-08-08 15:37     ` Markus Armbruster
  0 siblings, 1 reply; 105+ messages in thread
From: Dr. David Alan Gilbert @ 2017-08-08 14:31 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, quintela, berrange, qemu-block

* Markus Armbruster (armbru@redhat.com) wrote:
> Sizes, virtual and physical addresses should use QAPI type 'size'
> (uint64_t).  memsave, pmemsave parameters @val, @size are 'int'
> (int64_t).  qmp_memsave() and qmp_pmemsave() implicitly convert to
> target_ulong or hwaddr.
> 
> Change the parameters to 'size'.
> 
> Both commands now accept size and address values between 2^63 and
> 2^64-1.  They accept negative values as before, because that's how the
> QObject input visitor works for backward compatibility.
> 
> The HMP commands' size parameters remain uint32_t, as HMP args_type
> strings can't do uint64_t byte counts: 'l' is signed, and 'o'
> multiplies by 2^20.  Their address parameters remain int64_t for the
> same reason.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  cpus.c           | 6 +++---
>  qapi-schema.json | 5 +++--
>  2 files changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index 9bed61e..8c5ee05 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -1947,14 +1947,14 @@ CpuInfoList *qmp_query_cpus(Error **errp)
>      return head;
>  }
>  
> -void qmp_memsave(int64_t addr, int64_t size, const char *filename,
> +void qmp_memsave(uint64_t addr, uint64_t size, const char *filename,
>                   bool has_cpu, int64_t cpu_index, Error **errp)
>  {
>      FILE *f;
>      uint32_t l;
>      CPUState *cpu;
>      uint8_t buf[1024];
> -    int64_t orig_addr = addr, orig_size = size;
> +    uint64_t orig_addr = addr, orig_size = size;
>  
>      if (!has_cpu) {
>          cpu_index = 0;

a little bit further down is a:
            error_setg(errp, "Invalid addr 0x%016" PRIx64 "/size %" PRId64
                             " specified", orig_addr, orig_size);

that PRId64 should be a PRIu64 now

However, other than that;


Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

> @@ -1994,7 +1994,7 @@ exit:
>      fclose(f);
>  }
>  
> -void qmp_pmemsave(int64_t addr, int64_t size, const char *filename,
> +void qmp_pmemsave(uint64_t addr, uint64_t size, const char *filename,
>                    Error **errp)
>  {
>      FILE *f;
> diff --git a/qapi-schema.json b/qapi-schema.json
> index f4a71df..80458fa 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -2460,7 +2460,8 @@
>  #
>  ##
>  { 'command': 'memsave',
> -  'data': {'val': 'int', 'size': 'int', 'filename': 'str', '*cpu-index': 'int'} }
> +  'data': {'val': 'size', 'size': 'size', 'filename': 'str',
> +           '*cpu-index': 'int'} }
>  
>  ##
>  # @pmemsave:
> @@ -2489,7 +2490,7 @@
>  #
>  ##
>  { 'command': 'pmemsave',
> -  'data': {'val': 'int', 'size': 'int', 'filename': 'str'} }
> +  'data': {'val': 'size', 'size': 'size', 'filename': 'str'} }
>  
>  ##
>  # @cont:
> -- 
> 2.7.5
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

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

* Re: [Qemu-devel] [RFC PATCH 03/56] monitor: Rewrite comment describing HMP .args_type
  2017-08-08 14:22     ` Paolo Bonzini
@ 2017-08-08 14:46       ` Dr. David Alan Gilbert
  0 siblings, 0 replies; 105+ messages in thread
From: Dr. David Alan Gilbert @ 2017-08-08 14:46 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Markus Armbruster, qemu-devel, eblake, kwolf, mreitz, jcody,
	famz, jsnow, marcandre.lureau, quintela, berrange, qemu-block

* Paolo Bonzini (pbonzini@redhat.com) wrote:
> On 08/08/2017 13:20, Dr. David Alan Gilbert wrote:
> > * Markus Armbruster (armbru@redhat.com) wrote:
> >> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> >> ---
> >>  monitor.c | 75 +++++++++++++++++++++++++++++++++++++++------------------------
> >>  1 file changed, 47 insertions(+), 28 deletions(-)
> >>
> >> diff --git a/monitor.c b/monitor.c
> >> index e0f8801..8b54ba1 100644
> >> --- a/monitor.c
> >> +++ b/monitor.c
> >> @@ -85,37 +85,56 @@
> >>  #endif
> >>  
> >>  /*
> >> - * Supported types:
> >> + * Command handlers (mon_cmd_t member @cmd) receive actual arguments
> >> + * in a QDict, which is built by the HMP core according to mon_cmd_t
> >> + * member @args_type.  It's a list of NAME:TYPE separated by comma.
> >>   *
> >> - * 'F'          filename
> >> - * 'B'          block device name
> >> - * 's'          string (accept optional quote)
> >> - * 'S'          it just appends the rest of the string (accept optional quote)
> >> - * 'O'          option string of the form NAME=VALUE,...
> >> - *              parsed according to QemuOptsList given by its name
> >> - *              Example: 'device:O' uses qemu_device_opts.
> >> - *              Restriction: only lists with empty desc are supported
> >> - *              TODO lift the restriction
> >> - * 'i'          32 bit integer
> >> - * 'l'          target long (32 or 64 bit)
> >> - * 'M'          Non-negative target long (32 or 64 bit), in user mode the
> >> - *              value is multiplied by 2^20 (think Mebibyte)
> >> - * 'o'          octets (aka bytes)
> >> - *              user mode accepts an optional E, e, P, p, T, t, G, g, M, m,
> >> - *              K, k suffix, which multiplies the value by 2^60 for suffixes E
> >> - *              and e, 2^50 for suffixes P and p, 2^40 for suffixes T and t,
> >> - *              2^30 for suffixes G and g, 2^20 for M and m, 2^10 for K and k
> >> - * 'T'          double
> >> - *              user mode accepts an optional ms, us, ns suffix,
> >> - *              which divides the value by 1e3, 1e6, 1e9, respectively
> >> - * '/'          optional gdb-like print format (like "/10x")
> >> + * TYPEs that put a string value with key NAME into the QDict:
> >> + * 's'    Argument is enclosed in '"' or delimited by whitespace.  In
> >> + *        the former case, escapes \n \r \\ \' and \" are recognized.
> >> + * 'F'    File name, like 's' except for completion.
> >> + * 'B'    BlockBackend name, like 's' except for completion.
> >> + * 'S'    Argument is the remainder of the line, less leading
> >> + *        whitespace.
> >> +
> >>   *
> >> - * '?'          optional type (for all types, except '/')
> >> - * '.'          other form of optional type (for 'i' and 'l')
> >> - * 'b'          boolean
> >> - *              user mode accepts "on" or "off"
> >> - * '-'          optional parameter (eg. '-f')
> >> + * TYPEs that put an int64_t value with key NAME:
> >> + * 'l'    Argument is an expression (QEMU pocket calculator).
> >> + * 'i'    Like 'l' except value must fit into 32 bit unsigned.
> >> + * 'M'    Like 'l' except value must not be negative and is multiplied
> >> + *        by 2^20 (think "mebibyte").
> >>   *
> >> + * TYPEs that put an uint64_t value with key NAME:
> >> + * 'o'    Argument is a size (think "octets").  Without suffix the
> >> + *        value is multiplied by 2^20 (mebibytes), with suffix E or e
> >> + *        by 2^60 (exbibytes), with P or p by 2^50 (pebibytes), with T
> >> + *        or t by 2^40 (tebibytes), with G or g by 2^30 (gibibytes),
> >> + *        with M or m by 2^10 (mebibytes), with K or k by 2^10
> >> + *        (kibibytes).
> > 
> > 'o' is messy.  It using qemu_strtosz_MiB which uses a 'double' intermediate
> > so I fear it can round.  It also has a note it can't take all f's due to
> > an overflow from the conversion.   Two things not mentioned are that
> > it also takes hex (as explicit 0x) and that it also does 'b' as a suffix
> > to multiply by 1.  Those two combine in bad ways - i.e. 0x1b is 27MB,
> > 1b is 1 byte (same for 'e').  These are probably OK except if you were
> > to start replacing 'l' by 'o' because you really wanted 64bit addresses
> > say.
> > (I also wouldn't bother expanding the size names and powers).
> > 
> >> + *
> >> + * TYPEs that put a double value with key NAME:
> >> + * 'T'    Argument is a time in seconds.  With optional ms, us, ns
> >> + *        suffix, the value divided by 1e3, 1e6, 1e9 respectively.
> >> + *
> >> + * TYPEs that put a bool value with key NAME:
> >> + * 'b'    Argument is either "on" (true) or "off" (false).
> >> + * '-' CHAR
> >> + *        Argument is either "-CHAR" (true) or absent (false).
> > 
> > I found the previous description clearer.
> > 
> >> + * TYPEs that put multiple values:
> >> + * 'O'    Option string of the form NAME=VALUE,... parsed according to
> >> + *        the QemuOptsList given by its name.
> >> + *        Example: 'device:O' uses qemu_device_opts.
> >> + *        Restriction: only lists with empty desc are supported.
> >> + *        Puts all the NAME=VALUE.
> >> + * '/'    Gdb-like print format (like "/10x"), always optional.
> >> + *        Puts keys "count", "format", "size", all int.
> >> + *
> >> + * Modifier character following the type string:
> >> + * '?'    Argument is optional, nothing is put when it is absent
> >> + *        (all types except 'O', '/', 'b').
> >> + * '.'    Argument is optional, must be preceded by '.' if present
> >> + *        (only types 'i', 'l', 'M')
> > 
> > That's obscure; I can only see one use of it in ioport_read and that's
> > extra-special!
> 
> It seems like the idea is that
> 
>     ioport_read 0x70.0xc
> 
> is expanded to
> 
>     write 0xc to 0x70
>     read from 0x71

Yes, and I have done that manually in the past with o/b and i.

> I can see how it can be useful for both RTC and VGA I/O ports, but on
> the other hand ioport_write doesn't support it and as you said it's
> really obscure.  I guess it can be removed or changed to not use "?",
> though it's such a nice little nugget. :)

Arguably this sugar is safer than doing it as two separate o/b and i
commands because with the lock held nothing can sneak in between the
two and change the selected port.

Dave

> Paolo
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

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

* Re: [Qemu-devel] [RFC PATCH 27/56] block/dirty-bitmap: Clean up signed vs. unsigned dirty counts
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 27/56] block/dirty-bitmap: Clean up signed vs. unsigned dirty counts Markus Armbruster
  2017-08-08  1:50   ` John Snow
@ 2017-08-08 14:53   ` Eric Blake
  2017-08-09  6:06     ` Markus Armbruster
  1 sibling, 1 reply; 105+ messages in thread
From: Eric Blake @ 2017-08-08 14:53 UTC (permalink / raw)
  To: Markus Armbruster, qemu-devel
  Cc: kwolf, mreitz, jcody, famz, jsnow, pbonzini, marcandre.lureau,
	dgilbert, quintela, berrange, qemu-block

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

On 08/07/2017 09:45 AM, Markus Armbruster wrote:
> hbitmap_count() returns uint64_t.
> 
> Clean up test-hbitmap.c to check its value with g_assert_cmpuint()
> instead of g_assert_cmpint().
> 
> bdrv_get_dirty_count() and bdrv_get_meta_dirty_count() return its
> value converted to int64_t.  Clean them up to return it unadulterated.
> 
> This moves the implicit conversion to some callers, so clean them up,
> too.
> 
> mirror_run() assigns the value of bdrv_get_meta_dirty_count() to a
> local int64_t variable.  Change it to uint64_t.  Signedness still gets
> mixed up in the computation of s->common.len, but messing with that is
> more than I can handle right now.
> 
> get_remaining_dirty() tallies bdrv_get_dirty_count() values in
> int64_t.  Its caller block_save_pending() converts it back to
> uint64_t.  Change get_remaining_dirty() to uint64_t.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  block/dirty-bitmap.c         |  4 ++--
>  block/mirror.c               |  4 ++--
>  block/trace-events           |  8 ++++----
>  include/block/dirty-bitmap.h |  4 ++--
>  migration/block.c            |  4 ++--
>  tests/test-hbitmap.c         | 16 +++++++++-------
>  6 files changed, 21 insertions(+), 19 deletions(-)

I don't know how much this will conflict with my pending work for
byte-based block status, but I suspect it may be easier for your RFC to
go in after my cleanups (I think you'll still have things to fix).

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]

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

* Re: [Qemu-devel] [RFC PATCH 28/56] block: Widen dirty bitmap granularity to uint64_t for safety
  2017-08-08  1:55   ` John Snow
@ 2017-08-08 14:55     ` Eric Blake
  2017-08-08 15:58     ` Markus Armbruster
  1 sibling, 0 replies; 105+ messages in thread
From: Eric Blake @ 2017-08-08 14:55 UTC (permalink / raw)
  To: John Snow, Markus Armbruster, qemu-devel
  Cc: kwolf, famz, qemu-block, quintela, jcody, dgilbert, mreitz,
	pbonzini, marcandre.lureau

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

On 08/07/2017 08:55 PM, John Snow wrote:
> 
> 
> On 08/07/2017 10:45 AM, Markus Armbruster wrote:
>> Block dirty bitmaps represent granularity in bytes as uint32_t.  It
>> must be a power of two and a multiple of BDRV_SECTOR_SIZE.
>>
>> The trouble with uint32_t is computations like this one in
>> mirror_do_read():
>>
>>     uint64_t max_bytes;
>>
>>     max_bytes = s->granularity * s->max_iov;
>>
>> The operands of * are uint32_t and int, so the product is computed in
>> uint32_t (assuming 32 bit int), then zero-extended to uint64_t.
>>
>> Since granularity is generally combined with 64 bit file offsets, it's
>> best to make it 64 bits, too.  Less opportunity to screw up.

And definitely conflicts with my work on byte-based block status.


>>  
>> -uint32_t bdrv_dirty_bitmap_meta_granularity(BdrvDirtyBitmap *bitmap)
>> -{
>> -    return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->meta);
>> -}
> 
> Why? Unused? Not cool enough to mention?

Already deleted as unused in my byte-based series.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]

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

* Re: [Qemu-devel] [RFC PATCH 09/56] balloon: Make balloon size unsigned in QAPI/QMP
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 09/56] balloon: Make balloon size " Markus Armbruster
@ 2017-08-08 14:58   ` Dr. David Alan Gilbert
  2017-08-09  6:04     ` Markus Armbruster
  0 siblings, 1 reply; 105+ messages in thread
From: Dr. David Alan Gilbert @ 2017-08-08 14:58 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, quintela, berrange, qemu-block

* Markus Armbruster (armbru@redhat.com) wrote:
> Sizes should use QAPI type 'size' (uint64_t).  balloon parameter
> @value is 'int' (int64_t).  qmp_balloon() implicitly converts to
> ram_addr_t, i.e. uint64_t.  BALLOON_CHANGE parameter @actual and
> BalloonInfo member @actual are also 'int'.
> virtio_balloon_set_config() and virtio_balloon_stat() implicitly
> convert from ram_addr_t.
> 
> Change all three to 'size', and adjust the code using them.
> 
> balloon now accepts size values between 2^63 and 2^64-1.  It accepts
> negative values as before, because that's how the QObject input
> visitor works for backward compatibility.
> 
> Doing the same for HMP's balloon deserves its own commit (the next
> one).
> 
> BALLOON_CHANGE and query-balloon now report sizes above 2^63-1
> correctly instead of their (negative) two's complement.
> 
> So does HMP's "info balloon".
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  balloon.c        | 2 +-
>  hmp.c            | 2 +-
>  qapi-schema.json | 4 ++--
>  qapi/event.json  | 2 +-
>  4 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/balloon.c b/balloon.c
> index 1d720ff..2ecca76 100644
> --- a/balloon.c
> +++ b/balloon.c
> @@ -102,7 +102,7 @@ BalloonInfo *qmp_query_balloon(Error **errp)
>      return info;
>  }
>  
> -void qmp_balloon(int64_t target, Error **errp)
> +void qmp_balloon(uint64_t target, Error **errp)
>  {
>      if (!have_balloon(errp)) {
>          return;

Can't you remove the:
      if (target <= 0) {

check?

(The type of the trace_balloon_event probably needs fixing
to be uint64_t rather than the unsigned long)

> diff --git a/hmp.c b/hmp.c
> index 8257dd0..4556045 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -781,7 +781,7 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
>          return;
>      }
>  
> -    monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
> +    monitor_printf(mon, "balloon: actual=%" PRIu64 "\n", info->actual >> 20);
>  
>      qapi_free_BalloonInfo(info);
>  }
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 3ad2bc0..23eb60d 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -2003,7 +2003,7 @@
>  # Since: 0.14.0
>  #
>  ##
> -{ 'struct': 'BalloonInfo', 'data': {'actual': 'int' } }
> +{ 'struct': 'BalloonInfo', 'data': {'actual': 'size' } }
>  
>  ##
>  # @query-balloon:
> @@ -2603,7 +2603,7 @@
>  # <- { "return": {} }
>  #
>  ##
> -{ 'command': 'balloon', 'data': {'value': 'int'} }
> +{ 'command': 'balloon', 'data': {'value': 'size'} }
>  
>  ##
>  # @Abort:
> diff --git a/qapi/event.json b/qapi/event.json
> index 6d22b02..9dfc70b 100644
> --- a/qapi/event.json
> +++ b/qapi/event.json
> @@ -488,7 +488,7 @@
>  #
>  ##
>  { 'event': 'BALLOON_CHANGE',
> -  'data': { 'actual': 'int' } }
> +  'data': { 'actual': 'size' } }

I was going to ask whether that was a problem for any external users,
but there again libvirt looks like it reads it into an unsigned long
long.

Dave

>  ##
>  # @GUEST_PANICKED:
> -- 
> 2.7.5
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

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

* Re: [Qemu-devel] [RFC PATCH 10/56] hmp: Make balloon's argument unsigned
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 10/56] hmp: Make balloon's argument unsigned Markus Armbruster
@ 2017-08-08 15:10   ` Dr. David Alan Gilbert
  2017-08-09  6:05     ` Markus Armbruster
  0 siblings, 1 reply; 105+ messages in thread
From: Dr. David Alan Gilbert @ 2017-08-08 15:10 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, quintela, berrange, qemu-block

* Markus Armbruster (armbru@redhat.com) wrote:
> The previous commit made it unsigned in QMP.  Switch HMP's args_type
> from 'M' to 'o'.  Loses support for expressions (QEMU pocket
> calculator), gains support for units other than mebibytes.  Negative
> values are no longer accepted and interpreted modulo 2^64.  Instead,
> values between 2^63 and 2^64-1 are now accepted.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  hmp-commands.hx | 2 +-
>  hmp.c           | 4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 1941e19..46ce79c 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1433,7 +1433,7 @@ ETEXI
>  
>      {
>          .name       = "balloon",
> -        .args_type  = "value:M",
> +        .args_type  = "value:o",
>          .params     = "target",
>          .help       = "request VM to change its memory allocation (in MB)",
>          .cmd        = hmp_balloon,
> diff --git a/hmp.c b/hmp.c
> index 4556045..1932a11 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -781,7 +781,7 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
>          return;
>      }
>  
> -    monitor_printf(mon, "balloon: actual=%" PRIu64 "\n", info->actual >> 20);
> +    monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);

That looks like a partial reversion of the last patch ?

Dave

>      qapi_free_BalloonInfo(info);
>  }
> @@ -1178,7 +1178,7 @@ void hmp_block_passwd(Monitor *mon, const QDict *qdict)
>  
>  void hmp_balloon(Monitor *mon, const QDict *qdict)
>  {
> -    int64_t value = qdict_get_int(qdict, "value");
> +    uint64_t value = qdict_get_uint(qdict, "value");
>      Error *err = NULL;
>  
>      qmp_balloon(value, &err);
> -- 
> 2.7.5
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

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

* Re: [Qemu-devel] [RFC PATCH 11/56] monitor: Drop unused HMP .args_type 'M'
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 11/56] monitor: Drop unused HMP .args_type 'M' Markus Armbruster
@ 2017-08-08 15:23   ` Dr. David Alan Gilbert
  0 siblings, 0 replies; 105+ messages in thread
From: Dr. David Alan Gilbert @ 2017-08-08 15:23 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, quintela, berrange, qemu-block

* Markus Armbruster (armbru@redhat.com) wrote:
> The previous commit switched balloon from 'M' to 'o', rendering 'M'
> unused.  It was never used for anything else.  Drop it.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>

Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

> ---
>  monitor.c | 11 +----------
>  1 file changed, 1 insertion(+), 10 deletions(-)
> 
> diff --git a/monitor.c b/monitor.c
> index 8b54ba1..3b2757e 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -101,8 +101,6 @@
>   * TYPEs that put an int64_t value with key NAME:
>   * 'l'    Argument is an expression (QEMU pocket calculator).
>   * 'i'    Like 'l' except value must fit into 32 bit unsigned.
> - * 'M'    Like 'l' except value must not be negative and is multiplied
> - *        by 2^20 (think "mebibyte").
>   *
>   * TYPEs that put an uint64_t value with key NAME:
>   * 'o'    Argument is a size (think "octets").  Without suffix the
> @@ -134,7 +132,7 @@
>   * '?'    Argument is optional, nothing is put when it is absent
>   *        (all types except 'O', '/', 'b').
>   * '.'    Argument is optional, must be preceded by '.' if present
> - *        (only types 'i', 'l', 'M')
> + *        (only types 'i', 'l')
>   */
>  
>  typedef struct mon_cmd_t {
> @@ -2913,7 +2911,6 @@ static QDict *monitor_parse_arguments(Monitor *mon,
>              break;
>          case 'i':
>          case 'l':
> -        case 'M':
>              {
>                  int64_t val;
>  
> @@ -2944,12 +2941,6 @@ static QDict *monitor_parse_arguments(Monitor *mon,
>                      monitor_printf(mon, "\'%s\' has failed: ", cmd->name);
>                      monitor_printf(mon, "integer is for 32-bit values\n");
>                      goto fail;
> -                } else if (c == 'M') {
> -                    if (val < 0) {
> -                        monitor_printf(mon, "enter a positive value\n");
> -                        goto fail;
> -                    }
> -                    val <<= 20;
>                  }
>                  qdict_put_int(qdict, key, val);
>              }
> -- 
> 2.7.5
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

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

* Re: [Qemu-devel] [RFC PATCH 32/56] hmp: Make block_set_io_throttle's arguments unsigned
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 32/56] hmp: Make block_set_io_throttle's arguments unsigned Markus Armbruster
@ 2017-08-08 15:34   ` Dr. David Alan Gilbert
  2017-08-09  6:10     ` Markus Armbruster
  0 siblings, 1 reply; 105+ messages in thread
From: Dr. David Alan Gilbert @ 2017-08-08 15:34 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, quintela, berrange, qemu-block

* Markus Armbruster (armbru@redhat.com) wrote:
> The previous commit made them unsigned in QMP.  Switch HMP's args_type
> from 'l' to 'o'.  Loses support for expressions (QEMU pocket
> calculator), gains support for unit suffixes.  Negative values are no
> longer accepted and interpreted modulo 2^64.  Instead, values between
> 2^63 and 2^64-1 are now accepted.

But that also means all these values are assumed to be in MB by default?

Dave

> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  hmp-commands.hx | 2 +-
>  hmp.c           | 6 +++---
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 46ce79c..bc3c066 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1668,7 +1668,7 @@ ETEXI
>  
>      {
>          .name       = "block_set_io_throttle",
> -        .args_type  = "device:B,bps:l,bps_rd:l,bps_wr:l,iops:l,iops_rd:l,iops_wr:l",
> +        .args_type  = "device:B,bps:o,bps_rd:o,bps_wr:o,iops:l,iops_rd:l,iops_wr:l",
>          .params     = "device bps bps_rd bps_wr iops iops_rd iops_wr",
>          .help       = "change I/O throttle limits for a block drive",
>          .cmd        = hmp_block_set_io_throttle,
> diff --git a/hmp.c b/hmp.c
> index 3253674..599e816 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -1764,9 +1764,9 @@ void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
>      BlockIOThrottle throttle = {
>          .has_device = true,
>          .device = (char *) qdict_get_str(qdict, "device"),
> -        .bps = qdict_get_int(qdict, "bps"),
> -        .bps_rd = qdict_get_int(qdict, "bps_rd"),
> -        .bps_wr = qdict_get_int(qdict, "bps_wr"),
> +        .bps = qdict_get_uint(qdict, "bps"),
> +        .bps_rd = qdict_get_uint(qdict, "bps_rd"),
> +        .bps_wr = qdict_get_uint(qdict, "bps_wr"),
>          .iops = qdict_get_int(qdict, "iops"),
>          .iops_rd = qdict_get_int(qdict, "iops_rd"),
>          .iops_wr = qdict_get_int(qdict, "iops_wr"),
> -- 
> 2.7.5
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

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

* Re: [Qemu-devel] [RFC PATCH 03/56] monitor: Rewrite comment describing HMP .args_type
  2017-08-08 11:20   ` Dr. David Alan Gilbert
  2017-08-08 14:22     ` Paolo Bonzini
@ 2017-08-08 15:36     ` Markus Armbruster
  2017-08-08 16:10       ` Dr. David Alan Gilbert
  1 sibling, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-08 15:36 UTC (permalink / raw)
  To: Dr. David Alan Gilbert
  Cc: kwolf, famz, qemu-block, quintela, jsnow, jcody, qemu-devel,
	mreitz, marcandre.lureau, pbonzini

"Dr. David Alan Gilbert" <dgilbert@redhat.com> writes:

> * Markus Armbruster (armbru@redhat.com) wrote:
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>>  monitor.c | 75 +++++++++++++++++++++++++++++++++++++++------------------------
>>  1 file changed, 47 insertions(+), 28 deletions(-)
>> 
>> diff --git a/monitor.c b/monitor.c
>> index e0f8801..8b54ba1 100644
>> --- a/monitor.c
>> +++ b/monitor.c
>> @@ -85,37 +85,56 @@
>>  #endif
>>  
>>  /*
>> - * Supported types:
>> + * Command handlers (mon_cmd_t member @cmd) receive actual arguments
>> + * in a QDict, which is built by the HMP core according to mon_cmd_t
>> + * member @args_type.  It's a list of NAME:TYPE separated by comma.
>>   *
>> - * 'F'          filename
>> - * 'B'          block device name
>> - * 's'          string (accept optional quote)
>> - * 'S'          it just appends the rest of the string (accept optional quote)
>> - * 'O'          option string of the form NAME=VALUE,...
>> - *              parsed according to QemuOptsList given by its name
>> - *              Example: 'device:O' uses qemu_device_opts.
>> - *              Restriction: only lists with empty desc are supported
>> - *              TODO lift the restriction
>> - * 'i'          32 bit integer
>> - * 'l'          target long (32 or 64 bit)
>> - * 'M'          Non-negative target long (32 or 64 bit), in user mode the
>> - *              value is multiplied by 2^20 (think Mebibyte)
>> - * 'o'          octets (aka bytes)
>> - *              user mode accepts an optional E, e, P, p, T, t, G, g, M, m,
>> - *              K, k suffix, which multiplies the value by 2^60 for suffixes E
>> - *              and e, 2^50 for suffixes P and p, 2^40 for suffixes T and t,
>> - *              2^30 for suffixes G and g, 2^20 for M and m, 2^10 for K and k
>> - * 'T'          double
>> - *              user mode accepts an optional ms, us, ns suffix,
>> - *              which divides the value by 1e3, 1e6, 1e9, respectively
>> - * '/'          optional gdb-like print format (like "/10x")
>> + * TYPEs that put a string value with key NAME into the QDict:
>> + * 's'    Argument is enclosed in '"' or delimited by whitespace.  In
>> + *        the former case, escapes \n \r \\ \' and \" are recognized.
>> + * 'F'    File name, like 's' except for completion.
>> + * 'B'    BlockBackend name, like 's' except for completion.
>> + * 'S'    Argument is the remainder of the line, less leading
>> + *        whitespace.
>> +
>>   *
>> - * '?'          optional type (for all types, except '/')
>> - * '.'          other form of optional type (for 'i' and 'l')
>> - * 'b'          boolean
>> - *              user mode accepts "on" or "off"
>> - * '-'          optional parameter (eg. '-f')
>> + * TYPEs that put an int64_t value with key NAME:
>> + * 'l'    Argument is an expression (QEMU pocket calculator).
>> + * 'i'    Like 'l' except value must fit into 32 bit unsigned.
>> + * 'M'    Like 'l' except value must not be negative and is multiplied
>> + *        by 2^20 (think "mebibyte").
>>   *
>> + * TYPEs that put an uint64_t value with key NAME:
>> + * 'o'    Argument is a size (think "octets").  Without suffix the
>> + *        value is multiplied by 2^20 (mebibytes), with suffix E or e
>> + *        by 2^60 (exbibytes), with P or p by 2^50 (pebibytes), with T
>> + *        or t by 2^40 (tebibytes), with G or g by 2^30 (gibibytes),
>> + *        with M or m by 2^10 (mebibytes), with K or k by 2^10
>> + *        (kibibytes).
>
> 'o' is messy.  It using qemu_strtosz_MiB which uses a 'double' intermediate
> so I fear it can round.

It does, but only when you have more than 53 significant bits.

>                          It also has a note it can't take all f's due to
> an overflow from the conversion.

Correct, because values between 0xfffffffffffffc00 and 2^64-1 round up
to 2^64.

If it bothers you, feel free to explore the following: feed the string
both to strtod() and to strtoll().  Whichever eats more characters wins.

This patch is of course just about better documenting what we have.  I
was starting to type something like "repeating the (complex) contract of
qemu_strtosz_MiB() here isn't so hot, let's include it by reference
instead", but then I looked it up.  Pffft.

>                                    Two things not mentioned are that
> it also takes hex (as explicit 0x) and that it also does 'b' as a suffix
> to multiply by 1.  Those two combine in bad ways - i.e. 0x1b is 27MB,
> 1b is 1 byte (same for 'e').  These are probably OK except if you were
> to start replacing 'l' by 'o' because you really wanted 64bit addresses
> say.

I guess the sanest solution is not to recognize suffixes when the number
is hexadecimal.

> (I also wouldn't bother expanding the size names and powers).

I erred on the side of tedious clarity.  Feel free to suggest something
you like better.

>> + *
>> + * TYPEs that put a double value with key NAME:
>> + * 'T'    Argument is a time in seconds.  With optional ms, us, ns
>> + *        suffix, the value divided by 1e3, 1e6, 1e9 respectively.
>> + *
>> + * TYPEs that put a bool value with key NAME:
>> + * 'b'    Argument is either "on" (true) or "off" (false).
>> + * '-' CHAR
>> + *        Argument is either "-CHAR" (true) or absent (false).
>
> I found the previous description clearer.

What I don't like about the previous description: it defines by example.
Examples are great, but they are for illustrating a definition, they
can't really replace one.

>> + * TYPEs that put multiple values:
>> + * 'O'    Option string of the form NAME=VALUE,... parsed according to
>> + *        the QemuOptsList given by its name.
>> + *        Example: 'device:O' uses qemu_device_opts.
>> + *        Restriction: only lists with empty desc are supported.
>> + *        Puts all the NAME=VALUE.
>> + * '/'    Gdb-like print format (like "/10x"), always optional.
>> + *        Puts keys "count", "format", "size", all int.
>> + *
>> + * Modifier character following the type string:
>> + * '?'    Argument is optional, nothing is put when it is absent
>> + *        (all types except 'O', '/', 'b').
>> + * '.'    Argument is optional, must be preceded by '.' if present
>> + *        (only types 'i', 'l', 'M')
>
> That's obscure; I can only see one use of it in ioport_read and that's
> extra-special!

Extra-special baroque!  Took me a while to figure out WTF it does :)

>>   */
>>  
>>  typedef struct mon_cmd_t {
>> -- 
>> 2.7.5

Thanks!

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

* Re: [Qemu-devel] [RFC PATCH 07/56] cpus: Make memsave, pmemsave sizes, addresses unsigned in QAPI/QMP
  2017-08-08 14:31   ` Dr. David Alan Gilbert
@ 2017-08-08 15:37     ` Markus Armbruster
  0 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-08 15:37 UTC (permalink / raw)
  To: Dr. David Alan Gilbert
  Cc: kwolf, famz, qemu-block, quintela, jsnow, jcody, qemu-devel,
	mreitz, marcandre.lureau, pbonzini

"Dr. David Alan Gilbert" <dgilbert@redhat.com> writes:

> * Markus Armbruster (armbru@redhat.com) wrote:
>> Sizes, virtual and physical addresses should use QAPI type 'size'
>> (uint64_t).  memsave, pmemsave parameters @val, @size are 'int'
>> (int64_t).  qmp_memsave() and qmp_pmemsave() implicitly convert to
>> target_ulong or hwaddr.
>> 
>> Change the parameters to 'size'.
>> 
>> Both commands now accept size and address values between 2^63 and
>> 2^64-1.  They accept negative values as before, because that's how the
>> QObject input visitor works for backward compatibility.
>> 
>> The HMP commands' size parameters remain uint32_t, as HMP args_type
>> strings can't do uint64_t byte counts: 'l' is signed, and 'o'
>> multiplies by 2^20.  Their address parameters remain int64_t for the
>> same reason.
>> 
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>>  cpus.c           | 6 +++---
>>  qapi-schema.json | 5 +++--
>>  2 files changed, 6 insertions(+), 5 deletions(-)
>> 
>> diff --git a/cpus.c b/cpus.c
>> index 9bed61e..8c5ee05 100644
>> --- a/cpus.c
>> +++ b/cpus.c
>> @@ -1947,14 +1947,14 @@ CpuInfoList *qmp_query_cpus(Error **errp)
>>      return head;
>>  }
>>  
>> -void qmp_memsave(int64_t addr, int64_t size, const char *filename,
>> +void qmp_memsave(uint64_t addr, uint64_t size, const char *filename,
>>                   bool has_cpu, int64_t cpu_index, Error **errp)
>>  {
>>      FILE *f;
>>      uint32_t l;
>>      CPUState *cpu;
>>      uint8_t buf[1024];
>> -    int64_t orig_addr = addr, orig_size = size;
>> +    uint64_t orig_addr = addr, orig_size = size;
>>  
>>      if (!has_cpu) {
>>          cpu_index = 0;
>
> a little bit further down is a:
>             error_setg(errp, "Invalid addr 0x%016" PRIx64 "/size %" PRId64
>                              " specified", orig_addr, orig_size);
>
> that PRId64 should be a PRIu64 now

Will fix.

> However, other than that;
>
>
> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

Thanks!

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

* Re: [Qemu-devel] [RFC PATCH 15/56] migration: Make XBZRLE cache size unsigned in QAPI/QMP
  2017-08-07 16:10   ` Juan Quintela
@ 2017-08-08 15:57     ` Markus Armbruster
  0 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-08 15:57 UTC (permalink / raw)
  To: Juan Quintela
  Cc: kwolf, famz, qemu-block, jsnow, jcody, qemu-devel, mreitz,
	marcandre.lureau, pbonzini, dgilbert

Juan Quintela <quintela@redhat.com> writes:

> Markus Armbruster <armbru@redhat.com> wrote:
>> Sizes should use QAPI type 'size' (uint64_t).  migrate-set-cache-size
>> parameter @value is 'int' (int64_t).  qmp_migrate_set_cache_size()
>> ensures it fits into size_t.  page_cache.c implicitly converts the
>> signed size to unsigned types (it can't quite decide whether to use
>> uint64_t or size_t for cache offsets, but that's not something I can
>> tackle now).
>>
>> XBZRLECacheStats member @cache-size and query-migrate-cache-size's
>> result are also 'int'.
>>
>> Change the migrate-set-cache-size parameter and the XBZRLECacheStats
>> members to 'size', fix up hmp_migrate_set_cache_size(), and tweak a
>> few variable types to reduce implicit conversions.
>>
>> migrate-set-cache-size now accepts size values between 2^63 and
>> 2^64-1.  It accepts negative values as before, because that's how the
>> QObject input visitor works for backward compatibility.
>>
>> So does HMP's migrate_set_cache_size.
>>
>> query-migrate and query-migrate-cache-size now report cache sizes
>> above 2^63-1 correctly instead of their (negative) two's complement.
>>
>> So does HMP's "info migrate_cache_size".  HMP's "info migrate" already
>> reported the cache size correctly, because it printed the signed
>> integer with PRIu32.
>>
>
> Reviewed-by: Juan Quintela <quintela@redhat.com>
>
>
>> diff --git a/qapi-schema.json b/qapi-schema.json
>> index c8cceb9..ecabff6 100644
>> --- a/qapi-schema.json
>> +++ b/qapi-schema.json
>> @@ -646,7 +646,7 @@
>>  # Since: 1.2
>>  ##
>>  { 'struct': 'XBZRLECacheStats',
>> -  'data': {'cache-size': 'int', 'bytes': 'int', 'pages': 'int',
>> +  'data': {'cache-size': 'size', 'bytes': 'int', 'pages': 'int',
>>             'cache-miss': 'int', 'cache-miss-rate': 'number',
>>             'overflow': 'int' } }
>>  
>> @@ -2875,7 +2875,7 @@
>>  # <- { "return": {} }
>>  #
>>  ##
>> -{ 'command': 'migrate-set-cache-size', 'data': {'value': 'int'} }
>> +{ 'command': 'migrate-set-cache-size', 'data': {'value': 'size'} }
>>  
>>  ##
>>  # @query-migrate-cache-size:
>> @@ -2892,7 +2892,7 @@
>>  # <- { "return": 67108864 }
>>  #
>>  ##
>> -{ 'command': 'query-migrate-cache-size', 'returns': 'int' }
>> +{ 'command': 'query-migrate-cache-size', 'returns': 'size' }
>>  
>>  ##
>>  # @ObjectPropertyInfo:
>
> I am ussming this bits are backward compatible (I don't understand QMP
> to assure this)

I guess I should've explained this in the cover letter.

Until recent commit 5923f85, integers between INT64_MAX+1 and UINT64_MAX
did not work in QMP.  QEMU sent and accepted integers between INT64_MIN
and -1 instead.

The fix maintains strict compatibility for QMP input: negative integers
are accepted as before for backward compatibility.  Perhaps we can get
rid of this wart some day.

It does not maintain strict compatibility for QMP output: we now output
the correct integer.  We figure that's tolerable, because the obvious
way to parse the old output is strtoull(), and that does the right thing
for the new output when it does the right thing for the old output.

Fixing a QAPI type from 'int' to 'size' has the same compatibility
impact.

Questions?

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

* Re: [Qemu-devel] [RFC PATCH 28/56] block: Widen dirty bitmap granularity to uint64_t for safety
  2017-08-08  1:55   ` John Snow
  2017-08-08 14:55     ` Eric Blake
@ 2017-08-08 15:58     ` Markus Armbruster
  1 sibling, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-08 15:58 UTC (permalink / raw)
  To: John Snow
  Cc: qemu-devel, kwolf, famz, qemu-block, quintela, jcody, dgilbert,
	mreitz, pbonzini, marcandre.lureau

John Snow <jsnow@redhat.com> writes:

> On 08/07/2017 10:45 AM, Markus Armbruster wrote:
>> Block dirty bitmaps represent granularity in bytes as uint32_t.  It
>> must be a power of two and a multiple of BDRV_SECTOR_SIZE.
>> 
>> The trouble with uint32_t is computations like this one in
>> mirror_do_read():
>> 
>>     uint64_t max_bytes;
>> 
>>     max_bytes = s->granularity * s->max_iov;
>> 
>> The operands of * are uint32_t and int, so the product is computed in
>> uint32_t (assuming 32 bit int), then zero-extended to uint64_t.
>> 
>> Since granularity is generally combined with 64 bit file offsets, it's
>> best to make it 64 bits, too.  Less opportunity to screw up.
>> 
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>
> [bweeooop]
>
>> --- a/block/dirty-bitmap.c
>> +++ b/block/dirty-bitmap.c
>
> [buuuuweeeep]
>
>> @@ -506,16 +506,11 @@ uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
>>      return granularity;
>>  }
>>  
>> -uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
>> +uint64_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
>>  {
>>      return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap);
>>  }
>>  
>> -uint32_t bdrv_dirty_bitmap_meta_granularity(BdrvDirtyBitmap *bitmap)
>> -{
>> -    return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->meta);
>> -}
>
> Why? Unused? Not cool enough to mention?

I didn't feel like fixing an unused function, so I dropped it.  Can
mention this in the commit message.

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

* Re: [Qemu-devel] [RFC PATCH 29/56] block: Make BlockDirtyInfo byte count unsigned in QAPI/QMP
  2017-08-08  1:56   ` John Snow
@ 2017-08-08 15:58     ` Markus Armbruster
  0 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-08 15:58 UTC (permalink / raw)
  To: John Snow
  Cc: qemu-devel, kwolf, famz, qemu-block, quintela, jcody, dgilbert,
	mreitz, pbonzini, marcandre.lureau

John Snow <jsnow@redhat.com> writes:

> On 08/07/2017 10:45 AM, Markus Armbruster wrote:
>> Byte counts should use QAPI type 'size' (uint64_t).  BlockDirtyInfo
>> member @count is 'int' (int64_t).  bdrv_query_dirty_bitmaps() computes
>> @count from bdrv_get_dirty_count() in uint64_t, then implicitly
>> converts to int64_t.  Before the commit before previous, the
>> conversion was in bdrv_get_dirty_count() instead.
>> 
>> Change member @count to 'size'.
>> 
>> query-block now reports @count values above 2^63-1 correctly instead
>> of their (negative) two's complement.
>> 
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>
> Assuming there's no "gotcha" here introduced by changing the QAPI, then
> ACK; but you're the expert there, so I trust you!

Juan asked the same question on PATCH 15, see my reply there.

> Reviewed-by: John Snow <jsnow@redhat.com>

Thanks!

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

* Re: [Qemu-devel] [RFC PATCH 03/56] monitor: Rewrite comment describing HMP .args_type
  2017-08-08 15:36     ` Markus Armbruster
@ 2017-08-08 16:10       ` Dr. David Alan Gilbert
  2017-08-09  6:00         ` Markus Armbruster
  0 siblings, 1 reply; 105+ messages in thread
From: Dr. David Alan Gilbert @ 2017-08-08 16:10 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: kwolf, famz, qemu-block, quintela, jsnow, jcody, qemu-devel,
	mreitz, marcandre.lureau, pbonzini

* Markus Armbruster (armbru@redhat.com) wrote:
> "Dr. David Alan Gilbert" <dgilbert@redhat.com> writes:
> 
> > * Markus Armbruster (armbru@redhat.com) wrote:
> >> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> >> ---
> >>  monitor.c | 75 +++++++++++++++++++++++++++++++++++++++------------------------
> >>  1 file changed, 47 insertions(+), 28 deletions(-)
> >> 
> >> diff --git a/monitor.c b/monitor.c
> >> index e0f8801..8b54ba1 100644
> >> --- a/monitor.c
> >> +++ b/monitor.c
> >> @@ -85,37 +85,56 @@
> >>  #endif
> >>  
> >>  /*
> >> - * Supported types:
> >> + * Command handlers (mon_cmd_t member @cmd) receive actual arguments
> >> + * in a QDict, which is built by the HMP core according to mon_cmd_t
> >> + * member @args_type.  It's a list of NAME:TYPE separated by comma.
> >>   *
> >> - * 'F'          filename
> >> - * 'B'          block device name
> >> - * 's'          string (accept optional quote)
> >> - * 'S'          it just appends the rest of the string (accept optional quote)
> >> - * 'O'          option string of the form NAME=VALUE,...
> >> - *              parsed according to QemuOptsList given by its name
> >> - *              Example: 'device:O' uses qemu_device_opts.
> >> - *              Restriction: only lists with empty desc are supported
> >> - *              TODO lift the restriction
> >> - * 'i'          32 bit integer
> >> - * 'l'          target long (32 or 64 bit)
> >> - * 'M'          Non-negative target long (32 or 64 bit), in user mode the
> >> - *              value is multiplied by 2^20 (think Mebibyte)
> >> - * 'o'          octets (aka bytes)
> >> - *              user mode accepts an optional E, e, P, p, T, t, G, g, M, m,
> >> - *              K, k suffix, which multiplies the value by 2^60 for suffixes E
> >> - *              and e, 2^50 for suffixes P and p, 2^40 for suffixes T and t,
> >> - *              2^30 for suffixes G and g, 2^20 for M and m, 2^10 for K and k
> >> - * 'T'          double
> >> - *              user mode accepts an optional ms, us, ns suffix,
> >> - *              which divides the value by 1e3, 1e6, 1e9, respectively
> >> - * '/'          optional gdb-like print format (like "/10x")
> >> + * TYPEs that put a string value with key NAME into the QDict:
> >> + * 's'    Argument is enclosed in '"' or delimited by whitespace.  In
> >> + *        the former case, escapes \n \r \\ \' and \" are recognized.
> >> + * 'F'    File name, like 's' except for completion.
> >> + * 'B'    BlockBackend name, like 's' except for completion.
> >> + * 'S'    Argument is the remainder of the line, less leading
> >> + *        whitespace.
> >> +
> >>   *
> >> - * '?'          optional type (for all types, except '/')
> >> - * '.'          other form of optional type (for 'i' and 'l')
> >> - * 'b'          boolean
> >> - *              user mode accepts "on" or "off"
> >> - * '-'          optional parameter (eg. '-f')
> >> + * TYPEs that put an int64_t value with key NAME:
> >> + * 'l'    Argument is an expression (QEMU pocket calculator).
> >> + * 'i'    Like 'l' except value must fit into 32 bit unsigned.
> >> + * 'M'    Like 'l' except value must not be negative and is multiplied
> >> + *        by 2^20 (think "mebibyte").
> >>   *
> >> + * TYPEs that put an uint64_t value with key NAME:
> >> + * 'o'    Argument is a size (think "octets").  Without suffix the
> >> + *        value is multiplied by 2^20 (mebibytes), with suffix E or e
> >> + *        by 2^60 (exbibytes), with P or p by 2^50 (pebibytes), with T
> >> + *        or t by 2^40 (tebibytes), with G or g by 2^30 (gibibytes),
> >> + *        with M or m by 2^10 (mebibytes), with K or k by 2^10
> >> + *        (kibibytes).
> >
> > 'o' is messy.  It using qemu_strtosz_MiB which uses a 'double' intermediate
> > so I fear it can round.
> 
> It does, but only when you have more than 53 significant bits.
> 
> >                          It also has a note it can't take all f's due to
> > an overflow from the conversion.
> 
> Correct, because values between 0xfffffffffffffc00 and 2^64-1 round up
> to 2^64.

Right, so these bother me not for normal sizes, but if we were to start
to use them for hex values with meanings, like addresses for example.
(Although I guess that's unlikely with the default assumption of MB)

> If it bothers you, feel free to explore the following: feed the string
> both to strtod() and to strtoll().  Whichever eats more characters wins.

Is the reason we're using strtod because we actively want users to be
able to say 3.5G ?  I guess that's a reason to keep it.

> This patch is of course just about better documenting what we have.  I
> was starting to type something like "repeating the (complex) contract of
> qemu_strtosz_MiB() here isn't so hot, let's include it by reference
> instead", but then I looked it up.  Pffft.
> 
> >                                    Two things not mentioned are that
> > it also takes hex (as explicit 0x) and that it also does 'b' as a suffix
> > to multiply by 1.  Those two combine in bad ways - i.e. 0x1b is 27MB,
> > 1b is 1 byte (same for 'e').  These are probably OK except if you were
> > to start replacing 'l' by 'o' because you really wanted 64bit addresses
> > say.
> 
> I guess the sanest solution is not to recognize suffixes when the number
> is hexadecimal.
> 
> > (I also wouldn't bother expanding the size names and powers).
> 
> I erred on the side of tedious clarity.  Feel free to suggest something
> you like better.

I think something like:
  The optional suffix's b/k/m/g/t/p/e are accepted (upper or lower case)
  to denote bytes, kibibytes, mebibytes etc.  With no suffix, values
  are interpreted as MiB.

> >> + *
> >> + * TYPEs that put a double value with key NAME:
> >> + * 'T'    Argument is a time in seconds.  With optional ms, us, ns
> >> + *        suffix, the value divided by 1e3, 1e6, 1e9 respectively.
> >> + *
> >> + * TYPEs that put a bool value with key NAME:
> >> + * 'b'    Argument is either "on" (true) or "off" (false).
> >> + * '-' CHAR
> >> + *        Argument is either "-CHAR" (true) or absent (false).
> >
> > I found the previous description clearer.
> 
> What I don't like about the previous description: it defines by example.
> Examples are great, but they are for illustrating a definition, they
> can't really replace one.

I'm less fussy if it's clear; how about
   '-' CHAR
       True if optional single character argument (e.g. -f) is present
       else absent.

  since you've got the '-' CHAR   you have the definition.

> >> + * TYPEs that put multiple values:
> >> + * 'O'    Option string of the form NAME=VALUE,... parsed according to
> >> + *        the QemuOptsList given by its name.
> >> + *        Example: 'device:O' uses qemu_device_opts.
> >> + *        Restriction: only lists with empty desc are supported.
> >> + *        Puts all the NAME=VALUE.
> >> + * '/'    Gdb-like print format (like "/10x"), always optional.
> >> + *        Puts keys "count", "format", "size", all int.
> >> + *
> >> + * Modifier character following the type string:
> >> + * '?'    Argument is optional, nothing is put when it is absent
> >> + *        (all types except 'O', '/', 'b').
> >> + * '.'    Argument is optional, must be preceded by '.' if present
> >> + *        (only types 'i', 'l', 'M')
> >
> > That's obscure; I can only see one use of it in ioport_read and that's
> > extra-special!
> 
> Extra-special baroque!  Took me a while to figure out WTF it does :)

Should we avoid a lot of the 'o' pain by adding a new type; something
like:
  '6'
      A 64bit unsigned value.  Decimal or hex integers are accepted;
   optional suffixes of k/m/g/t/p/e are accepted to denote kibibytes
   etc.  With no suffix values are interpreted as bytes.

  then that would be suffix_mul() * qemu_strtou64()

Dave

> >>   */
> >>  
> >>  typedef struct mon_cmd_t {
> >> -- 
> >> 2.7.5
> 
> Thanks!
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

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

* Re: [Qemu-devel] [RFC PATCH 03/56] monitor: Rewrite comment describing HMP .args_type
  2017-08-08 16:10       ` Dr. David Alan Gilbert
@ 2017-08-09  6:00         ` Markus Armbruster
  0 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-09  6:00 UTC (permalink / raw)
  To: Dr. David Alan Gilbert
  Cc: kwolf, famz, qemu-block, quintela, jcody, qemu-devel, mreitz,
	pbonzini, marcandre.lureau, jsnow

"Dr. David Alan Gilbert" <dgilbert@redhat.com> writes:

> * Markus Armbruster (armbru@redhat.com) wrote:
>> "Dr. David Alan Gilbert" <dgilbert@redhat.com> writes:
>> 
>> > * Markus Armbruster (armbru@redhat.com) wrote:
>> >> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> >> ---
>> >>  monitor.c | 75 +++++++++++++++++++++++++++++++++++++++------------------------
>> >>  1 file changed, 47 insertions(+), 28 deletions(-)
>> >> 
>> >> diff --git a/monitor.c b/monitor.c
>> >> index e0f8801..8b54ba1 100644
>> >> --- a/monitor.c
>> >> +++ b/monitor.c
>> >> @@ -85,37 +85,56 @@
>> >>  #endif
>> >>  
>> >>  /*
>> >> - * Supported types:
>> >> + * Command handlers (mon_cmd_t member @cmd) receive actual arguments
>> >> + * in a QDict, which is built by the HMP core according to mon_cmd_t
>> >> + * member @args_type.  It's a list of NAME:TYPE separated by comma.
>> >>   *
>> >> - * 'F'          filename
>> >> - * 'B'          block device name
>> >> - * 's'          string (accept optional quote)
>> >> - * 'S'          it just appends the rest of the string (accept optional quote)
>> >> - * 'O'          option string of the form NAME=VALUE,...
>> >> - *              parsed according to QemuOptsList given by its name
>> >> - *              Example: 'device:O' uses qemu_device_opts.
>> >> - *              Restriction: only lists with empty desc are supported
>> >> - *              TODO lift the restriction
>> >> - * 'i'          32 bit integer
>> >> - * 'l'          target long (32 or 64 bit)
>> >> - * 'M'          Non-negative target long (32 or 64 bit), in user mode the
>> >> - *              value is multiplied by 2^20 (think Mebibyte)
>> >> - * 'o'          octets (aka bytes)
>> >> - *              user mode accepts an optional E, e, P, p, T, t, G, g, M, m,
>> >> - *              K, k suffix, which multiplies the value by 2^60 for suffixes E
>> >> - *              and e, 2^50 for suffixes P and p, 2^40 for suffixes T and t,
>> >> - *              2^30 for suffixes G and g, 2^20 for M and m, 2^10 for K and k
>> >> - * 'T'          double
>> >> - *              user mode accepts an optional ms, us, ns suffix,
>> >> - *              which divides the value by 1e3, 1e6, 1e9, respectively
>> >> - * '/'          optional gdb-like print format (like "/10x")
>> >> + * TYPEs that put a string value with key NAME into the QDict:
>> >> + * 's'    Argument is enclosed in '"' or delimited by whitespace.  In
>> >> + *        the former case, escapes \n \r \\ \' and \" are recognized.
>> >> + * 'F'    File name, like 's' except for completion.
>> >> + * 'B'    BlockBackend name, like 's' except for completion.
>> >> + * 'S'    Argument is the remainder of the line, less leading
>> >> + *        whitespace.
>> >> +
>> >>   *
>> >> - * '?'          optional type (for all types, except '/')
>> >> - * '.'          other form of optional type (for 'i' and 'l')
>> >> - * 'b'          boolean
>> >> - *              user mode accepts "on" or "off"
>> >> - * '-'          optional parameter (eg. '-f')
>> >> + * TYPEs that put an int64_t value with key NAME:
>> >> + * 'l'    Argument is an expression (QEMU pocket calculator).
>> >> + * 'i'    Like 'l' except value must fit into 32 bit unsigned.
>> >> + * 'M'    Like 'l' except value must not be negative and is multiplied
>> >> + *        by 2^20 (think "mebibyte").
>> >>   *
>> >> + * TYPEs that put an uint64_t value with key NAME:
>> >> + * 'o'    Argument is a size (think "octets").  Without suffix the
>> >> + *        value is multiplied by 2^20 (mebibytes), with suffix E or e
>> >> + *        by 2^60 (exbibytes), with P or p by 2^50 (pebibytes), with T
>> >> + *        or t by 2^40 (tebibytes), with G or g by 2^30 (gibibytes),
>> >> + *        with M or m by 2^10 (mebibytes), with K or k by 2^10
>> >> + *        (kibibytes).
>> >
>> > 'o' is messy.  It using qemu_strtosz_MiB which uses a 'double' intermediate
>> > so I fear it can round.
>> 
>> It does, but only when you have more than 53 significant bits.
>> 
>> >                          It also has a note it can't take all f's due to
>> > an overflow from the conversion.
>> 
>> Correct, because values between 0xfffffffffffffc00 and 2^64-1 round up
>> to 2^64.
>
> Right, so these bother me not for normal sizes, but if we were to start
> to use them for hex values with meanings, like addresses for example.
> (Although I guess that's unlikely with the default assumption of MB)

Yes, 'o' is convenient in some cases, inconvenient in others, and
incapable when you need more than 53 significant bits.

>> If it bothers you, feel free to explore the following: feed the string
>> both to strtod() and to strtoll().  Whichever eats more characters wins.
>
> Is the reason we're using strtod because we actively want users to be
> able to say 3.5G ?  I guess that's a reason to keep it.

Early (and flawed) version(s) of the patch introducing strtosz() used
strtoll().  Jes decided to switch to strtod() precisely to support
things like 3.5G.

>> This patch is of course just about better documenting what we have.  I
>> was starting to type something like "repeating the (complex) contract of
>> qemu_strtosz_MiB() here isn't so hot, let's include it by reference
>> instead", but then I looked it up.  Pffft.
>> 
>> >                                    Two things not mentioned are that
>> > it also takes hex (as explicit 0x) and that it also does 'b' as a suffix
>> > to multiply by 1.  Those two combine in bad ways - i.e. 0x1b is 27MB,
>> > 1b is 1 byte (same for 'e').  These are probably OK except if you were
>> > to start replacing 'l' by 'o' because you really wanted 64bit addresses
>> > say.
>> 
>> I guess the sanest solution is not to recognize suffixes when the number
>> is hexadecimal.
>> 
>> > (I also wouldn't bother expanding the size names and powers).
>> 
>> I erred on the side of tedious clarity.  Feel free to suggest something
>> you like better.
>
> I think something like:
>   The optional suffix's b/k/m/g/t/p/e are accepted (upper or lower case)
>   to denote bytes, kibibytes, mebibytes etc.  With no suffix, values
>   are interpreted as MiB.

I like it.  I'll fix "suffix's" to "suffixes", and list the suffixes in
their "officially correct" case "b/k/M/G/T/P/E".

>> >> + *
>> >> + * TYPEs that put a double value with key NAME:
>> >> + * 'T'    Argument is a time in seconds.  With optional ms, us, ns
>> >> + *        suffix, the value divided by 1e3, 1e6, 1e9 respectively.
>> >> + *
>> >> + * TYPEs that put a bool value with key NAME:
>> >> + * 'b'    Argument is either "on" (true) or "off" (false).
>> >> + * '-' CHAR
>> >> + *        Argument is either "-CHAR" (true) or absent (false).
>> >
>> > I found the previous description clearer.
>> 
>> What I don't like about the previous description: it defines by example.
>> Examples are great, but they are for illustrating a definition, they
>> can't really replace one.
>
> I'm less fussy if it's clear; how about
>    '-' CHAR
>        True if optional single character argument (e.g. -f) is present
>        else absent.
>
>   since you've got the '-' CHAR   you have the definition.

Sold.

>> >> + * TYPEs that put multiple values:
>> >> + * 'O'    Option string of the form NAME=VALUE,... parsed according to
>> >> + *        the QemuOptsList given by its name.
>> >> + *        Example: 'device:O' uses qemu_device_opts.
>> >> + *        Restriction: only lists with empty desc are supported.
>> >> + *        Puts all the NAME=VALUE.
>> >> + * '/'    Gdb-like print format (like "/10x"), always optional.
>> >> + *        Puts keys "count", "format", "size", all int.
>> >> + *
>> >> + * Modifier character following the type string:
>> >> + * '?'    Argument is optional, nothing is put when it is absent
>> >> + *        (all types except 'O', '/', 'b').
>> >> + * '.'    Argument is optional, must be preceded by '.' if present
>> >> + *        (only types 'i', 'l', 'M')
>> >
>> > That's obscure; I can only see one use of it in ioport_read and that's
>> > extra-special!
>> 
>> Extra-special baroque!  Took me a while to figure out WTF it does :)
>
> Should we avoid a lot of the 'o' pain by adding a new type; something
> like:
>   '6'
>       A 64bit unsigned value.  Decimal or hex integers are accepted;
>    optional suffixes of k/m/g/t/p/e are accepted to denote kibibytes
>    etc.  With no suffix values are interpreted as bytes.
>
>   then that would be suffix_mul() * qemu_strtou64()

Feels like a good idea.  Of course you need to find a few uses for it.

Might even want to discourage new uses of 'o' then.

>
> Dave
>
>> >>   */
>> >>  
>> >>  typedef struct mon_cmd_t {
>> >> -- 
>> >> 2.7.5
>> 
>> Thanks!
> --
> Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

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

* Re: [Qemu-devel] [RFC PATCH 09/56] balloon: Make balloon size unsigned in QAPI/QMP
  2017-08-08 14:58   ` Dr. David Alan Gilbert
@ 2017-08-09  6:04     ` Markus Armbruster
  2017-08-09 10:47       ` Dr. David Alan Gilbert
  0 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-09  6:04 UTC (permalink / raw)
  To: Dr. David Alan Gilbert
  Cc: kwolf, famz, qemu-block, quintela, jsnow, jcody, qemu-devel,
	mreitz, marcandre.lureau, pbonzini

"Dr. David Alan Gilbert" <dgilbert@redhat.com> writes:

> * Markus Armbruster (armbru@redhat.com) wrote:
>> Sizes should use QAPI type 'size' (uint64_t).  balloon parameter
>> @value is 'int' (int64_t).  qmp_balloon() implicitly converts to
>> ram_addr_t, i.e. uint64_t.  BALLOON_CHANGE parameter @actual and
>> BalloonInfo member @actual are also 'int'.
>> virtio_balloon_set_config() and virtio_balloon_stat() implicitly
>> convert from ram_addr_t.
>> 
>> Change all three to 'size', and adjust the code using them.
>> 
>> balloon now accepts size values between 2^63 and 2^64-1.  It accepts
>> negative values as before, because that's how the QObject input
>> visitor works for backward compatibility.
>> 
>> Doing the same for HMP's balloon deserves its own commit (the next
>> one).
>> 
>> BALLOON_CHANGE and query-balloon now report sizes above 2^63-1
>> correctly instead of their (negative) two's complement.
>> 
>> So does HMP's "info balloon".
>> 
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>>  balloon.c        | 2 +-
>>  hmp.c            | 2 +-
>>  qapi-schema.json | 4 ++--
>>  qapi/event.json  | 2 +-
>>  4 files changed, 5 insertions(+), 5 deletions(-)
>> 
>> diff --git a/balloon.c b/balloon.c
>> index 1d720ff..2ecca76 100644
>> --- a/balloon.c
>> +++ b/balloon.c
>> @@ -102,7 +102,7 @@ BalloonInfo *qmp_query_balloon(Error **errp)
>>      return info;
>>  }
>>  
>> -void qmp_balloon(int64_t target, Error **errp)
>> +void qmp_balloon(uint64_t target, Error **errp)
>>  {
>>      if (!have_balloon(errp)) {
>>          return;
>
> Can't you remove the:
>       if (target <= 0) {
>
> check?

Functional change when target == 0.  Impact is not clear to me.

> (The type of the trace_balloon_event probably needs fixing
> to be uint64_t rather than the unsigned long)

You're right.  I'll fix it.

>> diff --git a/hmp.c b/hmp.c
>> index 8257dd0..4556045 100644
>> --- a/hmp.c
>> +++ b/hmp.c
>> @@ -781,7 +781,7 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
>>          return;
>>      }
>>  
>> -    monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
>> +    monitor_printf(mon, "balloon: actual=%" PRIu64 "\n", info->actual >> 20);
>>  
>>      qapi_free_BalloonInfo(info);
>>  }
>> diff --git a/qapi-schema.json b/qapi-schema.json
>> index 3ad2bc0..23eb60d 100644
>> --- a/qapi-schema.json
>> +++ b/qapi-schema.json
>> @@ -2003,7 +2003,7 @@
>>  # Since: 0.14.0
>>  #
>>  ##
>> -{ 'struct': 'BalloonInfo', 'data': {'actual': 'int' } }
>> +{ 'struct': 'BalloonInfo', 'data': {'actual': 'size' } }
>>  
>>  ##
>>  # @query-balloon:
>> @@ -2603,7 +2603,7 @@
>>  # <- { "return": {} }
>>  #
>>  ##
>> -{ 'command': 'balloon', 'data': {'value': 'int'} }
>> +{ 'command': 'balloon', 'data': {'value': 'size'} }
>>  
>>  ##
>>  # @Abort:
>> diff --git a/qapi/event.json b/qapi/event.json
>> index 6d22b02..9dfc70b 100644
>> --- a/qapi/event.json
>> +++ b/qapi/event.json
>> @@ -488,7 +488,7 @@
>>  #
>>  ##
>>  { 'event': 'BALLOON_CHANGE',
>> -  'data': { 'actual': 'int' } }
>> +  'data': { 'actual': 'size' } }
>
> I was going to ask whether that was a problem for any external users,
> but there again libvirt looks like it reads it into an unsigned long
> long.

Yes.  See also my reply to Juan's review of PATCH 15.

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

* Re: [Qemu-devel] [RFC PATCH 10/56] hmp: Make balloon's argument unsigned
  2017-08-08 15:10   ` Dr. David Alan Gilbert
@ 2017-08-09  6:05     ` Markus Armbruster
  0 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-09  6:05 UTC (permalink / raw)
  To: Dr. David Alan Gilbert
  Cc: kwolf, famz, qemu-block, quintela, jsnow, jcody, qemu-devel,
	mreitz, marcandre.lureau, pbonzini

"Dr. David Alan Gilbert" <dgilbert@redhat.com> writes:

> * Markus Armbruster (armbru@redhat.com) wrote:
>> The previous commit made it unsigned in QMP.  Switch HMP's args_type
>> from 'M' to 'o'.  Loses support for expressions (QEMU pocket
>> calculator), gains support for units other than mebibytes.  Negative
>> values are no longer accepted and interpreted modulo 2^64.  Instead,
>> values between 2^63 and 2^64-1 are now accepted.
>> 
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>>  hmp-commands.hx | 2 +-
>>  hmp.c           | 4 ++--
>>  2 files changed, 3 insertions(+), 3 deletions(-)
>> 
>> diff --git a/hmp-commands.hx b/hmp-commands.hx
>> index 1941e19..46ce79c 100644
>> --- a/hmp-commands.hx
>> +++ b/hmp-commands.hx
>> @@ -1433,7 +1433,7 @@ ETEXI
>>  
>>      {
>>          .name       = "balloon",
>> -        .args_type  = "value:M",
>> +        .args_type  = "value:o",
>>          .params     = "target",
>>          .help       = "request VM to change its memory allocation (in MB)",
>>          .cmd        = hmp_balloon,
>> diff --git a/hmp.c b/hmp.c
>> index 4556045..1932a11 100644
>> --- a/hmp.c
>> +++ b/hmp.c
>> @@ -781,7 +781,7 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
>>          return;
>>      }
>>  
>> -    monitor_printf(mon, "balloon: actual=%" PRIu64 "\n", info->actual >> 20);
>> +    monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
>
> That looks like a partial reversion of the last patch ?

Accident, will fix, thanks!

[...]

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

* Re: [Qemu-devel] [RFC PATCH 27/56] block/dirty-bitmap: Clean up signed vs. unsigned dirty counts
  2017-08-08 14:53   ` Eric Blake
@ 2017-08-09  6:06     ` Markus Armbruster
  0 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-09  6:06 UTC (permalink / raw)
  To: Eric Blake
  Cc: qemu-devel, kwolf, famz, qemu-block, quintela, jcody, dgilbert,
	mreitz, marcandre.lureau, pbonzini, jsnow

Eric Blake <eblake@redhat.com> writes:

> On 08/07/2017 09:45 AM, Markus Armbruster wrote:
>> hbitmap_count() returns uint64_t.
>> 
>> Clean up test-hbitmap.c to check its value with g_assert_cmpuint()
>> instead of g_assert_cmpint().
>> 
>> bdrv_get_dirty_count() and bdrv_get_meta_dirty_count() return its
>> value converted to int64_t.  Clean them up to return it unadulterated.
>> 
>> This moves the implicit conversion to some callers, so clean them up,
>> too.
>> 
>> mirror_run() assigns the value of bdrv_get_meta_dirty_count() to a
>> local int64_t variable.  Change it to uint64_t.  Signedness still gets
>> mixed up in the computation of s->common.len, but messing with that is
>> more than I can handle right now.
>> 
>> get_remaining_dirty() tallies bdrv_get_dirty_count() values in
>> int64_t.  Its caller block_save_pending() converts it back to
>> uint64_t.  Change get_remaining_dirty() to uint64_t.
>> 
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>>  block/dirty-bitmap.c         |  4 ++--
>>  block/mirror.c               |  4 ++--
>>  block/trace-events           |  8 ++++----
>>  include/block/dirty-bitmap.h |  4 ++--
>>  migration/block.c            |  4 ++--
>>  tests/test-hbitmap.c         | 16 +++++++++-------
>>  6 files changed, 21 insertions(+), 19 deletions(-)
>
> I don't know how much this will conflict with my pending work for
> byte-based block status, but I suspect it may be easier for your RFC to
> go in after my cleanups (I think you'll still have things to fix).

I fully expect to rebase on your work.

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

* Re: [Qemu-devel] [RFC PATCH 32/56] hmp: Make block_set_io_throttle's arguments unsigned
  2017-08-08 15:34   ` Dr. David Alan Gilbert
@ 2017-08-09  6:10     ` Markus Armbruster
  0 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-09  6:10 UTC (permalink / raw)
  To: Dr. David Alan Gilbert
  Cc: kwolf, famz, qemu-block, quintela, jsnow, jcody, qemu-devel,
	mreitz, marcandre.lureau, pbonzini

"Dr. David Alan Gilbert" <dgilbert@redhat.com> writes:

> * Markus Armbruster (armbru@redhat.com) wrote:
>> The previous commit made them unsigned in QMP.  Switch HMP's args_type
>> from 'l' to 'o'.  Loses support for expressions (QEMU pocket
>> calculator), gains support for unit suffixes.  Negative values are no
>> longer accepted and interpreted modulo 2^64.  Instead, values between
>> 2^63 and 2^64-1 are now accepted.
>
> But that also means all these values are assumed to be in MB by default?

Yes.

We could debate whether that's acceptable, as HMP is not a stable
interface, but as a matter of fact, I'm no friend of defaulting the unit
to anything but one.  Looks like we have a customer for your proposed
args_type '6'.

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

* Re: [Qemu-devel] [RFC PATCH 09/56] balloon: Make balloon size unsigned in QAPI/QMP
  2017-08-09  6:04     ` Markus Armbruster
@ 2017-08-09 10:47       ` Dr. David Alan Gilbert
  0 siblings, 0 replies; 105+ messages in thread
From: Dr. David Alan Gilbert @ 2017-08-09 10:47 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: kwolf, famz, qemu-block, quintela, jsnow, jcody, qemu-devel,
	mreitz, marcandre.lureau, pbonzini

* Markus Armbruster (armbru@redhat.com) wrote:
> "Dr. David Alan Gilbert" <dgilbert@redhat.com> writes:
> 
> > * Markus Armbruster (armbru@redhat.com) wrote:
> >> Sizes should use QAPI type 'size' (uint64_t).  balloon parameter
> >> @value is 'int' (int64_t).  qmp_balloon() implicitly converts to
> >> ram_addr_t, i.e. uint64_t.  BALLOON_CHANGE parameter @actual and
> >> BalloonInfo member @actual are also 'int'.
> >> virtio_balloon_set_config() and virtio_balloon_stat() implicitly
> >> convert from ram_addr_t.
> >> 
> >> Change all three to 'size', and adjust the code using them.
> >> 
> >> balloon now accepts size values between 2^63 and 2^64-1.  It accepts
> >> negative values as before, because that's how the QObject input
> >> visitor works for backward compatibility.
> >> 
> >> Doing the same for HMP's balloon deserves its own commit (the next
> >> one).
> >> 
> >> BALLOON_CHANGE and query-balloon now report sizes above 2^63-1
> >> correctly instead of their (negative) two's complement.
> >> 
> >> So does HMP's "info balloon".
> >> 
> >> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> >> ---
> >>  balloon.c        | 2 +-
> >>  hmp.c            | 2 +-
> >>  qapi-schema.json | 4 ++--
> >>  qapi/event.json  | 2 +-
> >>  4 files changed, 5 insertions(+), 5 deletions(-)
> >> 
> >> diff --git a/balloon.c b/balloon.c
> >> index 1d720ff..2ecca76 100644
> >> --- a/balloon.c
> >> +++ b/balloon.c
> >> @@ -102,7 +102,7 @@ BalloonInfo *qmp_query_balloon(Error **errp)
> >>      return info;
> >>  }
> >>  
> >> -void qmp_balloon(int64_t target, Error **errp)
> >> +void qmp_balloon(uint64_t target, Error **errp)
> >>  {
> >>      if (!have_balloon(errp)) {
> >>          return;
> >
> > Can't you remove the:
> >       if (target <= 0) {
> >
> > check?
> 
> Functional change when target == 0.  Impact is not clear to me.

Hmm yes; I don't know whether 0 is legal.

Dave

> > (The type of the trace_balloon_event probably needs fixing
> > to be uint64_t rather than the unsigned long)
> 
> You're right.  I'll fix it.
> 
> >> diff --git a/hmp.c b/hmp.c
> >> index 8257dd0..4556045 100644
> >> --- a/hmp.c
> >> +++ b/hmp.c
> >> @@ -781,7 +781,7 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
> >>          return;
> >>      }
> >>  
> >> -    monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
> >> +    monitor_printf(mon, "balloon: actual=%" PRIu64 "\n", info->actual >> 20);
> >>  
> >>      qapi_free_BalloonInfo(info);
> >>  }
> >> diff --git a/qapi-schema.json b/qapi-schema.json
> >> index 3ad2bc0..23eb60d 100644
> >> --- a/qapi-schema.json
> >> +++ b/qapi-schema.json
> >> @@ -2003,7 +2003,7 @@
> >>  # Since: 0.14.0
> >>  #
> >>  ##
> >> -{ 'struct': 'BalloonInfo', 'data': {'actual': 'int' } }
> >> +{ 'struct': 'BalloonInfo', 'data': {'actual': 'size' } }
> >>  
> >>  ##
> >>  # @query-balloon:
> >> @@ -2603,7 +2603,7 @@
> >>  # <- { "return": {} }
> >>  #
> >>  ##
> >> -{ 'command': 'balloon', 'data': {'value': 'int'} }
> >> +{ 'command': 'balloon', 'data': {'value': 'size'} }
> >>  
> >>  ##
> >>  # @Abort:
> >> diff --git a/qapi/event.json b/qapi/event.json
> >> index 6d22b02..9dfc70b 100644
> >> --- a/qapi/event.json
> >> +++ b/qapi/event.json
> >> @@ -488,7 +488,7 @@
> >>  #
> >>  ##
> >>  { 'event': 'BALLOON_CHANGE',
> >> -  'data': { 'actual': 'int' } }
> >> +  'data': { 'actual': 'size' } }
> >
> > I was going to ask whether that was a problem for any external users,
> > but there again libvirt looks like it reads it into an unsigned long
> > long.
> 
> Yes.  See also my reply to Juan's review of PATCH 15.
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

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

* Re: [Qemu-devel] [RFC PATCH 01/56] qobject: Touch up comments to say @param instead of 'param'
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 01/56] qobject: Touch up comments to say @param instead of 'param' Markus Armbruster
@ 2017-08-09 14:39   ` Eric Blake
  2017-08-10  8:20     ` Markus Armbruster
  0 siblings, 1 reply; 105+ messages in thread
From: Eric Blake @ 2017-08-09 14:39 UTC (permalink / raw)
  To: Markus Armbruster, qemu-devel
  Cc: kwolf, mreitz, jcody, famz, jsnow, pbonzini, marcandre.lureau,
	dgilbert, quintela, berrange, qemu-block

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

On 08/07/2017 09:45 AM, Markus Armbruster wrote:
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  qobject/qdict.c | 68 ++++++++++++++++++++++++++++-----------------------------
>  qobject/qlist.c |  2 +-
>  2 files changed, 35 insertions(+), 35 deletions(-)
> 
> diff --git a/qobject/qdict.c b/qobject/qdict.c
> index 576018e..d795079 100644
> --- a/qobject/qdict.c
> +++ b/qobject/qdict.c
> @@ -116,13 +116,13 @@ static QDictEntry *qdict_find(const QDict *qdict,
>  /**
>   * qdict_put_obj(): Put a new QObject into the dictionary
>   *
> - * Insert the pair 'key:value' into 'qdict', if 'key' already exists
> - * its 'value' will be replaced.
> + * Insert the pair @key:@value into @qdict, if @key already exists
> + * its value will be replaced.

Maybe s/,/;/ while at it.

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]

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

* Re: [Qemu-devel] [RFC PATCH 01/56] qobject: Touch up comments to say @param instead of 'param'
  2017-08-09 14:39   ` Eric Blake
@ 2017-08-10  8:20     ` Markus Armbruster
  0 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-10  8:20 UTC (permalink / raw)
  To: Eric Blake
  Cc: qemu-devel, kwolf, famz, qemu-block, quintela, jcody, dgilbert,
	mreitz, marcandre.lureau, pbonzini, jsnow

Eric Blake <eblake@redhat.com> writes:

> On 08/07/2017 09:45 AM, Markus Armbruster wrote:
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>>  qobject/qdict.c | 68 ++++++++++++++++++++++++++++-----------------------------
>>  qobject/qlist.c |  2 +-
>>  2 files changed, 35 insertions(+), 35 deletions(-)
>> 
>> diff --git a/qobject/qdict.c b/qobject/qdict.c
>> index 576018e..d795079 100644
>> --- a/qobject/qdict.c
>> +++ b/qobject/qdict.c
>> @@ -116,13 +116,13 @@ static QDictEntry *qdict_find(const QDict *qdict,
>>  /**
>>   * qdict_put_obj(): Put a new QObject into the dictionary
>>   *
>> - * Insert the pair 'key:value' into 'qdict', if 'key' already exists
>> - * its 'value' will be replaced.
>> + * Insert the pair @key:@value into @qdict, if @key already exists
>> + * its value will be replaced.
>
> Maybe s/,/;/ while at it.

Or even *gasp* a period.

> Reviewed-by: Eric Blake <eblake@redhat.com>

Thanks!

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

* Re: [Qemu-devel] [RFC PATCH 02/56] qdict: New helpers to put and get unsigned integers
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 02/56] qdict: New helpers to put and get unsigned integers Markus Armbruster
@ 2017-08-22 11:27   ` Marc-André Lureau
  2017-08-22 12:49     ` Markus Armbruster
  0 siblings, 1 reply; 105+ messages in thread
From: Marc-André Lureau @ 2017-08-22 11:27 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	dgilbert, quintela, berrange, qemu-block

Hi

Is this based on https://lists.gnu.org/archive/html/qemu-devel/2017-06/msg01894.html ?

If so, you should probably keep me signed-off.

My patch had also a test :)
 
----- Original Message -----
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  include/qapi/qmp/qdict.h |  5 +++++
>  qobject/qdict.c          | 43 ++++++++++++++++++++++++++++++++++++-------
>  2 files changed, 41 insertions(+), 7 deletions(-)
> 
> diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
> index 363e431..3b52481 100644
> --- a/include/qapi/qmp/qdict.h
> +++ b/include/qapi/qmp/qdict.h
> @@ -56,6 +56,8 @@ void qdict_destroy_obj(QObject *obj);
>  /* Helpers for int, bool, and string */
>  #define qdict_put_int(qdict, key, value) \
>          qdict_put(qdict, key, qnum_from_int(value))
> +#define qdict_put_uint(qdict, key, value) \
> +        qdict_put(qdict, key, qnum_from_uint(value))
>  #define qdict_put_bool(qdict, key, value) \
>          qdict_put(qdict, key, qbool_from_bool(value))
>  #define qdict_put_str(qdict, key, value) \
> @@ -64,12 +66,15 @@ void qdict_destroy_obj(QObject *obj);
>  /* High level helpers */
>  double qdict_get_double(const QDict *qdict, const char *key);
>  int64_t qdict_get_int(const QDict *qdict, const char *key);
> +uint64_t qdict_get_uint(const QDict *qdict, const char *key);
>  bool qdict_get_bool(const QDict *qdict, const char *key);
>  QList *qdict_get_qlist(const QDict *qdict, const char *key);
>  QDict *qdict_get_qdict(const QDict *qdict, const char *key);
>  const char *qdict_get_str(const QDict *qdict, const char *key);
>  int64_t qdict_get_try_int(const QDict *qdict, const char *key,
>                            int64_t def_value);
> +uint64_t qdict_get_try_uint(const QDict *qdict, const char *key,
> +                            uint64_t def_value);
>  bool qdict_get_try_bool(const QDict *qdict, const char *key, bool
>  def_value);
>  const char *qdict_get_try_str(const QDict *qdict, const char *key);
>  
> diff --git a/qobject/qdict.c b/qobject/qdict.c
> index d795079..be919b9 100644
> --- a/qobject/qdict.c
> +++ b/qobject/qdict.c
> @@ -189,10 +189,9 @@ double qdict_get_double(const QDict *qdict, const char
> *key)
>  }
>  
>  /**
> - * qdict_get_int(): Get an integer mapped by @key
> + * qdict_get_int(): Get a signed integer mapped by @key
>   *
> - * This function assumes that @key exists and it stores a
> - * QNum representable as int.
> + * @qdict must map @key to an integer QNum that fits into int64_t.
>   *
>   * Return integer mapped by @key.
>   */
> @@ -202,6 +201,18 @@ int64_t qdict_get_int(const QDict *qdict, const char
> *key)
>  }
>  
>  /**
> + * qdict_get_uint(): Get an unsigned integer mapped by 'key'
> + *
> + * @qdict must map @key to an integer QNum that fits into uint64_t.
> + *
> + * Return integer mapped by 'key'.
> + */
> +uint64_t qdict_get_uint(const QDict *qdict, const char *key)
> +{
> +    return qnum_get_uint(qobject_to_qnum(qdict_get(qdict, key)));
> +}
> +
> +/**
>   * qdict_get_bool(): Get a bool mapped by @key
>   *
>   * This function assumes that @key exists and it stores a
> @@ -245,11 +256,10 @@ const char *qdict_get_str(const QDict *qdict, const
> char *key)
>  }
>  
>  /**
> - * qdict_get_try_int(): Try to get integer mapped by @key
> + * qdict_get_try_int(): Try to get signed integer mapped by @key
>   *
> - * Return integer mapped by @key, if it is not present in the
> - * dictionary or if the stored object is not a QNum representing an
> - * integer, @def_value will be returned.
> + * If @qdict maps @key to an integer QNum that fits into int64_t,
> + * return it.  Else return @def_value.
>   */
>  int64_t qdict_get_try_int(const QDict *qdict, const char *key,
>                            int64_t def_value)
> @@ -265,6 +275,25 @@ int64_t qdict_get_try_int(const QDict *qdict, const char
> *key,
>  }
>  
>  /**
> + * qdict_get_try_uint(): Try to get unsigned integer mapped by 'key'
> + *
> + * If @qdict maps @key to an integer QNum that fits into uint64_t,
> + * return it.  Else return @def_value.
> + */
> +uint64_t qdict_get_try_uint(const QDict *qdict, const char *key,
> +                            uint64_t def_value)
> +{
> +    QNum *qnum = qobject_to_qnum(qdict_get(qdict, key));
> +    uint64_t val;
> +
> +    if (!qnum || !qnum_get_try_uint(qnum, &val)) {
> +        return def_value;
> +    }
> +
> +    return val;
> +}
> +
> +/**
>   * qdict_get_try_bool(): Try to get a bool mapped by @key
>   *
>   * Return bool mapped by @key, if it is not present in the
> --
> 2.7.5
> 
> 

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

* Re: [Qemu-devel] [RFC PATCH 04/56] char: Make ringbuf-read size unsigned in QAPI/QMP
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 04/56] char: Make ringbuf-read size unsigned in QAPI/QMP Markus Armbruster
@ 2017-08-22 11:32   ` Marc-André Lureau
  2017-08-22 13:00     ` Markus Armbruster
  0 siblings, 1 reply; 105+ messages in thread
From: Marc-André Lureau @ 2017-08-22 11:32 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: QEMU, Kevin Wolf, Fam Zheng, open list:Block layer core,
	Juan Quintela, jcody, Dr. David Alan Gilbert, Max Reitz,
	Paolo Bonzini, John Snow

Hi

On Mon, Aug 7, 2017 at 4:45 PM, Markus Armbruster <armbru@redhat.com> wrote:
> Sizes should use QAPI type 'size' (uint64_t).  ringbuf-read parameter
> @size is 'int' (int64_t).  qmp_ringbuf_read() rejects negative values,
> then implicitly converts to size_t.
>
> Change the parameter to 'size' and drop the check for negative values.
>
> ringbuf-read now accepts size values between 2^63 and 2^64-1.  It
> accepts negative values as before, because that's how the QObject
> input visitor works for backward compatibility.
>

Negative values over json will be implicitly converted to positive
values with this change, right? Or are they rejected earlier?

If so that is a change of behaviour that I am not sure is worth doing
now (without explicit protocol break), but I don't mind.

> The HMP command's size parameter remains uint32_t, as HMP args_type
> strings can't do uint64_t byte counts: 'l' is signed, and 'o'
> multiplies by 2^20.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>

> ---
>  chardev/char-ringbuf.c | 11 +++--------
>  qapi-schema.json       |  2 +-
>  2 files changed, 4 insertions(+), 9 deletions(-)
>
> diff --git a/chardev/char-ringbuf.c b/chardev/char-ringbuf.c
> index df52b04..a9205ea 100644
> --- a/chardev/char-ringbuf.c
> +++ b/chardev/char-ringbuf.c
> @@ -65,10 +65,10 @@ static int ringbuf_chr_write(Chardev *chr, const uint8_t *buf, int len)
>      return len;
>  }
>
> -static int ringbuf_chr_read(Chardev *chr, uint8_t *buf, int len)
> +static int ringbuf_chr_read(Chardev *chr, uint8_t *buf, size_t len)
>  {
>      RingBufChardev *d = RINGBUF_CHARDEV(chr);
> -    int i;
> +    size_t i;
>
>      qemu_mutex_lock(&chr->chr_write_lock);
>      for (i = 0; i < len && d->cons != d->prod; i++) {
> @@ -151,7 +151,7 @@ void qmp_ringbuf_write(const char *device, const char *data,
>      }
>  }
>
> -char *qmp_ringbuf_read(const char *device, int64_t size,
> +char *qmp_ringbuf_read(const char *device, uint64_t size,
>                         bool has_format, enum DataFormat format,
>                         Error **errp)
>  {
> @@ -171,11 +171,6 @@ char *qmp_ringbuf_read(const char *device, int64_t size,
>          return NULL;
>      }
>
> -    if (size <= 0) {
> -        error_setg(errp, "size must be greater than zero");
> -        return NULL;
> -    }
> -
>      count = ringbuf_count(chr);
>      size = size > count ? count : size;
>      read_data = g_malloc(size + 1);
> diff --git a/qapi-schema.json b/qapi-schema.json
> index febe70e..18ec301 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -543,7 +543,7 @@
>  #
>  ##
>  { 'command': 'ringbuf-read',
> -  'data': {'device': 'str', 'size': 'int', '*format': 'DataFormat'},
> +  'data': {'device': 'str', 'size': 'size', '*format': 'DataFormat'},
>    'returns': 'str' }
>
>  ##
> --
> 2.7.5
>
>



-- 
Marc-André Lureau

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

* Re: [Qemu-devel] [RFC PATCH 02/56] qdict: New helpers to put and get unsigned integers
  2017-08-22 11:27   ` Marc-André Lureau
@ 2017-08-22 12:49     ` Markus Armbruster
  0 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-22 12:49 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: kwolf, famz, qemu-block, quintela, jsnow, jcody, qemu-devel,
	mreitz, pbonzini, dgilbert

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Hi
>
> Is this based on https://lists.gnu.org/archive/html/qemu-devel/2017-06/msg01894.html ?

I guess not, because I forgot it exists.

> If so, you should probably keep me signed-off.

I'll replace my patch by yours.

> My patch had also a test :)

Always welcome.

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

* Re: [Qemu-devel] [RFC PATCH 12/56] pc-dimm: Make size and address unsigned in QAPI/QMP
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 12/56] pc-dimm: Make size and address unsigned in QAPI/QMP Markus Armbruster
@ 2017-08-22 12:55   ` Igor Mammedov
  2017-08-22 13:50     ` Markus Armbruster
  0 siblings, 1 reply; 105+ messages in thread
From: Igor Mammedov @ 2017-08-22 12:55 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, kwolf, famz, qemu-block, quintela, jcody, dgilbert,
	mreitz, marcandre.lureau, pbonzini, jsnow

On Mon,  7 Aug 2017 16:45:16 +0200
Markus Armbruster <armbru@redhat.com> wrote:

> Sizes and addresses should use QAPI type 'size' (uint64_t).
> PCDIMMDeviceInfo members @addr and @size are 'int' (int64_t).
> qmp_pc_dimm_device_list() implicitly converts from uint64_t.
> 
> Change these PCDIMMDeviceInfo members to 'size'.
> 
> query-memory-devices now reports sizes and addresses above 2^63-1
> correctly instead of their (negative) two's complement.
> 
> HMP's "info memory-devices" already reported them correctly, because
> it printed the signed integers with PRIx64 and PRIu32.
s/signed/unsigned/

 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>

> ---
>  qapi-schema.json | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 23eb60d..6aa6be9 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -6057,8 +6057,8 @@
>  ##
>  { 'struct': 'PCDIMMDeviceInfo',
>    'data': { '*id': 'str',
> -            'addr': 'int',
> -            'size': 'int',
> +            'addr': 'size',
> +            'size': 'size',
>              'slot': 'int',
>              'node': 'int',
>              'memdev': 'str',

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

* Re: [Qemu-devel] [RFC PATCH 04/56] char: Make ringbuf-read size unsigned in QAPI/QMP
  2017-08-22 11:32   ` Marc-André Lureau
@ 2017-08-22 13:00     ` Markus Armbruster
  2017-08-22 15:54       ` Marc-André Lureau
  0 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-22 13:00 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: Kevin Wolf, Fam Zheng, open list:Block layer core, Juan Quintela,
	jcody, QEMU, Dr. David Alan Gilbert, Paolo Bonzini, Max Reitz,
	John Snow

Marc-André Lureau <marcandre.lureau@gmail.com> writes:

> Hi
>
> On Mon, Aug 7, 2017 at 4:45 PM, Markus Armbruster <armbru@redhat.com> wrote:
>> Sizes should use QAPI type 'size' (uint64_t).  ringbuf-read parameter
>> @size is 'int' (int64_t).  qmp_ringbuf_read() rejects negative values,
>> then implicitly converts to size_t.
>>
>> Change the parameter to 'size' and drop the check for negative values.
>>
>> ringbuf-read now accepts size values between 2^63 and 2^64-1.  It
>> accepts negative values as before, because that's how the QObject
>> input visitor works for backward compatibility.
>>
>
> Negative values over json will be implicitly converted to positive
> values with this change, right? Or are they rejected earlier?

Yes.  For details, see my reply to Juan's review of PATCH 15.

> If so that is a change of behaviour that I am not sure is worth doing
> now (without explicit protocol break), but I don't mind.

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

* Re: [Qemu-devel] [RFC PATCH 12/56] pc-dimm: Make size and address unsigned in QAPI/QMP
  2017-08-22 12:55   ` Igor Mammedov
@ 2017-08-22 13:50     ` Markus Armbruster
  2017-08-22 15:45       ` Igor Mammedov
  0 siblings, 1 reply; 105+ messages in thread
From: Markus Armbruster @ 2017-08-22 13:50 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: kwolf, famz, qemu-block, quintela, jcody, qemu-devel, dgilbert,
	pbonzini, marcandre.lureau, mreitz, jsnow

Igor Mammedov <imammedo@redhat.com> writes:

> On Mon,  7 Aug 2017 16:45:16 +0200
> Markus Armbruster <armbru@redhat.com> wrote:
>
>> Sizes and addresses should use QAPI type 'size' (uint64_t).
>> PCDIMMDeviceInfo members @addr and @size are 'int' (int64_t).
>> qmp_pc_dimm_device_list() implicitly converts from uint64_t.
>> 
>> Change these PCDIMMDeviceInfo members to 'size'.
>> 
>> query-memory-devices now reports sizes and addresses above 2^63-1
>> correctly instead of their (negative) two's complement.
>> 
>> HMP's "info memory-devices" already reported them correctly, because
>> it printed the signed integers with PRIx64 and PRIu32.
> s/signed/unsigned/

Before this patch: signed.  Afterwards: unsigned.  Would

   HMP's "info memory-devices" already reported them correctly, because
   it printed the signed (before the patch) integers with PRIx64 and
   PRIu32.

be clearer?

>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> Reviewed-by: Igor Mammedov <imammedo@redhat.com>

Thanks!

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

* Re: [Qemu-devel] [RFC PATCH 13/56] pci: Make PCI addresses and sizes unsigned in QAPI/QMP
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 13/56] pci: Make PCI addresses and sizes " Markus Armbruster
@ 2017-08-22 14:03   ` Marcel Apfelbaum
  0 siblings, 0 replies; 105+ messages in thread
From: Marcel Apfelbaum @ 2017-08-22 14:03 UTC (permalink / raw)
  To: Markus Armbruster, qemu-devel
  Cc: eblake, kwolf, mreitz, jcody, famz, jsnow, pbonzini,
	marcandre.lureau, dgilbert, quintela, berrange, qemu-block

Hi Markus,

On 07/08/2017 17:45, Markus Armbruster wrote:
> Sizes and addresses should use QAPI type 'size' (uint64_t).
> PciMemoryRegion members @address and @size are 'int' (int64_t).
> qmp_query_pci_regions() implicitly converts from pcibus_t,
> i.e. uint64_t.
> 
> Change these PciMemoryRegion members to 'size'.
> 
> query-pci now reports sizes and addresses above 2^63-1 correctly
> instead of their (negative) two's complement.
> 
> HMP's "info pci" already reported them correctly, because it
> implicitly converted back to uint64_t.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>   qapi-schema.json | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 6aa6be9..c8cceb9 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -2062,7 +2062,7 @@
>   # Since: 0.14.0
>   ##
>   { 'struct': 'PciMemoryRegion',
> -  'data': {'bar': 'int', 'type': 'str', 'address': 'int', 'size': 'int',
> +  'data': {'bar': 'int', 'type': 'str', 'address': 'size', 'size': 'size',
>              '*prefetch': 'bool', '*mem_type_64': 'bool' } }
>   
>   ##
> 

Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>

Thanks,
Marcel

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

* Re: [Qemu-devel] [RFC PATCH 12/56] pc-dimm: Make size and address unsigned in QAPI/QMP
  2017-08-22 13:50     ` Markus Armbruster
@ 2017-08-22 15:45       ` Igor Mammedov
  2017-08-22 16:38         ` Markus Armbruster
  0 siblings, 1 reply; 105+ messages in thread
From: Igor Mammedov @ 2017-08-22 15:45 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: kwolf, famz, qemu-block, quintela, jcody, qemu-devel, dgilbert,
	pbonzini, marcandre.lureau, mreitz, jsnow

On Tue, 22 Aug 2017 15:50:14 +0200
Markus Armbruster <armbru@redhat.com> wrote:

> Igor Mammedov <imammedo@redhat.com> writes:
> 
> > On Mon,  7 Aug 2017 16:45:16 +0200
> > Markus Armbruster <armbru@redhat.com> wrote:
> >  
> >> Sizes and addresses should use QAPI type 'size' (uint64_t).
> >> PCDIMMDeviceInfo members @addr and @size are 'int' (int64_t).
> >> qmp_pc_dimm_device_list() implicitly converts from uint64_t.
> >> 
> >> Change these PCDIMMDeviceInfo members to 'size'.
> >> 
> >> query-memory-devices now reports sizes and addresses above 2^63-1
> >> correctly instead of their (negative) two's complement.
> >> 
> >> HMP's "info memory-devices" already reported them correctly, because
> >> it printed the signed integers with PRIx64 and PRIu32.  
> > s/signed/unsigned/  
> 
> Before this patch: signed.  Afterwards: unsigned.  Would
> 
>    HMP's "info memory-devices" already reported them correctly, because
>    it printed the signed (before the patch) integers with PRIx64 and
>    PRIu32.
> 
> be clearer?
yes, that's more clear

Thanks.

> 
> >> Signed-off-by: Markus Armbruster <armbru@redhat.com>  
> > Reviewed-by: Igor Mammedov <imammedo@redhat.com>  
> 
> Thanks!

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

* Re: [Qemu-devel] [RFC PATCH 04/56] char: Make ringbuf-read size unsigned in QAPI/QMP
  2017-08-22 13:00     ` Markus Armbruster
@ 2017-08-22 15:54       ` Marc-André Lureau
  2017-08-22 16:22         ` Markus Armbruster
  0 siblings, 1 reply; 105+ messages in thread
From: Marc-André Lureau @ 2017-08-22 15:54 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Kevin Wolf, Fam Zheng, open list:Block layer core, Juan Quintela,
	jcody, QEMU, Dr. David Alan Gilbert, Paolo Bonzini, Max Reitz,
	John Snow

Hi

On Tue, Aug 22, 2017 at 3:00 PM, Markus Armbruster <armbru@redhat.com> wrote:
> Marc-André Lureau <marcandre.lureau@gmail.com> writes:
>
>> Hi
>>
>> On Mon, Aug 7, 2017 at 4:45 PM, Markus Armbruster <armbru@redhat.com> wrote:
>>> Sizes should use QAPI type 'size' (uint64_t).  ringbuf-read parameter
>>> @size is 'int' (int64_t).  qmp_ringbuf_read() rejects negative values,
>>> then implicitly converts to size_t.
>>>
>>> Change the parameter to 'size' and drop the check for negative values.
>>>
>>> ringbuf-read now accepts size values between 2^63 and 2^64-1.  It
>>> accepts negative values as before, because that's how the QObject
>>> input visitor works for backward compatibility.
>>>
>>
>> Negative values over json will be implicitly converted to positive
>> values with this change, right? Or are they rejected earlier?
>
> Yes.  For details, see my reply to Juan's review of PATCH 15.
>
>> If so that is a change of behaviour that I am not sure is worth doing
>> now (without explicit protocol break), but I don't mind.

So before this change:

(QEMU) ringbuf-read device=foo size=-1
{"error": {"class": "GenericError", "desc": "size must be greater than zero"}}

after:

(QEMU) ringbuf-read device=foo size=-1
{"return": ""}

Is this really what we want?

-- 
Marc-André Lureau

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

* Re: [Qemu-devel] [RFC PATCH 04/56] char: Make ringbuf-read size unsigned in QAPI/QMP
  2017-08-22 15:54       ` Marc-André Lureau
@ 2017-08-22 16:22         ` Markus Armbruster
  0 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-22 16:22 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: Kevin Wolf, Fam Zheng, open list:Block layer core, Juan Quintela,
	jcody, QEMU, Dr. David Alan Gilbert, Paolo Bonzini, Max Reitz,
	John Snow

Marc-André Lureau <marcandre.lureau@gmail.com> writes:

> Hi
>
> On Tue, Aug 22, 2017 at 3:00 PM, Markus Armbruster <armbru@redhat.com> wrote:
>> Marc-André Lureau <marcandre.lureau@gmail.com> writes:
>>
>>> Hi
>>>
>>> On Mon, Aug 7, 2017 at 4:45 PM, Markus Armbruster <armbru@redhat.com> wrote:
>>>> Sizes should use QAPI type 'size' (uint64_t).  ringbuf-read parameter
>>>> @size is 'int' (int64_t).  qmp_ringbuf_read() rejects negative values,
>>>> then implicitly converts to size_t.
>>>>
>>>> Change the parameter to 'size' and drop the check for negative values.
>>>>
>>>> ringbuf-read now accepts size values between 2^63 and 2^64-1.  It
>>>> accepts negative values as before, because that's how the QObject
>>>> input visitor works for backward compatibility.
>>>>
>>>
>>> Negative values over json will be implicitly converted to positive
>>> values with this change, right? Or are they rejected earlier?
>>
>> Yes.  For details, see my reply to Juan's review of PATCH 15.
>>
>>> If so that is a change of behaviour that I am not sure is worth doing
>>> now (without explicit protocol break), but I don't mind.
>
> So before this change:
>
> (QEMU) ringbuf-read device=foo size=-1
> {"error": {"class": "GenericError", "desc": "size must be greater than zero"}}
>
> after:
>
> (QEMU) ringbuf-read device=foo size=-1
> {"return": ""}
>
> Is this really what we want?

Yes, because it's what all the other commands do with byte counts, and
because it's the price of admission for "size": 18446744073709551615 to
work.

We could split QAPI type size into legacy-size (accepts negative for
backward compatibility, do not use in new code) and size (rejects
negative, do use in new code and for cases that previously rejected
negative manually).  Trades consistency for tightness.

This series picked consistency.

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

* Re: [Qemu-devel] [RFC PATCH 12/56] pc-dimm: Make size and address unsigned in QAPI/QMP
  2017-08-22 15:45       ` Igor Mammedov
@ 2017-08-22 16:38         ` Markus Armbruster
  0 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-22 16:38 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: kwolf, famz, qemu-block, quintela, jcody, qemu-devel, dgilbert,
	marcandre.lureau, pbonzini, mreitz, jsnow

Igor Mammedov <imammedo@redhat.com> writes:

> On Tue, 22 Aug 2017 15:50:14 +0200
> Markus Armbruster <armbru@redhat.com> wrote:
>
>> Igor Mammedov <imammedo@redhat.com> writes:
>> 
>> > On Mon,  7 Aug 2017 16:45:16 +0200
>> > Markus Armbruster <armbru@redhat.com> wrote:
>> >  
>> >> Sizes and addresses should use QAPI type 'size' (uint64_t).
>> >> PCDIMMDeviceInfo members @addr and @size are 'int' (int64_t).
>> >> qmp_pc_dimm_device_list() implicitly converts from uint64_t.
>> >> 
>> >> Change these PCDIMMDeviceInfo members to 'size'.
>> >> 
>> >> query-memory-devices now reports sizes and addresses above 2^63-1
>> >> correctly instead of their (negative) two's complement.
>> >> 
>> >> HMP's "info memory-devices" already reported them correctly, because
>> >> it printed the signed integers with PRIx64 and PRIu32.  
>> > s/signed/unsigned/  
>> 
>> Before this patch: signed.  Afterwards: unsigned.  Would
>> 
>>    HMP's "info memory-devices" already reported them correctly, because
>>    it printed the signed (before the patch) integers with PRIx64 and
>>    PRIu32.
>> 
>> be clearer?
> yes, that's more clear

Okay, I'll update my commit messages.  Thanks!

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

* Re: [Qemu-devel] [Qemu-block] [RFC PATCH 31/56] block: Make throttle byte rates and sizes unsigned in QAPI/QMP
  2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 31/56] block: Make throttle byte rates and sizes " Markus Armbruster
@ 2017-08-23 13:42   ` Alberto Garcia
  2017-08-24  7:24     ` Markus Armbruster
  0 siblings, 1 reply; 105+ messages in thread
From: Alberto Garcia @ 2017-08-23 13:42 UTC (permalink / raw)
  To: Markus Armbruster, qemu-devel
  Cc: kwolf, famz, qemu-block, quintela, dgilbert, mreitz, berrange,
	marcandre.lureau, pbonzini

On Mon 07 Aug 2017 04:45:35 PM CEST, Markus Armbruster wrote:
> Sizes and byte rates should use QAPI type 'size' (uint64_t).
> BlockIOThrottle and BlockDeviceInfo members @bps, @bps_rd, @bps_wr,
> @bps_max, @bps_rd_max, @bps_wr_max, @iops_size are 'int' (int64_t).
> qmp_block_set_io_throttle() and bdrv_block_device_info() copy @bps,
> @bps_rd, @bps_wr to / from LeakyBucket member @avg (implicit
> conversion to / from double), @bps_max, @bps_rd_max, @bps_wr_max to /
> from LeakyBucket member @max (implicit conversion to / from double),
> and @iops_size to / from ThrottleConfig member op_size (implicit
> conversion to / from uint64_t).
>
> Change these BlockIOThrottle and BlockDeviceInfo members to 'size'.
>
> block_set_io_throttle now accepts sizes and rates between 2^63 and
> 2^64-1.  It accepts negative values as before, because that's how the
> QObject input visitor works for backward compatibility.
>
> Doing the same for HMP's block_set_io_throttle deserves its own commit
> (the next one).
>
> query-block and query-named-block-nodes now report sizes and rates
> above 2^63-1 correctly instead of their (negative) two's complement.
>
> So does HMP's "info block".
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>

This is fine because all those parameters are limited to [0, 10^15], so
changing int64_t -> uint64_t is not a problem.

I have already sent a patch that changes the fields in the data
structure in throttle.h from double to uint64_t

Reviewed-by: Alberto Garcia <berto@igalia.com>

Berto

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

* Re: [Qemu-devel] [Qemu-block] [RFC PATCH 31/56] block: Make throttle byte rates and sizes unsigned in QAPI/QMP
  2017-08-23 13:42   ` [Qemu-devel] [Qemu-block] " Alberto Garcia
@ 2017-08-24  7:24     ` Markus Armbruster
  0 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-08-24  7:24 UTC (permalink / raw)
  To: Alberto Garcia
  Cc: qemu-devel, kwolf, famz, qemu-block, quintela, dgilbert, mreitz,
	pbonzini, marcandre.lureau

Alberto Garcia <berto@igalia.com> writes:

> On Mon 07 Aug 2017 04:45:35 PM CEST, Markus Armbruster wrote:
>> Sizes and byte rates should use QAPI type 'size' (uint64_t).
>> BlockIOThrottle and BlockDeviceInfo members @bps, @bps_rd, @bps_wr,
>> @bps_max, @bps_rd_max, @bps_wr_max, @iops_size are 'int' (int64_t).
>> qmp_block_set_io_throttle() and bdrv_block_device_info() copy @bps,
>> @bps_rd, @bps_wr to / from LeakyBucket member @avg (implicit
>> conversion to / from double), @bps_max, @bps_rd_max, @bps_wr_max to /
>> from LeakyBucket member @max (implicit conversion to / from double),
>> and @iops_size to / from ThrottleConfig member op_size (implicit
>> conversion to / from uint64_t).
>>
>> Change these BlockIOThrottle and BlockDeviceInfo members to 'size'.
>>
>> block_set_io_throttle now accepts sizes and rates between 2^63 and
>> 2^64-1.  It accepts negative values as before, because that's how the
>> QObject input visitor works for backward compatibility.
>>
>> Doing the same for HMP's block_set_io_throttle deserves its own commit
>> (the next one).
>>
>> query-block and query-named-block-nodes now report sizes and rates
>> above 2^63-1 correctly instead of their (negative) two's complement.
>>
>> So does HMP's "info block".
>>
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>
> This is fine because all those parameters are limited to [0, 10^15], so
> changing int64_t -> uint64_t is not a problem.
>
> I have already sent a patch that changes the fields in the data
> structure in throttle.h from double to uint64_t

I expect v2 to be based on your patch.  Might simplify the commit
message.

> Reviewed-by: Alberto Garcia <berto@igalia.com>

Thanks!

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

* Re: [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets
  2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
                   ` (55 preceding siblings ...)
  2017-08-07 14:46 ` [Qemu-devel] [RFC PATCH 56/56] crypto: Make QCryptoBlockInfoLUKS offsets unsigned in QAPI/QMP Markus Armbruster
@ 2017-09-06 15:32 ` Kevin Wolf
  2017-09-06 17:58   ` Markus Armbruster
  56 siblings, 1 reply; 105+ messages in thread
From: Kevin Wolf @ 2017-09-06 15:32 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, famz, qemu-block, quintela, jcody, dgilbert, mreitz,
	marcandre.lureau, pbonzini, jsnow

Am 07.08.2017 um 16:45 hat Markus Armbruster geschrieben:
> Byte sizes, offsets and the like should use QAPI type 'size'
> (uint64_t).  This rule is more honored in the breach than in the
> observance.  Fix the obvious offenders.
> 
> The series is RFC for at least two reasons:
> 
> 1. It's only lightly tested.  Commit message claims like "FOO now
>    works" haven't been verified, yet.
> 
> 2. The block layer represents file offsets and sizes as int64_t in
>    many places.  Must not be negative, except for function return
>    values, where it means failure.
> 
>    If you pass negative values via QMP, things explode.  Rejecting
>    them cleanly would be better, but we do that only haphazardly, as
>    far as I can tell.
> 
>    Changing the QAPI schema from 'int' (C: int64_t) to 'size' (C:
>    uint64_t) arguably makes things slightly worse: you can't
>    reasonably expect negative offsets and sizes to work, but expecting
>    offsets and sizes between 2^63 and 2^64-1 to work is less
>    unreasonable.  The explosions stay the same.
> 
>    Perhaps we should have a dedicated QAPI type for file offsets, just
>    like libc has off_t.  Which is also signed, by the way.

I discussed this a bit on IRC with Markus and I'll just reply here with
some of our findings:

* Having a 63-bit unsigned type makes sense. Not because it's the most
  accurate type for most places and will catch all invalid arguments,
  it's probably still too large in most places and individual function
  needs to keep (or finally introduce) checks for the valid range. But
  compared to 'int' it doesn't allow us to forget the < 0 check, and
  compared to 'uint64' the resulting values are immune to careless
  casting between unsigned and signed C types. These seem to be common
  bugs, so getting rid of them would be nice.

* 'size' is the right type for sizes, offsets, etc. but the problem is
  likely to affect other arguments, too. 'size' enables additional
  syntax in the string visitor, so it is different from the other
  integer types. This means that we probably want both a 63 bit size
  type and a 63 bit plain unsigned integer type.

* 'int' is an alias for (signed) 'int64'. People don't seem to think
  much about using 'int' because it's the simplest type. That doesn't
  make it right to use, though. It may be better to remove the 'int'
  type and force any definitions to be specific about the signedness and
  width they need. My intuitive guess is that most places that use 'int'
  today don't actually want to accept negative numbers.

* Schema introspection doesn't distinguish between integer types, this
  is purely internal, so changing a definition from one integer type to
  another is okay.

Markus, did I forget anything important?

Kevin

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

* Re: [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets
  2017-09-06 15:32 ` [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Kevin Wolf
@ 2017-09-06 17:58   ` Markus Armbruster
  0 siblings, 0 replies; 105+ messages in thread
From: Markus Armbruster @ 2017-09-06 17:58 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: famz, qemu-block, quintela, jcody, dgilbert, qemu-devel,
	pbonzini, marcandre.lureau, mreitz, jsnow

Kevin Wolf <kwolf@redhat.com> writes:

> Am 07.08.2017 um 16:45 hat Markus Armbruster geschrieben:
>> Byte sizes, offsets and the like should use QAPI type 'size'
>> (uint64_t).  This rule is more honored in the breach than in the
>> observance.  Fix the obvious offenders.
>> 
>> The series is RFC for at least two reasons:
>> 
>> 1. It's only lightly tested.  Commit message claims like "FOO now
>>    works" haven't been verified, yet.
>> 
>> 2. The block layer represents file offsets and sizes as int64_t in
>>    many places.  Must not be negative, except for function return
>>    values, where it means failure.
>> 
>>    If you pass negative values via QMP, things explode.  Rejecting
>>    them cleanly would be better, but we do that only haphazardly, as
>>    far as I can tell.
>> 
>>    Changing the QAPI schema from 'int' (C: int64_t) to 'size' (C:
>>    uint64_t) arguably makes things slightly worse: you can't
>>    reasonably expect negative offsets and sizes to work, but expecting
>>    offsets and sizes between 2^63 and 2^64-1 to work is less
>>    unreasonable.  The explosions stay the same.
>> 
>>    Perhaps we should have a dedicated QAPI type for file offsets, just
>>    like libc has off_t.  Which is also signed, by the way.
>
> I discussed this a bit on IRC with Markus and I'll just reply here with
> some of our findings:
>
> * Having a 63-bit unsigned type makes sense. Not because it's the most
>   accurate type for most places and will catch all invalid arguments,
>   it's probably still too large in most places and individual function
>   needs to keep (or finally introduce) checks for the valid range. But
>   compared to 'int' it doesn't allow us to forget the < 0 check, and
>   compared to 'uint64' the resulting values are immune to careless
>   casting between unsigned and signed C types. These seem to be common
>   bugs, so getting rid of them would be nice.

The block layer at least has the excuse "return negative errno on error,
file offset on success" for using / casting to signed.  Because of that,
it needs (but neglects) to limit QMP file offset arguments to [0,2^63-1]
in QMP command handlers.  Fixing the handlers would be straightforward,
but tedious, and new code would be prone to forget the range check
again.  Being able to leave it to the QAPI core should be convenient.

Do we want a dedicated file offset QAPI type (similar to C has off_t)
for the block layer, or are we fine with using a general 'uint63' type?
I guess the latter, as the block layer seems to be happily using general
int64_t rather than dedicated off_t.

> * 'size' is the right type for sizes, offsets, etc. but the problem is
>   likely to affect other arguments, too. 'size' enables additional
>   syntax in the string visitor, so it is different from the other
>   integer types. This means that we probably want both a 63 bit size
>   type and a 63 bit plain unsigned integer type.

Yes, "want alternate format" is orthogonal to "want only 63 bits".  We
may well run into all four cases.

Aside: creating separate built-in types to enable alternate formats
won't scale to multiple alternate formats.  But it's what we've done for
'uint64' and 'size', and what we now may have to do for 'uint63' and
'size63'.

> * 'int' is an alias for (signed) 'int64'. People don't seem to think
>   much about using 'int' because it's the simplest type. That doesn't
>   make it right to use, though. It may be better to remove the 'int'
>   type and force any definitions to be specific about the signedness and
>   width they need. My intuitive guess is that most places that use 'int'
>   today don't actually want to accept negative numbers.

Hmm.  Perhaps we should make an effort to fix up incorrect uses of
'int', then see how many uses are left.

> * Schema introspection doesn't distinguish between integer types, this
>   is purely internal, so changing a definition from one integer type to
>   another is okay.

Yes.

> Markus, did I forget anything important?

I think that's it.  Thanks!

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

end of thread, other threads:[~2017-09-06 17:59 UTC | newest]

Thread overview: 105+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-07 14:45 [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 01/56] qobject: Touch up comments to say @param instead of 'param' Markus Armbruster
2017-08-09 14:39   ` Eric Blake
2017-08-10  8:20     ` Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 02/56] qdict: New helpers to put and get unsigned integers Markus Armbruster
2017-08-22 11:27   ` Marc-André Lureau
2017-08-22 12:49     ` Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 03/56] monitor: Rewrite comment describing HMP .args_type Markus Armbruster
2017-08-08 11:20   ` Dr. David Alan Gilbert
2017-08-08 14:22     ` Paolo Bonzini
2017-08-08 14:46       ` Dr. David Alan Gilbert
2017-08-08 15:36     ` Markus Armbruster
2017-08-08 16:10       ` Dr. David Alan Gilbert
2017-08-09  6:00         ` Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 04/56] char: Make ringbuf-read size unsigned in QAPI/QMP Markus Armbruster
2017-08-22 11:32   ` Marc-André Lureau
2017-08-22 13:00     ` Markus Armbruster
2017-08-22 15:54       ` Marc-André Lureau
2017-08-22 16:22         ` Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 05/56] char: Make ringbuf size unsigned in QAPI Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 06/56] char: Don't truncate -chardev and HMP chardev-add ringbuf size Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 07/56] cpus: Make memsave, pmemsave sizes, addresses unsigned in QAPI/QMP Markus Armbruster
2017-08-08 14:31   ` Dr. David Alan Gilbert
2017-08-08 15:37     ` Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 08/56] dump: Make sizes and " Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 09/56] balloon: Make balloon size " Markus Armbruster
2017-08-08 14:58   ` Dr. David Alan Gilbert
2017-08-09  6:04     ` Markus Armbruster
2017-08-09 10:47       ` Dr. David Alan Gilbert
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 10/56] hmp: Make balloon's argument unsigned Markus Armbruster
2017-08-08 15:10   ` Dr. David Alan Gilbert
2017-08-09  6:05     ` Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 11/56] monitor: Drop unused HMP .args_type 'M' Markus Armbruster
2017-08-08 15:23   ` Dr. David Alan Gilbert
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 12/56] pc-dimm: Make size and address unsigned in QAPI/QMP Markus Armbruster
2017-08-22 12:55   ` Igor Mammedov
2017-08-22 13:50     ` Markus Armbruster
2017-08-22 15:45       ` Igor Mammedov
2017-08-22 16:38         ` Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 13/56] pci: Make PCI addresses and sizes " Markus Armbruster
2017-08-22 14:03   ` Marcel Apfelbaum
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 14/56] migration: Fix migrate-set-cache-size error reporting Markus Armbruster
2017-08-07 16:07   ` Juan Quintela
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 15/56] migration: Make XBZRLE cache size unsigned in QAPI/QMP Markus Armbruster
2017-08-07 16:10   ` Juan Quintela
2017-08-08 15:57     ` Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 16/56] migration: Make XBZRLE transferred " Markus Armbruster
2017-08-07 16:47   ` Juan Quintela
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 17/56] migration: Make MigrationStats sizes " Markus Armbruster
2017-08-07 16:48   ` Juan Quintela
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 18/56] migration: Make parameter max-bandwidth " Markus Armbruster
2017-08-07 16:50   ` Juan Quintela
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 19/56] block: Make snapshot VM state size " Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 20/56] block: Make ImageInfo sizes " Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 21/56] block: Clean up get_human_readable_size() Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 22/56] block: Mix up signed and unsigned less in bdrv_img_create() Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 23/56] option: Fix type of qemu_opt_set_number() parameter @val Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 24/56] block/qcow2: Change align_offset() to operate on uint64_t Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 25/56] block/qcow2: Change qcow2_calc_prealloc_size() to uint64_t Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 26/56] block: Make BlockMeasureInfo sizes unsigned in QAPI Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 27/56] block/dirty-bitmap: Clean up signed vs. unsigned dirty counts Markus Armbruster
2017-08-08  1:50   ` John Snow
2017-08-08 14:53   ` Eric Blake
2017-08-09  6:06     ` Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 28/56] block: Widen dirty bitmap granularity to uint64_t for safety Markus Armbruster
2017-08-08  1:55   ` John Snow
2017-08-08 14:55     ` Eric Blake
2017-08-08 15:58     ` Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 29/56] block: Make BlockDirtyInfo byte count unsigned in QAPI/QMP Markus Armbruster
2017-08-08  1:56   ` John Snow
2017-08-08 15:58     ` Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 30/56] block: Make write thresholds " Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 31/56] block: Make throttle byte rates and sizes " Markus Armbruster
2017-08-23 13:42   ` [Qemu-devel] [Qemu-block] " Alberto Garcia
2017-08-24  7:24     ` Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 32/56] hmp: Make block_set_io_throttle's arguments unsigned Markus Armbruster
2017-08-08 15:34   ` Dr. David Alan Gilbert
2017-08-09  6:10     ` Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 33/56] block: Make block_resize size unsigned in QAPI/QMP Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 34/56] block: Make BlockDeviceStats sizes, offsets " Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 35/56] blockjob: Lift speed sign conversion into block_job_set_speed() Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 36/56] blockjob: Drop unused parameter @errp of method set_speed() Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 37/56] blockjob: Make BlockJobInfo and event speed unsigned in QAPI/QMP Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 38/56] blockjob: Lift speed sign conversion out of block_job_set_speed() Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 39/56] blockjob: Lift speed sign conversion out of block_job_create() Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 40/56] blockjob: Lift speed sign conversion out of backup_job_create() Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 41/56] blockjob: Lift speed sign conversion out of mirror_start_job() Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 42/56] blockjob: Lift speed sign conversion out of stream_start() Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 43/56] blockjob: Lift speed sign conversion out of mirror_start() Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 44/56] blockjob: Lift speed sign conversion out of blockdev_mirror_common() Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 45/56] blockjob: Lift speed sign conversion out of commit_start() etc Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 46/56] blockjob: Make job commands' speed parameter unsigned in QAPI/QMP Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 47/56] blockjob: Make BlockJobInfo and event offsets " Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 48/56] block: Make mirror buffer size " Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 49/56] block: Make ImageCheck file offset unsigned in QAPI Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 50/56] block: Make BLOCK_IMAGE_CORRUPTED offset, size unsigned in QAPI/QMP Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 51/56] block/nfs: Fix for readahead-size, page-cache-size > INT64_MAX Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 52/56] block/nfs: Reject negative readahead-size, page-cache-size Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 53/56] block: Make blockdev-add byte counts unsigned in QAPI/QMP Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 54/56] qemu-img: blk_getlength() can fail, fix img_map() to check Markus Armbruster
2017-08-07 14:45 ` [Qemu-devel] [RFC PATCH 55/56] block: Make MapEntry offsets and size unsigned in QAPI Markus Armbruster
2017-08-07 14:46 ` [Qemu-devel] [RFC PATCH 56/56] crypto: Make QCryptoBlockInfoLUKS offsets unsigned in QAPI/QMP Markus Armbruster
2017-08-07 15:10   ` Daniel P. Berrange
2017-09-06 15:32 ` [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets Kevin Wolf
2017-09-06 17:58   ` Markus Armbruster

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.