1
The following changes since commit 86f4c7e05b1c44dbe1b329a51f311f10aef6ff34:
1
The following changes since commit b2f7a038bb4c4fc5ce6b8486e8513dfd97665e2a:
2
2
3
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180302' into staging (2018-03-02 14:37:10 +0000)
3
Merge remote-tracking branch 'remotes/rth/tags/pull-softfloat-20181104' into staging (2018-11-05 10:32:49 +0000)
4
4
5
are available in the git repository at:
5
are available in the Git repository at:
6
6
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to 9d9b4b640f9e583ff4b24dc762630945f3ccc16d:
9
for you to fetch changes up to 1240ac558d348f6c7a5752b1a57c1da58e4efe3e:
10
10
11
Merge remote-tracking branch 'mreitz/tags/pull-block-2018-03-02' into queue-block (2018-03-02 18:45:03 +0100)
11
include: Add a comment to explain the origin of sizes' lookup table (2018-11-05 15:29:59 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches
14
Block layer patches:
15
16
- auto-read-only option to fix commit job when used with -blockdev
17
- Fix help text related qemu-iotests failure (by improving the help text
18
and updating the reference output)
19
- quorum: Add missing checks when adding/removing child nodes
20
- Don't take address of fields in packed structs
21
- vvfat: Fix crash when reporting error about too many files in directory
15
22
16
----------------------------------------------------------------
23
----------------------------------------------------------------
17
Alberto Garcia (3):
24
Alberto Garcia (7):
18
specs/qcow2: Fix documentation of the compressed cluster descriptor
25
block: replace "discard" literal with BDRV_OPT_DISCARD macro
19
docs: document how to use the l2-cache-entry-size parameter
26
qcow2: Get the request alignment for encrypted images from QCryptoBlock
20
qcow2: Replace align_offset() with ROUND_UP()
27
quorum: Remove quorum_err()
28
quorum: Return an error if the blkverify mode has invalid settings
29
iotest: Test the blkverify mode of the Quorum driver
30
quorum: Forbid adding children in blkverify mode
31
iotest: Test x-blockdev-change on a Quorum
21
32
22
Anton Nefedov (2):
33
Cleber Rosa (1):
23
block: fix write with zero flag set and iovector provided
34
iotests: make 083 specific to raw
24
iotest 033: add misaligned write-zeroes test via truncate
25
35
26
Eric Blake (21):
36
Daniel P. Berrangé (1):
27
block: Add .bdrv_co_block_status() callback
37
crypto: initialize sector size even when opening with no IO flag
28
nvme: Drop pointless .bdrv_co_get_block_status()
29
block: Switch passthrough drivers to .bdrv_co_block_status()
30
file-posix: Switch to .bdrv_co_block_status()
31
gluster: Switch to .bdrv_co_block_status()
32
iscsi: Switch cluster_sectors to byte-based
33
iscsi: Switch iscsi_allocmap_update() to byte-based
34
iscsi: Switch to .bdrv_co_block_status()
35
null: Switch to .bdrv_co_block_status()
36
parallels: Switch to .bdrv_co_block_status()
37
qcow: Switch to .bdrv_co_block_status()
38
qcow2: Switch to .bdrv_co_block_status()
39
qed: Switch to .bdrv_co_block_status()
40
raw: Switch to .bdrv_co_block_status()
41
sheepdog: Switch to .bdrv_co_block_status()
42
vdi: Avoid bitrot of debugging code
43
vdi: Switch to .bdrv_co_block_status()
44
vmdk: Switch to .bdrv_co_block_status()
45
vpc: Switch to .bdrv_co_block_status()
46
vvfat: Switch to .bdrv_co_block_status()
47
block: Drop unused .bdrv_co_get_block_status()
48
38
49
Kevin Wolf (2):
39
Kevin Wolf (12):
50
block: test blk_aio_flush() with blk->root == NULL
40
vpc: Don't leak opts in vpc_open()
51
Merge remote-tracking branch 'mreitz/tags/pull-block-2018-03-02' into queue-block
41
block: Update flags in bdrv_set_read_only()
42
block: Add auto-read-only option
43
rbd: Close image in qemu_rbd_open() error path
44
block: Require auto-read-only for existing fallbacks
45
nbd: Support auto-read-only option
46
file-posix: Support auto-read-only option
47
curl: Support auto-read-only option
48
gluster: Support auto-read-only option
49
iscsi: Support auto-read-only option
50
block: Make auto-read-only=on default for -drive
51
qemu-iotests: Test auto-read-only with -drive and -blockdev
52
52
53
Max Reitz (4):
53
Leonid Bloch (2):
54
qemu-img: Make resize error message more general
54
vdi: Use a literal number of bytes for DEFAULT_CLUSTER_SIZE
55
block/ssh: Pull ssh_grow_file() from ssh_create()
55
include: Add a comment to explain the origin of sizes' lookup table
56
block/ssh: Make ssh_grow_file() blocking
57
block/ssh: Add basic .bdrv_truncate()
58
56
59
Stefan Hajnoczi (6):
57
Li Qiang (1):
60
aio: rename aio_context_in_iothread() to in_aio_context_home_thread()
58
block: change some function return type to bool
61
block: extract AIO_WAIT_WHILE() from BlockDriverState
62
block: add BlockBackend->in_flight counter
63
Revert "IDE: Do not flush empty CDROM drives"
64
block: rename .bdrv_create() to .bdrv_co_create_opts()
65
qcow2: make qcow2_co_create2() a coroutine_fn
66
59
67
docs/interop/qcow2.txt | 16 ++++-
60
Max Reitz (5):
68
docs/qcow2-cache.txt | 46 ++++++++++++-
61
option: Make option help nicer to read
69
block/qcow2.h | 6 --
62
chardev: Indent list of chardevs
70
include/block/aio-wait.h | 116 ++++++++++++++++++++++++++++++++
63
qdev-monitor: Make device options help nicer
71
include/block/aio.h | 7 +-
64
object: Make option help nicer to read
72
include/block/block.h | 54 ++++-----------
65
fw_cfg: Drop newline in @file description
73
include/block/block_int.h | 61 ++++++++++-------
74
block.c | 11 ++-
75
block/blkdebug.c | 20 +++---
76
block/block-backend.c | 60 +++++++++++++++--
77
block/commit.c | 2 +-
78
block/crypto.c | 8 +--
79
block/file-posix.c | 79 +++++++++++-----------
80
block/file-win32.c | 5 +-
81
block/gluster.c | 83 ++++++++++++-----------
82
block/io.c | 98 +++++++++++----------------
83
block/iscsi.c | 164 ++++++++++++++++++++++++---------------------
84
block/mirror.c | 2 +-
85
block/nfs.c | 5 +-
86
block/null.c | 23 ++++---
87
block/nvme.c | 14 ----
88
block/parallels.c | 28 +++++---
89
block/qcow.c | 32 +++++----
90
block/qcow2-bitmap.c | 4 +-
91
block/qcow2-cluster.c | 4 +-
92
block/qcow2-refcount.c | 4 +-
93
block/qcow2-snapshot.c | 10 +--
94
block/qcow2.c | 60 +++++++++--------
95
block/qed.c | 82 ++++++++---------------
96
block/raw-format.c | 21 +++---
97
block/rbd.c | 6 +-
98
block/sheepdog.c | 36 +++++-----
99
block/ssh.c | 66 +++++++++++++++---
100
block/throttle.c | 2 +-
101
block/vdi.c | 50 +++++++-------
102
block/vhdx.c | 5 +-
103
block/vmdk.c | 43 +++++-------
104
block/vpc.c | 50 +++++++-------
105
block/vvfat.c | 16 ++---
106
hw/ide/core.c | 10 +--
107
qemu-img.c | 2 +-
108
tests/test-block-backend.c | 82 +++++++++++++++++++++++
109
util/aio-wait.c | 40 +++++++++++
110
tests/Makefile.include | 2 +
111
tests/qemu-iotests/033 | 29 ++++++++
112
tests/qemu-iotests/033.out | 13 ++++
113
util/Makefile.objs | 2 +-
114
47 files changed, 973 insertions(+), 606 deletions(-)
115
create mode 100644 include/block/aio-wait.h
116
create mode 100644 tests/test-block-backend.c
117
create mode 100644 util/aio-wait.c
118
66
67
Peter Maydell (5):
68
block/qcow2: Don't take address of fields in packed structs
69
block/qcow: Don't take address of fields in packed structs
70
block/qcow2-bitmap: Don't take address of fields in packed structs
71
block/vhdx: Don't take address of fields in packed structs
72
block/vdi: Don't take address of fields in packed structs
73
74
Stefan Weil (1):
75
qemu-io-cmds: Fix two format strings
76
77
Thomas Huth (1):
78
block/vvfat: Fix crash when reporting error about too many files in directory
79
80
qapi/block-core.json | 7 +
81
block/vhdx.h | 12 +-
82
include/block/block.h | 5 +-
83
include/qemu/option.h | 2 +-
84
include/qemu/units.h | 18 +
85
include/sysemu/block-backend.h | 6 +-
86
block.c | 60 ++-
87
block/block-backend.c | 8 +-
88
block/bochs.c | 17 +-
89
block/cloop.c | 16 +-
90
block/curl.c | 8 +-
91
block/dmg.c | 16 +-
92
block/file-posix.c | 19 +-
93
block/gluster.c | 12 +-
94
block/iscsi.c | 8 +-
95
block/nbd-client.c | 10 +-
96
block/qcow.c | 18 +-
97
block/qcow2-bitmap.c | 24 +-
98
block/qcow2.c | 66 +--
99
block/quorum.c | 45 +-
100
block/rbd.c | 14 +-
101
block/vdi.c | 68 +--
102
block/vhdx-endian.c | 118 ++---
103
block/vhdx-log.c | 4 +-
104
block/vhdx.c | 18 +-
105
block/vpc.c | 2 +
106
block/vvfat.c | 15 +-
107
blockdev.c | 3 +-
108
chardev/char.c | 2 +-
109
crypto/block-qcow.c | 2 +
110
qdev-monitor.c | 13 +-
111
qemu-img.c | 4 +-
112
qemu-io-cmds.c | 4 +-
113
util/qemu-option.c | 32 +-
114
vl.c | 15 +-
115
tests/qemu-iotests/081 | 116 +++++
116
tests/qemu-iotests/081.out | 70 +++
117
tests/qemu-iotests/082.out | 956 ++++++++++++++++++++---------------------
118
tests/qemu-iotests/083 | 2 +-
119
tests/qemu-iotests/232 | 147 +++++++
120
tests/qemu-iotests/232.out | 59 +++
121
tests/qemu-iotests/group | 1 +
122
42 files changed, 1266 insertions(+), 776 deletions(-)
123
create mode 100755 tests/qemu-iotests/232
124
create mode 100644 tests/qemu-iotests/232.out
125
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually moving away from sector-based interfaces, towards
4
byte-based. Now that the block layer exposes byte-based allocation,
5
it's time to tackle the drivers. Add a new callback that operates
6
on as small as byte boundaries. Subsequent patches will then update
7
individual drivers, then finally remove .bdrv_co_get_block_status().
8
9
The new code also passes through the 'want_zero' hint, which will
10
allow subsequent patches to further optimize callers that only care
11
about how much of the image is allocated (want_zero is false),
12
rather than full details about runs of zeroes and which offsets the
13
allocation actually maps to (want_zero is true). As part of this
14
effort, fix another part of the documentation: the claim in commit
15
4c41cb4 that BDRV_BLOCK_ALLOCATED is short for 'DATA || ZERO' is a
16
lie at the block layer (see commit e88ae2264), even though it is
17
how the bit is computed from the driver layer. After all, there
18
are intentionally cases where we return ZERO but not ALLOCATED at
19
the block layer, when we know that a read sees zero because the
20
backing file is too short. Note that the driver interface is thus
21
slightly different than the public interface with regards to which
22
bits will be set, and what guarantees are provided on input.
23
24
We also add an assertion that any driver using the new callback will
25
make progress (the only time pnum will be 0 is if the block layer
26
already handled an out-of-bounds request, or if there is an error);
27
the old driver interface did not provide this guarantee, which
28
could lead to some inf-loops in drastic corner-case failures.
29
30
Signed-off-by: Eric Blake <eblake@redhat.com>
31
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
32
Reviewed-by: Fam Zheng <famz@redhat.com>
33
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
34
---
35
include/block/block.h | 14 +++++++-------
36
include/block/block_int.h | 20 +++++++++++++++-----
37
block/io.c | 28 +++++++++++++++++++---------
38
3 files changed, 41 insertions(+), 21 deletions(-)
39
40
diff --git a/include/block/block.h b/include/block/block.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/include/block/block.h
43
+++ b/include/block/block.h
44
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
45
* BDRV_BLOCK_ZERO: offset reads as zero
46
* BDRV_BLOCK_OFFSET_VALID: an associated offset exists for accessing raw data
47
* BDRV_BLOCK_ALLOCATED: the content of the block is determined by this
48
- * layer (short for DATA || ZERO), set by block layer
49
- * BDRV_BLOCK_EOF: the returned pnum covers through end of file for this layer
50
+ * layer rather than any backing, set by block layer
51
+ * BDRV_BLOCK_EOF: the returned pnum covers through end of file for this
52
+ * layer, set by block layer
53
*
54
* Internal flag:
55
* BDRV_BLOCK_RAW: for use by passthrough drivers, such as raw, to request
56
* that the block layer recompute the answer from the returned
57
* BDS; must be accompanied by just BDRV_BLOCK_OFFSET_VALID.
58
*
59
- * If BDRV_BLOCK_OFFSET_VALID is set, bits 9-62 (BDRV_BLOCK_OFFSET_MASK) of
60
- * the return value (old interface) or the entire map parameter (new
61
- * interface) represent the offset in the returned BDS that is allocated for
62
- * the corresponding raw data. However, whether that offset actually
63
- * contains data also depends on BDRV_BLOCK_DATA, as follows:
64
+ * If BDRV_BLOCK_OFFSET_VALID is set, the map parameter represents the
65
+ * host offset within the returned BDS that is allocated for the
66
+ * corresponding raw guest data. However, whether that offset
67
+ * actually contains data also depends on BDRV_BLOCK_DATA, as follows:
68
*
69
* DATA ZERO OFFSET_VALID
70
* t t t sectors read as zero, returned file is zero at offset
71
diff --git a/include/block/block_int.h b/include/block/block_int.h
72
index XXXXXXX..XXXXXXX 100644
73
--- a/include/block/block_int.h
74
+++ b/include/block/block_int.h
75
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
76
/*
77
* Building block for bdrv_block_status[_above] and
78
* bdrv_is_allocated[_above]. The driver should answer only
79
- * according to the current layer, and should not set
80
- * BDRV_BLOCK_ALLOCATED, but may set BDRV_BLOCK_RAW. See block.h
81
- * for the meaning of _DATA, _ZERO, and _OFFSET_VALID. The block
82
- * layer guarantees input aligned to request_alignment, as well as
83
- * non-NULL pnum and file.
84
+ * according to the current layer, and should only need to set
85
+ * BDRV_BLOCK_DATA, BDRV_BLOCK_ZERO, BDRV_BLOCK_OFFSET_VALID,
86
+ * and/or BDRV_BLOCK_RAW; if the current layer defers to a backing
87
+ * layer, the result should be 0 (and not BDRV_BLOCK_ZERO). See
88
+ * block.h for the overall meaning of the bits. As a hint, the
89
+ * flag want_zero is true if the caller cares more about precise
90
+ * mappings (favor accurate _OFFSET_VALID/_ZERO) or false for
91
+ * overall allocation (favor larger *pnum, perhaps by reporting
92
+ * _DATA instead of _ZERO). The block layer guarantees input
93
+ * clamped to bdrv_getlength() and aligned to request_alignment,
94
+ * as well as non-NULL pnum, map, and file; in turn, the driver
95
+ * must return an error or set pnum to an aligned non-zero value.
96
*/
97
int64_t coroutine_fn (*bdrv_co_get_block_status)(BlockDriverState *bs,
98
int64_t sector_num, int nb_sectors, int *pnum,
99
BlockDriverState **file);
100
+ int coroutine_fn (*bdrv_co_block_status)(BlockDriverState *bs,
101
+ bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
102
+ int64_t *map, BlockDriverState **file);
103
104
/*
105
* Invalidate any cached meta-data.
106
diff --git a/block/io.c b/block/io.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/block/io.c
109
+++ b/block/io.c
110
@@ -XXX,XX +XXX,XX @@ int64_t coroutine_fn bdrv_co_get_block_status_from_backing(BlockDriverState *bs,
111
* Drivers not implementing the functionality are assumed to not support
112
* backing files, hence all their sectors are reported as allocated.
113
*
114
- * If 'want_zero' is true, the caller is querying for mapping purposes,
115
- * and the result should include BDRV_BLOCK_OFFSET_VALID and
116
- * BDRV_BLOCK_ZERO where possible; otherwise, the result may omit those
117
- * bits particularly if it allows for a larger value in 'pnum'.
118
+ * If 'want_zero' is true, the caller is querying for mapping
119
+ * purposes, with a focus on valid BDRV_BLOCK_OFFSET_VALID, _DATA, and
120
+ * _ZERO where possible; otherwise, the result favors larger 'pnum',
121
+ * with a focus on accurate BDRV_BLOCK_ALLOCATED.
122
*
123
* If 'offset' is beyond the end of the disk image the return value is
124
* BDRV_BLOCK_EOF and 'pnum' is set to 0.
125
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
126
127
/* Must be non-NULL or bdrv_getlength() would have failed */
128
assert(bs->drv);
129
- if (!bs->drv->bdrv_co_get_block_status) {
130
+ if (!bs->drv->bdrv_co_get_block_status && !bs->drv->bdrv_co_block_status) {
131
*pnum = bytes;
132
ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED;
133
if (offset + bytes == total_size) {
134
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
135
bdrv_inc_in_flight(bs);
136
137
/* Round out to request_alignment boundaries */
138
- /* TODO: until we have a byte-based driver callback, we also have to
139
- * round out to sectors, even if that is bigger than request_alignment */
140
- align = MAX(bs->bl.request_alignment, BDRV_SECTOR_SIZE);
141
+ align = bs->bl.request_alignment;
142
+ if (bs->drv->bdrv_co_get_block_status && align < BDRV_SECTOR_SIZE) {
143
+ align = BDRV_SECTOR_SIZE;
144
+ }
145
aligned_offset = QEMU_ALIGN_DOWN(offset, align);
146
aligned_bytes = ROUND_UP(offset + bytes, align) - aligned_offset;
147
148
- {
149
+ if (bs->drv->bdrv_co_get_block_status) {
150
int count; /* sectors */
151
int64_t longret;
152
153
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
154
}
155
ret = longret & ~BDRV_BLOCK_OFFSET_MASK;
156
*pnum = count * BDRV_SECTOR_SIZE;
157
+ } else {
158
+ ret = bs->drv->bdrv_co_block_status(bs, want_zero, aligned_offset,
159
+ aligned_bytes, pnum, &local_map,
160
+ &local_file);
161
+ if (ret < 0) {
162
+ *pnum = 0;
163
+ goto out;
164
+ }
165
+ assert(*pnum); /* The block driver must make progress */
166
}
167
168
/*
169
--
170
2.13.6
171
172
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
We are gradually moving away from sector-based interfaces, towards
3
When using the vvfat driver with a directory that contains too many files,
4
byte-based. Update the vvfat driver accordingly. Note that we
4
QEMU currently crashes. This can be triggered like this for example:
5
can rely on the block driver having already clamped limits to our
6
block size, and simplify accordingly.
7
5
8
Signed-off-by: Eric Blake <eblake@redhat.com>
6
mkdir /tmp/vvfattest
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
cd /tmp/vvfattest
10
Reviewed-by: Fam Zheng <famz@redhat.com>
8
for ((x=0;x<=513;x++)); do mkdir $x; done
9
qemu-system-x86_64 -drive \
10
file.driver=vvfat,file.dir=.,read-only=on,media=cdrom
11
12
Seems like read_directory() is changing the mapping->path variable. Make
13
sure we use the right pointer instead.
14
15
Signed-off-by: Thomas Huth <thuth@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
17
---
13
block/vvfat.c | 16 +++++++---------
18
block/vvfat.c | 4 ++--
14
1 file changed, 7 insertions(+), 9 deletions(-)
19
1 file changed, 2 insertions(+), 2 deletions(-)
15
20
16
diff --git a/block/vvfat.c b/block/vvfat.c
21
diff --git a/block/vvfat.c b/block/vvfat.c
17
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
18
--- a/block/vvfat.c
23
--- a/block/vvfat.c
19
+++ b/block/vvfat.c
24
+++ b/block/vvfat.c
20
@@ -XXX,XX +XXX,XX @@ vvfat_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
25
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
21
return ret;
26
mapping = array_get(&(s->mapping), i);
22
}
27
23
28
if (mapping->mode & MODE_DIRECTORY) {
24
-static int64_t coroutine_fn vvfat_co_get_block_status(BlockDriverState *bs,
29
+ char *path = mapping->path;
25
- int64_t sector_num, int nb_sectors, int *n, BlockDriverState **file)
30
mapping->begin = cluster;
26
+static int coroutine_fn vvfat_co_block_status(BlockDriverState *bs,
31
if(read_directory(s, i)) {
27
+ bool want_zero, int64_t offset,
32
- error_setg(errp, "Could not read directory %s",
28
+ int64_t bytes, int64_t *n,
33
- mapping->path);
29
+ int64_t *map,
34
+ error_setg(errp, "Could not read directory %s", path);
30
+ BlockDriverState **file)
35
return -1;
31
{
36
}
32
- *n = bs->total_sectors - sector_num;
37
mapping = array_get(&(s->mapping), i);
33
- if (*n > nb_sectors) {
34
- *n = nb_sectors;
35
- } else if (*n < 0) {
36
- return 0;
37
- }
38
+ *n = bytes;
39
return BDRV_BLOCK_DATA;
40
}
41
42
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vvfat = {
43
44
.bdrv_co_preadv = vvfat_co_preadv,
45
.bdrv_co_pwritev = vvfat_co_pwritev,
46
- .bdrv_co_get_block_status = vvfat_co_get_block_status,
47
+ .bdrv_co_block_status = vvfat_co_block_status,
48
};
49
50
static void bdrv_vvfat_init(void)
51
--
38
--
52
2.13.6
39
2.19.1
53
40
54
41
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
We are gradually moving away from sector-based interfaces, towards
3
Signed-off-by: Alberto Garcia <berto@igalia.com>
4
byte-based. Update the sheepdog driver accordingly.
5
6
Signed-off-by: Eric Blake <eblake@redhat.com>
7
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Reviewed-by: Fam Zheng <famz@redhat.com>
9
Reviewed-by: Jeff Cody <jcody@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
5
---
12
block/sheepdog.c | 26 +++++++++++++-------------
6
block.c | 6 +++---
13
1 file changed, 13 insertions(+), 13 deletions(-)
7
1 file changed, 3 insertions(+), 3 deletions(-)
14
8
15
diff --git a/block/sheepdog.c b/block/sheepdog.c
9
diff --git a/block.c b/block.c
16
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
17
--- a/block/sheepdog.c
11
--- a/block.c
18
+++ b/block/sheepdog.c
12
+++ b/block.c
19
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int sd_co_pdiscard(BlockDriverState *bs, int64_t offset,
13
@@ -XXX,XX +XXX,XX @@ QemuOptsList bdrv_runtime_opts = {
20
return acb.ret;
14
.help = "try to optimize zero writes (off, on, unmap)",
21
}
15
},
22
16
{
23
-static coroutine_fn int64_t
17
- .name = "discard",
24
-sd_co_get_block_status(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
18
+ .name = BDRV_OPT_DISCARD,
25
- int *pnum, BlockDriverState **file)
19
.type = QEMU_OPT_STRING,
26
+static coroutine_fn int
20
.help = "discard operation (ignore/off, unmap/on)",
27
+sd_co_block_status(BlockDriverState *bs, bool want_zero, int64_t offset,
21
},
28
+ int64_t bytes, int64_t *pnum, int64_t *map,
22
@@ -XXX,XX +XXX,XX @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
29
+ BlockDriverState **file)
30
{
31
BDRVSheepdogState *s = bs->opaque;
32
SheepdogInode *inode = &s->inode;
33
uint32_t object_size = (UINT32_C(1) << inode->block_size_shift);
34
- uint64_t offset = sector_num * BDRV_SECTOR_SIZE;
35
unsigned long start = offset / object_size,
36
- end = DIV_ROUND_UP((sector_num + nb_sectors) *
37
- BDRV_SECTOR_SIZE, object_size);
38
+ end = DIV_ROUND_UP(offset + bytes, object_size);
39
unsigned long idx;
40
- int64_t ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | offset;
41
+ *map = offset;
42
+ int ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
43
44
for (idx = start; idx < end; idx++) {
45
if (inode->data_vdi_id[idx] == 0) {
46
@@ -XXX,XX +XXX,XX @@ sd_co_get_block_status(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
47
}
23
}
48
}
24
}
49
25
50
- *pnum = (idx - start) * object_size / BDRV_SECTOR_SIZE;
26
- discard = qemu_opt_get(opts, "discard");
51
- if (*pnum > nb_sectors) {
27
+ discard = qemu_opt_get(opts, BDRV_OPT_DISCARD);
52
- *pnum = nb_sectors;
28
if (discard != NULL) {
53
+ *pnum = (idx - start) * object_size;
29
if (bdrv_parse_discard_flags(discard, &bs->open_flags) != 0) {
54
+ if (*pnum > bytes) {
30
error_setg(errp, "Invalid discard option");
55
+ *pnum = bytes;
31
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
56
}
32
57
if (ret > 0 && ret & BDRV_BLOCK_OFFSET_VALID) {
33
update_flags_from_options(&reopen_state->flags, opts);
58
*file = bs;
34
59
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_sheepdog = {
35
- discard = qemu_opt_get_del(opts, "discard");
60
.bdrv_co_writev = sd_co_writev,
36
+ discard = qemu_opt_get_del(opts, BDRV_OPT_DISCARD);
61
.bdrv_co_flush_to_disk = sd_co_flush_to_disk,
37
if (discard != NULL) {
62
.bdrv_co_pdiscard = sd_co_pdiscard,
38
if (bdrv_parse_discard_flags(discard, &reopen_state->flags) != 0) {
63
- .bdrv_co_get_block_status = sd_co_get_block_status,
39
error_setg(errp, "Invalid discard option");
64
+ .bdrv_co_block_status = sd_co_block_status,
65
66
.bdrv_snapshot_create = sd_snapshot_create,
67
.bdrv_snapshot_goto = sd_snapshot_goto,
68
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_sheepdog_tcp = {
69
.bdrv_co_writev = sd_co_writev,
70
.bdrv_co_flush_to_disk = sd_co_flush_to_disk,
71
.bdrv_co_pdiscard = sd_co_pdiscard,
72
- .bdrv_co_get_block_status = sd_co_get_block_status,
73
+ .bdrv_co_block_status = sd_co_block_status,
74
75
.bdrv_snapshot_create = sd_snapshot_create,
76
.bdrv_snapshot_goto = sd_snapshot_goto,
77
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_sheepdog_unix = {
78
.bdrv_co_writev = sd_co_writev,
79
.bdrv_co_flush_to_disk = sd_co_flush_to_disk,
80
.bdrv_co_pdiscard = sd_co_pdiscard,
81
- .bdrv_co_get_block_status = sd_co_get_block_status,
82
+ .bdrv_co_block_status = sd_co_block_status,
83
84
.bdrv_snapshot_create = sd_snapshot_create,
85
.bdrv_snapshot_goto = sd_snapshot_goto,
86
--
40
--
87
2.13.6
41
2.19.1
88
42
89
43
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
From: Stefan Weil <sw@weilnetz.de>
2
2
3
This reverts commit 4da97120d51a4383aa96d741a2b837f8c4bbcd0b.
3
Use %zu instead of %zd for unsigned numbers.
4
4
5
blk_aio_flush() now handles the blk->root == NULL case, so we no longer
5
This fixes two error messages from the LSTM static code analyzer:
6
need this workaround.
7
6
8
Cc: John Snow <jsnow@redhat.com>
7
This argument should be of type 'ssize_t' but is of type 'unsigned long'
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
10
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Signed-off-by: Stefan Weil <sw@weilnetz.de>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
12
---
13
hw/ide/core.c | 10 +---------
13
qemu-io-cmds.c | 4 ++--
14
1 file changed, 1 insertion(+), 9 deletions(-)
14
1 file changed, 2 insertions(+), 2 deletions(-)
15
15
16
diff --git a/hw/ide/core.c b/hw/ide/core.c
16
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/ide/core.c
18
--- a/qemu-io-cmds.c
19
+++ b/hw/ide/core.c
19
+++ b/qemu-io-cmds.c
20
@@ -XXX,XX +XXX,XX @@ static void ide_flush_cache(IDEState *s)
20
@@ -XXX,XX +XXX,XX @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
21
s->status |= BUSY_STAT;
21
memset(cmp_buf, pattern, qiov.size);
22
ide_set_retry(s);
22
if (memcmp(buf, cmp_buf, qiov.size)) {
23
block_acct_start(blk_get_stats(s->blk), &s->acct, 0, BLOCK_ACCT_FLUSH);
23
printf("Pattern verification failed at offset %"
24
-
24
- PRId64 ", %zd bytes\n", offset, qiov.size);
25
- if (blk_bs(s->blk)) {
25
+ PRId64 ", %zu bytes\n", offset, qiov.size);
26
- s->pio_aiocb = blk_aio_flush(s->blk, ide_flush_cb, s);
26
ret = -EINVAL;
27
- } else {
27
}
28
- /* XXX blk_aio_flush() crashes when blk_bs(blk) is NULL, remove this
28
g_free(cmp_buf);
29
- * temporary workaround when blk_aio_*() functions handle NULL blk_bs.
29
@@ -XXX,XX +XXX,XX @@ static void aio_read_done(void *opaque, int ret)
30
- */
30
memset(cmp_buf, ctx->pattern, ctx->qiov.size);
31
- ide_flush_cb(s, 0);
31
if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
32
- }
32
printf("Pattern verification failed at offset %"
33
+ s->pio_aiocb = blk_aio_flush(s->blk, ide_flush_cb, s);
33
- PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
34
}
34
+ PRId64 ", %zu bytes\n", ctx->offset, ctx->qiov.size);
35
35
}
36
static void ide_cfata_metadata_inquiry(IDEState *s)
36
g_free(cmp_buf);
37
}
37
--
38
--
38
2.13.6
39
2.19.1
39
40
40
41
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Peter Maydell <peter.maydell@linaro.org>
2
2
3
We are gradually moving away from sector-based interfaces, towards
3
Taking the address of a field in a packed struct is a bad idea, because
4
byte-based. Update the qcow2 driver accordingly.
4
it might not be actually aligned enough for that pointer type (and
5
thus cause a crash on dereference on some host architectures). Newer
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
5
8
6
For now, we are ignoring the 'want_zero' hint. However, it should
9
There are a few places where the in-place swap function is
7
be relatively straightforward to honor the hint as a way to return
10
used on something other than a packed struct field; we convert
8
larger *pnum values when we have consecutive clusters with the same
11
those anyway, for consistency.
9
data/zero status but which differ only in having non-consecutive
10
mappings.
11
12
12
Signed-off-by: Eric Blake <eblake@redhat.com>
13
This patch was produced with the following spatch script
13
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
14
(and hand-editing to fold a few resulting overlength lines):
14
Reviewed-by: Fam Zheng <famz@redhat.com>
15
16
@@
17
expression E;
18
@@
19
-be16_to_cpus(&E);
20
+E = be16_to_cpu(E);
21
@@
22
expression E;
23
@@
24
-be32_to_cpus(&E);
25
+E = be32_to_cpu(E);
26
@@
27
expression E;
28
@@
29
-be64_to_cpus(&E);
30
+E = be64_to_cpu(E);
31
@@
32
expression E;
33
@@
34
-cpu_to_be16s(&E);
35
+E = cpu_to_be16(E);
36
@@
37
expression E;
38
@@
39
-cpu_to_be32s(&E);
40
+E = cpu_to_be32(E);
41
@@
42
expression E;
43
@@
44
-cpu_to_be64s(&E);
45
+E = cpu_to_be64(E);
46
47
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
49
Tested-by: John Snow <jsnow@redhat.com>
50
Reviewed-by: John Snow <jsnow@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
51
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
52
---
17
block/qcow2.c | 24 +++++++++++++-----------
53
block/qcow2.c | 64 +++++++++++++++++++++++++++------------------------
18
1 file changed, 13 insertions(+), 11 deletions(-)
54
1 file changed, 34 insertions(+), 30 deletions(-)
19
55
20
diff --git a/block/qcow2.c b/block/qcow2.c
56
diff --git a/block/qcow2.c b/block/qcow2.c
21
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
22
--- a/block/qcow2.c
58
--- a/block/qcow2.c
23
+++ b/block/qcow2.c
59
+++ b/block/qcow2.c
24
@@ -XXX,XX +XXX,XX @@ static void qcow2_join_options(QDict *options, QDict *old_options)
60
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
61
"pread fail from offset %" PRIu64, offset);
62
return 1;
63
}
64
- be32_to_cpus(&ext.magic);
65
- be32_to_cpus(&ext.len);
66
+ ext.magic = be32_to_cpu(ext.magic);
67
+ ext.len = be32_to_cpu(ext.len);
68
offset += sizeof(ext);
69
#ifdef DEBUG_EXT
70
printf("ext.magic = 0x%x\n", ext.magic);
71
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
72
"Unable to read CRYPTO header extension");
73
return ret;
74
}
75
- be64_to_cpus(&s->crypto_header.offset);
76
- be64_to_cpus(&s->crypto_header.length);
77
+ s->crypto_header.offset = be64_to_cpu(s->crypto_header.offset);
78
+ s->crypto_header.length = be64_to_cpu(s->crypto_header.length);
79
80
if ((s->crypto_header.offset % s->cluster_size) != 0) {
81
error_setg(errp, "Encryption header offset '%" PRIu64 "' is "
82
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
83
return -EINVAL;
84
}
85
86
- be32_to_cpus(&bitmaps_ext.nb_bitmaps);
87
- be64_to_cpus(&bitmaps_ext.bitmap_directory_size);
88
- be64_to_cpus(&bitmaps_ext.bitmap_directory_offset);
89
+ bitmaps_ext.nb_bitmaps = be32_to_cpu(bitmaps_ext.nb_bitmaps);
90
+ bitmaps_ext.bitmap_directory_size =
91
+ be64_to_cpu(bitmaps_ext.bitmap_directory_size);
92
+ bitmaps_ext.bitmap_directory_offset =
93
+ be64_to_cpu(bitmaps_ext.bitmap_directory_offset);
94
95
if (bitmaps_ext.nb_bitmaps > QCOW2_MAX_BITMAPS) {
96
error_setg(errp,
97
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
98
error_setg_errno(errp, -ret, "Could not read qcow2 header");
99
goto fail;
25
}
100
}
26
}
101
- be32_to_cpus(&header.magic);
27
102
- be32_to_cpus(&header.version);
28
-static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs,
103
- be64_to_cpus(&header.backing_file_offset);
29
- int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file)
104
- be32_to_cpus(&header.backing_file_size);
30
+static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
105
- be64_to_cpus(&header.size);
31
+ bool want_zero,
106
- be32_to_cpus(&header.cluster_bits);
32
+ int64_t offset, int64_t count,
107
- be32_to_cpus(&header.crypt_method);
33
+ int64_t *pnum, int64_t *map,
108
- be64_to_cpus(&header.l1_table_offset);
34
+ BlockDriverState **file)
109
- be32_to_cpus(&header.l1_size);
35
{
110
- be64_to_cpus(&header.refcount_table_offset);
36
BDRVQcow2State *s = bs->opaque;
111
- be32_to_cpus(&header.refcount_table_clusters);
37
uint64_t cluster_offset;
112
- be64_to_cpus(&header.snapshots_offset);
38
int index_in_cluster, ret;
113
- be32_to_cpus(&header.nb_snapshots);
39
unsigned int bytes;
114
+ header.magic = be32_to_cpu(header.magic);
40
- int64_t status = 0;
115
+ header.version = be32_to_cpu(header.version);
41
+ int status = 0;
116
+ header.backing_file_offset = be64_to_cpu(header.backing_file_offset);
42
117
+ header.backing_file_size = be32_to_cpu(header.backing_file_size);
43
- bytes = MIN(INT_MAX, nb_sectors * BDRV_SECTOR_SIZE);
118
+ header.size = be64_to_cpu(header.size);
44
+ bytes = MIN(INT_MAX, count);
119
+ header.cluster_bits = be32_to_cpu(header.cluster_bits);
45
qemu_co_mutex_lock(&s->lock);
120
+ header.crypt_method = be32_to_cpu(header.crypt_method);
46
- ret = qcow2_get_cluster_offset(bs, sector_num << BDRV_SECTOR_BITS, &bytes,
121
+ header.l1_table_offset = be64_to_cpu(header.l1_table_offset);
47
- &cluster_offset);
122
+ header.l1_size = be32_to_cpu(header.l1_size);
48
+ ret = qcow2_get_cluster_offset(bs, offset, &bytes, &cluster_offset);
123
+ header.refcount_table_offset = be64_to_cpu(header.refcount_table_offset);
49
qemu_co_mutex_unlock(&s->lock);
124
+ header.refcount_table_clusters =
50
if (ret < 0) {
125
+ be32_to_cpu(header.refcount_table_clusters);
51
return ret;
126
+ header.snapshots_offset = be64_to_cpu(header.snapshots_offset);
127
+ header.nb_snapshots = be32_to_cpu(header.nb_snapshots);
128
129
if (header.magic != QCOW_MAGIC) {
130
error_setg(errp, "Image is not in qcow2 format");
131
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
132
header.refcount_order = 4;
133
header.header_length = 72;
134
} else {
135
- be64_to_cpus(&header.incompatible_features);
136
- be64_to_cpus(&header.compatible_features);
137
- be64_to_cpus(&header.autoclear_features);
138
- be32_to_cpus(&header.refcount_order);
139
- be32_to_cpus(&header.header_length);
140
+ header.incompatible_features =
141
+ be64_to_cpu(header.incompatible_features);
142
+ header.compatible_features = be64_to_cpu(header.compatible_features);
143
+ header.autoclear_features = be64_to_cpu(header.autoclear_features);
144
+ header.refcount_order = be32_to_cpu(header.refcount_order);
145
+ header.header_length = be32_to_cpu(header.header_length);
146
147
if (header.header_length < 104) {
148
error_setg(errp, "qcow2 header too short");
149
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
150
goto fail;
151
}
152
for(i = 0;i < s->l1_size; i++) {
153
- be64_to_cpus(&s->l1_table[i]);
154
+ s->l1_table[i] = be64_to_cpu(s->l1_table[i]);
155
}
52
}
156
}
53
157
54
- *pnum = bytes >> BDRV_SECTOR_BITS;
158
@@ -XXX,XX +XXX,XX @@ int qcow2_update_header(BlockDriverState *bs)
55
+ *pnum = bytes;
159
56
160
/* Full disk encryption header pointer extension */
57
if (cluster_offset != 0 && ret != QCOW2_CLUSTER_COMPRESSED &&
161
if (s->crypto_header.offset != 0) {
58
!s->crypto) {
162
- cpu_to_be64s(&s->crypto_header.offset);
59
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
163
- cpu_to_be64s(&s->crypto_header.length);
60
- cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS);
164
+ s->crypto_header.offset = cpu_to_be64(s->crypto_header.offset);
61
+ index_in_cluster = offset & (s->cluster_size - 1);
165
+ s->crypto_header.length = cpu_to_be64(s->crypto_header.length);
62
+ *map = cluster_offset | index_in_cluster;
166
ret = header_ext_add(buf, QCOW2_EXT_MAGIC_CRYPTO_HEADER,
63
*file = bs->file->bs;
167
&s->crypto_header, sizeof(s->crypto_header),
64
- status |= BDRV_BLOCK_OFFSET_VALID | cluster_offset;
168
buflen);
65
+ status |= BDRV_BLOCK_OFFSET_VALID;
169
- be64_to_cpus(&s->crypto_header.offset);
66
}
170
- be64_to_cpus(&s->crypto_header.length);
67
if (ret == QCOW2_CLUSTER_ZERO_PLAIN || ret == QCOW2_CLUSTER_ZERO_ALLOC) {
171
+ s->crypto_header.offset = be64_to_cpu(s->crypto_header.offset);
68
status |= BDRV_BLOCK_ZERO;
172
+ s->crypto_header.length = be64_to_cpu(s->crypto_header.length);
69
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
173
if (ret < 0) {
70
.bdrv_child_perm = bdrv_format_default_perms,
174
goto fail;
71
.bdrv_create = qcow2_create,
175
}
72
.bdrv_has_zero_init = bdrv_has_zero_init_1,
73
- .bdrv_co_get_block_status = qcow2_co_get_block_status,
74
+ .bdrv_co_block_status = qcow2_co_block_status,
75
76
.bdrv_co_preadv = qcow2_co_preadv,
77
.bdrv_co_pwritev = qcow2_co_pwritev,
78
--
176
--
79
2.13.6
177
2.19.1
80
178
81
179
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Peter Maydell <peter.maydell@linaro.org>
2
2
3
We are gradually moving away from sector-based interfaces, towards
3
Taking the address of a field in a packed struct is a bad idea, because
4
byte-based. Update the qcow driver accordingly. There is no
4
it might not be actually aligned enough for that pointer type (and
5
intent to optimize based on the want_zero flag for this format.
5
thus cause a crash on dereference on some host architectures). Newer
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
6
8
7
Signed-off-by: Eric Blake <eblake@redhat.com>
9
There are a few places where the in-place swap function is
8
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
used on something other than a packed struct field; we convert
9
Reviewed-by: Fam Zheng <famz@redhat.com>
11
those anyway, for consistency.
12
13
This patch was produced with the following spatch script:
14
15
@@
16
expression E;
17
@@
18
-be16_to_cpus(&E);
19
+E = be16_to_cpu(E);
20
@@
21
expression E;
22
@@
23
-be32_to_cpus(&E);
24
+E = be32_to_cpu(E);
25
@@
26
expression E;
27
@@
28
-be64_to_cpus(&E);
29
+E = be64_to_cpu(E);
30
@@
31
expression E;
32
@@
33
-cpu_to_be16s(&E);
34
+E = cpu_to_be16(E);
35
@@
36
expression E;
37
@@
38
-cpu_to_be32s(&E);
39
+E = cpu_to_be32(E);
40
@@
41
expression E;
42
@@
43
-cpu_to_be64s(&E);
44
+E = cpu_to_be64(E);
45
46
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
47
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
48
Tested-by: John Snow <jsnow@redhat.com>
49
Reviewed-by: John Snow <jsnow@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
50
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
51
---
12
block/qcow.c | 27 ++++++++++++++++-----------
52
block/qcow.c | 18 +++++++++---------
13
1 file changed, 16 insertions(+), 11 deletions(-)
53
1 file changed, 9 insertions(+), 9 deletions(-)
14
54
15
diff --git a/block/qcow.c b/block/qcow.c
55
diff --git a/block/qcow.c b/block/qcow.c
16
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
17
--- a/block/qcow.c
57
--- a/block/qcow.c
18
+++ b/block/qcow.c
58
+++ b/block/qcow.c
19
@@ -XXX,XX +XXX,XX @@ static int get_cluster_offset(BlockDriverState *bs,
59
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
20
return 1;
21
}
22
23
-static int64_t coroutine_fn qcow_co_get_block_status(BlockDriverState *bs,
24
- int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file)
25
+static int coroutine_fn qcow_co_block_status(BlockDriverState *bs,
26
+ bool want_zero,
27
+ int64_t offset, int64_t bytes,
28
+ int64_t *pnum, int64_t *map,
29
+ BlockDriverState **file)
30
{
31
BDRVQcowState *s = bs->opaque;
32
- int index_in_cluster, n, ret;
33
+ int index_in_cluster, ret;
34
+ int64_t n;
35
uint64_t cluster_offset;
36
37
qemu_co_mutex_lock(&s->lock);
38
- ret = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0, &cluster_offset);
39
+ ret = get_cluster_offset(bs, offset, 0, 0, 0, 0, &cluster_offset);
40
qemu_co_mutex_unlock(&s->lock);
41
if (ret < 0) {
60
if (ret < 0) {
42
return ret;
61
goto fail;
43
}
62
}
44
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
63
- be32_to_cpus(&header.magic);
45
- n = s->cluster_sectors - index_in_cluster;
64
- be32_to_cpus(&header.version);
46
- if (n > nb_sectors)
65
- be64_to_cpus(&header.backing_file_offset);
47
- n = nb_sectors;
66
- be32_to_cpus(&header.backing_file_size);
48
+ index_in_cluster = offset & (s->cluster_size - 1);
67
- be32_to_cpus(&header.mtime);
49
+ n = s->cluster_size - index_in_cluster;
68
- be64_to_cpus(&header.size);
50
+ if (n > bytes) {
69
- be32_to_cpus(&header.crypt_method);
51
+ n = bytes;
70
- be64_to_cpus(&header.l1_table_offset);
52
+ }
71
+ header.magic = be32_to_cpu(header.magic);
53
*pnum = n;
72
+ header.version = be32_to_cpu(header.version);
54
if (!cluster_offset) {
73
+ header.backing_file_offset = be64_to_cpu(header.backing_file_offset);
55
return 0;
74
+ header.backing_file_size = be32_to_cpu(header.backing_file_size);
56
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn qcow_co_get_block_status(BlockDriverState *bs,
75
+ header.mtime = be32_to_cpu(header.mtime);
57
if ((cluster_offset & QCOW_OFLAG_COMPRESSED) || s->crypto) {
76
+ header.size = be64_to_cpu(header.size);
58
return BDRV_BLOCK_DATA;
77
+ header.crypt_method = be32_to_cpu(header.crypt_method);
78
+ header.l1_table_offset = be64_to_cpu(header.l1_table_offset);
79
80
if (header.magic != QCOW_MAGIC) {
81
error_setg(errp, "Image not in qcow format");
82
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
59
}
83
}
60
- cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS);
84
61
+ *map = cluster_offset | index_in_cluster;
85
for(i = 0;i < s->l1_size; i++) {
62
*file = bs->file->bs;
86
- be64_to_cpus(&s->l1_table[i]);
63
- return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | cluster_offset;
87
+ s->l1_table[i] = be64_to_cpu(s->l1_table[i]);
64
+ return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
88
}
65
}
89
66
90
/* alloc L2 cache (max. 64k * 16 * 8 = 8 MB) */
67
static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
68
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_qcow = {
69
70
.bdrv_co_readv = qcow_co_readv,
71
.bdrv_co_writev = qcow_co_writev,
72
- .bdrv_co_get_block_status = qcow_co_get_block_status,
73
+ .bdrv_co_block_status = qcow_co_block_status,
74
75
.bdrv_make_empty = qcow_make_empty,
76
.bdrv_co_pwritev_compressed = qcow_co_pwritev_compressed,
77
--
91
--
78
2.13.6
92
2.19.1
79
93
80
94
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Peter Maydell <peter.maydell@linaro.org>
2
2
3
We are gradually converting to byte-based interfaces, as they are
3
Taking the address of a field in a packed struct is a bad idea, because
4
easier to reason about than sector-based. Convert all uses of
4
it might not be actually aligned enough for that pointer type (and
5
the allocmap (no semantic change). Callers that already had bytes
5
thus cause a crash on dereference on some host architectures). Newer
6
available are simpler, and callers that now scale to bytes will be
6
versions of clang warn about this. Avoid the bug by not using the
7
easier to switch to byte-based in the future.
7
"modify in place" byte swapping functions.
8
8
9
Signed-off-by: Eric Blake <eblake@redhat.com>
9
There are a few places where the in-place swap function is
10
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
10
used on something other than a packed struct field; we convert
11
Reviewed-by: Fam Zheng <famz@redhat.com>
11
those anyway, for consistency.
12
13
This patch was produced with the following spatch script:
14
15
@@
16
expression E;
17
@@
18
-be16_to_cpus(&E);
19
+E = be16_to_cpu(E);
20
@@
21
expression E;
22
@@
23
-be32_to_cpus(&E);
24
+E = be32_to_cpu(E);
25
@@
26
expression E;
27
@@
28
-be64_to_cpus(&E);
29
+E = be64_to_cpu(E);
30
@@
31
expression E;
32
@@
33
-cpu_to_be16s(&E);
34
+E = cpu_to_be16(E);
35
@@
36
expression E;
37
@@
38
-cpu_to_be32s(&E);
39
+E = cpu_to_be32(E);
40
@@
41
expression E;
42
@@
43
-cpu_to_be64s(&E);
44
+E = cpu_to_be64(E);
45
46
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
47
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
48
Tested-by: John Snow <jsnow@redhat.com>
49
Reviewed-by: John Snow <jsnow@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
50
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
51
---
14
block/iscsi.c | 90 +++++++++++++++++++++++++++++------------------------------
52
block/qcow2-bitmap.c | 24 ++++++++++++------------
15
1 file changed, 44 insertions(+), 46 deletions(-)
53
1 file changed, 12 insertions(+), 12 deletions(-)
16
54
17
diff --git a/block/iscsi.c b/block/iscsi.c
55
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
18
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
19
--- a/block/iscsi.c
57
--- a/block/qcow2-bitmap.c
20
+++ b/block/iscsi.c
58
+++ b/block/qcow2-bitmap.c
21
@@ -XXX,XX +XXX,XX @@ static int iscsi_allocmap_init(IscsiLun *iscsilun, int open_flags)
59
@@ -XXX,XX +XXX,XX @@ static inline void bitmap_table_to_be(uint64_t *bitmap_table, size_t size)
60
size_t i;
61
62
for (i = 0; i < size; ++i) {
63
- cpu_to_be64s(&bitmap_table[i]);
64
+ bitmap_table[i] = cpu_to_be64(bitmap_table[i]);
65
}
22
}
66
}
23
67
24
static void
68
@@ -XXX,XX +XXX,XX @@ static int bitmap_table_load(BlockDriverState *bs, Qcow2BitmapTable *tb,
25
-iscsi_allocmap_update(IscsiLun *iscsilun, int64_t sector_num,
69
}
26
- int nb_sectors, bool allocated, bool valid)
70
27
+iscsi_allocmap_update(IscsiLun *iscsilun, int64_t offset,
71
for (i = 0; i < tb->size; ++i) {
28
+ int64_t bytes, bool allocated, bool valid)
72
- be64_to_cpus(&table[i]);
73
+ table[i] = be64_to_cpu(table[i]);
74
ret = check_table_entry(table[i], s->cluster_size);
75
if (ret < 0) {
76
goto fail;
77
@@ -XXX,XX +XXX,XX @@ fail:
78
79
static inline void bitmap_dir_entry_to_cpu(Qcow2BitmapDirEntry *entry)
29
{
80
{
30
int64_t cl_num_expanded, nb_cls_expanded, cl_num_shrunk, nb_cls_shrunk;
81
- be64_to_cpus(&entry->bitmap_table_offset);
31
- int cluster_sectors = iscsilun->cluster_size >> BDRV_SECTOR_BITS;
82
- be32_to_cpus(&entry->bitmap_table_size);
32
83
- be32_to_cpus(&entry->flags);
33
if (iscsilun->allocmap == NULL) {
84
- be16_to_cpus(&entry->name_size);
34
return;
85
- be32_to_cpus(&entry->extra_data_size);
35
}
86
+ entry->bitmap_table_offset = be64_to_cpu(entry->bitmap_table_offset);
36
/* expand to entirely contain all affected clusters */
87
+ entry->bitmap_table_size = be32_to_cpu(entry->bitmap_table_size);
37
- assert(cluster_sectors);
88
+ entry->flags = be32_to_cpu(entry->flags);
38
- cl_num_expanded = sector_num / cluster_sectors;
89
+ entry->name_size = be16_to_cpu(entry->name_size);
39
- nb_cls_expanded = DIV_ROUND_UP(sector_num + nb_sectors,
90
+ entry->extra_data_size = be32_to_cpu(entry->extra_data_size);
40
- cluster_sectors) - cl_num_expanded;
41
+ assert(iscsilun->cluster_size);
42
+ cl_num_expanded = offset / iscsilun->cluster_size;
43
+ nb_cls_expanded = DIV_ROUND_UP(offset + bytes,
44
+ iscsilun->cluster_size) - cl_num_expanded;
45
/* shrink to touch only completely contained clusters */
46
- cl_num_shrunk = DIV_ROUND_UP(sector_num, cluster_sectors);
47
- nb_cls_shrunk = (sector_num + nb_sectors) / cluster_sectors
48
- - cl_num_shrunk;
49
+ cl_num_shrunk = DIV_ROUND_UP(offset, iscsilun->cluster_size);
50
+ nb_cls_shrunk = (offset + bytes) / iscsilun->cluster_size - cl_num_shrunk;
51
if (allocated) {
52
bitmap_set(iscsilun->allocmap, cl_num_expanded, nb_cls_expanded);
53
} else {
54
@@ -XXX,XX +XXX,XX @@ iscsi_allocmap_update(IscsiLun *iscsilun, int64_t sector_num,
55
}
91
}
56
92
57
static void
93
static inline void bitmap_dir_entry_to_be(Qcow2BitmapDirEntry *entry)
58
-iscsi_allocmap_set_allocated(IscsiLun *iscsilun, int64_t sector_num,
59
- int nb_sectors)
60
+iscsi_allocmap_set_allocated(IscsiLun *iscsilun, int64_t offset,
61
+ int64_t bytes)
62
{
94
{
63
- iscsi_allocmap_update(iscsilun, sector_num, nb_sectors, true, true);
95
- cpu_to_be64s(&entry->bitmap_table_offset);
64
+ iscsi_allocmap_update(iscsilun, offset, bytes, true, true);
96
- cpu_to_be32s(&entry->bitmap_table_size);
97
- cpu_to_be32s(&entry->flags);
98
- cpu_to_be16s(&entry->name_size);
99
- cpu_to_be32s(&entry->extra_data_size);
100
+ entry->bitmap_table_offset = cpu_to_be64(entry->bitmap_table_offset);
101
+ entry->bitmap_table_size = cpu_to_be32(entry->bitmap_table_size);
102
+ entry->flags = cpu_to_be32(entry->flags);
103
+ entry->name_size = cpu_to_be16(entry->name_size);
104
+ entry->extra_data_size = cpu_to_be32(entry->extra_data_size);
65
}
105
}
66
106
67
static void
107
static inline int calc_dir_entry_size(size_t name_size, size_t extra_data_size)
68
-iscsi_allocmap_set_unallocated(IscsiLun *iscsilun, int64_t sector_num,
69
- int nb_sectors)
70
+iscsi_allocmap_set_unallocated(IscsiLun *iscsilun, int64_t offset,
71
+ int64_t bytes)
72
{
73
/* Note: if cache.direct=on the fifth argument to iscsi_allocmap_update
74
* is ignored, so this will in effect be an iscsi_allocmap_set_invalid.
75
*/
76
- iscsi_allocmap_update(iscsilun, sector_num, nb_sectors, false, true);
77
+ iscsi_allocmap_update(iscsilun, offset, bytes, false, true);
78
}
79
80
-static void iscsi_allocmap_set_invalid(IscsiLun *iscsilun, int64_t sector_num,
81
- int nb_sectors)
82
+static void iscsi_allocmap_set_invalid(IscsiLun *iscsilun, int64_t offset,
83
+ int64_t bytes)
84
{
85
- iscsi_allocmap_update(iscsilun, sector_num, nb_sectors, false, false);
86
+ iscsi_allocmap_update(iscsilun, offset, bytes, false, false);
87
}
88
89
static void iscsi_allocmap_invalidate(IscsiLun *iscsilun)
90
@@ -XXX,XX +XXX,XX @@ static void iscsi_allocmap_invalidate(IscsiLun *iscsilun)
91
}
92
93
static inline bool
94
-iscsi_allocmap_is_allocated(IscsiLun *iscsilun, int64_t sector_num,
95
- int nb_sectors)
96
+iscsi_allocmap_is_allocated(IscsiLun *iscsilun, int64_t offset,
97
+ int64_t bytes)
98
{
99
unsigned long size;
100
if (iscsilun->allocmap == NULL) {
101
return true;
102
}
103
assert(iscsilun->cluster_size);
104
- size = DIV_ROUND_UP(sector_num + nb_sectors,
105
- iscsilun->cluster_size >> BDRV_SECTOR_BITS);
106
+ size = DIV_ROUND_UP(offset + bytes, iscsilun->cluster_size);
107
return !(find_next_bit(iscsilun->allocmap, size,
108
- sector_num * BDRV_SECTOR_SIZE /
109
- iscsilun->cluster_size) == size);
110
+ offset / iscsilun->cluster_size) == size);
111
}
112
113
static inline bool iscsi_allocmap_is_valid(IscsiLun *iscsilun,
114
- int64_t sector_num, int nb_sectors)
115
+ int64_t offset, int64_t bytes)
116
{
117
unsigned long size;
118
if (iscsilun->allocmap_valid == NULL) {
119
return false;
120
}
121
assert(iscsilun->cluster_size);
122
- size = DIV_ROUND_UP(sector_num + nb_sectors,
123
- iscsilun->cluster_size >> BDRV_SECTOR_BITS);
124
+ size = DIV_ROUND_UP(offset + bytes, iscsilun->cluster_size);
125
return (find_next_zero_bit(iscsilun->allocmap_valid, size,
126
- sector_num * BDRV_SECTOR_SIZE /
127
- iscsilun->cluster_size) == size);
128
+ offset / iscsilun->cluster_size) == size);
129
}
130
131
static int coroutine_fn
132
@@ -XXX,XX +XXX,XX @@ retry:
133
}
134
135
if (iTask.status != SCSI_STATUS_GOOD) {
136
- iscsi_allocmap_set_invalid(iscsilun, sector_num, nb_sectors);
137
+ iscsi_allocmap_set_invalid(iscsilun, sector_num * BDRV_SECTOR_SIZE,
138
+ nb_sectors * BDRV_SECTOR_SIZE);
139
error_report("iSCSI WRITE10/16 failed at lba %" PRIu64 ": %s", lba,
140
iTask.err_str);
141
r = iTask.err_code;
142
goto out_unlock;
143
}
144
145
- iscsi_allocmap_set_allocated(iscsilun, sector_num, nb_sectors);
146
+ iscsi_allocmap_set_allocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
147
+ nb_sectors * BDRV_SECTOR_SIZE);
148
149
out_unlock:
150
qemu_mutex_unlock(&iscsilun->mutex);
151
@@ -XXX,XX +XXX,XX @@ retry:
152
}
153
154
if (ret & BDRV_BLOCK_ZERO) {
155
- iscsi_allocmap_set_unallocated(iscsilun, sector_num, *pnum);
156
+ iscsi_allocmap_set_unallocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
157
+ *pnum * BDRV_SECTOR_SIZE);
158
} else {
159
- iscsi_allocmap_set_allocated(iscsilun, sector_num, *pnum);
160
+ iscsi_allocmap_set_allocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
161
+ *pnum * BDRV_SECTOR_SIZE);
162
}
163
164
if (*pnum > nb_sectors) {
165
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs,
166
/* if cache.direct is off and we have a valid entry in our allocation map
167
* we can skip checking the block status and directly return zeroes if
168
* the request falls within an unallocated area */
169
- if (iscsi_allocmap_is_valid(iscsilun, sector_num, nb_sectors) &&
170
- !iscsi_allocmap_is_allocated(iscsilun, sector_num, nb_sectors)) {
171
+ if (iscsi_allocmap_is_valid(iscsilun, sector_num * BDRV_SECTOR_SIZE,
172
+ nb_sectors * BDRV_SECTOR_SIZE) &&
173
+ !iscsi_allocmap_is_allocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
174
+ nb_sectors * BDRV_SECTOR_SIZE)) {
175
qemu_iovec_memset(iov, 0, 0x00, iov->size);
176
return 0;
177
}
178
179
if (nb_sectors >= ISCSI_CHECKALLOC_THRES &&
180
- !iscsi_allocmap_is_valid(iscsilun, sector_num, nb_sectors) &&
181
- !iscsi_allocmap_is_allocated(iscsilun, sector_num, nb_sectors)) {
182
+ !iscsi_allocmap_is_valid(iscsilun, sector_num * BDRV_SECTOR_SIZE,
183
+ nb_sectors * BDRV_SECTOR_SIZE) &&
184
+ !iscsi_allocmap_is_allocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
185
+ nb_sectors * BDRV_SECTOR_SIZE)) {
186
int pnum;
187
BlockDriverState *file;
188
/* check the block status from the beginning of the cluster
189
@@ -XXX,XX +XXX,XX @@ retry:
190
goto retry;
191
}
192
193
- iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS,
194
- bytes >> BDRV_SECTOR_BITS);
195
+ iscsi_allocmap_set_invalid(iscsilun, offset, bytes);
196
197
if (iTask.status == SCSI_STATUS_CHECK_CONDITION) {
198
/* the target might fail with a check condition if it
199
@@ -XXX,XX +XXX,XX @@ retry:
200
}
201
202
if (iTask.status != SCSI_STATUS_GOOD) {
203
- iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS,
204
- bytes >> BDRV_SECTOR_BITS);
205
+ iscsi_allocmap_set_invalid(iscsilun, offset, bytes);
206
error_report("iSCSI WRITESAME10/16 failed at lba %" PRIu64 ": %s",
207
lba, iTask.err_str);
208
r = iTask.err_code;
209
@@ -XXX,XX +XXX,XX @@ retry:
210
}
211
212
if (flags & BDRV_REQ_MAY_UNMAP) {
213
- iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS,
214
- bytes >> BDRV_SECTOR_BITS);
215
+ iscsi_allocmap_set_invalid(iscsilun, offset, bytes);
216
} else {
217
- iscsi_allocmap_set_allocated(iscsilun, offset >> BDRV_SECTOR_BITS,
218
- bytes >> BDRV_SECTOR_BITS);
219
+ iscsi_allocmap_set_allocated(iscsilun, offset, bytes);
220
}
221
222
out_unlock:
223
--
108
--
224
2.13.6
109
2.19.1
225
110
226
111
diff view generated by jsdifflib
1
From: Anton Nefedov <anton.nefedov@virtuozzo.com>
1
From: Daniel P. Berrangé <berrange@redhat.com>
2
2
3
The normal bdrv_co_pwritev() use is either
3
The qcow2 block driver expects to see a valid sector size even when it
4
- BDRV_REQ_ZERO_WRITE clear and iovector provided
4
has opened the crypto layer with QCRYPTO_BLOCK_OPEN_NO_IO.
5
- BDRV_REQ_ZERO_WRITE set and iovector == NULL
6
5
7
while
6
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
8
- the flag clear and iovector == NULL is an assertion failure
9
in bdrv_co_do_zero_pwritev()
10
- the flag set and iovector provided is in fact allowed
11
(the flag prevails and zeroes are written)
12
13
However the alignment logic does not support the latter case so the padding
14
areas get overwritten with zeroes.
15
16
Currently, general functions like bdrv_rw_co() do provide iovector
17
regardless of flags. So, keep it supported and use bdrv_co_do_zero_pwritev()
18
alignment for it which also makes the code a bit more obvious anyway.
19
20
Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
21
Reviewed-by: Eric Blake <eblake@redhat.com>
22
Reviewed-by: Alberto Garcia <berto@igalia.com>
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
23
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
24
---
9
---
25
block/io.c | 2 +-
10
crypto/block-qcow.c | 2 ++
26
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 2 insertions(+)
27
12
28
diff --git a/block/io.c b/block/io.c
13
diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c
29
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
30
--- a/block/io.c
15
--- a/crypto/block-qcow.c
31
+++ b/block/io.c
16
+++ b/crypto/block-qcow.c
32
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
17
@@ -XXX,XX +XXX,XX @@ qcrypto_block_qcow_open(QCryptoBlock *block,
33
*/
18
Error **errp)
34
tracked_request_begin(&req, bs, offset, bytes, BDRV_TRACKED_WRITE);
19
{
35
20
if (flags & QCRYPTO_BLOCK_OPEN_NO_IO) {
36
- if (!qiov) {
21
+ block->sector_size = QCRYPTO_BLOCK_QCOW_SECTOR_SIZE;
37
+ if (flags & BDRV_REQ_ZERO_WRITE) {
22
+ block->payload_offset = 0;
38
ret = bdrv_co_do_zero_pwritev(child, offset, bytes, flags, &req);
23
return 0;
39
goto out;
24
} else {
40
}
25
if (!options->u.qcow.key_secret) {
41
--
26
--
42
2.13.6
27
2.19.1
43
28
44
29
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
qcow2_create2() calls qemu_co_mutex_lock(). Only a coroutine_fn may
3
This doesn't have any practical effect at the moment because the
4
call another coroutine_fn. In fact, qcow2_create2 is always called from
4
values of BDRV_SECTOR_SIZE, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE and
5
coroutine context.
5
QCRYPTO_BLOCK_QCOW_SECTOR_SIZE are all the same (512 bytes), but
6
future encryption methods could have different requirements.
6
7
7
Rename the function to add the "co" moniker and add coroutine_fn.
8
Signed-off-by: Alberto Garcia <berto@igalia.com>
8
9
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
9
Reported-by: Marc-André Lureau <marcandre.lureau@redhat.com>
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Message-Id: <20170705102231.20711-3-stefanha@redhat.com>
12
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
13
Reviewed-by: Eric Blake <eblake@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
11
---
16
block/qcow2.c | 17 +++++++++--------
12
block/qcow2.c | 2 +-
17
1 file changed, 9 insertions(+), 8 deletions(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
18
14
19
diff --git a/block/qcow2.c b/block/qcow2.c
15
diff --git a/block/qcow2.c b/block/qcow2.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/block/qcow2.c
17
--- a/block/qcow2.c
22
+++ b/block/qcow2.c
18
+++ b/block/qcow2.c
23
@@ -XXX,XX +XXX,XX @@ static uint64_t qcow2_opt_get_refcount_bits_del(QemuOpts *opts, int version,
19
@@ -XXX,XX +XXX,XX @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
24
return refcount_bits;
20
25
}
21
if (bs->encrypted) {
26
22
/* Encryption works on a sector granularity */
27
-static int qcow2_create2(const char *filename, int64_t total_size,
23
- bs->bl.request_alignment = BDRV_SECTOR_SIZE;
28
- const char *backing_file, const char *backing_format,
24
+ bs->bl.request_alignment = qcrypto_block_get_sector_size(s->crypto);
29
- int flags, size_t cluster_size, PreallocMode prealloc,
25
}
30
- QemuOpts *opts, int version, int refcount_order,
26
bs->bl.pwrite_zeroes_alignment = s->cluster_size;
31
- const char *encryptfmt, Error **errp)
27
bs->bl.pdiscard_alignment = s->cluster_size;
32
+static int coroutine_fn
33
+qcow2_co_create2(const char *filename, int64_t total_size,
34
+ const char *backing_file, const char *backing_format,
35
+ int flags, size_t cluster_size, PreallocMode prealloc,
36
+ QemuOpts *opts, int version, int refcount_order,
37
+ const char *encryptfmt, Error **errp)
38
{
39
QDict *options;
40
41
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_create_opts(const char *filename, QemuOpts *opt
42
43
refcount_order = ctz32(refcount_bits);
44
45
- ret = qcow2_create2(filename, size, backing_file, backing_fmt, flags,
46
- cluster_size, prealloc, opts, version, refcount_order,
47
- encryptfmt, &local_err);
48
+ ret = qcow2_co_create2(filename, size, backing_file, backing_fmt, flags,
49
+ cluster_size, prealloc, opts, version, refcount_order,
50
+ encryptfmt, &local_err);
51
error_propagate(errp, local_err);
52
53
finish:
54
--
28
--
55
2.13.6
29
2.19.1
56
30
57
31
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Li Qiang <liq3ea@163.com>
2
2
3
We are gradually moving away from sector-based interfaces, towards
3
Signed-off-by: Li Qiang <liq3ea@163.com>
4
byte-based. Update the generic helpers, and all passthrough clients
4
Reviewed-by: Alberto Garcia <berto@igalia.com>
5
(blkdebug, commit, mirror, throttle) accordingly.
6
7
Signed-off-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Reviewed-by: Fam Zheng <famz@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
6
---
12
include/block/block_int.h | 28 ++++++++++++++++------------
7
include/sysemu/block-backend.h | 6 +++---
13
block/blkdebug.c | 20 +++++++++++---------
8
block/block-backend.c | 8 ++++----
14
block/commit.c | 2 +-
9
2 files changed, 7 insertions(+), 7 deletions(-)
15
block/io.c | 36 ++++++++++++++++++++----------------
16
block/mirror.c | 2 +-
17
block/throttle.c | 2 +-
18
6 files changed, 50 insertions(+), 40 deletions(-)
19
10
20
diff --git a/include/block/block_int.h b/include/block/block_int.h
11
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
21
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
22
--- a/include/block/block_int.h
13
--- a/include/sysemu/block-backend.h
23
+++ b/include/block/block_int.h
14
+++ b/include/sysemu/block-backend.h
24
@@ -XXX,XX +XXX,XX @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
15
@@ -XXX,XX +XXX,XX @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
25
uint64_t *nperm, uint64_t *nshared);
16
int error);
26
17
void blk_error_action(BlockBackend *blk, BlockErrorAction action,
27
/*
18
bool is_read, int error);
28
- * Default implementation for drivers to pass bdrv_co_get_block_status() to
19
-int blk_is_read_only(BlockBackend *blk);
29
+ * Default implementation for drivers to pass bdrv_co_block_status() to
20
-int blk_is_sg(BlockBackend *blk);
30
* their file.
21
-int blk_enable_write_cache(BlockBackend *blk);
31
*/
22
+bool blk_is_read_only(BlockBackend *blk);
32
-int64_t coroutine_fn bdrv_co_get_block_status_from_file(BlockDriverState *bs,
23
+bool blk_is_sg(BlockBackend *blk);
33
- int64_t sector_num,
24
+bool blk_enable_write_cache(BlockBackend *blk);
34
- int nb_sectors,
25
void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
35
- int *pnum,
26
void blk_invalidate_cache(BlockBackend *blk, Error **errp);
36
- BlockDriverState **file);
27
bool blk_is_inserted(BlockBackend *blk);
37
+int coroutine_fn bdrv_co_block_status_from_file(BlockDriverState *bs,
28
diff --git a/block/block-backend.c b/block/block-backend.c
38
+ bool want_zero,
39
+ int64_t offset,
40
+ int64_t bytes,
41
+ int64_t *pnum,
42
+ int64_t *map,
43
+ BlockDriverState **file);
44
/*
45
- * Default implementation for drivers to pass bdrv_co_get_block_status() to
46
+ * Default implementation for drivers to pass bdrv_co_block_status() to
47
* their backing file.
48
*/
49
-int64_t coroutine_fn bdrv_co_get_block_status_from_backing(BlockDriverState *bs,
50
- int64_t sector_num,
51
- int nb_sectors,
52
- int *pnum,
53
- BlockDriverState **file);
54
+int coroutine_fn bdrv_co_block_status_from_backing(BlockDriverState *bs,
55
+ bool want_zero,
56
+ int64_t offset,
57
+ int64_t bytes,
58
+ int64_t *pnum,
59
+ int64_t *map,
60
+ BlockDriverState **file);
61
const char *bdrv_get_parent_name(const BlockDriverState *bs);
62
void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp);
63
bool blk_dev_has_removable_media(BlockBackend *blk);
64
diff --git a/block/blkdebug.c b/block/blkdebug.c
65
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
66
--- a/block/blkdebug.c
30
--- a/block/block-backend.c
67
+++ b/block/blkdebug.c
31
+++ b/block/block-backend.c
68
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs,
32
@@ -XXX,XX +XXX,XX @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
69
return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
33
}
70
}
34
}
71
35
72
-static int64_t coroutine_fn blkdebug_co_get_block_status(
36
-int blk_is_read_only(BlockBackend *blk)
73
- BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum,
37
+bool blk_is_read_only(BlockBackend *blk)
74
- BlockDriverState **file)
75
+static int coroutine_fn blkdebug_co_block_status(BlockDriverState *bs,
76
+ bool want_zero,
77
+ int64_t offset,
78
+ int64_t bytes,
79
+ int64_t *pnum,
80
+ int64_t *map,
81
+ BlockDriverState **file)
82
{
38
{
83
- assert(QEMU_IS_ALIGNED(sector_num | nb_sectors,
39
BlockDriverState *bs = blk_bs(blk);
84
- DIV_ROUND_UP(bs->bl.request_alignment,
40
85
- BDRV_SECTOR_SIZE)));
41
@@ -XXX,XX +XXX,XX @@ int blk_is_read_only(BlockBackend *blk)
86
- return bdrv_co_get_block_status_from_file(bs, sector_num, nb_sectors,
42
}
87
- pnum, file);
88
+ assert(QEMU_IS_ALIGNED(offset | bytes, bs->bl.request_alignment));
89
+ return bdrv_co_block_status_from_file(bs, want_zero, offset, bytes,
90
+ pnum, map, file);
91
}
43
}
92
44
93
static void blkdebug_close(BlockDriverState *bs)
45
-int blk_is_sg(BlockBackend *blk)
94
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_blkdebug = {
46
+bool blk_is_sg(BlockBackend *blk)
95
.bdrv_co_flush_to_disk = blkdebug_co_flush,
96
.bdrv_co_pwrite_zeroes = blkdebug_co_pwrite_zeroes,
97
.bdrv_co_pdiscard = blkdebug_co_pdiscard,
98
- .bdrv_co_get_block_status = blkdebug_co_get_block_status,
99
+ .bdrv_co_block_status = blkdebug_co_block_status,
100
101
.bdrv_debug_event = blkdebug_debug_event,
102
.bdrv_debug_breakpoint = blkdebug_debug_breakpoint,
103
diff --git a/block/commit.c b/block/commit.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/block/commit.c
106
+++ b/block/commit.c
107
@@ -XXX,XX +XXX,XX @@ static void bdrv_commit_top_child_perm(BlockDriverState *bs, BdrvChild *c,
108
static BlockDriver bdrv_commit_top = {
109
.format_name = "commit_top",
110
.bdrv_co_preadv = bdrv_commit_top_preadv,
111
- .bdrv_co_get_block_status = bdrv_co_get_block_status_from_backing,
112
+ .bdrv_co_block_status = bdrv_co_block_status_from_backing,
113
.bdrv_refresh_filename = bdrv_commit_top_refresh_filename,
114
.bdrv_close = bdrv_commit_top_close,
115
.bdrv_child_perm = bdrv_commit_top_child_perm,
116
diff --git a/block/io.c b/block/io.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/block/io.c
119
+++ b/block/io.c
120
@@ -XXX,XX +XXX,XX @@ typedef struct BdrvCoBlockStatusData {
121
bool done;
122
} BdrvCoBlockStatusData;
123
124
-int64_t coroutine_fn bdrv_co_get_block_status_from_file(BlockDriverState *bs,
125
- int64_t sector_num,
126
- int nb_sectors,
127
- int *pnum,
128
- BlockDriverState **file)
129
+int coroutine_fn bdrv_co_block_status_from_file(BlockDriverState *bs,
130
+ bool want_zero,
131
+ int64_t offset,
132
+ int64_t bytes,
133
+ int64_t *pnum,
134
+ int64_t *map,
135
+ BlockDriverState **file)
136
{
47
{
137
assert(bs->file && bs->file->bs);
48
BlockDriverState *bs = blk_bs(blk);
138
- *pnum = nb_sectors;
49
139
+ *pnum = bytes;
50
if (!bs) {
140
+ *map = offset;
51
- return 0;
141
*file = bs->file->bs;
52
+ return false;
142
- return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
53
}
143
- (sector_num << BDRV_SECTOR_BITS);
54
144
+ return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID;
55
return bdrv_is_sg(bs);
145
}
56
}
146
57
147
-int64_t coroutine_fn bdrv_co_get_block_status_from_backing(BlockDriverState *bs,
58
-int blk_enable_write_cache(BlockBackend *blk)
148
- int64_t sector_num,
59
+bool blk_enable_write_cache(BlockBackend *blk)
149
- int nb_sectors,
150
- int *pnum,
151
- BlockDriverState **file)
152
+int coroutine_fn bdrv_co_block_status_from_backing(BlockDriverState *bs,
153
+ bool want_zero,
154
+ int64_t offset,
155
+ int64_t bytes,
156
+ int64_t *pnum,
157
+ int64_t *map,
158
+ BlockDriverState **file)
159
{
60
{
160
assert(bs->backing && bs->backing->bs);
61
return blk->enable_write_cache;
161
- *pnum = nb_sectors;
162
+ *pnum = bytes;
163
+ *map = offset;
164
*file = bs->backing->bs;
165
- return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
166
- (sector_num << BDRV_SECTOR_BITS);
167
+ return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID;
168
}
62
}
169
170
/*
171
diff --git a/block/mirror.c b/block/mirror.c
172
index XXXXXXX..XXXXXXX 100644
173
--- a/block/mirror.c
174
+++ b/block/mirror.c
175
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_mirror_top = {
176
.bdrv_co_pwrite_zeroes = bdrv_mirror_top_pwrite_zeroes,
177
.bdrv_co_pdiscard = bdrv_mirror_top_pdiscard,
178
.bdrv_co_flush = bdrv_mirror_top_flush,
179
- .bdrv_co_get_block_status = bdrv_co_get_block_status_from_backing,
180
+ .bdrv_co_block_status = bdrv_co_block_status_from_backing,
181
.bdrv_refresh_filename = bdrv_mirror_top_refresh_filename,
182
.bdrv_close = bdrv_mirror_top_close,
183
.bdrv_child_perm = bdrv_mirror_top_child_perm,
184
diff --git a/block/throttle.c b/block/throttle.c
185
index XXXXXXX..XXXXXXX 100644
186
--- a/block/throttle.c
187
+++ b/block/throttle.c
188
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_throttle = {
189
.bdrv_reopen_prepare = throttle_reopen_prepare,
190
.bdrv_reopen_commit = throttle_reopen_commit,
191
.bdrv_reopen_abort = throttle_reopen_abort,
192
- .bdrv_co_get_block_status = bdrv_co_get_block_status_from_file,
193
+ .bdrv_co_block_status = bdrv_co_block_status_from_file,
194
195
.bdrv_co_drain_begin = throttle_co_drain_begin,
196
.bdrv_co_drain_end = throttle_co_drain_end,
197
--
63
--
198
2.13.6
64
2.19.1
199
65
200
66
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Cleber Rosa <crosa@redhat.com>
2
2
3
Commit bdd6a90 has a bug: drivers should never directly set
3
While testing the Python 3 changes which touch the 083 test, I noticed
4
BDRV_BLOCK_ALLOCATED, but only io.c should do that (as needed).
4
that it would fail with qcow2. Expanding the testing, I noticed it
5
Instead, drivers should report BDRV_BLOCK_DATA if it knows that
5
had nothing to do with the Python 3 changes, and in fact, it would not
6
data comes from this BDS.
6
pass on anything but raw:
7
7
8
But let's look at the bigger picture: semantically, the nvme
8
raw: pass
9
driver is similar to the nbd, null, and raw drivers (no backing
9
bochs: not generic
10
file, all data comes from this BDS). But while two of those
10
cloop: not generic
11
other drivers have to supply the callback (null because it can
11
parallels: fail
12
special-case BDRV_BLOCK_ZERO, raw because it can special-case
12
qcow: fail
13
a different offset), in this case the block layer defaults are
13
qcow2: fail
14
good enough without the callback at all (similar to nbd).
14
qed: fail
15
vdi: fail
16
vhdx: fail
17
vmdk: fail
18
vpc: fail
19
luks: fail
15
20
16
So, fix the bug by deletion ;)
21
The errors are a mixture I/O and "image not in xxx format", such as:
17
22
18
Signed-off-by: Eric Blake <eblake@redhat.com>
23
=== Check disconnect before data ===
24
25
Unexpected end-of-file before all bytes were read
26
-read failed: Input/output error
27
+can't open device nbd+tcp://127.0.0.1:PORT/foo: Could not open 'nbd://127.0.0.1:PORT/foo': Input/output error
28
29
=== Check disconnect after data ===
30
31
-read 512/512 bytes at offset 0
32
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
33
+can't open device nbd+tcp://127.0.0.1:PORT/foo: Image not in qcow format
34
35
I'm not aware if there's a quick fix, so, for the time being, it looks
36
like the honest approach is to make the test known to work on raw
37
only.
38
39
Signed-off-by: Cleber Rosa <crosa@redhat.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
40
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
---
41
---
21
block/nvme.c | 14 --------------
42
tests/qemu-iotests/083 | 2 +-
22
1 file changed, 14 deletions(-)
43
1 file changed, 1 insertion(+), 1 deletion(-)
23
44
24
diff --git a/block/nvme.c b/block/nvme.c
45
diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083
25
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100755
26
--- a/block/nvme.c
47
--- a/tests/qemu-iotests/083
27
+++ b/block/nvme.c
48
+++ b/tests/qemu-iotests/083
28
@@ -XXX,XX +XXX,XX @@ static int nvme_reopen_prepare(BDRVReopenState *reopen_state,
49
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
29
return 0;
50
. ./common.rc
30
}
51
. ./common.filter
31
52
32
-static int64_t coroutine_fn nvme_co_get_block_status(BlockDriverState *bs,
53
-_supported_fmt generic
33
- int64_t sector_num,
54
+_supported_fmt raw
34
- int nb_sectors, int *pnum,
55
_supported_proto nbd
35
- BlockDriverState **file)
56
_supported_os Linux
36
-{
37
- *pnum = nb_sectors;
38
- *file = bs;
39
-
40
- return BDRV_BLOCK_ALLOCATED | BDRV_BLOCK_OFFSET_VALID |
41
- (sector_num << BDRV_SECTOR_BITS);
42
-}
43
-
44
static void nvme_refresh_filename(BlockDriverState *bs, QDict *opts)
45
{
46
QINCREF(opts);
47
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nvme = {
48
.bdrv_co_flush_to_disk = nvme_co_flush,
49
.bdrv_reopen_prepare = nvme_reopen_prepare,
50
51
- .bdrv_co_get_block_status = nvme_co_get_block_status,
52
-
53
.bdrv_refresh_filename = nvme_refresh_filename,
54
.bdrv_refresh_limits = nvme_refresh_limits,
55
57
56
--
58
--
57
2.13.6
59
2.19.1
58
60
59
61
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
2
3
We are gradually moving away from sector-based interfaces, towards
4
byte-based. Update the vpc driver accordingly.
5
6
Signed-off-by: Eric Blake <eblake@redhat.com>
7
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Reviewed-by: Fam Zheng <famz@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Reviewed-by: Alberto Garcia <berto@igalia.com>
10
---
3
---
11
block/vpc.c | 45 +++++++++++++++++++++++----------------------
4
block/vpc.c | 2 ++
12
1 file changed, 23 insertions(+), 22 deletions(-)
5
1 file changed, 2 insertions(+)
13
6
14
diff --git a/block/vpc.c b/block/vpc.c
7
diff --git a/block/vpc.c b/block/vpc.c
15
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
16
--- a/block/vpc.c
9
--- a/block/vpc.c
17
+++ b/block/vpc.c
10
+++ b/block/vpc.c
18
@@ -XXX,XX +XXX,XX @@ fail:
11
@@ -XXX,XX +XXX,XX @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
19
return ret;
20
}
21
22
-static int64_t coroutine_fn vpc_co_get_block_status(BlockDriverState *bs,
23
- int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file)
24
+static int coroutine_fn vpc_co_block_status(BlockDriverState *bs,
25
+ bool want_zero,
26
+ int64_t offset, int64_t bytes,
27
+ int64_t *pnum, int64_t *map,
28
+ BlockDriverState **file)
29
{
30
BDRVVPCState *s = bs->opaque;
31
VHDFooter *footer = (VHDFooter*) s->footer_buf;
32
- int64_t start, offset;
33
+ int64_t image_offset;
34
bool allocated;
35
- int64_t ret;
36
- int n;
37
+ int ret;
38
+ int64_t n;
39
40
if (be32_to_cpu(footer->type) == VHD_FIXED) {
41
- *pnum = nb_sectors;
42
+ *pnum = bytes;
43
+ *map = offset;
44
*file = bs->file->bs;
45
- return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
46
- (sector_num << BDRV_SECTOR_BITS);
47
+ return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID;
48
}
12
}
49
13
50
qemu_co_mutex_lock(&s->lock);
14
qemu_co_mutex_init(&s->lock);
51
15
+ qemu_opts_del(opts);
52
- offset = get_image_offset(bs, sector_num << BDRV_SECTOR_BITS, false, NULL);
16
53
- start = offset;
17
return 0;
54
- allocated = (offset != -1);
18
55
+ image_offset = get_image_offset(bs, offset, false, NULL);
19
fail:
56
+ allocated = (image_offset != -1);
20
+ qemu_opts_del(opts);
57
*pnum = 0;
21
qemu_vfree(s->pagetable);
58
ret = 0;
22
#ifdef CACHE
59
23
g_free(s->pageentry_u8);
60
do {
61
/* All sectors in a block are contiguous (without using the bitmap) */
62
- n = ROUND_UP(sector_num + 1, s->block_size / BDRV_SECTOR_SIZE)
63
- - sector_num;
64
- n = MIN(n, nb_sectors);
65
+ n = ROUND_UP(offset + 1, s->block_size) - offset;
66
+ n = MIN(n, bytes);
67
68
*pnum += n;
69
- sector_num += n;
70
- nb_sectors -= n;
71
+ offset += n;
72
+ bytes -= n;
73
/* *pnum can't be greater than one block for allocated
74
* sectors since there is always a bitmap in between. */
75
if (allocated) {
76
*file = bs->file->bs;
77
- ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | start;
78
+ *map = image_offset;
79
+ ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
80
break;
81
}
82
- if (nb_sectors == 0) {
83
+ if (bytes == 0) {
84
break;
85
}
86
- offset = get_image_offset(bs, sector_num << BDRV_SECTOR_BITS, false,
87
- NULL);
88
- } while (offset == -1);
89
+ image_offset = get_image_offset(bs, offset, false, NULL);
90
+ } while (image_offset == -1);
91
92
qemu_co_mutex_unlock(&s->lock);
93
return ret;
94
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vpc = {
95
96
.bdrv_co_preadv = vpc_co_preadv,
97
.bdrv_co_pwritev = vpc_co_pwritev,
98
- .bdrv_co_get_block_status = vpc_co_get_block_status,
99
+ .bdrv_co_block_status = vpc_co_block_status,
100
101
.bdrv_get_info = vpc_get_info,
102
103
--
24
--
104
2.13.6
25
2.19.1
105
26
106
27
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Peter Maydell <peter.maydell@linaro.org>
2
2
3
We are gradually moving away from sector-based interfaces, towards
3
Taking the address of a field in a packed struct is a bad idea, because
4
byte-based. Update the iscsi driver accordingly. In this case,
4
it might not be actually aligned enough for that pointer type (and
5
it is handy to teach iscsi_co_block_status() to handle a NULL map
5
thus cause a crash on dereference on some host architectures). Newer
6
and file parameter, even though the block layer passes non-NULL
6
versions of clang warn about this. Avoid the bug by not using the
7
values, because we also call the function directly. For now, there
7
"modify in place" byte swapping functions.
8
are no optimizations done based on the want_zero flag.
8
9
9
There are a few places where the in-place swap function is
10
We can also make the simplification of asserting that the block
10
used on something other than a packed struct field; we convert
11
layer passed in aligned values.
11
those anyway, for consistency.
12
12
13
Signed-off-by: Eric Blake <eblake@redhat.com>
13
Patch produced with scripts/coccinelle/inplace-byteswaps.cocci.
14
Reviewed-by: Fam Zheng <famz@redhat.com>
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
18
---
17
block/iscsi.c | 69 ++++++++++++++++++++++++++++-------------------------------
19
block/vhdx.h | 12 ++---
18
1 file changed, 33 insertions(+), 36 deletions(-)
20
block/vhdx-endian.c | 118 ++++++++++++++++++++++----------------------
19
21
block/vhdx-log.c | 4 +-
20
diff --git a/block/iscsi.c b/block/iscsi.c
22
block/vhdx.c | 18 +++----
23
4 files changed, 76 insertions(+), 76 deletions(-)
24
25
diff --git a/block/vhdx.h b/block/vhdx.h
21
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
22
--- a/block/iscsi.c
27
--- a/block/vhdx.h
23
+++ b/block/iscsi.c
28
+++ b/block/vhdx.h
24
@@ -XXX,XX +XXX,XX @@ out_unlock:
29
@@ -XXX,XX +XXX,XX @@ int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
25
30
26
31
static inline void leguid_to_cpus(MSGUID *guid)
27
32
{
28
-static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
33
- le32_to_cpus(&guid->data1);
29
- int64_t sector_num,
34
- le16_to_cpus(&guid->data2);
30
- int nb_sectors, int *pnum,
35
- le16_to_cpus(&guid->data3);
31
- BlockDriverState **file)
36
+ guid->data1 = le32_to_cpu(guid->data1);
32
+static int coroutine_fn iscsi_co_block_status(BlockDriverState *bs,
37
+ guid->data2 = le16_to_cpu(guid->data2);
33
+ bool want_zero, int64_t offset,
38
+ guid->data3 = le16_to_cpu(guid->data3);
34
+ int64_t bytes, int64_t *pnum,
39
}
35
+ int64_t *map,
40
36
+ BlockDriverState **file)
41
static inline void cpu_to_leguids(MSGUID *guid)
37
{
42
{
38
IscsiLun *iscsilun = bs->opaque;
43
- cpu_to_le32s(&guid->data1);
39
struct scsi_get_lba_status *lbas = NULL;
44
- cpu_to_le16s(&guid->data2);
40
struct scsi_lba_status_descriptor *lbasd = NULL;
45
- cpu_to_le16s(&guid->data3);
41
struct IscsiTask iTask;
46
+ guid->data1 = cpu_to_le32(guid->data1);
42
uint64_t lba;
47
+ guid->data2 = cpu_to_le16(guid->data2);
43
- int64_t ret;
48
+ guid->data3 = cpu_to_le16(guid->data3);
44
+ int ret;
49
}
45
50
46
iscsi_co_init_iscsitask(iscsilun, &iTask);
51
void vhdx_header_le_import(VHDXHeader *h);
47
52
diff --git a/block/vhdx-endian.c b/block/vhdx-endian.c
48
- if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
53
index XXXXXXX..XXXXXXX 100644
49
- ret = -EINVAL;
54
--- a/block/vhdx-endian.c
50
- goto out;
55
+++ b/block/vhdx-endian.c
51
- }
56
@@ -XXX,XX +XXX,XX @@ void vhdx_header_le_import(VHDXHeader *h)
52
+ assert(QEMU_IS_ALIGNED(offset | bytes, iscsilun->block_size));
57
{
53
58
assert(h != NULL);
54
/* default to all sectors allocated */
59
55
- ret = BDRV_BLOCK_DATA;
60
- le32_to_cpus(&h->signature);
56
- ret |= (sector_num << BDRV_SECTOR_BITS) | BDRV_BLOCK_OFFSET_VALID;
61
- le32_to_cpus(&h->checksum);
57
- *pnum = nb_sectors;
62
- le64_to_cpus(&h->sequence_number);
58
+ ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
63
+ h->signature = le32_to_cpu(h->signature);
59
+ if (map) {
64
+ h->checksum = le32_to_cpu(h->checksum);
60
+ *map = offset;
65
+ h->sequence_number = le64_to_cpu(h->sequence_number);
61
+ }
66
62
+ *pnum = bytes;
67
leguid_to_cpus(&h->file_write_guid);
63
68
leguid_to_cpus(&h->data_write_guid);
64
/* LUN does not support logical block provisioning */
69
leguid_to_cpus(&h->log_guid);
65
if (!iscsilun->lbpme) {
70
66
goto out;
71
- le16_to_cpus(&h->log_version);
72
- le16_to_cpus(&h->version);
73
- le32_to_cpus(&h->log_length);
74
- le64_to_cpus(&h->log_offset);
75
+ h->log_version = le16_to_cpu(h->log_version);
76
+ h->version = le16_to_cpu(h->version);
77
+ h->log_length = le32_to_cpu(h->log_length);
78
+ h->log_offset = le64_to_cpu(h->log_offset);
79
}
80
81
void vhdx_header_le_export(VHDXHeader *orig_h, VHDXHeader *new_h)
82
@@ -XXX,XX +XXX,XX @@ void vhdx_log_desc_le_import(VHDXLogDescriptor *d)
83
{
84
assert(d != NULL);
85
86
- le32_to_cpus(&d->signature);
87
- le64_to_cpus(&d->file_offset);
88
- le64_to_cpus(&d->sequence_number);
89
+ d->signature = le32_to_cpu(d->signature);
90
+ d->file_offset = le64_to_cpu(d->file_offset);
91
+ d->sequence_number = le64_to_cpu(d->sequence_number);
92
}
93
94
void vhdx_log_desc_le_export(VHDXLogDescriptor *d)
95
{
96
assert(d != NULL);
97
98
- cpu_to_le32s(&d->signature);
99
- cpu_to_le32s(&d->trailing_bytes);
100
- cpu_to_le64s(&d->leading_bytes);
101
- cpu_to_le64s(&d->file_offset);
102
- cpu_to_le64s(&d->sequence_number);
103
+ d->signature = cpu_to_le32(d->signature);
104
+ d->trailing_bytes = cpu_to_le32(d->trailing_bytes);
105
+ d->leading_bytes = cpu_to_le64(d->leading_bytes);
106
+ d->file_offset = cpu_to_le64(d->file_offset);
107
+ d->sequence_number = cpu_to_le64(d->sequence_number);
108
}
109
110
void vhdx_log_data_le_import(VHDXLogDataSector *d)
111
{
112
assert(d != NULL);
113
114
- le32_to_cpus(&d->data_signature);
115
- le32_to_cpus(&d->sequence_high);
116
- le32_to_cpus(&d->sequence_low);
117
+ d->data_signature = le32_to_cpu(d->data_signature);
118
+ d->sequence_high = le32_to_cpu(d->sequence_high);
119
+ d->sequence_low = le32_to_cpu(d->sequence_low);
120
}
121
122
void vhdx_log_data_le_export(VHDXLogDataSector *d)
123
{
124
assert(d != NULL);
125
126
- cpu_to_le32s(&d->data_signature);
127
- cpu_to_le32s(&d->sequence_high);
128
- cpu_to_le32s(&d->sequence_low);
129
+ d->data_signature = cpu_to_le32(d->data_signature);
130
+ d->sequence_high = cpu_to_le32(d->sequence_high);
131
+ d->sequence_low = cpu_to_le32(d->sequence_low);
132
}
133
134
void vhdx_log_entry_hdr_le_import(VHDXLogEntryHeader *hdr)
135
{
136
assert(hdr != NULL);
137
138
- le32_to_cpus(&hdr->signature);
139
- le32_to_cpus(&hdr->checksum);
140
- le32_to_cpus(&hdr->entry_length);
141
- le32_to_cpus(&hdr->tail);
142
- le64_to_cpus(&hdr->sequence_number);
143
- le32_to_cpus(&hdr->descriptor_count);
144
+ hdr->signature = le32_to_cpu(hdr->signature);
145
+ hdr->checksum = le32_to_cpu(hdr->checksum);
146
+ hdr->entry_length = le32_to_cpu(hdr->entry_length);
147
+ hdr->tail = le32_to_cpu(hdr->tail);
148
+ hdr->sequence_number = le64_to_cpu(hdr->sequence_number);
149
+ hdr->descriptor_count = le32_to_cpu(hdr->descriptor_count);
150
leguid_to_cpus(&hdr->log_guid);
151
- le64_to_cpus(&hdr->flushed_file_offset);
152
- le64_to_cpus(&hdr->last_file_offset);
153
+ hdr->flushed_file_offset = le64_to_cpu(hdr->flushed_file_offset);
154
+ hdr->last_file_offset = le64_to_cpu(hdr->last_file_offset);
155
}
156
157
void vhdx_log_entry_hdr_le_export(VHDXLogEntryHeader *hdr)
158
{
159
assert(hdr != NULL);
160
161
- cpu_to_le32s(&hdr->signature);
162
- cpu_to_le32s(&hdr->checksum);
163
- cpu_to_le32s(&hdr->entry_length);
164
- cpu_to_le32s(&hdr->tail);
165
- cpu_to_le64s(&hdr->sequence_number);
166
- cpu_to_le32s(&hdr->descriptor_count);
167
+ hdr->signature = cpu_to_le32(hdr->signature);
168
+ hdr->checksum = cpu_to_le32(hdr->checksum);
169
+ hdr->entry_length = cpu_to_le32(hdr->entry_length);
170
+ hdr->tail = cpu_to_le32(hdr->tail);
171
+ hdr->sequence_number = cpu_to_le64(hdr->sequence_number);
172
+ hdr->descriptor_count = cpu_to_le32(hdr->descriptor_count);
173
cpu_to_leguids(&hdr->log_guid);
174
- cpu_to_le64s(&hdr->flushed_file_offset);
175
- cpu_to_le64s(&hdr->last_file_offset);
176
+ hdr->flushed_file_offset = cpu_to_le64(hdr->flushed_file_offset);
177
+ hdr->last_file_offset = cpu_to_le64(hdr->last_file_offset);
178
}
179
180
181
@@ -XXX,XX +XXX,XX @@ void vhdx_region_header_le_import(VHDXRegionTableHeader *hdr)
182
{
183
assert(hdr != NULL);
184
185
- le32_to_cpus(&hdr->signature);
186
- le32_to_cpus(&hdr->checksum);
187
- le32_to_cpus(&hdr->entry_count);
188
+ hdr->signature = le32_to_cpu(hdr->signature);
189
+ hdr->checksum = le32_to_cpu(hdr->checksum);
190
+ hdr->entry_count = le32_to_cpu(hdr->entry_count);
191
}
192
193
void vhdx_region_header_le_export(VHDXRegionTableHeader *hdr)
194
{
195
assert(hdr != NULL);
196
197
- cpu_to_le32s(&hdr->signature);
198
- cpu_to_le32s(&hdr->checksum);
199
- cpu_to_le32s(&hdr->entry_count);
200
+ hdr->signature = cpu_to_le32(hdr->signature);
201
+ hdr->checksum = cpu_to_le32(hdr->checksum);
202
+ hdr->entry_count = cpu_to_le32(hdr->entry_count);
203
}
204
205
void vhdx_region_entry_le_import(VHDXRegionTableEntry *e)
206
@@ -XXX,XX +XXX,XX @@ void vhdx_region_entry_le_import(VHDXRegionTableEntry *e)
207
assert(e != NULL);
208
209
leguid_to_cpus(&e->guid);
210
- le64_to_cpus(&e->file_offset);
211
- le32_to_cpus(&e->length);
212
- le32_to_cpus(&e->data_bits);
213
+ e->file_offset = le64_to_cpu(e->file_offset);
214
+ e->length = le32_to_cpu(e->length);
215
+ e->data_bits = le32_to_cpu(e->data_bits);
216
}
217
218
void vhdx_region_entry_le_export(VHDXRegionTableEntry *e)
219
@@ -XXX,XX +XXX,XX @@ void vhdx_region_entry_le_export(VHDXRegionTableEntry *e)
220
assert(e != NULL);
221
222
cpu_to_leguids(&e->guid);
223
- cpu_to_le64s(&e->file_offset);
224
- cpu_to_le32s(&e->length);
225
- cpu_to_le32s(&e->data_bits);
226
+ e->file_offset = cpu_to_le64(e->file_offset);
227
+ e->length = cpu_to_le32(e->length);
228
+ e->data_bits = cpu_to_le32(e->data_bits);
229
}
230
231
232
@@ -XXX,XX +XXX,XX @@ void vhdx_metadata_header_le_import(VHDXMetadataTableHeader *hdr)
233
{
234
assert(hdr != NULL);
235
236
- le64_to_cpus(&hdr->signature);
237
- le16_to_cpus(&hdr->entry_count);
238
+ hdr->signature = le64_to_cpu(hdr->signature);
239
+ hdr->entry_count = le16_to_cpu(hdr->entry_count);
240
}
241
242
void vhdx_metadata_header_le_export(VHDXMetadataTableHeader *hdr)
243
{
244
assert(hdr != NULL);
245
246
- cpu_to_le64s(&hdr->signature);
247
- cpu_to_le16s(&hdr->entry_count);
248
+ hdr->signature = cpu_to_le64(hdr->signature);
249
+ hdr->entry_count = cpu_to_le16(hdr->entry_count);
250
}
251
252
void vhdx_metadata_entry_le_import(VHDXMetadataTableEntry *e)
253
@@ -XXX,XX +XXX,XX @@ void vhdx_metadata_entry_le_import(VHDXMetadataTableEntry *e)
254
assert(e != NULL);
255
256
leguid_to_cpus(&e->item_id);
257
- le32_to_cpus(&e->offset);
258
- le32_to_cpus(&e->length);
259
- le32_to_cpus(&e->data_bits);
260
+ e->offset = le32_to_cpu(e->offset);
261
+ e->length = le32_to_cpu(e->length);
262
+ e->data_bits = le32_to_cpu(e->data_bits);
263
}
264
void vhdx_metadata_entry_le_export(VHDXMetadataTableEntry *e)
265
{
266
assert(e != NULL);
267
268
cpu_to_leguids(&e->item_id);
269
- cpu_to_le32s(&e->offset);
270
- cpu_to_le32s(&e->length);
271
- cpu_to_le32s(&e->data_bits);
272
+ e->offset = cpu_to_le32(e->offset);
273
+ e->length = cpu_to_le32(e->length);
274
+ e->data_bits = cpu_to_le32(e->data_bits);
275
}
276
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
277
index XXXXXXX..XXXXXXX 100644
278
--- a/block/vhdx-log.c
279
+++ b/block/vhdx-log.c
280
@@ -XXX,XX +XXX,XX @@ static void vhdx_log_raw_to_le_sector(VHDXLogDescriptor *desc,
281
/* 8 + 4084 + 4 = 4096, 1 log sector */
282
memcpy(&desc->leading_bytes, data, 8);
283
data += 8;
284
- cpu_to_le64s(&desc->leading_bytes);
285
+ desc->leading_bytes = cpu_to_le64(desc->leading_bytes);
286
memcpy(sector->data, data, 4084);
287
data += 4084;
288
memcpy(&desc->trailing_bytes, data, 4);
289
- cpu_to_le32s(&desc->trailing_bytes);
290
+ desc->trailing_bytes = cpu_to_le32(desc->trailing_bytes);
291
data += 4;
292
293
sector->sequence_high = (uint32_t) (seq >> 32);
294
diff --git a/block/vhdx.c b/block/vhdx.c
295
index XXXXXXX..XXXXXXX 100644
296
--- a/block/vhdx.c
297
+++ b/block/vhdx.c
298
@@ -XXX,XX +XXX,XX @@ uint32_t vhdx_update_checksum(uint8_t *buf, size_t size, int crc_offset)
299
300
memset(buf + crc_offset, 0, sizeof(crc));
301
crc = crc32c(0xffffffff, buf, size);
302
- cpu_to_le32s(&crc);
303
+ crc = cpu_to_le32(crc);
304
memcpy(buf + crc_offset, &crc, sizeof(crc));
305
306
return crc;
307
@@ -XXX,XX +XXX,XX @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
308
goto exit;
67
}
309
}
68
310
69
- lba = sector_qemu2lun(sector_num, iscsilun);
311
- le32_to_cpus(&s->params.block_size);
70
+ lba = offset / iscsilun->block_size;
312
- le32_to_cpus(&s->params.data_bits);
71
313
+ s->params.block_size = le32_to_cpu(s->params.block_size);
72
qemu_mutex_lock(&iscsilun->mutex);
314
+ s->params.data_bits = le32_to_cpu(s->params.data_bits);
73
retry:
315
74
@@ -XXX,XX +XXX,XX @@ retry:
316
75
317
/* We now have the file parameters, so we can tell if this is a
76
lbasd = &lbas->descriptors[0];
318
@@ -XXX,XX +XXX,XX @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
77
319
goto exit;
78
- if (sector_qemu2lun(sector_num, iscsilun) != lbasd->lba) {
79
+ if (lba != lbasd->lba) {
80
ret = -EIO;
81
goto out_unlock;
82
}
320
}
83
321
84
- *pnum = sector_lun2qemu(lbasd->num_blocks, iscsilun);
322
- le64_to_cpus(&s->virtual_disk_size);
85
+ *pnum = lbasd->num_blocks * iscsilun->block_size;
323
- le32_to_cpus(&s->logical_sector_size);
86
324
- le32_to_cpus(&s->physical_sector_size);
87
if (lbasd->provisioning == SCSI_PROVISIONING_TYPE_DEALLOCATED ||
325
+ s->virtual_disk_size = le64_to_cpu(s->virtual_disk_size);
88
lbasd->provisioning == SCSI_PROVISIONING_TYPE_ANCHORED) {
326
+ s->logical_sector_size = le32_to_cpu(s->logical_sector_size);
89
@@ -XXX,XX +XXX,XX @@ retry:
327
+ s->physical_sector_size = le32_to_cpu(s->physical_sector_size);
328
329
if (s->params.block_size < VHDX_BLOCK_SIZE_MIN ||
330
s->params.block_size > VHDX_BLOCK_SIZE_MAX) {
331
@@ -XXX,XX +XXX,XX @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
332
/* endian convert, and verify populated BAT field file offsets against
333
* region table and log entries */
334
for (i = 0; i < s->bat_entries; i++) {
335
- le64_to_cpus(&s->bat[i]);
336
+ s->bat[i] = le64_to_cpu(s->bat[i]);
337
if (payblocks--) {
338
/* payload bat entries */
339
if ((s->bat[i] & VHDX_BAT_STATE_BIT_MASK) ==
340
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_new_metadata(BlockBackend *blk,
341
mt_file_params->block_size = cpu_to_le32(block_size);
342
if (type == VHDX_TYPE_FIXED) {
343
mt_file_params->data_bits |= VHDX_PARAMS_LEAVE_BLOCKS_ALLOCED;
344
- cpu_to_le32s(&mt_file_params->data_bits);
345
+ mt_file_params->data_bits = cpu_to_le32(mt_file_params->data_bits);
90
}
346
}
91
347
92
if (ret & BDRV_BLOCK_ZERO) {
348
vhdx_guid_generate(&mt_page83->page_83_data);
93
- iscsi_allocmap_set_unallocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
349
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
94
- *pnum * BDRV_SECTOR_SIZE);
350
sinfo.file_offset = ROUND_UP(sinfo.file_offset, MiB);
95
+ iscsi_allocmap_set_unallocated(iscsilun, offset, *pnum);
351
vhdx_update_bat_table_entry(blk_bs(blk), s, &sinfo, &unused, &unused,
96
} else {
352
block_state);
97
- iscsi_allocmap_set_allocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
353
- cpu_to_le64s(&s->bat[sinfo.bat_idx]);
98
- *pnum * BDRV_SECTOR_SIZE);
354
+ s->bat[sinfo.bat_idx] = cpu_to_le64(s->bat[sinfo.bat_idx]);
99
+ iscsi_allocmap_set_allocated(iscsilun, offset, *pnum);
355
sector_num += s->sectors_per_block;
100
}
101
102
- if (*pnum > nb_sectors) {
103
- *pnum = nb_sectors;
104
+ if (*pnum > bytes) {
105
+ *pnum = bytes;
106
}
107
out_unlock:
108
qemu_mutex_unlock(&iscsilun->mutex);
109
@@ -XXX,XX +XXX,XX @@ out:
110
if (iTask.task != NULL) {
111
scsi_free_scsi_task(iTask.task);
112
}
113
- if (ret > 0 && ret & BDRV_BLOCK_OFFSET_VALID) {
114
+ if (ret > 0 && ret & BDRV_BLOCK_OFFSET_VALID && file) {
115
*file = bs;
116
}
117
return ret;
118
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs,
119
nb_sectors * BDRV_SECTOR_SIZE) &&
120
!iscsi_allocmap_is_allocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
121
nb_sectors * BDRV_SECTOR_SIZE)) {
122
- int pnum;
123
- BlockDriverState *file;
124
+ int64_t pnum;
125
/* check the block status from the beginning of the cluster
126
* containing the start sector */
127
- int cluster_sectors = iscsilun->cluster_size >> BDRV_SECTOR_BITS;
128
- int head;
129
- int64_t ret;
130
-
131
- assert(cluster_sectors);
132
- head = sector_num % cluster_sectors;
133
- ret = iscsi_co_get_block_status(bs, sector_num - head,
134
- BDRV_REQUEST_MAX_SECTORS, &pnum,
135
- &file);
136
+ int64_t head;
137
+ int ret;
138
+
139
+ assert(iscsilun->cluster_size);
140
+ head = (sector_num * BDRV_SECTOR_SIZE) % iscsilun->cluster_size;
141
+ ret = iscsi_co_block_status(bs, true,
142
+ sector_num * BDRV_SECTOR_SIZE - head,
143
+ BDRV_REQUEST_MAX_BYTES, &pnum, NULL, NULL);
144
if (ret < 0) {
145
return ret;
146
}
356
}
147
/* if the whole request falls into an unallocated area we can avoid
357
ret = blk_pwrite(blk, file_offset, s->bat, length, 0);
148
* reading and directly return zeroes instead */
149
- if (ret & BDRV_BLOCK_ZERO && pnum >= nb_sectors + head) {
150
+ if (ret & BDRV_BLOCK_ZERO &&
151
+ pnum >= nb_sectors * BDRV_SECTOR_SIZE + head) {
152
qemu_iovec_memset(iov, 0, 0x00, iov->size);
153
return 0;
154
}
155
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_iscsi = {
156
.bdrv_truncate = iscsi_truncate,
157
.bdrv_refresh_limits = iscsi_refresh_limits,
158
159
- .bdrv_co_get_block_status = iscsi_co_get_block_status,
160
+ .bdrv_co_block_status = iscsi_co_block_status,
161
.bdrv_co_pdiscard = iscsi_co_pdiscard,
162
.bdrv_co_pwrite_zeroes = iscsi_co_pwrite_zeroes,
163
.bdrv_co_readv = iscsi_co_readv,
164
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_iser = {
165
.bdrv_truncate = iscsi_truncate,
166
.bdrv_refresh_limits = iscsi_refresh_limits,
167
168
- .bdrv_co_get_block_status = iscsi_co_get_block_status,
169
+ .bdrv_co_block_status = iscsi_co_block_status,
170
.bdrv_co_pdiscard = iscsi_co_pdiscard,
171
.bdrv_co_pwrite_zeroes = iscsi_co_pwrite_zeroes,
172
.bdrv_co_readv = iscsi_co_readv,
173
--
358
--
174
2.13.6
359
2.19.1
175
360
176
361
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Peter Maydell <peter.maydell@linaro.org>
2
2
3
We are gradually moving away from sector-based interfaces, towards
3
Taking the address of a field in a packed struct is a bad idea, because
4
byte-based. Update the vdi driver accordingly. Note that the
4
it might not be actually aligned enough for that pointer type (and
5
TODO is already covered (the block layer guarantees bounds of its
5
thus cause a crash on dereference on some host architectures). Newer
6
requests), and that we can remove the now-unused s->block_sectors.
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
7
8
8
Signed-off-by: Eric Blake <eblake@redhat.com>
9
There are a few places where the in-place swap function is
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
used on something other than a packed struct field; we convert
10
Reviewed-by: Fam Zheng <famz@redhat.com>
11
those anyway, for consistency.
12
13
Patch produced with scripts/coccinelle/inplace-byteswaps.cocci.
14
15
There are other places where we take the address of a packed member
16
in this file for other purposes than passing it to a byteswap
17
function (all the calls to qemu_uuid_*()); we leave those for now.
18
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
22
---
13
block/vdi.c | 33 +++++++++++++--------------------
23
block/vdi.c | 64 ++++++++++++++++++++++++++---------------------------
14
1 file changed, 13 insertions(+), 20 deletions(-)
24
1 file changed, 32 insertions(+), 32 deletions(-)
15
25
16
diff --git a/block/vdi.c b/block/vdi.c
26
diff --git a/block/vdi.c b/block/vdi.c
17
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
18
--- a/block/vdi.c
28
--- a/block/vdi.c
19
+++ b/block/vdi.c
29
+++ b/block/vdi.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct {
30
@@ -XXX,XX +XXX,XX @@ typedef struct {
21
uint32_t *bmap;
31
22
/* Size of block (bytes). */
32
static void vdi_header_to_cpu(VdiHeader *header)
23
uint32_t block_size;
24
- /* Size of block (sectors). */
25
- uint32_t block_sectors;
26
/* First sector of block map. */
27
uint32_t bmap_sector;
28
/* VDI header (converted to host endianness). */
29
@@ -XXX,XX +XXX,XX @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
30
bs->total_sectors = header.disk_size / SECTOR_SIZE;
31
32
s->block_size = header.block_size;
33
- s->block_sectors = header.block_size / SECTOR_SIZE;
34
s->bmap_sector = header.offset_bmap / SECTOR_SIZE;
35
s->header = header;
36
37
@@ -XXX,XX +XXX,XX @@ static int vdi_reopen_prepare(BDRVReopenState *state,
38
return 0;
39
}
40
41
-static int64_t coroutine_fn vdi_co_get_block_status(BlockDriverState *bs,
42
- int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file)
43
+static int coroutine_fn vdi_co_block_status(BlockDriverState *bs,
44
+ bool want_zero,
45
+ int64_t offset, int64_t bytes,
46
+ int64_t *pnum, int64_t *map,
47
+ BlockDriverState **file)
48
{
33
{
49
- /* TODO: Check for too large sector_num (in bdrv_is_allocated or here). */
34
- le32_to_cpus(&header->signature);
50
BDRVVdiState *s = (BDRVVdiState *)bs->opaque;
35
- le32_to_cpus(&header->version);
51
- size_t bmap_index = sector_num / s->block_sectors;
36
- le32_to_cpus(&header->header_size);
52
- size_t sector_in_block = sector_num % s->block_sectors;
37
- le32_to_cpus(&header->image_type);
53
- int n_sectors = s->block_sectors - sector_in_block;
38
- le32_to_cpus(&header->image_flags);
54
+ size_t bmap_index = offset / s->block_size;
39
- le32_to_cpus(&header->offset_bmap);
55
+ size_t index_in_block = offset % s->block_size;
40
- le32_to_cpus(&header->offset_data);
56
uint32_t bmap_entry = le32_to_cpu(s->bmap[bmap_index]);
41
- le32_to_cpus(&header->cylinders);
57
- uint64_t offset;
42
- le32_to_cpus(&header->heads);
58
int result;
43
- le32_to_cpus(&header->sectors);
59
44
- le32_to_cpus(&header->sector_size);
60
- logout("%p, %" PRId64 ", %d, %p\n", bs, sector_num, nb_sectors, pnum);
45
- le64_to_cpus(&header->disk_size);
61
- if (n_sectors > nb_sectors) {
46
- le32_to_cpus(&header->block_size);
62
- n_sectors = nb_sectors;
47
- le32_to_cpus(&header->block_extra);
63
- }
48
- le32_to_cpus(&header->blocks_in_image);
64
- *pnum = n_sectors;
49
- le32_to_cpus(&header->blocks_allocated);
65
+ logout("%p, %" PRId64 ", %" PRId64 ", %p\n", bs, offset, bytes, pnum);
50
+ header->signature = le32_to_cpu(header->signature);
66
+ *pnum = MIN(s->block_size - index_in_block, bytes);
51
+ header->version = le32_to_cpu(header->version);
67
result = VDI_IS_ALLOCATED(bmap_entry);
52
+ header->header_size = le32_to_cpu(header->header_size);
68
if (!result) {
53
+ header->image_type = le32_to_cpu(header->image_type);
69
return 0;
54
+ header->image_flags = le32_to_cpu(header->image_flags);
70
}
55
+ header->offset_bmap = le32_to_cpu(header->offset_bmap);
71
56
+ header->offset_data = le32_to_cpu(header->offset_data);
72
- offset = s->header.offset_data +
57
+ header->cylinders = le32_to_cpu(header->cylinders);
73
- (uint64_t)bmap_entry * s->block_size +
58
+ header->heads = le32_to_cpu(header->heads);
74
- sector_in_block * SECTOR_SIZE;
59
+ header->sectors = le32_to_cpu(header->sectors);
75
+ *map = s->header.offset_data + (uint64_t)bmap_entry * s->block_size +
60
+ header->sector_size = le32_to_cpu(header->sector_size);
76
+ index_in_block;
61
+ header->disk_size = le64_to_cpu(header->disk_size);
77
*file = bs->file->bs;
62
+ header->block_size = le32_to_cpu(header->block_size);
78
- return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | offset;
63
+ header->block_extra = le32_to_cpu(header->block_extra);
79
+ return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
64
+ header->blocks_in_image = le32_to_cpu(header->blocks_in_image);
80
}
65
+ header->blocks_allocated = le32_to_cpu(header->blocks_allocated);
81
66
qemu_uuid_bswap(&header->uuid_image);
82
static int coroutine_fn
67
qemu_uuid_bswap(&header->uuid_last_snap);
83
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vdi = {
68
qemu_uuid_bswap(&header->uuid_link);
84
.bdrv_child_perm = bdrv_format_default_perms,
69
@@ -XXX,XX +XXX,XX @@ static void vdi_header_to_cpu(VdiHeader *header)
85
.bdrv_create = vdi_create,
70
86
.bdrv_has_zero_init = bdrv_has_zero_init_1,
71
static void vdi_header_to_le(VdiHeader *header)
87
- .bdrv_co_get_block_status = vdi_co_get_block_status,
72
{
88
+ .bdrv_co_block_status = vdi_co_block_status,
73
- cpu_to_le32s(&header->signature);
89
.bdrv_make_empty = vdi_make_empty,
74
- cpu_to_le32s(&header->version);
90
75
- cpu_to_le32s(&header->header_size);
91
.bdrv_co_preadv = vdi_co_preadv,
76
- cpu_to_le32s(&header->image_type);
77
- cpu_to_le32s(&header->image_flags);
78
- cpu_to_le32s(&header->offset_bmap);
79
- cpu_to_le32s(&header->offset_data);
80
- cpu_to_le32s(&header->cylinders);
81
- cpu_to_le32s(&header->heads);
82
- cpu_to_le32s(&header->sectors);
83
- cpu_to_le32s(&header->sector_size);
84
- cpu_to_le64s(&header->disk_size);
85
- cpu_to_le32s(&header->block_size);
86
- cpu_to_le32s(&header->block_extra);
87
- cpu_to_le32s(&header->blocks_in_image);
88
- cpu_to_le32s(&header->blocks_allocated);
89
+ header->signature = cpu_to_le32(header->signature);
90
+ header->version = cpu_to_le32(header->version);
91
+ header->header_size = cpu_to_le32(header->header_size);
92
+ header->image_type = cpu_to_le32(header->image_type);
93
+ header->image_flags = cpu_to_le32(header->image_flags);
94
+ header->offset_bmap = cpu_to_le32(header->offset_bmap);
95
+ header->offset_data = cpu_to_le32(header->offset_data);
96
+ header->cylinders = cpu_to_le32(header->cylinders);
97
+ header->heads = cpu_to_le32(header->heads);
98
+ header->sectors = cpu_to_le32(header->sectors);
99
+ header->sector_size = cpu_to_le32(header->sector_size);
100
+ header->disk_size = cpu_to_le64(header->disk_size);
101
+ header->block_size = cpu_to_le32(header->block_size);
102
+ header->block_extra = cpu_to_le32(header->block_extra);
103
+ header->blocks_in_image = cpu_to_le32(header->blocks_in_image);
104
+ header->blocks_allocated = cpu_to_le32(header->blocks_allocated);
105
qemu_uuid_bswap(&header->uuid_image);
106
qemu_uuid_bswap(&header->uuid_last_snap);
107
qemu_uuid_bswap(&header->uuid_link);
92
--
108
--
93
2.13.6
109
2.19.1
94
110
95
111
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
We are gradually moving away from sector-based interfaces, towards
3
This is a static function with only one caller, so there's no need to
4
byte-based. Update the vmdk driver accordingly. Drop the
4
keep it. Inlining the code in quorum_compare() makes it much simpler.
5
now-unused vmdk_find_index_in_cluster().
6
5
7
Also, fix a pre-existing bug: if find_extent() fails (unlikely,
6
Signed-off-by: Alberto Garcia <berto@igalia.com>
8
since the block layer did a bounds check), then we must return a
7
Reported-by: Markus Armbruster <armbru@redhat.com>
9
failure, rather than 0.
10
11
Signed-off-by: Eric Blake <eblake@redhat.com>
12
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
Reviewed-by: Fam Zheng <famz@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
9
---
16
block/vmdk.c | 38 ++++++++++++++------------------------
10
block/quorum.c | 24 +++++-------------------
17
1 file changed, 14 insertions(+), 24 deletions(-)
11
1 file changed, 5 insertions(+), 19 deletions(-)
18
12
19
diff --git a/block/vmdk.c b/block/vmdk.c
13
diff --git a/block/quorum.c b/block/quorum.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/block/vmdk.c
15
--- a/block/quorum.c
22
+++ b/block/vmdk.c
16
+++ b/block/quorum.c
23
@@ -XXX,XX +XXX,XX @@ static inline uint64_t vmdk_find_offset_in_cluster(VmdkExtent *extent,
17
@@ -XXX,XX +XXX,XX @@ static bool quorum_iovec_compare(QEMUIOVector *a, QEMUIOVector *b)
24
return extent_relative_offset % cluster_size;
18
return true;
25
}
19
}
26
20
27
-static inline uint64_t vmdk_find_index_in_cluster(VmdkExtent *extent,
21
-static void GCC_FMT_ATTR(2, 3) quorum_err(QuorumAIOCB *acb,
28
- int64_t sector_num)
22
- const char *fmt, ...)
29
-{
23
-{
30
- uint64_t offset;
24
- va_list ap;
31
- offset = vmdk_find_offset_in_cluster(extent, sector_num * BDRV_SECTOR_SIZE);
25
-
32
- return offset / BDRV_SECTOR_SIZE;
26
- va_start(ap, fmt);
27
- fprintf(stderr, "quorum: offset=%" PRIu64 " bytes=%" PRIu64 " ",
28
- acb->offset, acb->bytes);
29
- vfprintf(stderr, fmt, ap);
30
- fprintf(stderr, "\n");
31
- va_end(ap);
32
- exit(1);
33
-}
33
-}
34
-
34
-
35
-static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
35
-static bool quorum_compare(QuorumAIOCB *acb,
36
- int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file)
36
- QEMUIOVector *a,
37
+static int coroutine_fn vmdk_co_block_status(BlockDriverState *bs,
37
- QEMUIOVector *b)
38
+ bool want_zero,
38
+static bool quorum_compare(QuorumAIOCB *acb, QEMUIOVector *a, QEMUIOVector *b)
39
+ int64_t offset, int64_t bytes,
40
+ int64_t *pnum, int64_t *map,
41
+ BlockDriverState **file)
42
{
39
{
43
BDRVVmdkState *s = bs->opaque;
40
BDRVQuorumState *s = acb->bs->opaque;
44
int64_t index_in_cluster, n, ret;
41
ssize_t offset;
45
- uint64_t offset;
42
@@ -XXX,XX +XXX,XX @@ static bool quorum_compare(QuorumAIOCB *acb,
46
+ uint64_t cluster_offset;
43
if (s->is_blkverify) {
47
VmdkExtent *extent;
44
offset = qemu_iovec_compare(a, b);
48
45
if (offset != -1) {
49
- extent = find_extent(s, sector_num, NULL);
46
- quorum_err(acb, "contents mismatch at offset %" PRIu64,
50
+ extent = find_extent(s, offset >> BDRV_SECTOR_BITS, NULL);
47
- acb->offset + offset);
51
if (!extent) {
48
+ fprintf(stderr, "quorum: offset=%" PRIu64 " bytes=%" PRIu64
52
- return 0;
49
+ " contents mismatch at offset %" PRIu64 "\n",
53
+ return -EIO;
50
+ acb->offset, acb->bytes, acb->offset + offset);
51
+ exit(1);
52
}
53
return true;
54
}
54
}
55
qemu_co_mutex_lock(&s->lock);
56
- ret = get_cluster_offset(bs, extent, NULL,
57
- sector_num * 512, false, &offset,
58
+ ret = get_cluster_offset(bs, extent, NULL, offset, false, &cluster_offset,
59
0, 0);
60
qemu_co_mutex_unlock(&s->lock);
61
62
- index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
63
+ index_in_cluster = vmdk_find_offset_in_cluster(extent, offset);
64
switch (ret) {
65
case VMDK_ERROR:
66
ret = -EIO;
67
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
68
ret = BDRV_BLOCK_DATA;
69
if (!extent->compressed) {
70
ret |= BDRV_BLOCK_OFFSET_VALID;
71
- ret |= (offset + (index_in_cluster << BDRV_SECTOR_BITS))
72
- & BDRV_BLOCK_OFFSET_MASK;
73
+ *map = cluster_offset + index_in_cluster;
74
}
75
*file = extent->file->bs;
76
break;
77
}
78
79
- n = extent->cluster_sectors - index_in_cluster;
80
- if (n > nb_sectors) {
81
- n = nb_sectors;
82
- }
83
- *pnum = n;
84
+ n = extent->cluster_sectors * BDRV_SECTOR_SIZE - index_in_cluster;
85
+ *pnum = MIN(n, bytes);
86
return ret;
87
}
88
89
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vmdk = {
90
.bdrv_close = vmdk_close,
91
.bdrv_create = vmdk_create,
92
.bdrv_co_flush_to_disk = vmdk_co_flush,
93
- .bdrv_co_get_block_status = vmdk_co_get_block_status,
94
+ .bdrv_co_block_status = vmdk_co_block_status,
95
.bdrv_get_allocated_file_size = vmdk_get_allocated_file_size,
96
.bdrv_has_zero_init = vmdk_has_zero_init,
97
.bdrv_get_specific_info = vmdk_get_specific_info,
98
--
55
--
99
2.13.6
56
2.19.1
100
57
101
58
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
The align_offset() function is equivalent to the ROUND_UP() macro so
3
The blkverify mode of Quorum can only be enabled if the number of
4
there's no need to use the former. The ROUND_UP() name is also a bit
4
children is exactly two and the value of vote-threshold is also two.
5
more explicit.
6
5
7
This patch uses ROUND_UP() instead of the slower QEMU_ALIGN_UP()
6
If the user tries to enable it but the other settings are incorrect
8
because align_offset() already requires that the second parameter is a
7
then QEMU simply prints an error message to stderr and carries on
9
power of two.
8
disabling the blkverify setting.
9
10
This patch makes quorum_open() fail and return an error in this case.
10
11
11
Signed-off-by: Alberto Garcia <berto@igalia.com>
12
Signed-off-by: Alberto Garcia <berto@igalia.com>
12
Reviewed-by: Eric Blake <eblake@redhat.com>
13
Reported-by: Markus Armbruster <armbru@redhat.com>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Message-id: 20180215131008.5153-1-berto@igalia.com
15
Signed-off-by: Max Reitz <mreitz@redhat.com>
16
---
15
---
17
block/qcow2.h | 6 ------
16
block/quorum.c | 13 ++++++-------
18
block/qcow2-bitmap.c | 4 ++--
17
1 file changed, 6 insertions(+), 7 deletions(-)
19
block/qcow2-cluster.c | 4 ++--
20
block/qcow2-refcount.c | 4 ++--
21
block/qcow2-snapshot.c | 10 +++++-----
22
block/qcow2.c | 14 +++++++-------
23
6 files changed, 18 insertions(+), 24 deletions(-)
24
18
25
diff --git a/block/qcow2.h b/block/qcow2.h
19
diff --git a/block/quorum.c b/block/quorum.c
26
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
27
--- a/block/qcow2.h
21
--- a/block/quorum.c
28
+++ b/block/qcow2.h
22
+++ b/block/quorum.c
29
@@ -XXX,XX +XXX,XX @@ static inline int offset_to_l2_slice_index(BDRVQcow2State *s, int64_t offset)
23
@@ -XXX,XX +XXX,XX @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
30
return (offset >> s->cluster_bits) & (s->l2_slice_size - 1);
24
s->read_pattern = ret;
31
}
25
32
26
if (s->read_pattern == QUORUM_READ_PATTERN_QUORUM) {
33
-static inline int64_t align_offset(int64_t offset, int n)
27
- /* is the driver in blkverify mode */
34
-{
28
- if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false) &&
35
- offset = (offset + n - 1) & ~(n - 1);
29
- s->num_children == 2 && s->threshold == 2) {
36
- return offset;
30
- s->is_blkverify = true;
37
-}
31
- } else if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false)) {
38
-
32
- fprintf(stderr, "blkverify mode is set by setting blkverify=on "
39
static inline int64_t qcow2_vm_state_offset(BDRVQcow2State *s)
33
- "and using two files with vote_threshold=2\n");
40
{
34
+ s->is_blkverify = qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false);
41
return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
35
+ if (s->is_blkverify && (s->num_children != 2 || s->threshold != 2)) {
42
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
36
+ error_setg(&local_err, "blkverify=on can only be set if there are "
43
index XXXXXXX..XXXXXXX 100644
37
+ "exactly two files and vote-threshold is 2");
44
--- a/block/qcow2-bitmap.c
38
+ ret = -EINVAL;
45
+++ b/block/qcow2-bitmap.c
39
+ goto exit;
46
@@ -XXX,XX +XXX,XX @@ static inline void bitmap_dir_entry_to_be(Qcow2BitmapDirEntry *entry)
47
48
static inline int calc_dir_entry_size(size_t name_size, size_t extra_data_size)
49
{
50
- return align_offset(sizeof(Qcow2BitmapDirEntry) +
51
- name_size + extra_data_size, 8);
52
+ int size = sizeof(Qcow2BitmapDirEntry) + name_size + extra_data_size;
53
+ return ROUND_UP(size, 8);
54
}
55
56
static inline int dir_entry_size(Qcow2BitmapDirEntry *entry)
57
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/block/qcow2-cluster.c
60
+++ b/block/qcow2-cluster.c
61
@@ -XXX,XX +XXX,XX @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
62
63
new_l1_size2 = sizeof(uint64_t) * new_l1_size;
64
new_l1_table = qemu_try_blockalign(bs->file->bs,
65
- align_offset(new_l1_size2, 512));
66
+ ROUND_UP(new_l1_size2, 512));
67
if (new_l1_table == NULL) {
68
return -ENOMEM;
69
}
70
- memset(new_l1_table, 0, align_offset(new_l1_size2, 512));
71
+ memset(new_l1_table, 0, ROUND_UP(new_l1_size2, 512));
72
73
if (s->l1_size) {
74
memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));
75
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/block/qcow2-refcount.c
78
+++ b/block/qcow2-refcount.c
79
@@ -XXX,XX +XXX,XX @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
80
* l1_table_offset when it is the current s->l1_table_offset! Be careful
81
* when changing this! */
82
if (l1_table_offset != s->l1_table_offset) {
83
- l1_table = g_try_malloc0(align_offset(l1_size2, 512));
84
+ l1_table = g_try_malloc0(ROUND_UP(l1_size2, 512));
85
if (l1_size2 && l1_table == NULL) {
86
ret = -ENOMEM;
87
goto fail;
88
@@ -XXX,XX +XXX,XX @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
89
}
90
91
/* align range to test to cluster boundaries */
92
- size = align_offset(offset_into_cluster(s, offset) + size, s->cluster_size);
93
+ size = ROUND_UP(offset_into_cluster(s, offset) + size, s->cluster_size);
94
offset = start_of_cluster(s, offset);
95
96
if ((chk & QCOW2_OL_ACTIVE_L1) && s->l1_size) {
97
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
98
index XXXXXXX..XXXXXXX 100644
99
--- a/block/qcow2-snapshot.c
100
+++ b/block/qcow2-snapshot.c
101
@@ -XXX,XX +XXX,XX @@ int qcow2_read_snapshots(BlockDriverState *bs)
102
103
for(i = 0; i < s->nb_snapshots; i++) {
104
/* Read statically sized part of the snapshot header */
105
- offset = align_offset(offset, 8);
106
+ offset = ROUND_UP(offset, 8);
107
ret = bdrv_pread(bs->file, offset, &h, sizeof(h));
108
if (ret < 0) {
109
goto fail;
110
@@ -XXX,XX +XXX,XX @@ static int qcow2_write_snapshots(BlockDriverState *bs)
111
offset = 0;
112
for(i = 0; i < s->nb_snapshots; i++) {
113
sn = s->snapshots + i;
114
- offset = align_offset(offset, 8);
115
+ offset = ROUND_UP(offset, 8);
116
offset += sizeof(h);
117
offset += sizeof(extra);
118
offset += strlen(sn->id_str);
119
@@ -XXX,XX +XXX,XX @@ static int qcow2_write_snapshots(BlockDriverState *bs)
120
assert(id_str_size <= UINT16_MAX && name_size <= UINT16_MAX);
121
h.id_str_size = cpu_to_be16(id_str_size);
122
h.name_size = cpu_to_be16(name_size);
123
- offset = align_offset(offset, 8);
124
+ offset = ROUND_UP(offset, 8);
125
126
ret = bdrv_pwrite(bs->file, offset, &h, sizeof(h));
127
if (ret < 0) {
128
@@ -XXX,XX +XXX,XX @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
129
/* The VM state isn't needed any more in the active L1 table; in fact, it
130
* hurts by causing expensive COW for the next snapshot. */
131
qcow2_cluster_discard(bs, qcow2_vm_state_offset(s),
132
- align_offset(sn->vm_state_size, s->cluster_size),
133
+ ROUND_UP(sn->vm_state_size, s->cluster_size),
134
QCOW2_DISCARD_NEVER, false);
135
136
#ifdef DEBUG_ALLOC
137
@@ -XXX,XX +XXX,XX @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs,
138
}
139
new_l1_bytes = sn->l1_size * sizeof(uint64_t);
140
new_l1_table = qemu_try_blockalign(bs->file->bs,
141
- align_offset(new_l1_bytes, 512));
142
+ ROUND_UP(new_l1_bytes, 512));
143
if (new_l1_table == NULL) {
144
return -ENOMEM;
145
}
146
diff --git a/block/qcow2.c b/block/qcow2.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/block/qcow2.c
149
+++ b/block/qcow2.c
150
@@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
151
152
if (s->l1_size > 0) {
153
s->l1_table = qemu_try_blockalign(bs->file->bs,
154
- align_offset(s->l1_size * sizeof(uint64_t), 512));
155
+ ROUND_UP(s->l1_size * sizeof(uint64_t), 512));
156
if (s->l1_table == NULL) {
157
error_setg(errp, "Could not allocate L1 table");
158
ret = -ENOMEM;
159
@@ -XXX,XX +XXX,XX @@ static int64_t qcow2_calc_prealloc_size(int64_t total_size,
160
{
161
int64_t meta_size = 0;
162
uint64_t nl1e, nl2e;
163
- int64_t aligned_total_size = align_offset(total_size, cluster_size);
164
+ int64_t aligned_total_size = ROUND_UP(total_size, cluster_size);
165
166
/* header: 1 cluster */
167
meta_size += cluster_size;
168
169
/* total size of L2 tables */
170
nl2e = aligned_total_size / cluster_size;
171
- nl2e = align_offset(nl2e, cluster_size / sizeof(uint64_t));
172
+ nl2e = ROUND_UP(nl2e, cluster_size / sizeof(uint64_t));
173
meta_size += nl2e * sizeof(uint64_t);
174
175
/* total size of L1 tables */
176
nl1e = nl2e * sizeof(uint64_t) / cluster_size;
177
- nl1e = align_offset(nl1e, cluster_size / sizeof(uint64_t));
178
+ nl1e = ROUND_UP(nl1e, cluster_size / sizeof(uint64_t));
179
meta_size += nl1e * sizeof(uint64_t);
180
181
/* total size of refcount table and blocks */
182
@@ -XXX,XX +XXX,XX @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
183
has_backing_file = !!optstr;
184
g_free(optstr);
185
186
- virtual_size = align_offset(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
187
- cluster_size);
188
+ virtual_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
189
+ virtual_size = ROUND_UP(virtual_size, cluster_size);
190
191
/* Check that virtual disk size is valid */
192
l2_tables = DIV_ROUND_UP(virtual_size / cluster_size,
193
@@ -XXX,XX +XXX,XX @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
194
goto err;
195
}
40
}
196
41
197
- virtual_size = align_offset(ssize, cluster_size);
42
s->rewrite_corrupted = qemu_opt_get_bool(opts, QUORUM_OPT_REWRITE,
198
+ virtual_size = ROUND_UP(ssize, cluster_size);
199
200
if (has_backing_file) {
201
/* We don't how much of the backing chain is shared by the input
202
--
43
--
203
2.13.6
44
2.19.1
204
45
205
46
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
This patch fixes several mistakes in the documentation of the
4
compressed cluster descriptor:
5
6
1) the documentation claims that the cluster descriptor contains the
7
number of sectors used to store the compressed data, but what it
8
actually contains is the number of sectors *minus one* or, in other
9
words, the number of additional sectors after the first one.
10
11
2) the width of the fields is incorrectly specified. The number of bits
12
used by each field is
13
14
x = 62 - (cluster_bits - 8) for the offset field
15
y = (cluster_bits - 8) for the size field
16
17
So the offset field's location is [0, x-1], not [0, x] as stated.
18
19
3) the size field does not contain the size of the compressed data,
20
but rather the number of sectors where that data is stored. The
21
compressed data starts at the exact point specified in the offset
22
field and ends when there's enough data to produce a cluster of
23
decompressed data. Both points can be in the middle of a sector,
24
allowing several compressed clusters to be stored next to one
25
another, sharing sectors if necessary.
26
27
Cc: qemu-stable@nongnu.org
28
Signed-off-by: Alberto Garcia <berto@igalia.com>
3
Signed-off-by: Alberto Garcia <berto@igalia.com>
29
Reviewed-by: Eric Blake <eblake@redhat.com>
30
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
31
---
5
---
32
docs/interop/qcow2.txt | 16 +++++++++++++---
6
tests/qemu-iotests/081 | 30 ++++++++++++++++++++++++++++++
33
1 file changed, 13 insertions(+), 3 deletions(-)
7
tests/qemu-iotests/081.out | 16 ++++++++++++++++
8
2 files changed, 46 insertions(+)
34
9
35
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
10
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
11
index XXXXXXX..XXXXXXX 100755
12
--- a/tests/qemu-iotests/081
13
+++ b/tests/qemu-iotests/081
14
@@ -XXX,XX +XXX,XX @@ echo "== checking that quorum is broken =="
15
16
$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
17
18
+echo
19
+echo "== checking the blkverify mode with broken content =="
20
+
21
+quorum="driver=raw,file.driver=quorum,file.vote-threshold=2,file.blkverify=on"
22
+quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw"
23
+quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw"
24
+quorum="$quorum,file.children.0.driver=raw"
25
+quorum="$quorum,file.children.1.driver=raw"
26
+
27
+$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
28
+
29
+echo
30
+echo "== writing the same data to both files =="
31
+
32
+$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io
33
+$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io
34
+
35
+echo
36
+echo "== checking the blkverify mode with valid content =="
37
+
38
+$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
39
+
40
+echo
41
+echo "== checking the blkverify mode with invalid settings =="
42
+
43
+quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw"
44
+quorum="$quorum,file.children.2.driver=raw"
45
+
46
+$QEMU_IO -c "open -o $quorum" | _filter_qemu_io
47
+
48
# success, all done
49
echo "*** done"
50
rm -f $seq.full
51
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
36
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
37
--- a/docs/interop/qcow2.txt
53
--- a/tests/qemu-iotests/081.out
38
+++ b/docs/interop/qcow2.txt
54
+++ b/tests/qemu-iotests/081.out
39
@@ -XXX,XX +XXX,XX @@ Standard Cluster Descriptor:
55
@@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 0
40
56
41
Compressed Clusters Descriptor (x = 62 - (cluster_bits - 8)):
57
== checking that quorum is broken ==
42
58
read failed: Input/output error
43
- Bit 0 - x: Host cluster offset. This is usually _not_ aligned to a
44
- cluster boundary!
45
+ Bit 0 - x-1: Host cluster offset. This is usually _not_ aligned to a
46
+ cluster or sector boundary!
47
48
- x+1 - 61: Compressed size of the images in sectors of 512 bytes
49
+ x - 61: Number of additional 512-byte sectors used for the
50
+ compressed data, beyond the sector containing the offset
51
+ in the previous field. Some of these sectors may reside
52
+ in the next contiguous host cluster.
53
+
59
+
54
+ Note that the compressed data does not necessarily occupy
60
+== checking the blkverify mode with broken content ==
55
+ all of the bytes in the final sector; rather, decompression
61
+quorum: offset=0 bytes=10485760 contents mismatch at offset 0
56
+ stops when it has produced a cluster of data.
57
+
62
+
58
+ Another compressed cluster may map to the tail of the final
63
+== writing the same data to both files ==
59
+ sector used by this compressed cluster.
64
+wrote 10485760/10485760 bytes at offset 0
60
65
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
61
If a cluster is unallocated, read requests shall read the data from the backing
66
+wrote 10485760/10485760 bytes at offset 0
62
file (except if bit 0 in the Standard Cluster Descriptor is set). If there is
67
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
68
+
69
+== checking the blkverify mode with valid content ==
70
+read 10485760/10485760 bytes at offset 0
71
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
72
+
73
+== checking the blkverify mode with invalid settings ==
74
+can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
75
*** done
63
--
76
--
64
2.13.6
77
2.19.1
65
78
66
79
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
This patch updates docs/qcow2-cache.txt explaining how to use the new
3
The blkverify mode of Quorum only works when the number of children is
4
l2-cache-entry-size parameter.
4
exactly two, so any attempt to add a new one must return an error.
5
5
6
Here's a more detailed technical description of this feature:
6
quorum_del_child() on the other hand doesn't need any additional check
7
7
because decreasing the number of children would make it go under the
8
https://lists.gnu.org/archive/html/qemu-block/2017-09/msg00635.html
8
vote threshold.
9
10
And here are some performance numbers:
11
12
https://lists.gnu.org/archive/html/qemu-block/2017-12/msg00507.html
13
9
14
Signed-off-by: Alberto Garcia <berto@igalia.com>
10
Signed-off-by: Alberto Garcia <berto@igalia.com>
15
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Reported-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
13
---
18
docs/qcow2-cache.txt | 46 +++++++++++++++++++++++++++++++++++++++++++---
14
block/quorum.c | 8 ++++++++
19
1 file changed, 43 insertions(+), 3 deletions(-)
15
1 file changed, 8 insertions(+)
20
16
21
diff --git a/docs/qcow2-cache.txt b/docs/qcow2-cache.txt
17
diff --git a/block/quorum.c b/block/quorum.c
22
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
23
--- a/docs/qcow2-cache.txt
19
--- a/block/quorum.c
24
+++ b/docs/qcow2-cache.txt
20
+++ b/block/quorum.c
25
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs,
26
qcow2 L2/refcount cache configuration
22
char indexstr[32];
27
=====================================
23
int ret;
28
-Copyright (C) 2015 Igalia, S.L.
24
29
+Copyright (C) 2015, 2018 Igalia, S.L.
25
+ if (s->is_blkverify) {
30
Author: Alberto Garcia <berto@igalia.com>
26
+ error_setg(errp, "Cannot add a child to a quorum in blkverify mode");
31
27
+ return;
32
This work is licensed under the terms of the GNU GPL, version 2 or
28
+ }
33
@@ -XXX,XX +XXX,XX @@ There are three options available, and all of them take bytes:
34
35
There are two things that need to be taken into account:
36
37
- - Both caches must have a size that is a multiple of the cluster
38
- size.
39
+ - Both caches must have a size that is a multiple of the cluster size
40
+ (or the cache entry size: see "Using smaller cache sizes" below).
41
42
- If you only set one of the options above, QEMU will automatically
43
adjust the others so that the L2 cache is 4 times bigger than the
44
@@ -XXX,XX +XXX,XX @@ much less often than the L2 cache, so it's perfectly reasonable to
45
keep it small.
46
47
48
+Using smaller cache entries
49
+---------------------------
50
+The qcow2 L2 cache stores complete tables by default. This means that
51
+if QEMU needs an entry from an L2 table then the whole table is read
52
+from disk and is kept in the cache. If the cache is full then a
53
+complete table needs to be evicted first.
54
+
29
+
55
+This can be inefficient with large cluster sizes since it results in
30
assert(s->num_children <= INT_MAX / sizeof(BdrvChild *));
56
+more disk I/O and wastes more cache memory.
31
if (s->num_children == INT_MAX / sizeof(BdrvChild *) ||
32
s->next_child_index == UINT_MAX) {
33
@@ -XXX,XX +XXX,XX @@ static void quorum_del_child(BlockDriverState *bs, BdrvChild *child,
34
return;
35
}
36
37
+ /* We know now that num_children > threshold, so blkverify must be false */
38
+ assert(!s->is_blkverify);
57
+
39
+
58
+Since QEMU 2.12 you can change the size of the L2 cache entry and make
40
bdrv_drained_begin(bs);
59
+it smaller than the cluster size. This can be configured using the
41
60
+"l2-cache-entry-size" parameter:
42
/* We can safely remove this child now */
61
+
62
+ -drive file=hd.qcow2,l2-cache-size=2097152,l2-cache-entry-size=4096
63
+
64
+Some things to take into account:
65
+
66
+ - The L2 cache entry size has the same restrictions as the cluster
67
+ size (power of two, at least 512 bytes).
68
+
69
+ - Smaller entry sizes generally improve the cache efficiency and make
70
+ disk I/O faster. This is particularly true with solid state drives
71
+ so it's a good idea to reduce the entry size in those cases. With
72
+ rotating hard drives the situation is a bit more complicated so you
73
+ should test it first and stay with the default size if unsure.
74
+
75
+ - Try different entry sizes to see which one gives faster performance
76
+ in your case. The block size of the host filesystem is generally a
77
+ good default (usually 4096 bytes in the case of ext4).
78
+
79
+ - Only the L2 cache can be configured this way. The refcount cache
80
+ always uses the cluster size as the entry size.
81
+
82
+ - If the L2 cache is big enough to hold all of the image's L2 tables
83
+ (as explained in the "Choosing the right cache sizes" section
84
+ earlier in this document) then none of this is necessary and you
85
+ can omit the "l2-cache-entry-size" parameter altogether.
86
+
87
+
88
Reducing the memory usage
89
-------------------------
90
It is possible to clean unused cache entries in order to reduce the
91
--
43
--
92
2.13.6
44
2.19.1
93
45
94
46
diff view generated by jsdifflib
1
From: Anton Nefedov <anton.nefedov@virtuozzo.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
This new test case only makes sense for qcow2 while iotest 033 is generic;
3
This patch tests that you can add and remove drives from a Quorum
4
however it matches the test purpose perfectly and also 033 contains those
4
using the x-blockdev-change command.
5
do_test() tricks to pass the alignment, which won't look nice being
6
duplicated in other tests or moved to the common code.
7
5
8
Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
6
Signed-off-by: Alberto Garcia <berto@igalia.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
8
---
11
tests/qemu-iotests/033 | 29 +++++++++++++++++++++++++++++
9
tests/qemu-iotests/081 | 86 ++++++++++++++++++++++++++++++++++++++
12
tests/qemu-iotests/033.out | 13 +++++++++++++
10
tests/qemu-iotests/081.out | 54 ++++++++++++++++++++++++
13
2 files changed, 42 insertions(+)
11
2 files changed, 140 insertions(+)
14
12
15
diff --git a/tests/qemu-iotests/033 b/tests/qemu-iotests/033
13
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
16
index XXXXXXX..XXXXXXX 100755
14
index XXXXXXX..XXXXXXX 100755
17
--- a/tests/qemu-iotests/033
15
--- a/tests/qemu-iotests/081
18
+++ b/tests/qemu-iotests/033
16
+++ b/tests/qemu-iotests/081
19
@@ -XXX,XX +XXX,XX @@ do_test()
17
@@ -XXX,XX +XXX,XX @@ quorum="$quorum,file.children.2.driver=raw"
20
    } | $QEMU_IO $IO_EXTRA_ARGS
18
21
}
19
$QEMU_IO -c "open -o $quorum" | _filter_qemu_io
22
20
23
+echo
21
+echo
24
+echo "=== Test aligned and misaligned write zeroes operations ==="
22
+echo "== dynamically adding a child to a quorum =="
25
+
23
+
26
for write_zero_cmd in "write -z" "aio_write -z"; do
24
+for verify in false true; do
27
for align in 512 4k; do
25
+ run_qemu <<EOF
28
    echo
26
+ { "execute": "qmp_capabilities" }
29
@@ -XXX,XX +XXX,XX @@ for align in 512 4k; do
27
+ { "execute": "blockdev-add",
30
done
28
+ "arguments": {
31
done
29
+ "driver": "quorum",
32
30
+ "node-name": "drive0-quorum",
33
+
31
+ "vote-threshold": 2,
34
+# Trigger truncate that would shrink qcow2 L1 table, which is done by
32
+ "blkverify": ${verify},
35
+# clearing one entry (8 bytes) with bdrv_co_pwrite_zeroes()
33
+ "children": [
34
+ {
35
+ "driver": "$IMGFMT",
36
+ "file": {
37
+ "driver": "file",
38
+ "filename": "$TEST_DIR/1.raw"
39
+ }
40
+ },
41
+ {
42
+ "driver": "$IMGFMT",
43
+ "file": {
44
+ "driver": "file",
45
+ "filename": "$TEST_DIR/2.raw"
46
+ }
47
+ }
48
+ ]
49
+ }
50
+ }
51
+ { "execute": "blockdev-add",
52
+ "arguments": {
53
+ "node-name": "drive3",
54
+ "driver": "$IMGFMT",
55
+ "file": {
56
+ "driver": "file",
57
+ "filename": "$TEST_DIR/2.raw"
58
+ }
59
+ }
60
+ }
61
+ { "execute": "x-blockdev-change",
62
+ "arguments": { "parent": "drive0-quorum",
63
+ "node": "drive3" } }
64
+ { "execute": "quit" }
65
+EOF
66
+done
36
+
67
+
37
+echo
68
+echo
38
+echo "=== Test misaligned write zeroes via truncate ==="
69
+echo "== dynamically removing a child from a quorum =="
39
+echo
40
+
70
+
41
+# any size will do, but the smaller the size the smaller the required image
71
+for verify in false true; do
42
+CLUSTER_SIZE=$((4 * 1024))
72
+ for vote_threshold in 1 2; do
43
+L2_COVERAGE=$(($CLUSTER_SIZE * $CLUSTER_SIZE / 8))
73
+ run_qemu <<EOF
44
+_make_test_img $(($L2_COVERAGE * 2))
74
+ { "execute": "qmp_capabilities" }
45
+
75
+ { "execute": "blockdev-add",
46
+do_test 512 "write -P 1 0 0x200" "$TEST_IMG" | _filter_qemu_io
76
+ "arguments": {
47
+# next L2 table
77
+ "driver": "quorum",
48
+do_test 512 "write -P 1 $L2_COVERAGE 0x200" "$TEST_IMG" | _filter_qemu_io
78
+ "node-name": "drive0-quorum",
49
+
79
+ "vote-threshold": ${vote_threshold},
50
+# only interested in qcow2 here; also other formats might respond with
80
+ "blkverify": ${verify},
51
+# "not supported" error message
81
+ "children": [
52
+if [ $IMGFMT = "qcow2" ]; then
82
+ {
53
+ do_test 512 "truncate $L2_COVERAGE" "$TEST_IMG" | _filter_qemu_io
83
+ "driver": "$IMGFMT",
54
+fi
84
+ "file": {
55
+
85
+ "driver": "file",
56
+do_test 512 "read -P 1 0 0x200" "$TEST_IMG" | _filter_qemu_io
86
+ "filename": "$TEST_DIR/1.raw"
87
+ }
88
+ },
89
+ {
90
+ "driver": "$IMGFMT",
91
+ "file": {
92
+ "driver": "file",
93
+ "filename": "$TEST_DIR/2.raw"
94
+ }
95
+ }
96
+ ]
97
+ }
98
+ }
99
+ { "execute": "x-blockdev-change",
100
+ "arguments": { "parent": "drive0-quorum",
101
+ "child": "children.1" } }
102
+ { "execute": "quit" }
103
+EOF
104
+ done
105
+done
57
+
106
+
58
# success, all done
107
# success, all done
59
+echo
60
echo "*** done"
108
echo "*** done"
61
rm -f $seq.full
109
rm -f $seq.full
62
status=0
110
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
63
diff --git a/tests/qemu-iotests/033.out b/tests/qemu-iotests/033.out
64
index XXXXXXX..XXXXXXX 100644
111
index XXXXXXX..XXXXXXX 100644
65
--- a/tests/qemu-iotests/033.out
112
--- a/tests/qemu-iotests/081.out
66
+++ b/tests/qemu-iotests/033.out
113
+++ b/tests/qemu-iotests/081.out
67
@@ -XXX,XX +XXX,XX @@
114
@@ -XXX,XX +XXX,XX @@ read 10485760/10485760 bytes at offset 0
68
QA output created by 033
115
69
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
116
== checking the blkverify mode with invalid settings ==
70
117
can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
71
+=== Test aligned and misaligned write zeroes operations ===
72
+
118
+
73
== preparing image ==
119
+== dynamically adding a child to a quorum ==
74
wrote 1024/1024 bytes at offset 512
120
+Testing:
75
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
121
+QMP_VERSION
76
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 512
122
+{"return": {}}
77
read 3072/3072 bytes at offset 1024
123
+{"return": {}}
78
3 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
124
+{"return": {}}
79
125
+{"return": {}}
126
+{"return": {}}
127
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
80
+
128
+
81
+=== Test misaligned write zeroes via truncate ===
129
+Testing:
130
+QMP_VERSION
131
+{"return": {}}
132
+{"return": {}}
133
+{"return": {}}
134
+{"error": {"class": "GenericError", "desc": "Cannot add a child to a quorum in blkverify mode"}}
135
+{"return": {}}
136
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
82
+
137
+
83
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4194304
138
+
84
+wrote 512/512 bytes at offset 0
139
+== dynamically removing a child from a quorum ==
85
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
140
+Testing:
86
+wrote 512/512 bytes at offset 2097152
141
+QMP_VERSION
87
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
142
+{"return": {}}
88
+read 512/512 bytes at offset 0
143
+{"return": {}}
89
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
144
+{"return": {}}
145
+{"return": {}}
146
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
147
+
148
+Testing:
149
+QMP_VERSION
150
+{"return": {}}
151
+{"return": {}}
152
+{"error": {"class": "GenericError", "desc": "The number of children cannot be lower than the vote threshold 2"}}
153
+{"return": {}}
154
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
155
+
156
+Testing:
157
+QMP_VERSION
158
+{"return": {}}
159
+{"error": {"class": "GenericError", "desc": "blkverify=on can only be set if there are exactly two files and vote-threshold is 2"}}
160
+{"error": {"class": "GenericError", "desc": "Cannot find device=drive0-quorum nor node_name=drive0-quorum"}}
161
+{"return": {}}
162
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
163
+
164
+Testing:
165
+QMP_VERSION
166
+{"return": {}}
167
+{"return": {}}
168
+{"error": {"class": "GenericError", "desc": "The number of children cannot be lower than the vote threshold 2"}}
169
+{"return": {}}
170
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
90
+
171
+
91
*** done
172
*** done
92
--
173
--
93
2.13.6
174
2.19.1
94
175
95
176
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
To fully change the read-only state of a node, we must not only change
2
2
bs->read_only, but also update bs->open_flags.
3
BlockBackend currently relies on BlockDriverState->in_flight to track
4
requests for blk_drain(). There is a corner case where
5
BlockDriverState->in_flight cannot be used though: blk->root can be NULL
6
when there is no medium. This results in a segfault when the NULL
7
pointer is dereferenced.
8
9
Introduce a BlockBackend->in_flight counter for aio requests so it works
10
even when blk->root == NULL.
11
12
Based on a patch by Kevin Wolf <kwolf@redhat.com>.
13
3
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
17
---
7
---
18
block.c | 2 +-
8
block.c | 7 +++++++
19
block/block-backend.c | 60 +++++++++++++++++++++++++++++++++++++++++++++------
9
1 file changed, 7 insertions(+)
20
2 files changed, 54 insertions(+), 8 deletions(-)
21
10
22
diff --git a/block.c b/block.c
11
diff --git a/block.c b/block.c
23
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
24
--- a/block.c
13
--- a/block.c
25
+++ b/block.c
14
+++ b/block.c
26
@@ -XXX,XX +XXX,XX @@ out:
15
@@ -XXX,XX +XXX,XX @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
27
16
}
28
AioContext *bdrv_get_aio_context(BlockDriverState *bs)
17
29
{
18
bs->read_only = read_only;
30
- return bs->aio_context;
31
+ return bs ? bs->aio_context : qemu_get_aio_context();
32
}
33
34
AioWait *bdrv_get_aio_wait(BlockDriverState *bs)
35
diff --git a/block/block-backend.c b/block/block-backend.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/block/block-backend.c
38
+++ b/block/block-backend.c
39
@@ -XXX,XX +XXX,XX @@ struct BlockBackend {
40
int quiesce_counter;
41
VMChangeStateEntry *vmsh;
42
bool force_allow_inactivate;
43
+
19
+
44
+ /* Number of in-flight aio requests. BlockDriverState also counts
20
+ if (read_only) {
45
+ * in-flight requests but aio requests can exist even when blk->root is
21
+ bs->open_flags &= ~BDRV_O_RDWR;
46
+ * NULL, so we cannot rely on its counter for that case.
22
+ } else {
47
+ * Accessed with atomic ops.
23
+ bs->open_flags |= BDRV_O_RDWR;
48
+ */
49
+ unsigned int in_flight;
50
+ AioWait wait;
51
};
52
53
typedef struct BlockBackendAIOCB {
54
@@ -XXX,XX +XXX,XX @@ int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags)
55
return bdrv_make_zero(blk->root, flags);
56
}
57
58
+static void blk_inc_in_flight(BlockBackend *blk)
59
+{
60
+ atomic_inc(&blk->in_flight);
61
+}
62
+
63
+static void blk_dec_in_flight(BlockBackend *blk)
64
+{
65
+ atomic_dec(&blk->in_flight);
66
+ aio_wait_kick(&blk->wait);
67
+}
68
+
69
static void error_callback_bh(void *opaque)
70
{
71
struct BlockBackendAIOCB *acb = opaque;
72
73
- bdrv_dec_in_flight(acb->common.bs);
74
+ blk_dec_in_flight(acb->blk);
75
acb->common.cb(acb->common.opaque, acb->ret);
76
qemu_aio_unref(acb);
77
}
78
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
79
{
80
struct BlockBackendAIOCB *acb;
81
82
- bdrv_inc_in_flight(blk_bs(blk));
83
+ blk_inc_in_flight(blk);
84
acb = blk_aio_get(&block_backend_aiocb_info, blk, cb, opaque);
85
acb->blk = blk;
86
acb->ret = ret;
87
@@ -XXX,XX +XXX,XX @@ static const AIOCBInfo blk_aio_em_aiocb_info = {
88
static void blk_aio_complete(BlkAioEmAIOCB *acb)
89
{
90
if (acb->has_returned) {
91
- bdrv_dec_in_flight(acb->common.bs);
92
+ blk_dec_in_flight(acb->rwco.blk);
93
acb->common.cb(acb->common.opaque, acb->rwco.ret);
94
qemu_aio_unref(acb);
95
}
96
@@ -XXX,XX +XXX,XX @@ static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes,
97
BlkAioEmAIOCB *acb;
98
Coroutine *co;
99
100
- bdrv_inc_in_flight(blk_bs(blk));
101
+ blk_inc_in_flight(blk);
102
acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque);
103
acb->rwco = (BlkRwCo) {
104
.blk = blk,
105
@@ -XXX,XX +XXX,XX @@ int blk_flush(BlockBackend *blk)
106
107
void blk_drain(BlockBackend *blk)
108
{
109
- if (blk_bs(blk)) {
110
- bdrv_drain(blk_bs(blk));
111
+ BlockDriverState *bs = blk_bs(blk);
112
+
113
+ if (bs) {
114
+ bdrv_drained_begin(bs);
115
+ }
24
+ }
116
+
25
+
117
+ /* We may have -ENOMEDIUM completions in flight */
26
return 0;
118
+ AIO_WAIT_WHILE(&blk->wait,
119
+ blk_get_aio_context(blk),
120
+ atomic_mb_read(&blk->in_flight) > 0);
121
+
122
+ if (bs) {
123
+ bdrv_drained_end(bs);
124
}
125
}
27
}
126
28
127
void blk_drain_all(void)
128
{
129
- bdrv_drain_all();
130
+ BlockBackend *blk = NULL;
131
+
132
+ bdrv_drain_all_begin();
133
+
134
+ while ((blk = blk_all_next(blk)) != NULL) {
135
+ AioContext *ctx = blk_get_aio_context(blk);
136
+
137
+ aio_context_acquire(ctx);
138
+
139
+ /* We may have -ENOMEDIUM completions in flight */
140
+ AIO_WAIT_WHILE(&blk->wait, ctx,
141
+ atomic_mb_read(&blk->in_flight) > 0);
142
+
143
+ aio_context_release(ctx);
144
+ }
145
+
146
+ bdrv_drain_all_end();
147
}
148
149
void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
150
--
29
--
151
2.13.6
30
2.19.1
152
31
153
32
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
If a management application builds the block graph node by node, the
2
protocol layer doesn't inherit its read-only option from the format
3
layer any more, so it must be set explicitly.
2
4
3
BlockDriverState has the BDRV_POLL_WHILE() macro to wait on event loop
5
Backing files should work on read-only storage, but at the same time, a
4
activity while a condition evaluates to true. This is used to implement
6
block job like commit should be able to reopen them read-write if they
5
synchronous operations where it acts as a condvar between the IOThread
7
are on read-write storage. However, without option inheritance, reopen
6
running the operation and the main loop waiting for the operation. It
8
only changes the read-only option for the root node (typically the
7
can also be called from the thread that owns the AioContext and in that
9
format layer), but not the protocol layer, so reopening fails (the
8
case it's just a nested event loop.
10
format layer wants to get write permissions, but the protocol layer is
11
still read-only).
9
12
10
BlockBackend needs this behavior but doesn't always have a
13
A simple workaround for the problem in the management tool would be to
11
BlockDriverState it can use. This patch extracts BDRV_POLL_WHILE() into
14
open the protocol layer always read-write and to make only the format
12
the AioWait abstraction, which can be used with AioContext and isn't
15
layer read-only for backing files. However, sometimes the file is
13
tied to BlockDriverState anymore.
16
actually stored on read-only storage and we don't know whether the image
17
can be opened read-write (for example, for NBD it depends on the server
18
we're trying to connect to). This adds an option that makes QEMU try to
19
open the image read-write, but allows it to degrade to a read-only mode
20
without returning an error.
14
21
15
This feature could be built directly into AioContext but then all users
22
The documentation for this option is consciously phrased in a way that
16
would kick the event loop even if they signal different conditions.
23
allows QEMU to switch to a better model eventually: Instead of trying
17
Imagine an AioContext with many BlockDriverStates, each time a request
24
when the image is first opened, making the read-only flag dynamic and
18
completes any waiter would wake up and re-check their condition. It's
25
changing it automatically whenever the first BLK_PERM_WRITE user is
19
nicer to keep a separate AioWait object for each condition instead.
26
attached or the last one is detached would be much more useful
27
behaviour.
20
28
21
Please see "block/aio-wait.h" for details on the API.
29
Unfortunately, this more useful behaviour is also a lot harder to
30
implement, and libvirt needs a solution now before it can switch to
31
-blockdev, so let's start with this easier approach for now.
22
32
23
The name AIO_WAIT_WHILE() avoids the confusion between AIO_POLL_WHILE()
33
Instead of adding a new auto-read-only option, turning the existing
24
and AioContext polling.
34
read-only into an enum (with a bool alternate for compatibility) was
35
considered, but it complicated the implementation to the point that it
36
didn't seem to be worth it.
25
37
26
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
38
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
27
Reviewed-by: Eric Blake <eblake@redhat.com>
39
Reviewed-by: Eric Blake <eblake@redhat.com>
28
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
29
---
40
---
30
include/block/aio-wait.h | 116 ++++++++++++++++++++++++++++++++++++++++++++++
41
qapi/block-core.json | 7 +++++++
31
include/block/block.h | 40 +++-------------
42
include/block/block.h | 2 ++
32
include/block/block_int.h | 7 ++-
43
block.c | 17 +++++++++++++++++
33
block.c | 5 ++
44
block/vvfat.c | 1 +
34
block/io.c | 10 +---
45
blockdev.c | 2 +-
35
util/aio-wait.c | 40 ++++++++++++++++
46
5 files changed, 28 insertions(+), 1 deletion(-)
36
util/Makefile.objs | 2 +-
37
7 files changed, 174 insertions(+), 46 deletions(-)
38
create mode 100644 include/block/aio-wait.h
39
create mode 100644 util/aio-wait.c
40
47
41
diff --git a/include/block/aio-wait.h b/include/block/aio-wait.h
48
diff --git a/qapi/block-core.json b/qapi/block-core.json
42
new file mode 100644
49
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX
50
--- a/qapi/block-core.json
44
--- /dev/null
51
+++ b/qapi/block-core.json
45
+++ b/include/block/aio-wait.h
46
@@ -XXX,XX +XXX,XX @@
52
@@ -XXX,XX +XXX,XX @@
47
+/*
53
# either generally or in certain configurations. In this case,
48
+ * AioContext wait support
54
# the default value does not work and the option must be
49
+ *
55
# specified explicitly.
50
+ * Copyright (C) 2018 Red Hat, Inc.
56
+# @auto-read-only: if true and @read-only is false, QEMU may automatically
51
+ *
57
+# decide not to open the image read-write as requested, but
52
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
58
+# fall back to read-only instead (and switch between the modes
53
+ * of this software and associated documentation files (the "Software"), to deal
59
+# later), e.g. depending on whether the image file is writable
54
+ * in the Software without restriction, including without limitation the rights
60
+# or whether a writing user is attached to the node
55
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
61
+# (default: false, since 3.1)
56
+ * copies of the Software, and to permit persons to whom the Software is
62
# @detect-zeroes: detect and optimize zero writes (Since 2.1)
57
+ * furnished to do so, subject to the following conditions:
63
# (default: off)
58
+ *
64
# @force-share: force share all permission on added nodes.
59
+ * The above copyright notice and this permission notice shall be included in
65
@@ -XXX,XX +XXX,XX @@
60
+ * all copies or substantial portions of the Software.
66
'*discard': 'BlockdevDiscardOptions',
61
+ *
67
'*cache': 'BlockdevCacheOptions',
62
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
68
'*read-only': 'bool',
63
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
69
+ '*auto-read-only': 'bool',
64
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
70
'*force-share': 'bool',
65
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
71
'*detect-zeroes': 'BlockdevDetectZeroesOptions' },
66
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
72
'discriminator': 'driver',
67
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
68
+ * THE SOFTWARE.
69
+ */
70
+
71
+#ifndef QEMU_AIO_WAIT_H
72
+#define QEMU_AIO_WAIT_H
73
+
74
+#include "block/aio.h"
75
+
76
+/**
77
+ * AioWait:
78
+ *
79
+ * An object that facilitates synchronous waiting on a condition. The main
80
+ * loop can wait on an operation running in an IOThread as follows:
81
+ *
82
+ * AioWait *wait = ...;
83
+ * AioContext *ctx = ...;
84
+ * MyWork work = { .done = false };
85
+ * schedule_my_work_in_iothread(ctx, &work);
86
+ * AIO_WAIT_WHILE(wait, ctx, !work.done);
87
+ *
88
+ * The IOThread must call aio_wait_kick() to notify the main loop when
89
+ * work.done changes:
90
+ *
91
+ * static void do_work(...)
92
+ * {
93
+ * ...
94
+ * work.done = true;
95
+ * aio_wait_kick(wait);
96
+ * }
97
+ */
98
+typedef struct {
99
+ /* Is the main loop waiting for a kick? Accessed with atomic ops. */
100
+ bool need_kick;
101
+} AioWait;
102
+
103
+/**
104
+ * AIO_WAIT_WHILE:
105
+ * @wait: the aio wait object
106
+ * @ctx: the aio context
107
+ * @cond: wait while this conditional expression is true
108
+ *
109
+ * Wait while a condition is true. Use this to implement synchronous
110
+ * operations that require event loop activity.
111
+ *
112
+ * The caller must be sure that something calls aio_wait_kick() when the value
113
+ * of @cond might have changed.
114
+ *
115
+ * The caller's thread must be the IOThread that owns @ctx or the main loop
116
+ * thread (with @ctx acquired exactly once). This function cannot be used to
117
+ * wait on conditions between two IOThreads since that could lead to deadlock,
118
+ * go via the main loop instead.
119
+ */
120
+#define AIO_WAIT_WHILE(wait, ctx, cond) ({ \
121
+ bool waited_ = false; \
122
+ bool busy_ = true; \
123
+ AioWait *wait_ = (wait); \
124
+ AioContext *ctx_ = (ctx); \
125
+ if (in_aio_context_home_thread(ctx_)) { \
126
+ while ((cond) || busy_) { \
127
+ busy_ = aio_poll(ctx_, (cond)); \
128
+ waited_ |= !!(cond) | busy_; \
129
+ } \
130
+ } else { \
131
+ assert(qemu_get_current_aio_context() == \
132
+ qemu_get_aio_context()); \
133
+ assert(!wait_->need_kick); \
134
+ /* Set wait_->need_kick before evaluating cond. */ \
135
+ atomic_mb_set(&wait_->need_kick, true); \
136
+ while (busy_) { \
137
+ if ((cond)) { \
138
+ waited_ = busy_ = true; \
139
+ aio_context_release(ctx_); \
140
+ aio_poll(qemu_get_aio_context(), true); \
141
+ aio_context_acquire(ctx_); \
142
+ } else { \
143
+ busy_ = aio_poll(ctx_, false); \
144
+ waited_ |= busy_; \
145
+ } \
146
+ } \
147
+ atomic_set(&wait_->need_kick, false); \
148
+ } \
149
+ waited_; })
150
+
151
+/**
152
+ * aio_wait_kick:
153
+ * @wait: the aio wait object that should re-evaluate its condition
154
+ *
155
+ * Wake up the main thread if it is waiting on AIO_WAIT_WHILE(). During
156
+ * synchronous operations performed in an IOThread, the main thread lets the
157
+ * IOThread's event loop run, waiting for the operation to complete. A
158
+ * aio_wait_kick() call will wake up the main thread.
159
+ */
160
+void aio_wait_kick(AioWait *wait);
161
+
162
+#endif /* QEMU_AIO_WAIT */
163
diff --git a/include/block/block.h b/include/block/block.h
73
diff --git a/include/block/block.h b/include/block/block.h
164
index XXXXXXX..XXXXXXX 100644
74
index XXXXXXX..XXXXXXX 100644
165
--- a/include/block/block.h
75
--- a/include/block/block.h
166
+++ b/include/block/block.h
76
+++ b/include/block/block.h
167
@@ -XXX,XX +XXX,XX @@
77
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
168
#define BLOCK_H
78
select an appropriate protocol driver,
169
79
ignoring the format layer */
170
#include "block/aio.h"
80
#define BDRV_O_NO_IO 0x10000 /* don't initialize for I/O */
171
+#include "block/aio-wait.h"
81
+#define BDRV_O_AUTO_RDONLY 0x20000 /* degrade to read-only if opening read-write fails */
172
#include "qapi-types.h"
82
173
#include "qemu/iov.h"
83
#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_NO_FLUSH)
174
#include "qemu/coroutine.h"
84
175
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_begin(void);
85
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
176
void bdrv_drain_all_end(void);
86
#define BDRV_OPT_CACHE_DIRECT "cache.direct"
177
void bdrv_drain_all(void);
87
#define BDRV_OPT_CACHE_NO_FLUSH "cache.no-flush"
178
88
#define BDRV_OPT_READ_ONLY "read-only"
179
+/* Returns NULL when bs == NULL */
89
+#define BDRV_OPT_AUTO_READ_ONLY "auto-read-only"
180
+AioWait *bdrv_get_aio_wait(BlockDriverState *bs);
90
#define BDRV_OPT_DISCARD "discard"
181
+
91
#define BDRV_OPT_FORCE_SHARE "force-share"
182
#define BDRV_POLL_WHILE(bs, cond) ({ \
92
183
- bool waited_ = false; \
184
- bool busy_ = true; \
185
BlockDriverState *bs_ = (bs); \
186
- AioContext *ctx_ = bdrv_get_aio_context(bs_); \
187
- if (in_aio_context_home_thread(ctx_)) { \
188
- while ((cond) || busy_) { \
189
- busy_ = aio_poll(ctx_, (cond)); \
190
- waited_ |= !!(cond) | busy_; \
191
- } \
192
- } else { \
193
- assert(qemu_get_current_aio_context() == \
194
- qemu_get_aio_context()); \
195
- /* Ask bdrv_dec_in_flight to wake up the main \
196
- * QEMU AioContext. Extra I/O threads never take \
197
- * other I/O threads' AioContexts (see for example \
198
- * block_job_defer_to_main_loop for how to do it). \
199
- */ \
200
- assert(!bs_->wakeup); \
201
- /* Set bs->wakeup before evaluating cond. */ \
202
- atomic_mb_set(&bs_->wakeup, true); \
203
- while (busy_) { \
204
- if ((cond)) { \
205
- waited_ = busy_ = true; \
206
- aio_context_release(ctx_); \
207
- aio_poll(qemu_get_aio_context(), true); \
208
- aio_context_acquire(ctx_); \
209
- } else { \
210
- busy_ = aio_poll(ctx_, false); \
211
- waited_ |= busy_; \
212
- } \
213
- } \
214
- atomic_set(&bs_->wakeup, false); \
215
- } \
216
- waited_; })
217
+ AIO_WAIT_WHILE(bdrv_get_aio_wait(bs_), \
218
+ bdrv_get_aio_context(bs_), \
219
+ cond); })
220
221
int bdrv_pdiscard(BlockDriverState *bs, int64_t offset, int bytes);
222
int bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset, int bytes);
223
diff --git a/include/block/block_int.h b/include/block/block_int.h
224
index XXXXXXX..XXXXXXX 100644
225
--- a/include/block/block_int.h
226
+++ b/include/block/block_int.h
227
@@ -XXX,XX +XXX,XX @@
228
229
#include "block/accounting.h"
230
#include "block/block.h"
231
+#include "block/aio-wait.h"
232
#include "qemu/queue.h"
233
#include "qemu/coroutine.h"
234
#include "qemu/stats64.h"
235
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
236
unsigned int in_flight;
237
unsigned int serialising_in_flight;
238
239
- /* Internal to BDRV_POLL_WHILE and bdrv_wakeup. Accessed with atomic
240
- * ops.
241
- */
242
- bool wakeup;
243
+ /* Kicked to signal main loop when a request completes. */
244
+ AioWait wait;
245
246
/* counter for nested bdrv_io_plug.
247
* Accessed with atomic ops.
248
diff --git a/block.c b/block.c
93
diff --git a/block.c b/block.c
249
index XXXXXXX..XXXXXXX 100644
94
index XXXXXXX..XXXXXXX 100644
250
--- a/block.c
95
--- a/block.c
251
+++ b/block.c
96
+++ b/block.c
252
@@ -XXX,XX +XXX,XX @@ AioContext *bdrv_get_aio_context(BlockDriverState *bs)
97
@@ -XXX,XX +XXX,XX @@ static void bdrv_inherited_options(int *child_flags, QDict *child_options,
253
return bs->aio_context;
98
99
/* Inherit the read-only option from the parent if it's not set */
100
qdict_copy_default(child_options, parent_options, BDRV_OPT_READ_ONLY);
101
+ qdict_copy_default(child_options, parent_options, BDRV_OPT_AUTO_READ_ONLY);
102
103
/* Our block drivers take care to send flushes and respect unmap policy,
104
* so we can default to enable both on lower layers regardless of the
105
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_options(int *child_flags, QDict *child_options,
106
107
/* backing files always opened read-only */
108
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "on");
109
+ qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
110
flags &= ~BDRV_O_COPY_ON_READ;
111
112
/* snapshot=on is handled on the top layer */
113
@@ -XXX,XX +XXX,XX @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
114
*flags |= BDRV_O_RDWR;
115
}
116
117
+ assert(qemu_opt_find(opts, BDRV_OPT_AUTO_READ_ONLY));
118
+ if (qemu_opt_get_bool_del(opts, BDRV_OPT_AUTO_READ_ONLY, false)) {
119
+ *flags |= BDRV_O_AUTO_RDONLY;
120
+ }
254
}
121
}
255
122
256
+AioWait *bdrv_get_aio_wait(BlockDriverState *bs)
123
static void update_options_from_flags(QDict *options, int flags)
257
+{
124
@@ -XXX,XX +XXX,XX @@ static void update_options_from_flags(QDict *options, int flags)
258
+ return bs ? &bs->wait : NULL;
125
if (!qdict_haskey(options, BDRV_OPT_READ_ONLY)) {
259
+}
126
qdict_put_bool(options, BDRV_OPT_READ_ONLY, !(flags & BDRV_O_RDWR));
127
}
128
+ if (!qdict_haskey(options, BDRV_OPT_AUTO_READ_ONLY)) {
129
+ qdict_put_bool(options, BDRV_OPT_AUTO_READ_ONLY,
130
+ flags & BDRV_O_AUTO_RDONLY);
131
+ }
132
}
133
134
static void bdrv_assign_node_name(BlockDriverState *bs,
135
@@ -XXX,XX +XXX,XX @@ QemuOptsList bdrv_runtime_opts = {
136
.type = QEMU_OPT_BOOL,
137
.help = "Node is opened in read-only mode",
138
},
139
+ {
140
+ .name = BDRV_OPT_AUTO_READ_ONLY,
141
+ .type = QEMU_OPT_BOOL,
142
+ .help = "Node can become read-only if opening read-write fails",
143
+ },
144
{
145
.name = "detect-zeroes",
146
.type = QEMU_OPT_STRING,
147
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
148
qdict_set_default_str(qdict, BDRV_OPT_CACHE_DIRECT, "off");
149
qdict_set_default_str(qdict, BDRV_OPT_CACHE_NO_FLUSH, "off");
150
qdict_set_default_str(qdict, BDRV_OPT_READ_ONLY, "off");
151
+ qdict_set_default_str(qdict, BDRV_OPT_AUTO_READ_ONLY, "off");
260
+
152
+
261
void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co)
153
}
154
155
bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, errp);
156
diff --git a/block/vvfat.c b/block/vvfat.c
157
index XXXXXXX..XXXXXXX 100644
158
--- a/block/vvfat.c
159
+++ b/block/vvfat.c
160
@@ -XXX,XX +XXX,XX @@ static void vvfat_qcow_options(int *child_flags, QDict *child_options,
161
int parent_flags, QDict *parent_options)
262
{
162
{
263
aio_co_enter(bdrv_get_aio_context(bs), co);
163
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "off");
264
diff --git a/block/io.c b/block/io.c
164
+ qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
165
qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on");
166
}
167
168
diff --git a/blockdev.c b/blockdev.c
265
index XXXXXXX..XXXXXXX 100644
169
index XXXXXXX..XXXXXXX 100644
266
--- a/block/io.c
170
--- a/blockdev.c
267
+++ b/block/io.c
171
+++ b/blockdev.c
268
@@ -XXX,XX +XXX,XX @@
172
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_change_medium(bool has_device, const char *device,
269
#include "qemu/osdep.h"
173
270
#include "trace.h"
174
bdrv_flags = blk_get_open_flags_from_root_state(blk);
271
#include "sysemu/block-backend.h"
175
bdrv_flags &= ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING |
272
+#include "block/aio-wait.h"
176
- BDRV_O_PROTOCOL);
273
#include "block/blockjob.h"
177
+ BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY);
274
#include "block/blockjob_int.h"
178
275
#include "block/block_int.h"
179
if (!has_read_only) {
276
@@ -XXX,XX +XXX,XX @@ void bdrv_inc_in_flight(BlockDriverState *bs)
180
read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
277
atomic_inc(&bs->in_flight);
278
}
279
280
-static void dummy_bh_cb(void *opaque)
281
-{
282
-}
283
-
284
void bdrv_wakeup(BlockDriverState *bs)
285
{
286
- /* The barrier (or an atomic op) is in the caller. */
287
- if (atomic_read(&bs->wakeup)) {
288
- aio_bh_schedule_oneshot(qemu_get_aio_context(), dummy_bh_cb, NULL);
289
- }
290
+ aio_wait_kick(bdrv_get_aio_wait(bs));
291
}
292
293
void bdrv_dec_in_flight(BlockDriverState *bs)
294
diff --git a/util/aio-wait.c b/util/aio-wait.c
295
new file mode 100644
296
index XXXXXXX..XXXXXXX
297
--- /dev/null
298
+++ b/util/aio-wait.c
299
@@ -XXX,XX +XXX,XX @@
300
+/*
301
+ * AioContext wait support
302
+ *
303
+ * Copyright (C) 2018 Red Hat, Inc.
304
+ *
305
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
306
+ * of this software and associated documentation files (the "Software"), to deal
307
+ * in the Software without restriction, including without limitation the rights
308
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
309
+ * copies of the Software, and to permit persons to whom the Software is
310
+ * furnished to do so, subject to the following conditions:
311
+ *
312
+ * The above copyright notice and this permission notice shall be included in
313
+ * all copies or substantial portions of the Software.
314
+ *
315
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
316
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
317
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
318
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
319
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
320
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
321
+ * THE SOFTWARE.
322
+ */
323
+
324
+#include "qemu/osdep.h"
325
+#include "qemu/main-loop.h"
326
+#include "block/aio-wait.h"
327
+
328
+static void dummy_bh_cb(void *opaque)
329
+{
330
+ /* The point is to make AIO_WAIT_WHILE()'s aio_poll() return */
331
+}
332
+
333
+void aio_wait_kick(AioWait *wait)
334
+{
335
+ /* The barrier (or an atomic op) is in the caller. */
336
+ if (atomic_read(&wait->need_kick)) {
337
+ aio_bh_schedule_oneshot(qemu_get_aio_context(), dummy_bh_cb, NULL);
338
+ }
339
+}
340
diff --git a/util/Makefile.objs b/util/Makefile.objs
341
index XXXXXXX..XXXXXXX 100644
342
--- a/util/Makefile.objs
343
+++ b/util/Makefile.objs
344
@@ -XXX,XX +XXX,XX @@
345
util-obj-y = osdep.o cutils.o unicode.o qemu-timer-common.o
346
util-obj-y += bufferiszero.o
347
util-obj-y += lockcnt.o
348
-util-obj-y += aiocb.o async.o thread-pool.o qemu-timer.o
349
+util-obj-y += aiocb.o async.o aio-wait.o thread-pool.o qemu-timer.o
350
util-obj-y += main-loop.o iohandler.o
351
util-obj-$(CONFIG_POSIX) += aio-posix.o
352
util-obj-$(CONFIG_POSIX) += compatfd.o
353
--
181
--
354
2.13.6
182
2.19.1
355
183
356
184
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
Commit e2b8247a322 introduced an error path in qemu_rbd_open() after
2
calling rbd_open(), but neglected to close the image again in this error
3
path. The error path should contain everything that the regular close
4
function qemu_rbd_close() contains.
2
5
3
The name aio_context_in_iothread() is misleading because it also returns
6
This adds the missing rbd_close() call.
4
true when called on the main AioContext from the main loop thread, which
5
is not an IOThread.
6
7
7
This patch renames it to in_aio_context_home_thread() and expands the
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
doc comment to make the semantics clearer.
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
---
11
block/rbd.c | 1 +
12
1 file changed, 1 insertion(+)
9
13
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
diff --git a/block/rbd.c b/block/rbd.c
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
include/block/aio.h | 7 +++++--
15
include/block/block.h | 2 +-
16
2 files changed, 6 insertions(+), 3 deletions(-)
17
18
diff --git a/include/block/aio.h b/include/block/aio.h
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/include/block/aio.h
16
--- a/block/rbd.c
21
+++ b/include/block/aio.h
17
+++ b/block/rbd.c
22
@@ -XXX,XX +XXX,XX @@ void aio_co_enter(AioContext *ctx, struct Coroutine *co);
18
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
23
AioContext *qemu_get_current_aio_context(void);
19
"automatically marking the image read-only.");
24
20
r = bdrv_set_read_only(bs, true, &local_err);
25
/**
21
if (r < 0) {
26
+ * in_aio_context_home_thread:
22
+ rbd_close(s->image);
27
* @ctx: the aio context
23
error_propagate(errp, local_err);
28
*
24
goto failed_open;
29
- * Return whether we are running in the I/O thread that manages @ctx.
25
}
30
+ * Return whether we are running in the thread that normally runs @ctx. Note
31
+ * that acquiring/releasing ctx does not affect the outcome, each AioContext
32
+ * still only has one home thread that is responsible for running it.
33
*/
34
-static inline bool aio_context_in_iothread(AioContext *ctx)
35
+static inline bool in_aio_context_home_thread(AioContext *ctx)
36
{
37
return ctx == qemu_get_current_aio_context();
38
}
39
diff --git a/include/block/block.h b/include/block/block.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/include/block/block.h
42
+++ b/include/block/block.h
43
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all(void);
44
bool busy_ = true; \
45
BlockDriverState *bs_ = (bs); \
46
AioContext *ctx_ = bdrv_get_aio_context(bs_); \
47
- if (aio_context_in_iothread(ctx_)) { \
48
+ if (in_aio_context_home_thread(ctx_)) { \
49
while ((cond) || busy_) { \
50
busy_ = aio_poll(ctx_, (cond)); \
51
waited_ |= !!(cond) | busy_; \
52
--
26
--
53
2.13.6
27
2.19.1
54
28
55
29
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
Some block drivers have traditionally changed their node to read-only
2
2
mode without asking the user. This behaviour has been marked deprecated
3
BlockDriver->bdrv_create() has been called from coroutine context since
3
since 2.11, expecting users to provide an explicit read-only=on option.
4
commit 5b7e1542cfa41a281af9629d31cef03704d976e6 ("block: make
4
5
bdrv_create adopt coroutine").
5
Now that we have auto-read-only=on, enable these drivers to make use of
6
6
the option.
7
Make this explicit by renaming to .bdrv_co_create_opts() and add the
7
8
coroutine_fn annotation. This makes it obvious to block driver authors
8
This is the only use of bdrv_set_read_only(), so we can make it a bit
9
that they may yield, use CoMutex, or other coroutine_fn APIs.
9
more specific and turn it into a bdrv_apply_auto_read_only() that is
10
bdrv_co_create is reserved for the QAPI-based version that Kevin is
10
more convenient for drivers to use.
11
working on.
11
12
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Message-Id: <20170705102231.20711-2-stefanha@redhat.com>
15
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
16
Reviewed-by: Eric Blake <eblake@redhat.com>
13
Reviewed-by: Eric Blake <eblake@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
14
---
19
include/block/block_int.h | 3 ++-
15
include/block/block.h | 3 ++-
20
block.c | 4 ++--
16
block.c | 42 +++++++++++++++++++++++++++---------------
21
block/crypto.c | 8 ++++----
17
block/bochs.c | 17 ++++++-----------
22
block/file-posix.c | 15 ++++++++-------
18
block/cloop.c | 16 +++++-----------
23
block/file-win32.c | 5 +++--
19
block/dmg.c | 16 +++++-----------
24
block/gluster.c | 13 +++++++------
20
block/rbd.c | 15 ++++-----------
25
block/iscsi.c | 7 ++++---
21
block/vvfat.c | 10 ++--------
26
block/nfs.c | 5 +++--
22
7 files changed, 51 insertions(+), 68 deletions(-)
27
block/parallels.c | 6 ++++--
23
28
block/qcow.c | 5 +++--
24
diff --git a/include/block/block.h b/include/block/block.h
29
block/qcow2.c | 5 +++--
25
index XXXXXXX..XXXXXXX 100644
30
block/qed.c | 6 ++++--
26
--- a/include/block/block.h
31
block/raw-format.c | 5 +++--
27
+++ b/include/block/block.h
32
block/rbd.c | 6 ++++--
28
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
33
block/sheepdog.c | 10 +++++-----
29
bool bdrv_is_read_only(BlockDriverState *bs);
34
block/ssh.c | 5 +++--
30
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
35
block/vdi.c | 5 +++--
31
bool ignore_allow_rdw, Error **errp);
36
block/vhdx.c | 5 +++--
32
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
37
block/vmdk.c | 5 +++--
33
+int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
38
block/vpc.c | 5 +++--
34
+ Error **errp);
39
20 files changed, 74 insertions(+), 54 deletions(-)
35
bool bdrv_is_writable(BlockDriverState *bs);
40
36
bool bdrv_is_sg(BlockDriverState *bs);
41
diff --git a/include/block/block_int.h b/include/block/block_int.h
37
bool bdrv_is_inserted(BlockDriverState *bs);
42
index XXXXXXX..XXXXXXX 100644
43
--- a/include/block/block_int.h
44
+++ b/include/block/block_int.h
45
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
46
int (*bdrv_file_open)(BlockDriverState *bs, QDict *options, int flags,
47
Error **errp);
48
void (*bdrv_close)(BlockDriverState *bs);
49
- int (*bdrv_create)(const char *filename, QemuOpts *opts, Error **errp);
50
+ int coroutine_fn (*bdrv_co_create_opts)(const char *filename, QemuOpts *opts,
51
+ Error **errp);
52
int (*bdrv_make_empty)(BlockDriverState *bs);
53
54
void (*bdrv_refresh_filename)(BlockDriverState *bs, QDict *options);
55
diff --git a/block.c b/block.c
38
diff --git a/block.c b/block.c
56
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
57
--- a/block.c
40
--- a/block.c
58
+++ b/block.c
41
+++ b/block.c
59
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
42
@@ -XXX,XX +XXX,XX @@ int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
60
CreateCo *cco = opaque;
61
assert(cco->drv);
62
63
- ret = cco->drv->bdrv_create(cco->filename, cco->opts, &local_err);
64
+ ret = cco->drv->bdrv_co_create_opts(cco->filename, cco->opts, &local_err);
65
error_propagate(&cco->err, local_err);
66
cco->ret = ret;
67
}
68
@@ -XXX,XX +XXX,XX @@ int bdrv_create(BlockDriver *drv, const char* filename,
69
.err = NULL,
70
};
71
72
- if (!drv->bdrv_create) {
73
+ if (!drv->bdrv_co_create_opts) {
74
error_setg(errp, "Driver '%s' does not support image creation", drv->format_name);
75
ret = -ENOTSUP;
76
goto out;
77
diff --git a/block/crypto.c b/block/crypto.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/block/crypto.c
80
+++ b/block/crypto.c
81
@@ -XXX,XX +XXX,XX @@ static int block_crypto_open_luks(BlockDriverState *bs,
82
bs, options, flags, errp);
83
}
84
85
-static int block_crypto_create_luks(const char *filename,
86
- QemuOpts *opts,
87
- Error **errp)
88
+static int coroutine_fn block_crypto_co_create_opts_luks(const char *filename,
89
+ QemuOpts *opts,
90
+ Error **errp)
91
{
92
return block_crypto_create_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
93
filename, opts, errp);
94
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_crypto_luks = {
95
.bdrv_open = block_crypto_open_luks,
96
.bdrv_close = block_crypto_close,
97
.bdrv_child_perm = bdrv_format_default_perms,
98
- .bdrv_create = block_crypto_create_luks,
99
+ .bdrv_co_create_opts = block_crypto_co_create_opts_luks,
100
.bdrv_truncate = block_crypto_truncate,
101
.create_opts = &block_crypto_create_opts_luks,
102
103
diff --git a/block/file-posix.c b/block/file-posix.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/block/file-posix.c
106
+++ b/block/file-posix.c
107
@@ -XXX,XX +XXX,XX @@ static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
108
return (int64_t)st.st_blocks * 512;
109
}
110
111
-static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
112
+static int coroutine_fn raw_co_create_opts(const char *filename, QemuOpts *opts,
113
+ Error **errp)
114
{
115
int fd;
116
int result = 0;
117
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_file = {
118
.bdrv_reopen_commit = raw_reopen_commit,
119
.bdrv_reopen_abort = raw_reopen_abort,
120
.bdrv_close = raw_close,
121
- .bdrv_create = raw_create,
122
+ .bdrv_co_create_opts = raw_co_create_opts,
123
.bdrv_has_zero_init = bdrv_has_zero_init_1,
124
.bdrv_co_block_status = raw_co_block_status,
125
.bdrv_co_pwrite_zeroes = raw_co_pwrite_zeroes,
126
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int hdev_co_pwrite_zeroes(BlockDriverState *bs,
127
return -ENOTSUP;
128
}
129
130
-static int hdev_create(const char *filename, QemuOpts *opts,
131
- Error **errp)
132
+static int coroutine_fn hdev_co_create_opts(const char *filename, QemuOpts *opts,
133
+ Error **errp)
134
{
135
int fd;
136
int ret = 0;
137
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = {
138
.bdrv_reopen_prepare = raw_reopen_prepare,
139
.bdrv_reopen_commit = raw_reopen_commit,
140
.bdrv_reopen_abort = raw_reopen_abort,
141
- .bdrv_create = hdev_create,
142
+ .bdrv_co_create_opts = hdev_co_create_opts,
143
.create_opts = &raw_create_opts,
144
.bdrv_co_pwrite_zeroes = hdev_co_pwrite_zeroes,
145
146
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
147
.bdrv_reopen_prepare = raw_reopen_prepare,
148
.bdrv_reopen_commit = raw_reopen_commit,
149
.bdrv_reopen_abort = raw_reopen_abort,
150
- .bdrv_create = hdev_create,
151
+ .bdrv_co_create_opts = hdev_co_create_opts,
152
.create_opts = &raw_create_opts,
153
154
155
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
156
.bdrv_reopen_prepare = raw_reopen_prepare,
157
.bdrv_reopen_commit = raw_reopen_commit,
158
.bdrv_reopen_abort = raw_reopen_abort,
159
- .bdrv_create = hdev_create,
160
+ .bdrv_co_create_opts = hdev_co_create_opts,
161
.create_opts = &raw_create_opts,
162
163
.bdrv_co_preadv = raw_co_preadv,
164
diff --git a/block/file-win32.c b/block/file-win32.c
165
index XXXXXXX..XXXXXXX 100644
166
--- a/block/file-win32.c
167
+++ b/block/file-win32.c
168
@@ -XXX,XX +XXX,XX @@ static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
169
return st.st_size;
170
}
171
172
-static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
173
+static int coroutine_fn raw_co_create_opts(const char *filename, QemuOpts *opts,
174
+ Error **errp)
175
{
176
int fd;
177
int64_t total_size = 0;
178
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_file = {
179
.bdrv_file_open = raw_open,
180
.bdrv_refresh_limits = raw_probe_alignment,
181
.bdrv_close = raw_close,
182
- .bdrv_create = raw_create,
183
+ .bdrv_co_create_opts = raw_co_create_opts,
184
.bdrv_has_zero_init = bdrv_has_zero_init_1,
185
186
.bdrv_aio_readv = raw_aio_readv,
187
diff --git a/block/gluster.c b/block/gluster.c
188
index XXXXXXX..XXXXXXX 100644
189
--- a/block/gluster.c
190
+++ b/block/gluster.c
191
@@ -XXX,XX +XXX,XX @@ static int qemu_gluster_do_truncate(struct glfs_fd *fd, int64_t offset,
192
return 0;
43
return 0;
193
}
44
}
194
45
195
-static int qemu_gluster_create(const char *filename,
46
-/* TODO Remove (deprecated since 2.11)
196
- QemuOpts *opts, Error **errp)
47
- * Block drivers are not supposed to automatically change bs->read_only.
197
+static int coroutine_fn qemu_gluster_co_create_opts(const char *filename,
48
- * Instead, they should just check whether they can provide what the user
198
+ QemuOpts *opts,
49
- * explicitly requested and error out if read-write is requested, but they can
199
+ Error **errp)
50
- * only provide read-only access. */
200
{
51
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
201
BlockdevOptionsGluster *gconf;
52
+/*
202
struct glfs *glfs;
53
+ * Called by a driver that can only provide a read-only image.
203
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster = {
54
+ *
204
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
55
+ * Returns 0 if the node is already read-only or it could switch the node to
205
.bdrv_reopen_abort = qemu_gluster_reopen_abort,
56
+ * read-only because BDRV_O_AUTO_RDONLY is set.
206
.bdrv_close = qemu_gluster_close,
57
+ *
207
- .bdrv_create = qemu_gluster_create,
58
+ * Returns -EACCES if the node is read-write and BDRV_O_AUTO_RDONLY is not set
208
+ .bdrv_co_create_opts = qemu_gluster_co_create_opts,
59
+ * or bdrv_can_set_read_only() forbids making the node read-only. If @errmsg
209
.bdrv_getlength = qemu_gluster_getlength,
60
+ * is not NULL, it is used as the error message for the Error object.
210
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
61
+ */
211
.bdrv_truncate = qemu_gluster_truncate,
62
+int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
212
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_tcp = {
63
+ Error **errp)
213
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
214
.bdrv_reopen_abort = qemu_gluster_reopen_abort,
215
.bdrv_close = qemu_gluster_close,
216
- .bdrv_create = qemu_gluster_create,
217
+ .bdrv_co_create_opts = qemu_gluster_co_create_opts,
218
.bdrv_getlength = qemu_gluster_getlength,
219
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
220
.bdrv_truncate = qemu_gluster_truncate,
221
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_unix = {
222
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
223
.bdrv_reopen_abort = qemu_gluster_reopen_abort,
224
.bdrv_close = qemu_gluster_close,
225
- .bdrv_create = qemu_gluster_create,
226
+ .bdrv_co_create_opts = qemu_gluster_co_create_opts,
227
.bdrv_getlength = qemu_gluster_getlength,
228
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
229
.bdrv_truncate = qemu_gluster_truncate,
230
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_rdma = {
231
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
232
.bdrv_reopen_abort = qemu_gluster_reopen_abort,
233
.bdrv_close = qemu_gluster_close,
234
- .bdrv_create = qemu_gluster_create,
235
+ .bdrv_co_create_opts = qemu_gluster_co_create_opts,
236
.bdrv_getlength = qemu_gluster_getlength,
237
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
238
.bdrv_truncate = qemu_gluster_truncate,
239
diff --git a/block/iscsi.c b/block/iscsi.c
240
index XXXXXXX..XXXXXXX 100644
241
--- a/block/iscsi.c
242
+++ b/block/iscsi.c
243
@@ -XXX,XX +XXX,XX @@ static int iscsi_truncate(BlockDriverState *bs, int64_t offset,
244
return 0;
245
}
246
247
-static int iscsi_create(const char *filename, QemuOpts *opts, Error **errp)
248
+static int coroutine_fn iscsi_co_create_opts(const char *filename, QemuOpts *opts,
249
+ Error **errp)
250
{
64
{
251
int ret = 0;
65
int ret = 0;
252
int64_t total_size = 0;
66
253
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_iscsi = {
67
- ret = bdrv_can_set_read_only(bs, read_only, false, errp);
254
.bdrv_parse_filename = iscsi_parse_filename,
68
- if (ret < 0) {
255
.bdrv_file_open = iscsi_open,
69
- return ret;
256
.bdrv_close = iscsi_close,
70
+ if (!(bs->open_flags & BDRV_O_RDWR)) {
257
- .bdrv_create = iscsi_create,
71
+ return 0;
258
+ .bdrv_co_create_opts = iscsi_co_create_opts,
72
+ }
259
.create_opts = &iscsi_create_opts,
73
+ if (!(bs->open_flags & BDRV_O_AUTO_RDONLY)) {
260
.bdrv_reopen_prepare = iscsi_reopen_prepare,
74
+ goto fail;
261
.bdrv_reopen_commit = iscsi_reopen_commit,
75
}
262
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_iser = {
76
263
.bdrv_parse_filename = iscsi_parse_filename,
77
- bs->read_only = read_only;
264
.bdrv_file_open = iscsi_open,
78
-
265
.bdrv_close = iscsi_close,
79
- if (read_only) {
266
- .bdrv_create = iscsi_create,
80
- bs->open_flags &= ~BDRV_O_RDWR;
267
+ .bdrv_co_create_opts = iscsi_co_create_opts,
81
- } else {
268
.create_opts = &iscsi_create_opts,
82
- bs->open_flags |= BDRV_O_RDWR;
269
.bdrv_reopen_prepare = iscsi_reopen_prepare,
83
+ ret = bdrv_can_set_read_only(bs, true, false, NULL);
270
.bdrv_reopen_commit = iscsi_reopen_commit,
84
+ if (ret < 0) {
271
diff --git a/block/nfs.c b/block/nfs.c
85
+ goto fail;
272
index XXXXXXX..XXXXXXX 100644
86
}
273
--- a/block/nfs.c
87
274
+++ b/block/nfs.c
88
+ bs->read_only = true;
275
@@ -XXX,XX +XXX,XX @@ static QemuOptsList nfs_create_opts = {
89
+ bs->open_flags &= ~BDRV_O_RDWR;
276
}
90
+
277
};
91
return 0;
278
92
+
279
-static int nfs_file_create(const char *url, QemuOpts *opts, Error **errp)
93
+fail:
280
+static int coroutine_fn nfs_file_co_create_opts(const char *url, QemuOpts *opts,
94
+ error_setg(errp, "%s", errmsg ?: "Image is read-only");
281
+ Error **errp)
95
+ return -EACCES;
282
{
283
int64_t ret, total_size;
284
NFSClient *client = g_new0(NFSClient, 1);
285
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nfs = {
286
287
.bdrv_file_open = nfs_file_open,
288
.bdrv_close = nfs_file_close,
289
- .bdrv_create = nfs_file_create,
290
+ .bdrv_co_create_opts = nfs_file_co_create_opts,
291
.bdrv_reopen_prepare = nfs_reopen_prepare,
292
293
.bdrv_co_preadv = nfs_co_preadv,
294
diff --git a/block/parallels.c b/block/parallels.c
295
index XXXXXXX..XXXXXXX 100644
296
--- a/block/parallels.c
297
+++ b/block/parallels.c
298
@@ -XXX,XX +XXX,XX @@ static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res,
299
}
96
}
300
97
301
98
void bdrv_get_full_backing_filename_from_filename(const char *backed,
302
-static int parallels_create(const char *filename, QemuOpts *opts, Error **errp)
99
diff --git a/block/bochs.c b/block/bochs.c
303
+static int coroutine_fn parallels_co_create_opts(const char *filename,
100
index XXXXXXX..XXXXXXX 100644
304
+ QemuOpts *opts,
101
--- a/block/bochs.c
305
+ Error **errp)
102
+++ b/block/bochs.c
306
{
103
@@ -XXX,XX +XXX,XX @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
307
int64_t total_size, cl_size;
104
struct bochs_header bochs;
308
uint8_t tmp[BDRV_SECTOR_SIZE];
105
int ret;
309
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_parallels = {
106
310
.bdrv_co_readv = parallels_co_readv,
107
+ /* No write support yet */
311
.bdrv_co_writev = parallels_co_writev,
108
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
312
.supports_backing = true,
109
+ if (ret < 0) {
313
- .bdrv_create = parallels_create,
110
+ return ret;
314
+ .bdrv_co_create_opts = parallels_co_create_opts,
111
+ }
315
.bdrv_check = parallels_check,
112
+
316
.create_opts = &parallels_create_opts,
113
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
317
};
114
false, errp);
318
diff --git a/block/qcow.c b/block/qcow.c
115
if (!bs->file) {
319
index XXXXXXX..XXXXXXX 100644
116
return -EINVAL;
320
--- a/block/qcow.c
117
}
321
+++ b/block/qcow.c
118
322
@@ -XXX,XX +XXX,XX @@ static void qcow_close(BlockDriverState *bs)
119
- if (!bdrv_is_read_only(bs)) {
323
error_free(s->migration_blocker);
120
- error_report("Opening bochs images without an explicit read-only=on "
324
}
121
- "option is deprecated. Future versions will refuse to "
325
122
- "open the image instead of automatically marking the "
326
-static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
123
- "image read-only.");
327
+static int coroutine_fn qcow_co_create_opts(const char *filename, QemuOpts *opts,
124
- ret = bdrv_set_read_only(bs, true, errp); /* no write support yet */
328
+ Error **errp)
125
- if (ret < 0) {
329
{
126
- return ret;
330
int header_size, backing_filename_len, l1_size, shift, i;
127
- }
331
QCowHeader header;
128
- }
332
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_qcow = {
129
-
333
.bdrv_close        = qcow_close,
130
ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
334
.bdrv_child_perm = bdrv_format_default_perms,
131
if (ret < 0) {
335
.bdrv_reopen_prepare = qcow_reopen_prepare,
132
return ret;
336
- .bdrv_create = qcow_create,
133
diff --git a/block/cloop.c b/block/cloop.c
337
+ .bdrv_co_create_opts = qcow_co_create_opts,
134
index XXXXXXX..XXXXXXX 100644
338
.bdrv_has_zero_init = bdrv_has_zero_init_1,
135
--- a/block/cloop.c
339
.supports_backing = true,
136
+++ b/block/cloop.c
340
137
@@ -XXX,XX +XXX,XX @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
341
diff --git a/block/qcow2.c b/block/qcow2.c
138
uint32_t offsets_size, max_compressed_block_size = 1, i;
342
index XXXXXXX..XXXXXXX 100644
139
int ret;
343
--- a/block/qcow2.c
140
344
+++ b/block/qcow2.c
141
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
345
@@ -XXX,XX +XXX,XX @@ out:
142
+ if (ret < 0) {
346
return ret;
143
+ return ret;
347
}
144
+ }
348
145
+
349
-static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
146
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
350
+static int coroutine_fn qcow2_co_create_opts(const char *filename, QemuOpts *opts,
147
false, errp);
351
+ Error **errp)
148
if (!bs->file) {
352
{
149
return -EINVAL;
353
char *backing_file = NULL;
150
}
354
char *backing_fmt = NULL;
151
355
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
152
- if (!bdrv_is_read_only(bs)) {
356
.bdrv_reopen_abort = qcow2_reopen_abort,
153
- error_report("Opening cloop images without an explicit read-only=on "
357
.bdrv_join_options = qcow2_join_options,
154
- "option is deprecated. Future versions will refuse to "
358
.bdrv_child_perm = bdrv_format_default_perms,
155
- "open the image instead of automatically marking the "
359
- .bdrv_create = qcow2_create,
156
- "image read-only.");
360
+ .bdrv_co_create_opts = qcow2_co_create_opts,
157
- ret = bdrv_set_read_only(bs, true, errp);
361
.bdrv_has_zero_init = bdrv_has_zero_init_1,
158
- if (ret < 0) {
362
.bdrv_co_block_status = qcow2_co_block_status,
159
- return ret;
363
160
- }
364
diff --git a/block/qed.c b/block/qed.c
161
- }
365
index XXXXXXX..XXXXXXX 100644
162
-
366
--- a/block/qed.c
163
/* read header */
367
+++ b/block/qed.c
164
ret = bdrv_pread(bs->file, 128, &s->block_size, 4);
368
@@ -XXX,XX +XXX,XX @@ out:
165
if (ret < 0) {
369
return ret;
166
diff --git a/block/dmg.c b/block/dmg.c
370
}
167
index XXXXXXX..XXXXXXX 100644
371
168
--- a/block/dmg.c
372
-static int bdrv_qed_create(const char *filename, QemuOpts *opts, Error **errp)
169
+++ b/block/dmg.c
373
+static int coroutine_fn bdrv_qed_co_create_opts(const char *filename,
170
@@ -XXX,XX +XXX,XX @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
374
+ QemuOpts *opts,
171
int64_t offset;
375
+ Error **errp)
172
int ret;
376
{
173
377
uint64_t image_size = 0;
174
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
378
uint32_t cluster_size = QED_DEFAULT_CLUSTER_SIZE;
175
+ if (ret < 0) {
379
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_qed = {
176
+ return ret;
380
.bdrv_close = bdrv_qed_close,
177
+ }
381
.bdrv_reopen_prepare = bdrv_qed_reopen_prepare,
178
+
382
.bdrv_child_perm = bdrv_format_default_perms,
179
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
383
- .bdrv_create = bdrv_qed_create,
180
false, errp);
384
+ .bdrv_co_create_opts = bdrv_qed_co_create_opts,
181
if (!bs->file) {
385
.bdrv_has_zero_init = bdrv_has_zero_init_1,
182
return -EINVAL;
386
.bdrv_co_block_status = bdrv_qed_co_block_status,
183
}
387
.bdrv_co_readv = bdrv_qed_co_readv,
184
388
diff --git a/block/raw-format.c b/block/raw-format.c
185
- if (!bdrv_is_read_only(bs)) {
389
index XXXXXXX..XXXXXXX 100644
186
- error_report("Opening dmg images without an explicit read-only=on "
390
--- a/block/raw-format.c
187
- "option is deprecated. Future versions will refuse to "
391
+++ b/block/raw-format.c
188
- "open the image instead of automatically marking the "
392
@@ -XXX,XX +XXX,XX @@ static int raw_has_zero_init(BlockDriverState *bs)
189
- "image read-only.");
393
return bdrv_has_zero_init(bs->file->bs);
190
- ret = bdrv_set_read_only(bs, true, errp);
394
}
191
- if (ret < 0) {
395
192
- return ret;
396
-static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
193
- }
397
+static int coroutine_fn raw_co_create_opts(const char *filename, QemuOpts *opts,
194
- }
398
+ Error **errp)
195
-
399
{
196
block_module_load_one("dmg-bz2");
400
return bdrv_create_file(filename, opts, errp);
197
401
}
198
s->n_chunks = 0;
402
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_raw = {
403
.bdrv_open = &raw_open,
404
.bdrv_close = &raw_close,
405
.bdrv_child_perm = bdrv_filter_default_perms,
406
- .bdrv_create = &raw_create,
407
+ .bdrv_co_create_opts = &raw_co_create_opts,
408
.bdrv_co_preadv = &raw_co_preadv,
409
.bdrv_co_pwritev = &raw_co_pwritev,
410
.bdrv_co_pwrite_zeroes = &raw_co_pwrite_zeroes,
411
diff --git a/block/rbd.c b/block/rbd.c
199
diff --git a/block/rbd.c b/block/rbd.c
412
index XXXXXXX..XXXXXXX 100644
200
index XXXXXXX..XXXXXXX 100644
413
--- a/block/rbd.c
201
--- a/block/rbd.c
414
+++ b/block/rbd.c
202
+++ b/block/rbd.c
415
@@ -XXX,XX +XXX,XX @@ static QemuOptsList runtime_opts = {
203
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
416
},
204
/* If we are using an rbd snapshot, we must be r/o, otherwise
417
};
205
* leave as-is */
418
206
if (s->snap != NULL) {
419
-static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
207
- if (!bdrv_is_read_only(bs)) {
420
+static int coroutine_fn qemu_rbd_co_create_opts(const char *filename,
208
- error_report("Opening rbd snapshots without an explicit "
421
+ QemuOpts *opts,
209
- "read-only=on option is deprecated. Future versions "
422
+ Error **errp)
210
- "will refuse to open the image instead of "
423
{
211
- "automatically marking the image read-only.");
424
Error *local_err = NULL;
212
- r = bdrv_set_read_only(bs, true, &local_err);
425
int64_t bytes = 0;
213
- if (r < 0) {
426
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_rbd = {
214
- rbd_close(s->image);
427
.bdrv_file_open = qemu_rbd_open,
215
- error_propagate(errp, local_err);
428
.bdrv_close = qemu_rbd_close,
216
- goto failed_open;
429
.bdrv_reopen_prepare = qemu_rbd_reopen_prepare,
217
- }
430
- .bdrv_create = qemu_rbd_create,
218
+ r = bdrv_apply_auto_read_only(bs, "rbd snapshots are read-only", errp);
431
+ .bdrv_co_create_opts = qemu_rbd_co_create_opts,
219
+ if (r < 0) {
432
.bdrv_has_zero_init = bdrv_has_zero_init_1,
220
+ rbd_close(s->image);
433
.bdrv_get_info = qemu_rbd_getinfo,
221
+ goto failed_open;
434
.create_opts = &qemu_rbd_create_opts,
222
}
435
diff --git a/block/sheepdog.c b/block/sheepdog.c
223
}
436
index XXXXXXX..XXXXXXX 100644
224
437
--- a/block/sheepdog.c
225
diff --git a/block/vvfat.c b/block/vvfat.c
438
+++ b/block/sheepdog.c
226
index XXXXXXX..XXXXXXX 100644
439
@@ -XXX,XX +XXX,XX @@ static int parse_block_size_shift(BDRVSheepdogState *s, QemuOpts *opt)
227
--- a/block/vvfat.c
440
return 0;
228
+++ b/block/vvfat.c
441
}
229
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
442
230
"Unable to set VVFAT to 'rw' when drive is read-only");
443
-static int sd_create(const char *filename, QemuOpts *opts,
231
goto fail;
444
- Error **errp)
232
}
445
+static int coroutine_fn sd_co_create_opts(const char *filename, QemuOpts *opts,
233
- } else if (!bdrv_is_read_only(bs)) {
446
+ Error **errp)
234
- error_report("Opening non-rw vvfat images without an explicit "
447
{
235
- "read-only=on option is deprecated. Future versions "
448
Error *err = NULL;
236
- "will refuse to open the image instead of "
449
int ret = 0;
237
- "automatically marking the image read-only.");
450
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_sheepdog = {
238
- /* read only is the default for safety */
451
.bdrv_reopen_commit = sd_reopen_commit,
239
- ret = bdrv_set_read_only(bs, true, &local_err);
452
.bdrv_reopen_abort = sd_reopen_abort,
240
+ } else {
453
.bdrv_close = sd_close,
241
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
454
- .bdrv_create = sd_create,
242
if (ret < 0) {
455
+ .bdrv_co_create_opts = sd_co_create_opts,
243
- error_propagate(errp, local_err);
456
.bdrv_has_zero_init = bdrv_has_zero_init_1,
244
goto fail;
457
.bdrv_getlength = sd_getlength,
245
}
458
.bdrv_get_allocated_file_size = sd_get_allocated_file_size,
246
}
459
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_sheepdog_tcp = {
460
.bdrv_reopen_commit = sd_reopen_commit,
461
.bdrv_reopen_abort = sd_reopen_abort,
462
.bdrv_close = sd_close,
463
- .bdrv_create = sd_create,
464
+ .bdrv_co_create_opts = sd_co_create_opts,
465
.bdrv_has_zero_init = bdrv_has_zero_init_1,
466
.bdrv_getlength = sd_getlength,
467
.bdrv_get_allocated_file_size = sd_get_allocated_file_size,
468
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_sheepdog_unix = {
469
.bdrv_reopen_commit = sd_reopen_commit,
470
.bdrv_reopen_abort = sd_reopen_abort,
471
.bdrv_close = sd_close,
472
- .bdrv_create = sd_create,
473
+ .bdrv_co_create_opts = sd_co_create_opts,
474
.bdrv_has_zero_init = bdrv_has_zero_init_1,
475
.bdrv_getlength = sd_getlength,
476
.bdrv_get_allocated_file_size = sd_get_allocated_file_size,
477
diff --git a/block/ssh.c b/block/ssh.c
478
index XXXXXXX..XXXXXXX 100644
479
--- a/block/ssh.c
480
+++ b/block/ssh.c
481
@@ -XXX,XX +XXX,XX @@ static QemuOptsList ssh_create_opts = {
482
}
483
};
484
485
-static int ssh_create(const char *filename, QemuOpts *opts, Error **errp)
486
+static int coroutine_fn ssh_co_create_opts(const char *filename, QemuOpts *opts,
487
+ Error **errp)
488
{
489
int r, ret;
490
int64_t total_size = 0;
491
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_ssh = {
492
.instance_size = sizeof(BDRVSSHState),
493
.bdrv_parse_filename = ssh_parse_filename,
494
.bdrv_file_open = ssh_file_open,
495
- .bdrv_create = ssh_create,
496
+ .bdrv_co_create_opts = ssh_co_create_opts,
497
.bdrv_close = ssh_close,
498
.bdrv_has_zero_init = ssh_has_zero_init,
499
.bdrv_co_readv = ssh_co_readv,
500
diff --git a/block/vdi.c b/block/vdi.c
501
index XXXXXXX..XXXXXXX 100644
502
--- a/block/vdi.c
503
+++ b/block/vdi.c
504
@@ -XXX,XX +XXX,XX @@ nonallocating_write:
505
return ret;
506
}
507
508
-static int vdi_create(const char *filename, QemuOpts *opts, Error **errp)
509
+static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
510
+ Error **errp)
511
{
512
int ret = 0;
513
uint64_t bytes = 0;
514
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vdi = {
515
.bdrv_close = vdi_close,
516
.bdrv_reopen_prepare = vdi_reopen_prepare,
517
.bdrv_child_perm = bdrv_format_default_perms,
518
- .bdrv_create = vdi_create,
519
+ .bdrv_co_create_opts = vdi_co_create_opts,
520
.bdrv_has_zero_init = bdrv_has_zero_init_1,
521
.bdrv_co_block_status = vdi_co_block_status,
522
.bdrv_make_empty = vdi_make_empty,
523
diff --git a/block/vhdx.c b/block/vhdx.c
524
index XXXXXXX..XXXXXXX 100644
525
--- a/block/vhdx.c
526
+++ b/block/vhdx.c
527
@@ -XXX,XX +XXX,XX @@ exit:
528
* .---- ~ ----------- ~ ------------ ~ ---------------- ~ -----------.
529
* 1MB
530
*/
531
-static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
532
+static int coroutine_fn vhdx_co_create_opts(const char *filename, QemuOpts *opts,
533
+ Error **errp)
534
{
535
int ret = 0;
536
uint64_t image_size = (uint64_t) 2 * GiB;
537
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vhdx = {
538
.bdrv_child_perm = bdrv_format_default_perms,
539
.bdrv_co_readv = vhdx_co_readv,
540
.bdrv_co_writev = vhdx_co_writev,
541
- .bdrv_create = vhdx_create,
542
+ .bdrv_co_create_opts = vhdx_co_create_opts,
543
.bdrv_get_info = vhdx_get_info,
544
.bdrv_check = vhdx_check,
545
.bdrv_has_zero_init = bdrv_has_zero_init_1,
546
diff --git a/block/vmdk.c b/block/vmdk.c
547
index XXXXXXX..XXXXXXX 100644
548
--- a/block/vmdk.c
549
+++ b/block/vmdk.c
550
@@ -XXX,XX +XXX,XX @@ static int filename_decompose(const char *filename, char *path, char *prefix,
551
return VMDK_OK;
552
}
553
554
-static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
555
+static int coroutine_fn vmdk_co_create_opts(const char *filename, QemuOpts *opts,
556
+ Error **errp)
557
{
558
int idx = 0;
559
BlockBackend *new_blk = NULL;
560
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vmdk = {
561
.bdrv_co_pwritev_compressed = vmdk_co_pwritev_compressed,
562
.bdrv_co_pwrite_zeroes = vmdk_co_pwrite_zeroes,
563
.bdrv_close = vmdk_close,
564
- .bdrv_create = vmdk_create,
565
+ .bdrv_co_create_opts = vmdk_co_create_opts,
566
.bdrv_co_flush_to_disk = vmdk_co_flush,
567
.bdrv_co_block_status = vmdk_co_block_status,
568
.bdrv_get_allocated_file_size = vmdk_get_allocated_file_size,
569
diff --git a/block/vpc.c b/block/vpc.c
570
index XXXXXXX..XXXXXXX 100644
571
--- a/block/vpc.c
572
+++ b/block/vpc.c
573
@@ -XXX,XX +XXX,XX @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
574
return ret;
575
}
576
577
-static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
578
+static int coroutine_fn vpc_co_create_opts(const char *filename, QemuOpts *opts,
579
+ Error **errp)
580
{
581
uint8_t buf[1024];
582
VHDFooter *footer = (VHDFooter *) buf;
583
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vpc = {
584
.bdrv_close = vpc_close,
585
.bdrv_reopen_prepare = vpc_reopen_prepare,
586
.bdrv_child_perm = bdrv_format_default_perms,
587
- .bdrv_create = vpc_create,
588
+ .bdrv_co_create_opts = vpc_co_create_opts,
589
590
.bdrv_co_preadv = vpc_co_preadv,
591
.bdrv_co_pwritev = vpc_co_pwritev,
592
--
247
--
593
2.13.6
248
2.19.1
594
249
595
250
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
If read-only=off, but auto-read-only=on is given, open a read-write NBD
2
connection if the server provides a read-write export, but instead of
3
erroring out for read-only exports, just degrade to read-only.
2
4
3
We are gradually moving away from sector-based interfaces, towards
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
byte-based. Now that all drivers have been updated to provide the
6
Reviewed-by: Eric Blake <eblake@redhat.com>
5
byte-based .bdrv_co_block_status(), we can delete the sector-based
7
---
6
interface.
8
block/nbd-client.c | 10 +++++-----
9
1 file changed, 5 insertions(+), 5 deletions(-)
7
10
8
Signed-off-by: Eric Blake <eblake@redhat.com>
11
diff --git a/block/nbd-client.c b/block/nbd-client.c
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Reviewed-by: Fam Zheng <famz@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
include/block/block_int.h | 3 ---
14
block/io.c | 50 ++++++++++-------------------------------------
15
2 files changed, 10 insertions(+), 43 deletions(-)
16
17
diff --git a/include/block/block_int.h b/include/block/block_int.h
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/include/block/block_int.h
13
--- a/block/nbd-client.c
20
+++ b/include/block/block_int.h
14
+++ b/block/nbd-client.c
21
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
15
@@ -XXX,XX +XXX,XX @@ int nbd_client_init(BlockDriverState *bs,
22
* as well as non-NULL pnum, map, and file; in turn, the driver
16
logout("Failed to negotiate with the NBD server\n");
23
* must return an error or set pnum to an aligned non-zero value.
17
return ret;
24
*/
25
- int64_t coroutine_fn (*bdrv_co_get_block_status)(BlockDriverState *bs,
26
- int64_t sector_num, int nb_sectors, int *pnum,
27
- BlockDriverState **file);
28
int coroutine_fn (*bdrv_co_block_status)(BlockDriverState *bs,
29
bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
30
int64_t *map, BlockDriverState **file);
31
diff --git a/block/io.c b/block/io.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/block/io.c
34
+++ b/block/io.c
35
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
36
37
/* Must be non-NULL or bdrv_getlength() would have failed */
38
assert(bs->drv);
39
- if (!bs->drv->bdrv_co_get_block_status && !bs->drv->bdrv_co_block_status) {
40
+ if (!bs->drv->bdrv_co_block_status) {
41
*pnum = bytes;
42
ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED;
43
if (offset + bytes == total_size) {
44
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
45
46
/* Round out to request_alignment boundaries */
47
align = bs->bl.request_alignment;
48
- if (bs->drv->bdrv_co_get_block_status && align < BDRV_SECTOR_SIZE) {
49
- align = BDRV_SECTOR_SIZE;
50
- }
51
aligned_offset = QEMU_ALIGN_DOWN(offset, align);
52
aligned_bytes = ROUND_UP(offset + bytes, align) - aligned_offset;
53
54
- if (bs->drv->bdrv_co_get_block_status) {
55
- int count; /* sectors */
56
- int64_t longret;
57
-
58
- assert(QEMU_IS_ALIGNED(aligned_offset | aligned_bytes,
59
- BDRV_SECTOR_SIZE));
60
- /*
61
- * The contract allows us to return pnum smaller than bytes, even
62
- * if the next query would see the same status; we truncate the
63
- * request to avoid overflowing the driver's 32-bit interface.
64
- */
65
- longret = bs->drv->bdrv_co_get_block_status(
66
- bs, aligned_offset >> BDRV_SECTOR_BITS,
67
- MIN(INT_MAX, aligned_bytes) >> BDRV_SECTOR_BITS, &count,
68
- &local_file);
69
- if (longret < 0) {
70
- assert(INT_MIN <= longret);
71
- ret = longret;
72
- goto out;
73
- }
74
- if (longret & BDRV_BLOCK_OFFSET_VALID) {
75
- local_map = longret & BDRV_BLOCK_OFFSET_MASK;
76
- }
77
- ret = longret & ~BDRV_BLOCK_OFFSET_MASK;
78
- *pnum = count * BDRV_SECTOR_SIZE;
79
- } else {
80
- ret = bs->drv->bdrv_co_block_status(bs, want_zero, aligned_offset,
81
- aligned_bytes, pnum, &local_map,
82
- &local_file);
83
- if (ret < 0) {
84
- *pnum = 0;
85
- goto out;
86
- }
87
- assert(*pnum); /* The block driver must make progress */
88
+ ret = bs->drv->bdrv_co_block_status(bs, want_zero, aligned_offset,
89
+ aligned_bytes, pnum, &local_map,
90
+ &local_file);
91
+ if (ret < 0) {
92
+ *pnum = 0;
93
+ goto out;
94
}
18
}
95
19
- if (client->info.flags & NBD_FLAG_READ_ONLY &&
96
/*
20
- !bdrv_is_read_only(bs)) {
97
- * The driver's result must be a multiple of request_alignment.
21
- error_setg(errp,
98
+ * The driver's result must be a non-zero multiple of request_alignment.
22
- "request for write access conflicts with read-only export");
99
* Clamp pnum and adjust map to original request.
23
- return -EACCES;
100
*/
24
+ if (client->info.flags & NBD_FLAG_READ_ONLY) {
101
- assert(QEMU_IS_ALIGNED(*pnum, align) && align > offset - aligned_offset);
25
+ ret = bdrv_apply_auto_read_only(bs, "NBD export is read-only", errp);
102
+ assert(*pnum && QEMU_IS_ALIGNED(*pnum, align) &&
26
+ if (ret < 0) {
103
+ align > offset - aligned_offset);
27
+ return ret;
104
*pnum -= offset - aligned_offset;
28
+ }
105
if (*pnum > bytes) {
29
}
106
*pnum = bytes;
30
if (client->info.flags & NBD_FLAG_SEND_FUA) {
31
bs->supported_write_flags = BDRV_REQ_FUA;
107
--
32
--
108
2.13.6
33
2.19.1
109
34
110
35
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
If read-only=off, but auto-read-only=on is given, open the file
2
read-write if we have the permissions, but instead of erroring out for
3
read-only files, just degrade to read-only.
2
4
3
We are gradually moving away from sector-based interfaces, towards
4
byte-based. Update the file protocol driver accordingly.
5
6
In want_zero mode, we continue to report fine-grained hole
7
information (the caller wants as much mapping detail as possible);
8
but when not in that mode, the caller prefers larger *pnum and
9
merely cares about what offsets are allocated at this layer, rather
10
than where the holes live. Since holes still read as zeroes at
11
this layer (rather than deferring to a backing layer), we can take
12
the shortcut of skipping lseek(), and merely state that all bytes
13
are allocated.
14
15
We can also drop redundant bounds checks that are already
16
guaranteed by the block layer.
17
18
Signed-off-by: Eric Blake <eblake@redhat.com>
19
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
20
Reviewed-by: Fam Zheng <famz@redhat.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
22
---
7
---
23
block/file-posix.c | 64 +++++++++++++++++++++++++-----------------------------
8
block/file-posix.c | 19 ++++++++++++++++---
24
1 file changed, 30 insertions(+), 34 deletions(-)
9
1 file changed, 16 insertions(+), 3 deletions(-)
25
10
26
diff --git a/block/file-posix.c b/block/file-posix.c
11
diff --git a/block/file-posix.c b/block/file-posix.c
27
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
28
--- a/block/file-posix.c
13
--- a/block/file-posix.c
29
+++ b/block/file-posix.c
14
+++ b/block/file-posix.c
30
@@ -XXX,XX +XXX,XX @@ static int find_allocation(BlockDriverState *bs, off_t start,
15
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
31
}
16
32
17
s->fd = -1;
33
/*
18
fd = qemu_open(filename, s->open_flags, 0644);
34
- * Returns the allocation status of the specified sectors.
19
- if (fd < 0) {
35
+ * Returns the allocation status of the specified offset.
20
- ret = -errno;
36
*
21
- error_setg_errno(errp, errno, "Could not open '%s'", filename);
37
- * If 'sector_num' is beyond the end of the disk image the return value is 0
22
+ ret = fd < 0 ? -errno : 0;
38
- * and 'pnum' is set to 0.
23
+
39
+ * The block layer guarantees 'offset' and 'bytes' are within bounds.
24
+ if (ret == -EACCES || ret == -EROFS) {
40
*
25
+ /* Try to degrade to read-only, but if it doesn't work, still use the
41
- * 'pnum' is set to the number of sectors (including and immediately following
26
+ * normal error message. */
42
- * the specified sector) that are known to be in the same
27
+ if (bdrv_apply_auto_read_only(bs, NULL, NULL) == 0) {
43
+ * 'pnum' is set to the number of bytes (including and immediately following
28
+ bdrv_flags &= ~BDRV_O_RDWR;
44
+ * the specified offset) that are known to be in the same
29
+ raw_parse_flags(bdrv_flags, &s->open_flags);
45
* allocated/unallocated state.
30
+ assert(!(s->open_flags & O_CREAT));
46
*
31
+ fd = qemu_open(filename, s->open_flags);
47
- * 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes
32
+ ret = fd < 0 ? -errno : 0;
48
- * beyond the end of the disk image it will be clamped.
33
+ }
49
+ * 'bytes' is the max value 'pnum' should be set to.
34
+ }
50
*/
35
+
51
-static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
36
+ if (ret < 0) {
52
- int64_t sector_num,
37
+ error_setg_errno(errp, -ret, "Could not open '%s'", filename);
53
- int nb_sectors, int *pnum,
38
if (ret == -EROFS) {
54
- BlockDriverState **file)
39
ret = -EACCES;
55
-{
40
}
56
- off_t start, data = 0, hole = 0;
57
- int64_t total_size;
58
+static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
59
+ bool want_zero,
60
+ int64_t offset,
61
+ int64_t bytes, int64_t *pnum,
62
+ int64_t *map,
63
+ BlockDriverState **file)
64
+{
65
+ off_t data = 0, hole = 0;
66
int ret;
67
68
ret = fd_open(bs);
69
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
70
return ret;
71
}
72
73
- start = sector_num * BDRV_SECTOR_SIZE;
74
- total_size = bdrv_getlength(bs);
75
- if (total_size < 0) {
76
- return total_size;
77
- } else if (start >= total_size) {
78
- *pnum = 0;
79
- return 0;
80
- } else if (start + nb_sectors * BDRV_SECTOR_SIZE > total_size) {
81
- nb_sectors = DIV_ROUND_UP(total_size - start, BDRV_SECTOR_SIZE);
82
+ if (!want_zero) {
83
+ *pnum = bytes;
84
+ *map = offset;
85
+ *file = bs;
86
+ return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
87
}
88
89
- ret = find_allocation(bs, start, &data, &hole);
90
+ ret = find_allocation(bs, offset, &data, &hole);
91
if (ret == -ENXIO) {
92
/* Trailing hole */
93
- *pnum = nb_sectors;
94
+ *pnum = bytes;
95
ret = BDRV_BLOCK_ZERO;
96
} else if (ret < 0) {
97
/* No info available, so pretend there are no holes */
98
- *pnum = nb_sectors;
99
+ *pnum = bytes;
100
ret = BDRV_BLOCK_DATA;
101
- } else if (data == start) {
102
- /* On a data extent, compute sectors to the end of the extent,
103
+ } else if (data == offset) {
104
+ /* On a data extent, compute bytes to the end of the extent,
105
* possibly including a partial sector at EOF. */
106
- *pnum = MIN(nb_sectors, DIV_ROUND_UP(hole - start, BDRV_SECTOR_SIZE));
107
+ *pnum = MIN(bytes, hole - offset);
108
ret = BDRV_BLOCK_DATA;
109
} else {
110
- /* On a hole, compute sectors to the beginning of the next extent. */
111
- assert(hole == start);
112
- *pnum = MIN(nb_sectors, (data - start) / BDRV_SECTOR_SIZE);
113
+ /* On a hole, compute bytes to the beginning of the next extent. */
114
+ assert(hole == offset);
115
+ *pnum = MIN(bytes, data - offset);
116
ret = BDRV_BLOCK_ZERO;
117
}
118
+ *map = offset;
119
*file = bs;
120
- return ret | BDRV_BLOCK_OFFSET_VALID | start;
121
+ return ret | BDRV_BLOCK_OFFSET_VALID;
122
}
123
124
static coroutine_fn BlockAIOCB *raw_aio_pdiscard(BlockDriverState *bs,
125
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_file = {
126
.bdrv_close = raw_close,
127
.bdrv_create = raw_create,
128
.bdrv_has_zero_init = bdrv_has_zero_init_1,
129
- .bdrv_co_get_block_status = raw_co_get_block_status,
130
+ .bdrv_co_block_status = raw_co_block_status,
131
.bdrv_co_pwrite_zeroes = raw_co_pwrite_zeroes,
132
133
.bdrv_co_preadv = raw_co_preadv,
134
--
41
--
135
2.13.6
42
2.19.1
136
43
137
44
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
If read-only=off, but auto-read-only=on is given, just degrade to
2
read-only.
2
3
3
We are gradually moving away from sector-based interfaces, towards
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
byte-based. Update the qed driver accordingly, taking the opportunity
5
Reviewed-by: Eric Blake <eblake@redhat.com>
5
to inline qed_is_allocated_cb() into its lone caller (the callback
6
---
6
used to be important, until we switched qed to coroutines). There is
7
block/curl.c | 8 ++++----
7
no intent to optimize based on the want_zero flag for this format.
8
1 file changed, 4 insertions(+), 4 deletions(-)
8
9
9
Signed-off-by: Eric Blake <eblake@redhat.com>
10
diff --git a/block/curl.c b/block/curl.c
10
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Reviewed-by: Fam Zheng <famz@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block/qed.c | 76 +++++++++++++++++++------------------------------------------
15
1 file changed, 24 insertions(+), 52 deletions(-)
16
17
diff --git a/block/qed.c b/block/qed.c
18
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qed.c
12
--- a/block/curl.c
20
+++ b/block/qed.c
13
+++ b/block/curl.c
21
@@ -XXX,XX +XXX,XX @@ finish:
14
@@ -XXX,XX +XXX,XX @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
22
return ret;
15
const char *protocol_delimiter;
23
}
16
int ret;
24
17
25
-typedef struct {
26
- BlockDriverState *bs;
27
- Coroutine *co;
28
- uint64_t pos;
29
- int64_t status;
30
- int *pnum;
31
- BlockDriverState **file;
32
-} QEDIsAllocatedCB;
33
-
18
-
34
-/* Called with table_lock held. */
19
- if (flags & BDRV_O_RDWR) {
35
-static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t len)
20
- error_setg(errp, "curl block device does not support writes");
36
+static int coroutine_fn bdrv_qed_co_block_status(BlockDriverState *bs,
21
- return -EROFS;
37
+ bool want_zero,
22
+ ret = bdrv_apply_auto_read_only(bs, "curl driver does not support writes",
38
+ int64_t pos, int64_t bytes,
23
+ errp);
39
+ int64_t *pnum, int64_t *map,
24
+ if (ret < 0) {
40
+ BlockDriverState **file)
25
+ return ret;
41
{
42
- QEDIsAllocatedCB *cb = opaque;
43
- BDRVQEDState *s = cb->bs->opaque;
44
- *cb->pnum = len / BDRV_SECTOR_SIZE;
45
+ BDRVQEDState *s = bs->opaque;
46
+ size_t len = MIN(bytes, SIZE_MAX);
47
+ int status;
48
+ QEDRequest request = { .l2_table = NULL };
49
+ uint64_t offset;
50
+ int ret;
51
+
52
+ qemu_co_mutex_lock(&s->table_lock);
53
+ ret = qed_find_cluster(s, &request, pos, &len, &offset);
54
+
55
+ *pnum = len;
56
switch (ret) {
57
case QED_CLUSTER_FOUND:
58
- offset |= qed_offset_into_cluster(s, cb->pos);
59
- cb->status = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | offset;
60
- *cb->file = cb->bs->file->bs;
61
+ *map = offset | qed_offset_into_cluster(s, pos);
62
+ status = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
63
+ *file = bs->file->bs;
64
break;
65
case QED_CLUSTER_ZERO:
66
- cb->status = BDRV_BLOCK_ZERO;
67
+ status = BDRV_BLOCK_ZERO;
68
break;
69
case QED_CLUSTER_L2:
70
case QED_CLUSTER_L1:
71
- cb->status = 0;
72
+ status = 0;
73
break;
74
default:
75
assert(ret < 0);
76
- cb->status = ret;
77
+ status = ret;
78
break;
79
}
26
}
80
27
81
- if (cb->co) {
28
if (!libcurl_initialized) {
82
- aio_co_wake(cb->co);
83
- }
84
-}
85
-
86
-static int64_t coroutine_fn bdrv_qed_co_get_block_status(BlockDriverState *bs,
87
- int64_t sector_num,
88
- int nb_sectors, int *pnum,
89
- BlockDriverState **file)
90
-{
91
- BDRVQEDState *s = bs->opaque;
92
- size_t len = (size_t)nb_sectors * BDRV_SECTOR_SIZE;
93
- QEDIsAllocatedCB cb = {
94
- .bs = bs,
95
- .pos = (uint64_t)sector_num * BDRV_SECTOR_SIZE,
96
- .status = BDRV_BLOCK_OFFSET_MASK,
97
- .pnum = pnum,
98
- .file = file,
99
- };
100
- QEDRequest request = { .l2_table = NULL };
101
- uint64_t offset;
102
- int ret;
103
-
104
- qemu_co_mutex_lock(&s->table_lock);
105
- ret = qed_find_cluster(s, &request, cb.pos, &len, &offset);
106
- qed_is_allocated_cb(&cb, ret, offset, len);
107
-
108
- /* The callback was invoked immediately */
109
- assert(cb.status != BDRV_BLOCK_OFFSET_MASK);
110
-
111
qed_unref_l2_cache_entry(request.l2_table);
112
qemu_co_mutex_unlock(&s->table_lock);
113
114
- return cb.status;
115
+ return status;
116
}
117
118
static BDRVQEDState *acb_to_s(QEDAIOCB *acb)
119
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_qed = {
120
.bdrv_child_perm = bdrv_format_default_perms,
121
.bdrv_create = bdrv_qed_create,
122
.bdrv_has_zero_init = bdrv_has_zero_init_1,
123
- .bdrv_co_get_block_status = bdrv_qed_co_get_block_status,
124
+ .bdrv_co_block_status = bdrv_qed_co_block_status,
125
.bdrv_co_readv = bdrv_qed_co_readv,
126
.bdrv_co_writev = bdrv_qed_co_writev,
127
.bdrv_co_pwrite_zeroes = bdrv_qed_co_pwrite_zeroes,
128
--
29
--
129
2.13.6
30
2.19.1
130
31
131
32
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
If read-only=off, but auto-read-only=on is given, open the file
2
read-write if we have the permissions, but instead of erroring out for
3
read-only files, just degrade to read-only.
2
4
3
We are gradually moving away from sector-based interfaces, towards
4
byte-based. Update the gluster driver accordingly.
5
6
In want_zero mode, we continue to report fine-grained hole
7
information (the caller wants as much mapping detail as possible);
8
but when not in that mode, the caller prefers larger *pnum and
9
merely cares about what offsets are allocated at this layer, rather
10
than where the holes live. Since holes still read as zeroes at
11
this layer (rather than deferring to a backing layer), we can take
12
the shortcut of skipping find_allocation(), and merely state that
13
all bytes are allocated.
14
15
We can also drop redundant bounds checks that are already
16
guaranteed by the block layer.
17
18
Signed-off-by: Eric Blake <eblake@redhat.com>
19
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
20
Reviewed-by: Fam Zheng <famz@redhat.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Niels de Vos <ndevos@redhat.com>
22
---
7
---
23
block/gluster.c | 70 ++++++++++++++++++++++++++++-----------------------------
8
block/gluster.c | 12 ++++++++++--
24
1 file changed, 34 insertions(+), 36 deletions(-)
9
1 file changed, 10 insertions(+), 2 deletions(-)
25
10
26
diff --git a/block/gluster.c b/block/gluster.c
11
diff --git a/block/gluster.c b/block/gluster.c
27
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
28
--- a/block/gluster.c
13
--- a/block/gluster.c
29
+++ b/block/gluster.c
14
+++ b/block/gluster.c
30
@@ -XXX,XX +XXX,XX @@ exit:
15
@@ -XXX,XX +XXX,XX @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
31
}
16
qemu_gluster_parse_flags(bdrv_flags, &open_flags);
32
17
33
/*
18
s->fd = glfs_open(s->glfs, gconf->path, open_flags);
34
- * Returns the allocation status of the specified sectors.
19
- if (!s->fd) {
35
+ * Returns the allocation status of the specified offset.
20
- ret = -errno;
36
*
21
+ ret = s->fd ? 0 : -errno;
37
- * If 'sector_num' is beyond the end of the disk image the return value is 0
22
+
38
- * and 'pnum' is set to 0.
23
+ if (ret == -EACCES || ret == -EROFS) {
39
+ * The block layer guarantees 'offset' and 'bytes' are within bounds.
24
+ /* Try to degrade to read-only, but if it doesn't work, still use the
40
*
25
+ * normal error message. */
41
- * 'pnum' is set to the number of sectors (including and immediately following
26
+ if (bdrv_apply_auto_read_only(bs, NULL, NULL) == 0) {
42
- * the specified sector) that are known to be in the same
27
+ open_flags = (open_flags & ~O_RDWR) | O_RDONLY;
43
+ * 'pnum' is set to the number of bytes (including and immediately following
28
+ s->fd = glfs_open(s->glfs, gconf->path, open_flags);
44
+ * the specified offset) that are known to be in the same
29
+ ret = s->fd ? 0 : -errno;
45
* allocated/unallocated state.
30
+ }
46
*
47
- * 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes
48
- * beyond the end of the disk image it will be clamped.
49
+ * 'bytes' is the max value 'pnum' should be set to.
50
*
51
- * (Based on raw_co_get_block_status() from file-posix.c.)
52
+ * (Based on raw_co_block_status() from file-posix.c.)
53
*/
54
-static int64_t coroutine_fn qemu_gluster_co_get_block_status(
55
- BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum,
56
- BlockDriverState **file)
57
+static int coroutine_fn qemu_gluster_co_block_status(BlockDriverState *bs,
58
+ bool want_zero,
59
+ int64_t offset,
60
+ int64_t bytes,
61
+ int64_t *pnum,
62
+ int64_t *map,
63
+ BlockDriverState **file)
64
{
65
BDRVGlusterState *s = bs->opaque;
66
- off_t start, data = 0, hole = 0;
67
- int64_t total_size;
68
+ off_t data = 0, hole = 0;
69
int ret = -EINVAL;
70
71
if (!s->fd) {
72
return ret;
73
}
31
}
74
32
75
- start = sector_num * BDRV_SECTOR_SIZE;
33
s->supports_seek_data = qemu_gluster_test_seek(s->fd);
76
- total_size = bdrv_getlength(bs);
77
- if (total_size < 0) {
78
- return total_size;
79
- } else if (start >= total_size) {
80
- *pnum = 0;
81
- return 0;
82
- } else if (start + nb_sectors * BDRV_SECTOR_SIZE > total_size) {
83
- nb_sectors = DIV_ROUND_UP(total_size - start, BDRV_SECTOR_SIZE);
84
+ if (!want_zero) {
85
+ *pnum = bytes;
86
+ *map = offset;
87
+ *file = bs;
88
+ return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
89
}
90
91
- ret = find_allocation(bs, start, &data, &hole);
92
+ ret = find_allocation(bs, offset, &data, &hole);
93
if (ret == -ENXIO) {
94
/* Trailing hole */
95
- *pnum = nb_sectors;
96
+ *pnum = bytes;
97
ret = BDRV_BLOCK_ZERO;
98
} else if (ret < 0) {
99
/* No info available, so pretend there are no holes */
100
- *pnum = nb_sectors;
101
+ *pnum = bytes;
102
ret = BDRV_BLOCK_DATA;
103
- } else if (data == start) {
104
- /* On a data extent, compute sectors to the end of the extent,
105
+ } else if (data == offset) {
106
+ /* On a data extent, compute bytes to the end of the extent,
107
* possibly including a partial sector at EOF. */
108
- *pnum = MIN(nb_sectors, DIV_ROUND_UP(hole - start, BDRV_SECTOR_SIZE));
109
+ *pnum = MIN(bytes, hole - offset);
110
ret = BDRV_BLOCK_DATA;
111
} else {
112
- /* On a hole, compute sectors to the beginning of the next extent. */
113
- assert(hole == start);
114
- *pnum = MIN(nb_sectors, (data - start) / BDRV_SECTOR_SIZE);
115
+ /* On a hole, compute bytes to the beginning of the next extent. */
116
+ assert(hole == offset);
117
+ *pnum = MIN(bytes, data - offset);
118
ret = BDRV_BLOCK_ZERO;
119
}
120
121
+ *map = offset;
122
*file = bs;
123
124
- return ret | BDRV_BLOCK_OFFSET_VALID | start;
125
+ return ret | BDRV_BLOCK_OFFSET_VALID;
126
}
127
128
129
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster = {
130
#ifdef CONFIG_GLUSTERFS_ZEROFILL
131
.bdrv_co_pwrite_zeroes = qemu_gluster_co_pwrite_zeroes,
132
#endif
133
- .bdrv_co_get_block_status = qemu_gluster_co_get_block_status,
134
+ .bdrv_co_block_status = qemu_gluster_co_block_status,
135
.create_opts = &qemu_gluster_create_opts,
136
};
137
138
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_tcp = {
139
#ifdef CONFIG_GLUSTERFS_ZEROFILL
140
.bdrv_co_pwrite_zeroes = qemu_gluster_co_pwrite_zeroes,
141
#endif
142
- .bdrv_co_get_block_status = qemu_gluster_co_get_block_status,
143
+ .bdrv_co_block_status = qemu_gluster_co_block_status,
144
.create_opts = &qemu_gluster_create_opts,
145
};
146
147
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_unix = {
148
#ifdef CONFIG_GLUSTERFS_ZEROFILL
149
.bdrv_co_pwrite_zeroes = qemu_gluster_co_pwrite_zeroes,
150
#endif
151
- .bdrv_co_get_block_status = qemu_gluster_co_get_block_status,
152
+ .bdrv_co_block_status = qemu_gluster_co_block_status,
153
.create_opts = &qemu_gluster_create_opts,
154
};
155
156
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_rdma = {
157
#ifdef CONFIG_GLUSTERFS_ZEROFILL
158
.bdrv_co_pwrite_zeroes = qemu_gluster_co_pwrite_zeroes,
159
#endif
160
- .bdrv_co_get_block_status = qemu_gluster_co_get_block_status,
161
+ .bdrv_co_block_status = qemu_gluster_co_block_status,
162
.create_opts = &qemu_gluster_create_opts,
163
};
164
165
--
34
--
166
2.13.6
35
2.19.1
167
36
168
37
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
If read-only=off, but auto-read-only=on is given, open the volume
2
read-write if we have the permissions, but instead of erroring out for
3
read-only volumes, just degrade to read-only.
2
4
3
We are gradually converting to byte-based interfaces, as they are
4
easier to reason about than sector-based. Convert all uses of
5
the cluster size in sectors, along with adding assertions that we
6
are not dividing by zero.
7
8
Improve some comment grammar while in the area.
9
10
Signed-off-by: Eric Blake <eblake@redhat.com>
11
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
12
Reviewed-by: Fam Zheng <famz@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
14
---
7
---
15
block/iscsi.c | 56 +++++++++++++++++++++++++++++++++++---------------------
8
block/iscsi.c | 8 +++++---
16
1 file changed, 35 insertions(+), 21 deletions(-)
9
1 file changed, 5 insertions(+), 3 deletions(-)
17
10
18
diff --git a/block/iscsi.c b/block/iscsi.c
11
diff --git a/block/iscsi.c b/block/iscsi.c
19
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
20
--- a/block/iscsi.c
13
--- a/block/iscsi.c
21
+++ b/block/iscsi.c
14
+++ b/block/iscsi.c
22
@@ -XXX,XX +XXX,XX @@ typedef struct IscsiLun {
15
@@ -XXX,XX +XXX,XX @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
23
unsigned long *allocmap;
16
/* Check the write protect flag of the LUN if we want to write */
24
unsigned long *allocmap_valid;
17
if (iscsilun->type == TYPE_DISK && (flags & BDRV_O_RDWR) &&
25
long allocmap_size;
18
iscsilun->write_protected) {
26
- int cluster_sectors;
19
- error_setg(errp, "Cannot open a write protected LUN as read-write");
27
+ int cluster_size;
20
- ret = -EACCES;
28
bool use_16_for_rw;
21
- goto out;
29
bool write_protected;
22
+ ret = bdrv_apply_auto_read_only(bs, "LUN is write protected", errp);
30
bool lbpme;
23
+ if (ret < 0) {
31
@@ -XXX,XX +XXX,XX @@ static int iscsi_allocmap_init(IscsiLun *iscsilun, int open_flags)
24
+ goto out;
32
{
25
+ }
33
iscsi_allocmap_free(iscsilun);
26
+ flags &= ~BDRV_O_RDWR;
34
35
+ assert(iscsilun->cluster_size);
36
iscsilun->allocmap_size =
37
- DIV_ROUND_UP(sector_lun2qemu(iscsilun->num_blocks, iscsilun),
38
- iscsilun->cluster_sectors);
39
+ DIV_ROUND_UP(iscsilun->num_blocks * iscsilun->block_size,
40
+ iscsilun->cluster_size);
41
42
iscsilun->allocmap = bitmap_try_new(iscsilun->allocmap_size);
43
if (!iscsilun->allocmap) {
44
@@ -XXX,XX +XXX,XX @@ static int iscsi_allocmap_init(IscsiLun *iscsilun, int open_flags)
45
}
27
}
46
28
47
if (open_flags & BDRV_O_NOCACHE) {
29
iscsi_readcapacity_sync(iscsilun, &local_err);
48
- /* in case that cache.direct = on all allocmap entries are
49
+ /* when cache.direct = on all allocmap entries are
50
* treated as invalid to force a relookup of the block
51
* status on every read request */
52
return 0;
53
@@ -XXX,XX +XXX,XX @@ iscsi_allocmap_update(IscsiLun *iscsilun, int64_t sector_num,
54
int nb_sectors, bool allocated, bool valid)
55
{
56
int64_t cl_num_expanded, nb_cls_expanded, cl_num_shrunk, nb_cls_shrunk;
57
+ int cluster_sectors = iscsilun->cluster_size >> BDRV_SECTOR_BITS;
58
59
if (iscsilun->allocmap == NULL) {
60
return;
61
}
62
/* expand to entirely contain all affected clusters */
63
- cl_num_expanded = sector_num / iscsilun->cluster_sectors;
64
+ assert(cluster_sectors);
65
+ cl_num_expanded = sector_num / cluster_sectors;
66
nb_cls_expanded = DIV_ROUND_UP(sector_num + nb_sectors,
67
- iscsilun->cluster_sectors) - cl_num_expanded;
68
+ cluster_sectors) - cl_num_expanded;
69
/* shrink to touch only completely contained clusters */
70
- cl_num_shrunk = DIV_ROUND_UP(sector_num, iscsilun->cluster_sectors);
71
- nb_cls_shrunk = (sector_num + nb_sectors) / iscsilun->cluster_sectors
72
+ cl_num_shrunk = DIV_ROUND_UP(sector_num, cluster_sectors);
73
+ nb_cls_shrunk = (sector_num + nb_sectors) / cluster_sectors
74
- cl_num_shrunk;
75
if (allocated) {
76
bitmap_set(iscsilun->allocmap, cl_num_expanded, nb_cls_expanded);
77
@@ -XXX,XX +XXX,XX @@ iscsi_allocmap_is_allocated(IscsiLun *iscsilun, int64_t sector_num,
78
if (iscsilun->allocmap == NULL) {
79
return true;
80
}
81
- size = DIV_ROUND_UP(sector_num + nb_sectors, iscsilun->cluster_sectors);
82
+ assert(iscsilun->cluster_size);
83
+ size = DIV_ROUND_UP(sector_num + nb_sectors,
84
+ iscsilun->cluster_size >> BDRV_SECTOR_BITS);
85
return !(find_next_bit(iscsilun->allocmap, size,
86
- sector_num / iscsilun->cluster_sectors) == size);
87
+ sector_num * BDRV_SECTOR_SIZE /
88
+ iscsilun->cluster_size) == size);
89
}
90
91
static inline bool iscsi_allocmap_is_valid(IscsiLun *iscsilun,
92
@@ -XXX,XX +XXX,XX @@ static inline bool iscsi_allocmap_is_valid(IscsiLun *iscsilun,
93
if (iscsilun->allocmap_valid == NULL) {
94
return false;
95
}
96
- size = DIV_ROUND_UP(sector_num + nb_sectors, iscsilun->cluster_sectors);
97
+ assert(iscsilun->cluster_size);
98
+ size = DIV_ROUND_UP(sector_num + nb_sectors,
99
+ iscsilun->cluster_size >> BDRV_SECTOR_BITS);
100
return (find_next_zero_bit(iscsilun->allocmap_valid, size,
101
- sector_num / iscsilun->cluster_sectors) == size);
102
+ sector_num * BDRV_SECTOR_SIZE /
103
+ iscsilun->cluster_size) == size);
104
}
105
106
static int coroutine_fn
107
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs,
108
BlockDriverState *file;
109
/* check the block status from the beginning of the cluster
110
* containing the start sector */
111
- int64_t ret = iscsi_co_get_block_status(bs,
112
- sector_num - sector_num % iscsilun->cluster_sectors,
113
- BDRV_REQUEST_MAX_SECTORS, &pnum, &file);
114
+ int cluster_sectors = iscsilun->cluster_size >> BDRV_SECTOR_BITS;
115
+ int head;
116
+ int64_t ret;
117
+
118
+ assert(cluster_sectors);
119
+ head = sector_num % cluster_sectors;
120
+ ret = iscsi_co_get_block_status(bs, sector_num - head,
121
+ BDRV_REQUEST_MAX_SECTORS, &pnum,
122
+ &file);
123
if (ret < 0) {
124
return ret;
125
}
126
/* if the whole request falls into an unallocated area we can avoid
127
- * to read and directly return zeroes instead */
128
- if (ret & BDRV_BLOCK_ZERO &&
129
- pnum >= nb_sectors + sector_num % iscsilun->cluster_sectors) {
130
+ * reading and directly return zeroes instead */
131
+ if (ret & BDRV_BLOCK_ZERO && pnum >= nb_sectors + head) {
132
qemu_iovec_memset(iov, 0, 0x00, iov->size);
133
return 0;
134
}
135
@@ -XXX,XX +XXX,XX @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
136
* reasonable size */
137
if (iscsilun->bl.opt_unmap_gran * iscsilun->block_size >= 4 * 1024 &&
138
iscsilun->bl.opt_unmap_gran * iscsilun->block_size <= 16 * 1024 * 1024) {
139
- iscsilun->cluster_sectors = (iscsilun->bl.opt_unmap_gran *
140
- iscsilun->block_size) >> BDRV_SECTOR_BITS;
141
+ iscsilun->cluster_size = iscsilun->bl.opt_unmap_gran *
142
+ iscsilun->block_size;
143
if (iscsilun->lbprz) {
144
ret = iscsi_allocmap_init(iscsilun, bs->open_flags);
145
}
146
@@ -XXX,XX +XXX,XX @@ static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
147
{
148
IscsiLun *iscsilun = bs->opaque;
149
bdi->unallocated_blocks_are_zero = iscsilun->lbprz;
150
- bdi->cluster_size = iscsilun->cluster_sectors * BDRV_SECTOR_SIZE;
151
+ bdi->cluster_size = iscsilun->cluster_size;
152
return 0;
153
}
154
155
--
30
--
156
2.13.6
31
2.19.1
157
32
158
33
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
While we want machine interfaces like -blockdev and QMP blockdev-add to
2
add as little auto-detection as possible so that management tools are
3
explicit about their needs, -drive is a convenience option for human
4
users. Enabling auto-read-only=on by default there enables users to use
5
read-only images for read-only guest devices without having to specify
6
read-only=on explicitly. If they try to attach the image to a read-write
7
device, they will still get an error message.
2
8
3
We are gradually moving away from sector-based interfaces, towards
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
byte-based. Update the raw driver accordingly.
10
Reviewed-by: Eric Blake <eblake@redhat.com>
11
---
12
blockdev.c | 1 +
13
1 file changed, 1 insertion(+)
5
14
6
Signed-off-by: Eric Blake <eblake@redhat.com>
15
diff --git a/blockdev.c b/blockdev.c
7
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Reviewed-by: Fam Zheng <famz@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
block/raw-format.c | 16 ++++++++--------
12
1 file changed, 8 insertions(+), 8 deletions(-)
13
14
diff --git a/block/raw-format.c b/block/raw-format.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/block/raw-format.c
17
--- a/blockdev.c
17
+++ b/block/raw-format.c
18
+++ b/blockdev.c
18
@@ -XXX,XX +XXX,XX @@ fail:
19
@@ -XXX,XX +XXX,XX @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
19
return ret;
20
qdict_set_default_str(bs_opts, BDRV_OPT_CACHE_NO_FLUSH, "off");
20
}
21
qdict_set_default_str(bs_opts, BDRV_OPT_READ_ONLY,
21
22
read_only ? "on" : "off");
22
-static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
23
+ qdict_set_default_str(bs_opts, BDRV_OPT_AUTO_READ_ONLY, "on");
23
- int64_t sector_num,
24
assert((bdrv_flags & BDRV_O_CACHE_MASK) == 0);
24
- int nb_sectors, int *pnum,
25
25
+static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
26
if (runstate_check(RUN_STATE_INMIGRATE)) {
26
+ bool want_zero, int64_t offset,
27
+ int64_t bytes, int64_t *pnum,
28
+ int64_t *map,
29
BlockDriverState **file)
30
{
31
BDRVRawState *s = bs->opaque;
32
- *pnum = nb_sectors;
33
+ *pnum = bytes;
34
*file = bs->file->bs;
35
- sector_num += s->offset / BDRV_SECTOR_SIZE;
36
- return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
37
- (sector_num << BDRV_SECTOR_BITS);
38
+ *map = offset + s->offset;
39
+ return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID;
40
}
41
42
static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs,
43
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_raw = {
44
.bdrv_co_pwritev = &raw_co_pwritev,
45
.bdrv_co_pwrite_zeroes = &raw_co_pwrite_zeroes,
46
.bdrv_co_pdiscard = &raw_co_pdiscard,
47
- .bdrv_co_get_block_status = &raw_co_get_block_status,
48
+ .bdrv_co_block_status = &raw_co_block_status,
49
.bdrv_truncate = &raw_truncate,
50
.bdrv_getlength = &raw_getlength,
51
.has_variable_length = true,
52
--
27
--
53
2.13.6
28
2.19.1
54
29
55
30
diff view generated by jsdifflib
1
This patch adds test cases for the scenario where blk_aio_flush() is
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
called on a BlockBackend with no root. Calling drain afterwards should
2
Reviewed-by: Eric Blake <eblake@redhat.com>
3
complete the requests with -ENOMEDIUM.
3
---
4
tests/qemu-iotests/232 | 147 +++++++++++++++++++++++++++++++++++++
5
tests/qemu-iotests/232.out | 59 +++++++++++++++
6
tests/qemu-iotests/group | 1 +
7
3 files changed, 207 insertions(+)
8
create mode 100755 tests/qemu-iotests/232
9
create mode 100644 tests/qemu-iotests/232.out
4
10
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
diff --git a/tests/qemu-iotests/232 b/tests/qemu-iotests/232
6
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
new file mode 100755
7
Reviewed-by: Eric Blake <eblake@redhat.com>
13
index XXXXXXX..XXXXXXX
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
--- /dev/null
9
---
15
+++ b/tests/qemu-iotests/232
10
tests/test-block-backend.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++
16
@@ -XXX,XX +XXX,XX @@
11
tests/Makefile.include | 2 ++
17
+#!/bin/bash
12
2 files changed, 84 insertions(+)
18
+#
13
create mode 100644 tests/test-block-backend.c
19
+# Test for auto-read-only
14
20
+#
15
diff --git a/tests/test-block-backend.c b/tests/test-block-backend.c
21
+# Copyright (C) 2018 Red Hat, Inc.
22
+#
23
+# This program is free software; you can redistribute it and/or modify
24
+# it under the terms of the GNU General Public License as published by
25
+# the Free Software Foundation; either version 2 of the License, or
26
+# (at your option) any later version.
27
+#
28
+# This program is distributed in the hope that it will be useful,
29
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
30
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31
+# GNU General Public License for more details.
32
+#
33
+# You should have received a copy of the GNU General Public License
34
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
35
+#
36
+
37
+# creator
38
+owner=kwolf@redhat.com
39
+
40
+seq=`basename $0`
41
+echo "QA output created by $seq"
42
+
43
+here=`pwd`
44
+status=1    # failure is the default!
45
+
46
+_cleanup()
47
+{
48
+ _cleanup_test_img
49
+ rm -f $TEST_IMG.snap
50
+}
51
+trap "_cleanup; exit \$status" 0 1 2 3 15
52
+
53
+# get standard environment, filters and checks
54
+. ./common.rc
55
+. ./common.filter
56
+
57
+_supported_fmt generic
58
+_supported_proto file
59
+_supported_os Linux
60
+
61
+function do_run_qemu()
62
+{
63
+ echo Testing: "$@"
64
+ (
65
+ if ! test -t 0; then
66
+ while read cmd; do
67
+ echo $cmd
68
+ done
69
+ fi
70
+ echo quit
71
+ ) | $QEMU -nographic -monitor stdio -nodefaults "$@"
72
+ echo
73
+}
74
+
75
+function run_qemu()
76
+{
77
+ do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_hmp |
78
+ _filter_generated_node_ids | _filter_imgfmt
79
+}
80
+
81
+function run_qemu_info_block()
82
+{
83
+ echo "info block -n" | run_qemu "$@" | grep -e "(file" -e "QEMU_PROG"
84
+}
85
+
86
+size=128M
87
+
88
+_make_test_img $size
89
+
90
+echo
91
+echo "=== -drive with read-write image: read-only/auto-read-only combinations ==="
92
+echo
93
+
94
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=off
95
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=on
96
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on
97
+echo
98
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=off
99
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=on
100
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off
101
+echo
102
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=off
103
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=on
104
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none
105
+
106
+echo
107
+echo "=== -drive with read-only image: read-only/auto-read-only combinations ==="
108
+echo
109
+
110
+chmod a-w $TEST_IMG
111
+
112
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=off
113
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=on
114
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on
115
+echo
116
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=off
117
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=on
118
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off
119
+echo
120
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=off
121
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=on
122
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none
123
+
124
+echo
125
+echo "=== -blockdev with read-write image: read-only/auto-read-only combinations ==="
126
+echo
127
+
128
+chmod a+w $TEST_IMG
129
+
130
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=off
131
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=on
132
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on
133
+echo
134
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=off
135
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=on
136
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off
137
+echo
138
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=off
139
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=on
140
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0
141
+
142
+echo
143
+echo "=== -blockdev with read-only image: read-only/auto-read-only combinations ==="
144
+echo
145
+
146
+chmod a-w $TEST_IMG
147
+
148
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=off
149
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=on
150
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on
151
+echo
152
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=off
153
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=on
154
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off
155
+echo
156
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=off
157
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=on
158
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0
159
+
160
+# success, all done
161
+echo "*** done"
162
+rm -f $seq.full
163
+status=0
164
diff --git a/tests/qemu-iotests/232.out b/tests/qemu-iotests/232.out
16
new file mode 100644
165
new file mode 100644
17
index XXXXXXX..XXXXXXX
166
index XXXXXXX..XXXXXXX
18
--- /dev/null
167
--- /dev/null
19
+++ b/tests/test-block-backend.c
168
+++ b/tests/qemu-iotests/232.out
20
@@ -XXX,XX +XXX,XX @@
169
@@ -XXX,XX +XXX,XX @@
21
+/*
170
+QA output created by 232
22
+ * BlockBackend tests
171
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
23
+ *
172
+
24
+ * Copyright (c) 2017 Kevin Wolf <kwolf@redhat.com>
173
+=== -drive with read-write image: read-only/auto-read-only combinations ===
25
+ *
174
+
26
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
175
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
27
+ * of this software and associated documentation files (the "Software"), to deal
176
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
28
+ * in the Software without restriction, including without limitation the rights
177
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
29
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
178
+
30
+ * copies of the Software, and to permit persons to whom the Software is
179
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
31
+ * furnished to do so, subject to the following conditions:
180
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
32
+ *
181
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
33
+ * The above copyright notice and this permission notice shall be included in
182
+
34
+ * all copies or substantial portions of the Software.
183
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
35
+ *
184
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
36
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
185
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
37
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
186
+
38
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
187
+=== -drive with read-only image: read-only/auto-read-only combinations ===
39
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
188
+
40
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
189
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
41
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
190
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
42
+ * THE SOFTWARE.
191
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
43
+ */
192
+
44
+
193
+QEMU_PROG: -drive driver=file,file=TEST_DIR/t.IMGFMT,if=none,read-only=off,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
45
+#include "qemu/osdep.h"
194
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
46
+#include "block/block.h"
195
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
47
+#include "sysemu/block-backend.h"
196
+
48
+#include "qapi/error.h"
197
+QEMU_PROG: -drive driver=file,file=TEST_DIR/t.IMGFMT,if=none,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
49
+
198
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
50
+static void test_drain_aio_error_flush_cb(void *opaque, int ret)
199
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
51
+{
200
+
52
+ bool *completed = opaque;
201
+=== -blockdev with read-write image: read-only/auto-read-only combinations ===
53
+
202
+
54
+ g_assert(ret == -ENOMEDIUM);
203
+node0: TEST_DIR/t.IMGFMT (file, read-only)
55
+ *completed = true;
204
+node0: TEST_DIR/t.IMGFMT (file, read-only)
56
+}
205
+node0: TEST_DIR/t.IMGFMT (file, read-only)
57
+
206
+
58
+static void test_drain_aio_error(void)
207
+node0: TEST_DIR/t.IMGFMT (file)
59
+{
208
+node0: TEST_DIR/t.IMGFMT (file)
60
+ BlockBackend *blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
209
+node0: TEST_DIR/t.IMGFMT (file)
61
+ BlockAIOCB *acb;
210
+
62
+ bool completed = false;
211
+node0: TEST_DIR/t.IMGFMT (file)
63
+
212
+node0: TEST_DIR/t.IMGFMT (file)
64
+ acb = blk_aio_flush(blk, test_drain_aio_error_flush_cb, &completed);
213
+node0: TEST_DIR/t.IMGFMT (file)
65
+ g_assert(acb != NULL);
214
+
66
+ g_assert(completed == false);
215
+=== -blockdev with read-only image: read-only/auto-read-only combinations ===
67
+
216
+
68
+ blk_drain(blk);
217
+node0: TEST_DIR/t.IMGFMT (file, read-only)
69
+ g_assert(completed == true);
218
+node0: TEST_DIR/t.IMGFMT (file, read-only)
70
+
219
+node0: TEST_DIR/t.IMGFMT (file, read-only)
71
+ blk_unref(blk);
220
+
72
+}
221
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0,read-only=off,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
73
+
222
+node0: TEST_DIR/t.IMGFMT (file, read-only)
74
+static void test_drain_all_aio_error(void)
223
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0,read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
75
+{
224
+
76
+ BlockBackend *blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
225
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
77
+ BlockAIOCB *acb;
226
+node0: TEST_DIR/t.IMGFMT (file, read-only)
78
+ bool completed = false;
227
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
79
+
228
+*** done
80
+ acb = blk_aio_flush(blk, test_drain_aio_error_flush_cb, &completed);
229
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
81
+ g_assert(acb != NULL);
82
+ g_assert(completed == false);
83
+
84
+ blk_drain_all();
85
+ g_assert(completed == true);
86
+
87
+ blk_unref(blk);
88
+}
89
+
90
+int main(int argc, char **argv)
91
+{
92
+ bdrv_init();
93
+ qemu_init_main_loop(&error_abort);
94
+
95
+ g_test_init(&argc, &argv, NULL);
96
+
97
+ g_test_add_func("/block-backend/drain_aio_error", test_drain_aio_error);
98
+ g_test_add_func("/block-backend/drain_all_aio_error",
99
+ test_drain_all_aio_error);
100
+
101
+ return g_test_run();
102
+}
103
diff --git a/tests/Makefile.include b/tests/Makefile.include
104
index XXXXXXX..XXXXXXX 100644
230
index XXXXXXX..XXXXXXX 100644
105
--- a/tests/Makefile.include
231
--- a/tests/qemu-iotests/group
106
+++ b/tests/Makefile.include
232
+++ b/tests/qemu-iotests/group
107
@@ -XXX,XX +XXX,XX @@ gcov-files-test-hbitmap-y = blockjob.c
233
@@ -XXX,XX +XXX,XX @@
108
check-unit-y += tests/test-bdrv-drain$(EXESUF)
234
227 auto quick
109
check-unit-y += tests/test-blockjob$(EXESUF)
235
229 auto quick
110
check-unit-y += tests/test-blockjob-txn$(EXESUF)
236
231 auto quick
111
+check-unit-y += tests/test-block-backend$(EXESUF)
237
+232 auto quick
112
check-unit-y += tests/test-x86-cpuid$(EXESUF)
113
# all code tested by test-x86-cpuid is inside topology.h
114
gcov-files-test-x86-cpuid-y =
115
@@ -XXX,XX +XXX,XX @@ tests/test-throttle$(EXESUF): tests/test-throttle.o $(test-block-obj-y)
116
tests/test-bdrv-drain$(EXESUF): tests/test-bdrv-drain.o $(test-block-obj-y) $(test-util-obj-y)
117
tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-util-obj-y)
118
tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y)
119
+tests/test-block-backend$(EXESUF): tests/test-block-backend.o $(test-block-obj-y) $(test-util-obj-y)
120
tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y)
121
tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y)
122
tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y) $(test-crypto-obj-y)
123
--
238
--
124
2.13.6
239
2.19.1
125
240
126
241
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
The issue:
3
This adds some whitespace into the option help (including indentation)
4
and puts angle brackets around the type names. Furthermore, the list
5
name is no longer printed as part of every line, but only once in
6
advance, and only if the caller did not print a caption already.
4
7
5
$ qemu-img resize -f qcow2 foo.qcow2
8
This patch also restores the description alignment we had before commit
6
qemu-img: Expecting one image file name
9
9cbef9d68ee1d8d0, just at 24 instead of 16 characters like we used to.
7
Try 'qemu-img --help' for more information
10
This increase is because now we have the type and two spaces of
11
indentation before the description, and with a usual type name length of
12
three chracters, this sums up to eight additional characters -- which
13
means that we now need 24 characters to get the same amount of padding
14
for most options. Also, 24 is a third of 80, which makes it kind of a
15
round number in terminal terms.
8
16
9
So we gave an image file name, but we omitted the length. qemu-img
17
Finally, this patch amends the reference output of iotest 082 to match
10
thinks the last argument is always the size and removes it immediately
18
the changes (and thus makes it pass again).
11
from argv (by decrementing argc), and tries to verify that it is a valid
12
size only at a later point.
13
19
14
So we do not actually know whether that last argument we called "size"
20
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
is indeed a size or whether the user instead forgot to specify that size
21
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
16
but did give a file name.
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
---
24
include/qemu/option.h | 2 +-
25
qemu-img.c | 4 +-
26
util/qemu-option.c | 32 +-
27
tests/qemu-iotests/082.out | 956 ++++++++++++++++++-------------------
28
4 files changed, 507 insertions(+), 487 deletions(-)
17
29
18
Therefore, the error message should be more general.
30
diff --git a/include/qemu/option.h b/include/qemu/option.h
19
31
index XXXXXXX..XXXXXXX 100644
20
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1523458
32
--- a/include/qemu/option.h
21
Signed-off-by: Max Reitz <mreitz@redhat.com>
33
+++ b/include/qemu/option.h
22
Message-id: 20180205162745.23650-1-mreitz@redhat.com
34
@@ -XXX,XX +XXX,XX @@ typedef int (*qemu_opts_loopfunc)(void *opaque, QemuOpts *opts, Error **errp);
23
Reviewed-by: John Snow <jsnow@redhat.com>
35
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func,
24
Reviewed-by: Eric Blake <eblake@redhat.com>
36
void *opaque, Error **errp);
25
Signed-off-by: Max Reitz <mreitz@redhat.com>
37
void qemu_opts_print(QemuOpts *opts, const char *sep);
26
---
38
-void qemu_opts_print_help(QemuOptsList *list);
27
qemu-img.c | 2 +-
39
+void qemu_opts_print_help(QemuOptsList *list, bool print_caption);
28
1 file changed, 1 insertion(+), 1 deletion(-)
40
void qemu_opts_free(QemuOptsList *list);
29
41
QemuOptsList *qemu_opts_append(QemuOptsList *dst, QemuOptsList *list);
42
30
diff --git a/qemu-img.c b/qemu-img.c
43
diff --git a/qemu-img.c b/qemu-img.c
31
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
32
--- a/qemu-img.c
45
--- a/qemu-img.c
33
+++ b/qemu-img.c
46
+++ b/qemu-img.c
34
@@ -XXX,XX +XXX,XX @@ static int img_resize(int argc, char **argv)
47
@@ -XXX,XX +XXX,XX @@ static int print_block_option_help(const char *filename, const char *fmt)
48
}
49
50
printf("Supported options:\n");
51
- qemu_opts_print_help(create_opts);
52
+ qemu_opts_print_help(create_opts, false);
53
qemu_opts_free(create_opts);
54
return 0;
55
}
56
@@ -XXX,XX +XXX,XX @@ static int print_amend_option_help(const char *format)
57
assert(drv->create_opts);
58
59
printf("Creation options for '%s':\n", format);
60
- qemu_opts_print_help(drv->create_opts);
61
+ qemu_opts_print_help(drv->create_opts, false);
62
printf("\nNote that not all of these options may be amendable.\n");
63
return 0;
64
}
65
diff --git a/util/qemu-option.c b/util/qemu-option.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/util/qemu-option.c
68
+++ b/util/qemu-option.c
69
@@ -XXX,XX +XXX,XX @@ static const char *opt_type_to_string(enum QemuOptType type)
70
g_assert_not_reached();
71
}
72
73
-void qemu_opts_print_help(QemuOptsList *list)
74
+/**
75
+ * Print the list of options available in the given list. If
76
+ * @print_caption is true, a caption (including the list name, if it
77
+ * exists) is printed. The options itself will be indented, so
78
+ * @print_caption should only be set to false if the caller prints its
79
+ * own custom caption (so that the indentation makes sense).
80
+ */
81
+void qemu_opts_print_help(QemuOptsList *list, bool print_caption)
82
{
83
QemuOptDesc *desc;
84
int i;
85
@@ -XXX,XX +XXX,XX @@ void qemu_opts_print_help(QemuOptsList *list)
86
desc = list->desc;
87
while (desc && desc->name) {
88
GString *str = g_string_new(NULL);
89
- if (list->name) {
90
- g_string_append_printf(str, "%s.", list->name);
91
- }
92
- g_string_append_printf(str, "%s=%s", desc->name,
93
+ g_string_append_printf(str, " %s=<%s>", desc->name,
94
opt_type_to_string(desc->type));
95
if (desc->help) {
96
+ if (str->len < 24) {
97
+ g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
98
+ }
99
g_string_append_printf(str, " - %s", desc->help);
35
}
100
}
101
g_ptr_array_add(array, g_string_free(str, false));
102
@@ -XXX,XX +XXX,XX @@ void qemu_opts_print_help(QemuOptsList *list)
36
}
103
}
37
if (optind != argc - 1) {
104
38
- error_exit("Expecting one image file name");
105
g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
39
+ error_exit("Expecting image file name and size");
106
+ if (print_caption && array->len > 0) {
107
+ if (list->name) {
108
+ printf("%s options:\n", list->name);
109
+ } else {
110
+ printf("Options:\n");
111
+ }
112
+ } else if (array->len == 0) {
113
+ if (list->name) {
114
+ printf("There are no options for %s.\n", list->name);
115
+ } else {
116
+ printf("No options available.\n");
117
+ }
118
+ }
119
for (i = 0; i < array->len; i++) {
120
printf("%s\n", (char *)array->pdata[i]);
40
}
121
}
41
filename = argv[optind++];
122
@@ -XXX,XX +XXX,XX @@ QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params,
42
123
opts = opts_parse(list, params, permit_abbrev, false, &invalidp, &err);
124
if (err) {
125
if (invalidp && has_help_option(params)) {
126
- qemu_opts_print_help(list);
127
+ qemu_opts_print_help(list, true);
128
error_free(err);
129
} else {
130
error_report_err(err);
131
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
132
index XXXXXXX..XXXXXXX 100644
133
--- a/tests/qemu-iotests/082.out
134
+++ b/tests/qemu-iotests/082.out
135
@@ -XXX,XX +XXX,XX @@ cluster_size: 8192
136
137
Testing: create -f qcow2 -o help TEST_DIR/t.qcow2 128M
138
Supported options:
139
-size Virtual disk size
140
-compat Compatibility level (0.10 or 1.1)
141
-backing_file File name of a base image
142
-backing_fmt Image format of the base image
143
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
144
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
145
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
146
-encrypt.cipher-alg Name of encryption cipher algorithm
147
-encrypt.cipher-mode Name of encryption cipher mode
148
-encrypt.ivgen-alg Name of IV generator algorithm
149
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
150
-encrypt.hash-alg Name of encryption hash algorithm
151
-encrypt.iter-time Time to spend in PBKDF in milliseconds
152
-cluster_size qcow2 cluster size
153
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
154
-lazy_refcounts Postpone refcount updates
155
-refcount_bits Width of a reference count entry in bits
156
-nocow Turn off copy-on-write (valid only on btrfs)
157
+ backing_file=<str> - File name of a base image
158
+ backing_fmt=<str> - Image format of the base image
159
+ cluster_size=<size> - qcow2 cluster size
160
+ compat=<str> - Compatibility level (0.10 or 1.1)
161
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
162
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
163
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
164
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
165
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
166
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
167
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
168
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
169
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
170
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
171
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
172
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
173
+ refcount_bits=<num> - Width of a reference count entry in bits
174
+ size=<size> - Virtual disk size
175
176
Testing: create -f qcow2 -o ? TEST_DIR/t.qcow2 128M
177
Supported options:
178
-size Virtual disk size
179
-compat Compatibility level (0.10 or 1.1)
180
-backing_file File name of a base image
181
-backing_fmt Image format of the base image
182
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
183
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
184
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
185
-encrypt.cipher-alg Name of encryption cipher algorithm
186
-encrypt.cipher-mode Name of encryption cipher mode
187
-encrypt.ivgen-alg Name of IV generator algorithm
188
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
189
-encrypt.hash-alg Name of encryption hash algorithm
190
-encrypt.iter-time Time to spend in PBKDF in milliseconds
191
-cluster_size qcow2 cluster size
192
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
193
-lazy_refcounts Postpone refcount updates
194
-refcount_bits Width of a reference count entry in bits
195
-nocow Turn off copy-on-write (valid only on btrfs)
196
+ backing_file=<str> - File name of a base image
197
+ backing_fmt=<str> - Image format of the base image
198
+ cluster_size=<size> - qcow2 cluster size
199
+ compat=<str> - Compatibility level (0.10 or 1.1)
200
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
201
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
202
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
203
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
204
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
205
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
206
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
207
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
208
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
209
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
210
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
211
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
212
+ refcount_bits=<num> - Width of a reference count entry in bits
213
+ size=<size> - Virtual disk size
214
215
Testing: create -f qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2 128M
216
Supported options:
217
-size Virtual disk size
218
-compat Compatibility level (0.10 or 1.1)
219
-backing_file File name of a base image
220
-backing_fmt Image format of the base image
221
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
222
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
223
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
224
-encrypt.cipher-alg Name of encryption cipher algorithm
225
-encrypt.cipher-mode Name of encryption cipher mode
226
-encrypt.ivgen-alg Name of IV generator algorithm
227
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
228
-encrypt.hash-alg Name of encryption hash algorithm
229
-encrypt.iter-time Time to spend in PBKDF in milliseconds
230
-cluster_size qcow2 cluster size
231
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
232
-lazy_refcounts Postpone refcount updates
233
-refcount_bits Width of a reference count entry in bits
234
-nocow Turn off copy-on-write (valid only on btrfs)
235
+ backing_file=<str> - File name of a base image
236
+ backing_fmt=<str> - Image format of the base image
237
+ cluster_size=<size> - qcow2 cluster size
238
+ compat=<str> - Compatibility level (0.10 or 1.1)
239
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
240
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
241
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
242
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
243
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
244
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
245
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
246
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
247
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
248
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
249
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
250
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
251
+ refcount_bits=<num> - Width of a reference count entry in bits
252
+ size=<size> - Virtual disk size
253
254
Testing: create -f qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2 128M
255
Supported options:
256
-size Virtual disk size
257
-compat Compatibility level (0.10 or 1.1)
258
-backing_file File name of a base image
259
-backing_fmt Image format of the base image
260
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
261
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
262
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
263
-encrypt.cipher-alg Name of encryption cipher algorithm
264
-encrypt.cipher-mode Name of encryption cipher mode
265
-encrypt.ivgen-alg Name of IV generator algorithm
266
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
267
-encrypt.hash-alg Name of encryption hash algorithm
268
-encrypt.iter-time Time to spend in PBKDF in milliseconds
269
-cluster_size qcow2 cluster size
270
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
271
-lazy_refcounts Postpone refcount updates
272
-refcount_bits Width of a reference count entry in bits
273
-nocow Turn off copy-on-write (valid only on btrfs)
274
+ backing_file=<str> - File name of a base image
275
+ backing_fmt=<str> - Image format of the base image
276
+ cluster_size=<size> - qcow2 cluster size
277
+ compat=<str> - Compatibility level (0.10 or 1.1)
278
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
279
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
280
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
281
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
282
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
283
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
284
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
285
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
286
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
287
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
288
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
289
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
290
+ refcount_bits=<num> - Width of a reference count entry in bits
291
+ size=<size> - Virtual disk size
292
293
Testing: create -f qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2 128M
294
Supported options:
295
-size Virtual disk size
296
-compat Compatibility level (0.10 or 1.1)
297
-backing_file File name of a base image
298
-backing_fmt Image format of the base image
299
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
300
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
301
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
302
-encrypt.cipher-alg Name of encryption cipher algorithm
303
-encrypt.cipher-mode Name of encryption cipher mode
304
-encrypt.ivgen-alg Name of IV generator algorithm
305
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
306
-encrypt.hash-alg Name of encryption hash algorithm
307
-encrypt.iter-time Time to spend in PBKDF in milliseconds
308
-cluster_size qcow2 cluster size
309
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
310
-lazy_refcounts Postpone refcount updates
311
-refcount_bits Width of a reference count entry in bits
312
-nocow Turn off copy-on-write (valid only on btrfs)
313
+ backing_file=<str> - File name of a base image
314
+ backing_fmt=<str> - Image format of the base image
315
+ cluster_size=<size> - qcow2 cluster size
316
+ compat=<str> - Compatibility level (0.10 or 1.1)
317
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
318
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
319
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
320
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
321
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
322
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
323
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
324
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
325
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
326
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
327
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
328
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
329
+ refcount_bits=<num> - Width of a reference count entry in bits
330
+ size=<size> - Virtual disk size
331
332
Testing: create -f qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2 128M
333
Supported options:
334
-size Virtual disk size
335
-compat Compatibility level (0.10 or 1.1)
336
-backing_file File name of a base image
337
-backing_fmt Image format of the base image
338
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
339
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
340
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
341
-encrypt.cipher-alg Name of encryption cipher algorithm
342
-encrypt.cipher-mode Name of encryption cipher mode
343
-encrypt.ivgen-alg Name of IV generator algorithm
344
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
345
-encrypt.hash-alg Name of encryption hash algorithm
346
-encrypt.iter-time Time to spend in PBKDF in milliseconds
347
-cluster_size qcow2 cluster size
348
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
349
-lazy_refcounts Postpone refcount updates
350
-refcount_bits Width of a reference count entry in bits
351
-nocow Turn off copy-on-write (valid only on btrfs)
352
+ backing_file=<str> - File name of a base image
353
+ backing_fmt=<str> - Image format of the base image
354
+ cluster_size=<size> - qcow2 cluster size
355
+ compat=<str> - Compatibility level (0.10 or 1.1)
356
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
357
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
358
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
359
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
360
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
361
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
362
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
363
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
364
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
365
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
366
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
367
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
368
+ refcount_bits=<num> - Width of a reference count entry in bits
369
+ size=<size> - Virtual disk size
370
371
Testing: create -f qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2 128M
372
Supported options:
373
-size Virtual disk size
374
-compat Compatibility level (0.10 or 1.1)
375
-backing_file File name of a base image
376
-backing_fmt Image format of the base image
377
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
378
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
379
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
380
-encrypt.cipher-alg Name of encryption cipher algorithm
381
-encrypt.cipher-mode Name of encryption cipher mode
382
-encrypt.ivgen-alg Name of IV generator algorithm
383
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
384
-encrypt.hash-alg Name of encryption hash algorithm
385
-encrypt.iter-time Time to spend in PBKDF in milliseconds
386
-cluster_size qcow2 cluster size
387
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
388
-lazy_refcounts Postpone refcount updates
389
-refcount_bits Width of a reference count entry in bits
390
-nocow Turn off copy-on-write (valid only on btrfs)
391
+ backing_file=<str> - File name of a base image
392
+ backing_fmt=<str> - Image format of the base image
393
+ cluster_size=<size> - qcow2 cluster size
394
+ compat=<str> - Compatibility level (0.10 or 1.1)
395
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
396
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
397
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
398
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
399
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
400
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
401
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
402
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
403
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
404
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
405
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
406
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
407
+ refcount_bits=<num> - Width of a reference count entry in bits
408
+ size=<size> - Virtual disk size
409
410
Testing: create -f qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2 128M
411
Supported options:
412
-size Virtual disk size
413
-compat Compatibility level (0.10 or 1.1)
414
-backing_file File name of a base image
415
-backing_fmt Image format of the base image
416
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
417
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
418
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
419
-encrypt.cipher-alg Name of encryption cipher algorithm
420
-encrypt.cipher-mode Name of encryption cipher mode
421
-encrypt.ivgen-alg Name of IV generator algorithm
422
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
423
-encrypt.hash-alg Name of encryption hash algorithm
424
-encrypt.iter-time Time to spend in PBKDF in milliseconds
425
-cluster_size qcow2 cluster size
426
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
427
-lazy_refcounts Postpone refcount updates
428
-refcount_bits Width of a reference count entry in bits
429
-nocow Turn off copy-on-write (valid only on btrfs)
430
+ backing_file=<str> - File name of a base image
431
+ backing_fmt=<str> - Image format of the base image
432
+ cluster_size=<size> - qcow2 cluster size
433
+ compat=<str> - Compatibility level (0.10 or 1.1)
434
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
435
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
436
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
437
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
438
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
439
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
440
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
441
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
442
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
443
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
444
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
445
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
446
+ refcount_bits=<num> - Width of a reference count entry in bits
447
+ size=<size> - Virtual disk size
448
449
Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 128M
450
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,help cluster_size=65536 lazy_refcounts=off refcount_bits=16
451
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
452
453
Testing: create -f qcow2 -o help
454
Supported options:
455
-size Virtual disk size
456
-compat Compatibility level (0.10 or 1.1)
457
-backing_file File name of a base image
458
-backing_fmt Image format of the base image
459
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
460
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
461
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
462
-encrypt.cipher-alg Name of encryption cipher algorithm
463
-encrypt.cipher-mode Name of encryption cipher mode
464
-encrypt.ivgen-alg Name of IV generator algorithm
465
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
466
-encrypt.hash-alg Name of encryption hash algorithm
467
-encrypt.iter-time Time to spend in PBKDF in milliseconds
468
-cluster_size qcow2 cluster size
469
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
470
-lazy_refcounts Postpone refcount updates
471
-refcount_bits Width of a reference count entry in bits
472
+ backing_file=<str> - File name of a base image
473
+ backing_fmt=<str> - Image format of the base image
474
+ cluster_size=<size> - qcow2 cluster size
475
+ compat=<str> - Compatibility level (0.10 or 1.1)
476
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
477
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
478
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
479
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
480
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
481
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
482
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
483
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
484
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
485
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
486
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
487
+ refcount_bits=<num> - Width of a reference count entry in bits
488
+ size=<size> - Virtual disk size
489
490
Testing: create -o help
491
Supported options:
492
-size Virtual disk size
493
+ size=<size> - Virtual disk size
494
495
Testing: create -f bochs -o help
496
qemu-img: Format driver 'bochs' does not support image creation
497
@@ -XXX,XX +XXX,XX @@ cluster_size: 8192
498
499
Testing: convert -O qcow2 -o help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
500
Supported options:
501
-size Virtual disk size
502
-compat Compatibility level (0.10 or 1.1)
503
-backing_file File name of a base image
504
-backing_fmt Image format of the base image
505
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
506
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
507
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
508
-encrypt.cipher-alg Name of encryption cipher algorithm
509
-encrypt.cipher-mode Name of encryption cipher mode
510
-encrypt.ivgen-alg Name of IV generator algorithm
511
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
512
-encrypt.hash-alg Name of encryption hash algorithm
513
-encrypt.iter-time Time to spend in PBKDF in milliseconds
514
-cluster_size qcow2 cluster size
515
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
516
-lazy_refcounts Postpone refcount updates
517
-refcount_bits Width of a reference count entry in bits
518
-nocow Turn off copy-on-write (valid only on btrfs)
519
+ backing_file=<str> - File name of a base image
520
+ backing_fmt=<str> - Image format of the base image
521
+ cluster_size=<size> - qcow2 cluster size
522
+ compat=<str> - Compatibility level (0.10 or 1.1)
523
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
524
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
525
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
526
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
527
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
528
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
529
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
530
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
531
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
532
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
533
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
534
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
535
+ refcount_bits=<num> - Width of a reference count entry in bits
536
+ size=<size> - Virtual disk size
537
538
Testing: convert -O qcow2 -o ? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
539
Supported options:
540
-size Virtual disk size
541
-compat Compatibility level (0.10 or 1.1)
542
-backing_file File name of a base image
543
-backing_fmt Image format of the base image
544
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
545
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
546
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
547
-encrypt.cipher-alg Name of encryption cipher algorithm
548
-encrypt.cipher-mode Name of encryption cipher mode
549
-encrypt.ivgen-alg Name of IV generator algorithm
550
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
551
-encrypt.hash-alg Name of encryption hash algorithm
552
-encrypt.iter-time Time to spend in PBKDF in milliseconds
553
-cluster_size qcow2 cluster size
554
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
555
-lazy_refcounts Postpone refcount updates
556
-refcount_bits Width of a reference count entry in bits
557
-nocow Turn off copy-on-write (valid only on btrfs)
558
+ backing_file=<str> - File name of a base image
559
+ backing_fmt=<str> - Image format of the base image
560
+ cluster_size=<size> - qcow2 cluster size
561
+ compat=<str> - Compatibility level (0.10 or 1.1)
562
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
563
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
564
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
565
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
566
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
567
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
568
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
569
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
570
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
571
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
572
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
573
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
574
+ refcount_bits=<num> - Width of a reference count entry in bits
575
+ size=<size> - Virtual disk size
576
577
Testing: convert -O qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
578
Supported options:
579
-size Virtual disk size
580
-compat Compatibility level (0.10 or 1.1)
581
-backing_file File name of a base image
582
-backing_fmt Image format of the base image
583
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
584
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
585
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
586
-encrypt.cipher-alg Name of encryption cipher algorithm
587
-encrypt.cipher-mode Name of encryption cipher mode
588
-encrypt.ivgen-alg Name of IV generator algorithm
589
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
590
-encrypt.hash-alg Name of encryption hash algorithm
591
-encrypt.iter-time Time to spend in PBKDF in milliseconds
592
-cluster_size qcow2 cluster size
593
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
594
-lazy_refcounts Postpone refcount updates
595
-refcount_bits Width of a reference count entry in bits
596
-nocow Turn off copy-on-write (valid only on btrfs)
597
+ backing_file=<str> - File name of a base image
598
+ backing_fmt=<str> - Image format of the base image
599
+ cluster_size=<size> - qcow2 cluster size
600
+ compat=<str> - Compatibility level (0.10 or 1.1)
601
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
602
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
603
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
604
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
605
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
606
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
607
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
608
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
609
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
610
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
611
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
612
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
613
+ refcount_bits=<num> - Width of a reference count entry in bits
614
+ size=<size> - Virtual disk size
615
616
Testing: convert -O qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
617
Supported options:
618
-size Virtual disk size
619
-compat Compatibility level (0.10 or 1.1)
620
-backing_file File name of a base image
621
-backing_fmt Image format of the base image
622
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
623
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
624
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
625
-encrypt.cipher-alg Name of encryption cipher algorithm
626
-encrypt.cipher-mode Name of encryption cipher mode
627
-encrypt.ivgen-alg Name of IV generator algorithm
628
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
629
-encrypt.hash-alg Name of encryption hash algorithm
630
-encrypt.iter-time Time to spend in PBKDF in milliseconds
631
-cluster_size qcow2 cluster size
632
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
633
-lazy_refcounts Postpone refcount updates
634
-refcount_bits Width of a reference count entry in bits
635
-nocow Turn off copy-on-write (valid only on btrfs)
636
+ backing_file=<str> - File name of a base image
637
+ backing_fmt=<str> - Image format of the base image
638
+ cluster_size=<size> - qcow2 cluster size
639
+ compat=<str> - Compatibility level (0.10 or 1.1)
640
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
641
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
642
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
643
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
644
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
645
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
646
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
647
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
648
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
649
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
650
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
651
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
652
+ refcount_bits=<num> - Width of a reference count entry in bits
653
+ size=<size> - Virtual disk size
654
655
Testing: convert -O qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
656
Supported options:
657
-size Virtual disk size
658
-compat Compatibility level (0.10 or 1.1)
659
-backing_file File name of a base image
660
-backing_fmt Image format of the base image
661
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
662
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
663
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
664
-encrypt.cipher-alg Name of encryption cipher algorithm
665
-encrypt.cipher-mode Name of encryption cipher mode
666
-encrypt.ivgen-alg Name of IV generator algorithm
667
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
668
-encrypt.hash-alg Name of encryption hash algorithm
669
-encrypt.iter-time Time to spend in PBKDF in milliseconds
670
-cluster_size qcow2 cluster size
671
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
672
-lazy_refcounts Postpone refcount updates
673
-refcount_bits Width of a reference count entry in bits
674
-nocow Turn off copy-on-write (valid only on btrfs)
675
+ backing_file=<str> - File name of a base image
676
+ backing_fmt=<str> - Image format of the base image
677
+ cluster_size=<size> - qcow2 cluster size
678
+ compat=<str> - Compatibility level (0.10 or 1.1)
679
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
680
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
681
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
682
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
683
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
684
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
685
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
686
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
687
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
688
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
689
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
690
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
691
+ refcount_bits=<num> - Width of a reference count entry in bits
692
+ size=<size> - Virtual disk size
693
694
Testing: convert -O qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
695
Supported options:
696
-size Virtual disk size
697
-compat Compatibility level (0.10 or 1.1)
698
-backing_file File name of a base image
699
-backing_fmt Image format of the base image
700
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
701
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
702
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
703
-encrypt.cipher-alg Name of encryption cipher algorithm
704
-encrypt.cipher-mode Name of encryption cipher mode
705
-encrypt.ivgen-alg Name of IV generator algorithm
706
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
707
-encrypt.hash-alg Name of encryption hash algorithm
708
-encrypt.iter-time Time to spend in PBKDF in milliseconds
709
-cluster_size qcow2 cluster size
710
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
711
-lazy_refcounts Postpone refcount updates
712
-refcount_bits Width of a reference count entry in bits
713
-nocow Turn off copy-on-write (valid only on btrfs)
714
+ backing_file=<str> - File name of a base image
715
+ backing_fmt=<str> - Image format of the base image
716
+ cluster_size=<size> - qcow2 cluster size
717
+ compat=<str> - Compatibility level (0.10 or 1.1)
718
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
719
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
720
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
721
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
722
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
723
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
724
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
725
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
726
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
727
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
728
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
729
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
730
+ refcount_bits=<num> - Width of a reference count entry in bits
731
+ size=<size> - Virtual disk size
732
733
Testing: convert -O qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
734
Supported options:
735
-size Virtual disk size
736
-compat Compatibility level (0.10 or 1.1)
737
-backing_file File name of a base image
738
-backing_fmt Image format of the base image
739
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
740
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
741
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
742
-encrypt.cipher-alg Name of encryption cipher algorithm
743
-encrypt.cipher-mode Name of encryption cipher mode
744
-encrypt.ivgen-alg Name of IV generator algorithm
745
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
746
-encrypt.hash-alg Name of encryption hash algorithm
747
-encrypt.iter-time Time to spend in PBKDF in milliseconds
748
-cluster_size qcow2 cluster size
749
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
750
-lazy_refcounts Postpone refcount updates
751
-refcount_bits Width of a reference count entry in bits
752
-nocow Turn off copy-on-write (valid only on btrfs)
753
+ backing_file=<str> - File name of a base image
754
+ backing_fmt=<str> - Image format of the base image
755
+ cluster_size=<size> - qcow2 cluster size
756
+ compat=<str> - Compatibility level (0.10 or 1.1)
757
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
758
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
759
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
760
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
761
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
762
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
763
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
764
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
765
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
766
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
767
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
768
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
769
+ refcount_bits=<num> - Width of a reference count entry in bits
770
+ size=<size> - Virtual disk size
771
772
Testing: convert -O qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
773
Supported options:
774
-size Virtual disk size
775
-compat Compatibility level (0.10 or 1.1)
776
-backing_file File name of a base image
777
-backing_fmt Image format of the base image
778
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
779
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
780
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
781
-encrypt.cipher-alg Name of encryption cipher algorithm
782
-encrypt.cipher-mode Name of encryption cipher mode
783
-encrypt.ivgen-alg Name of IV generator algorithm
784
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
785
-encrypt.hash-alg Name of encryption hash algorithm
786
-encrypt.iter-time Time to spend in PBKDF in milliseconds
787
-cluster_size qcow2 cluster size
788
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
789
-lazy_refcounts Postpone refcount updates
790
-refcount_bits Width of a reference count entry in bits
791
-nocow Turn off copy-on-write (valid only on btrfs)
792
+ backing_file=<str> - File name of a base image
793
+ backing_fmt=<str> - Image format of the base image
794
+ cluster_size=<size> - qcow2 cluster size
795
+ compat=<str> - Compatibility level (0.10 or 1.1)
796
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
797
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
798
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
799
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
800
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
801
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
802
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
803
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
804
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
805
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
806
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
807
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
808
+ refcount_bits=<num> - Width of a reference count entry in bits
809
+ size=<size> - Virtual disk size
810
811
Testing: convert -O qcow2 -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
812
qemu-img: Could not open 'TEST_DIR/t.qcow2.base': Could not open backing file: Could not open 'TEST_DIR/t.qcow2,help': No such file or directory
813
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
814
815
Testing: convert -O qcow2 -o help
816
Supported options:
817
-size Virtual disk size
818
-compat Compatibility level (0.10 or 1.1)
819
-backing_file File name of a base image
820
-backing_fmt Image format of the base image
821
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
822
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
823
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
824
-encrypt.cipher-alg Name of encryption cipher algorithm
825
-encrypt.cipher-mode Name of encryption cipher mode
826
-encrypt.ivgen-alg Name of IV generator algorithm
827
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
828
-encrypt.hash-alg Name of encryption hash algorithm
829
-encrypt.iter-time Time to spend in PBKDF in milliseconds
830
-cluster_size qcow2 cluster size
831
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
832
-lazy_refcounts Postpone refcount updates
833
-refcount_bits Width of a reference count entry in bits
834
+ backing_file=<str> - File name of a base image
835
+ backing_fmt=<str> - Image format of the base image
836
+ cluster_size=<size> - qcow2 cluster size
837
+ compat=<str> - Compatibility level (0.10 or 1.1)
838
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
839
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
840
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
841
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
842
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
843
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
844
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
845
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
846
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
847
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
848
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
849
+ refcount_bits=<num> - Width of a reference count entry in bits
850
+ size=<size> - Virtual disk size
851
852
Testing: convert -o help
853
Supported options:
854
-size Virtual disk size
855
+ size=<size> - Virtual disk size
856
857
Testing: convert -O bochs -o help
858
qemu-img: Format driver 'bochs' does not support image creation
859
@@ -XXX,XX +XXX,XX @@ cluster_size: 65536
860
861
Testing: amend -f qcow2 -o help TEST_DIR/t.qcow2
862
Creation options for 'qcow2':
863
-size Virtual disk size
864
-compat Compatibility level (0.10 or 1.1)
865
-backing_file File name of a base image
866
-backing_fmt Image format of the base image
867
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
868
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
869
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
870
-encrypt.cipher-alg Name of encryption cipher algorithm
871
-encrypt.cipher-mode Name of encryption cipher mode
872
-encrypt.ivgen-alg Name of IV generator algorithm
873
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
874
-encrypt.hash-alg Name of encryption hash algorithm
875
-encrypt.iter-time Time to spend in PBKDF in milliseconds
876
-cluster_size qcow2 cluster size
877
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
878
-lazy_refcounts Postpone refcount updates
879
-refcount_bits Width of a reference count entry in bits
880
+ backing_file=<str> - File name of a base image
881
+ backing_fmt=<str> - Image format of the base image
882
+ cluster_size=<size> - qcow2 cluster size
883
+ compat=<str> - Compatibility level (0.10 or 1.1)
884
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
885
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
886
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
887
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
888
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
889
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
890
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
891
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
892
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
893
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
894
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
895
+ refcount_bits=<num> - Width of a reference count entry in bits
896
+ size=<size> - Virtual disk size
897
898
Note that not all of these options may be amendable.
899
900
Testing: amend -f qcow2 -o ? TEST_DIR/t.qcow2
901
Creation options for 'qcow2':
902
-size Virtual disk size
903
-compat Compatibility level (0.10 or 1.1)
904
-backing_file File name of a base image
905
-backing_fmt Image format of the base image
906
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
907
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
908
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
909
-encrypt.cipher-alg Name of encryption cipher algorithm
910
-encrypt.cipher-mode Name of encryption cipher mode
911
-encrypt.ivgen-alg Name of IV generator algorithm
912
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
913
-encrypt.hash-alg Name of encryption hash algorithm
914
-encrypt.iter-time Time to spend in PBKDF in milliseconds
915
-cluster_size qcow2 cluster size
916
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
917
-lazy_refcounts Postpone refcount updates
918
-refcount_bits Width of a reference count entry in bits
919
+ backing_file=<str> - File name of a base image
920
+ backing_fmt=<str> - Image format of the base image
921
+ cluster_size=<size> - qcow2 cluster size
922
+ compat=<str> - Compatibility level (0.10 or 1.1)
923
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
924
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
925
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
926
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
927
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
928
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
929
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
930
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
931
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
932
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
933
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
934
+ refcount_bits=<num> - Width of a reference count entry in bits
935
+ size=<size> - Virtual disk size
936
937
Note that not all of these options may be amendable.
938
939
Testing: amend -f qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2
940
Creation options for 'qcow2':
941
-size Virtual disk size
942
-compat Compatibility level (0.10 or 1.1)
943
-backing_file File name of a base image
944
-backing_fmt Image format of the base image
945
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
946
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
947
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
948
-encrypt.cipher-alg Name of encryption cipher algorithm
949
-encrypt.cipher-mode Name of encryption cipher mode
950
-encrypt.ivgen-alg Name of IV generator algorithm
951
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
952
-encrypt.hash-alg Name of encryption hash algorithm
953
-encrypt.iter-time Time to spend in PBKDF in milliseconds
954
-cluster_size qcow2 cluster size
955
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
956
-lazy_refcounts Postpone refcount updates
957
-refcount_bits Width of a reference count entry in bits
958
+ backing_file=<str> - File name of a base image
959
+ backing_fmt=<str> - Image format of the base image
960
+ cluster_size=<size> - qcow2 cluster size
961
+ compat=<str> - Compatibility level (0.10 or 1.1)
962
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
963
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
964
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
965
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
966
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
967
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
968
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
969
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
970
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
971
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
972
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
973
+ refcount_bits=<num> - Width of a reference count entry in bits
974
+ size=<size> - Virtual disk size
975
976
Note that not all of these options may be amendable.
977
978
Testing: amend -f qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2
979
Creation options for 'qcow2':
980
-size Virtual disk size
981
-compat Compatibility level (0.10 or 1.1)
982
-backing_file File name of a base image
983
-backing_fmt Image format of the base image
984
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
985
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
986
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
987
-encrypt.cipher-alg Name of encryption cipher algorithm
988
-encrypt.cipher-mode Name of encryption cipher mode
989
-encrypt.ivgen-alg Name of IV generator algorithm
990
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
991
-encrypt.hash-alg Name of encryption hash algorithm
992
-encrypt.iter-time Time to spend in PBKDF in milliseconds
993
-cluster_size qcow2 cluster size
994
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
995
-lazy_refcounts Postpone refcount updates
996
-refcount_bits Width of a reference count entry in bits
997
+ backing_file=<str> - File name of a base image
998
+ backing_fmt=<str> - Image format of the base image
999
+ cluster_size=<size> - qcow2 cluster size
1000
+ compat=<str> - Compatibility level (0.10 or 1.1)
1001
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1002
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1003
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1004
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1005
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1006
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1007
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1008
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1009
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1010
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1011
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1012
+ refcount_bits=<num> - Width of a reference count entry in bits
1013
+ size=<size> - Virtual disk size
1014
1015
Note that not all of these options may be amendable.
1016
1017
Testing: amend -f qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2
1018
Creation options for 'qcow2':
1019
-size Virtual disk size
1020
-compat Compatibility level (0.10 or 1.1)
1021
-backing_file File name of a base image
1022
-backing_fmt Image format of the base image
1023
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1024
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1025
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1026
-encrypt.cipher-alg Name of encryption cipher algorithm
1027
-encrypt.cipher-mode Name of encryption cipher mode
1028
-encrypt.ivgen-alg Name of IV generator algorithm
1029
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1030
-encrypt.hash-alg Name of encryption hash algorithm
1031
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1032
-cluster_size qcow2 cluster size
1033
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1034
-lazy_refcounts Postpone refcount updates
1035
-refcount_bits Width of a reference count entry in bits
1036
+ backing_file=<str> - File name of a base image
1037
+ backing_fmt=<str> - Image format of the base image
1038
+ cluster_size=<size> - qcow2 cluster size
1039
+ compat=<str> - Compatibility level (0.10 or 1.1)
1040
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1041
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1042
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1043
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1044
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1045
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1046
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1047
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1048
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1049
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1050
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1051
+ refcount_bits=<num> - Width of a reference count entry in bits
1052
+ size=<size> - Virtual disk size
1053
1054
Note that not all of these options may be amendable.
1055
1056
Testing: amend -f qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2
1057
Creation options for 'qcow2':
1058
-size Virtual disk size
1059
-compat Compatibility level (0.10 or 1.1)
1060
-backing_file File name of a base image
1061
-backing_fmt Image format of the base image
1062
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1063
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1064
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1065
-encrypt.cipher-alg Name of encryption cipher algorithm
1066
-encrypt.cipher-mode Name of encryption cipher mode
1067
-encrypt.ivgen-alg Name of IV generator algorithm
1068
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1069
-encrypt.hash-alg Name of encryption hash algorithm
1070
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1071
-cluster_size qcow2 cluster size
1072
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1073
-lazy_refcounts Postpone refcount updates
1074
-refcount_bits Width of a reference count entry in bits
1075
+ backing_file=<str> - File name of a base image
1076
+ backing_fmt=<str> - Image format of the base image
1077
+ cluster_size=<size> - qcow2 cluster size
1078
+ compat=<str> - Compatibility level (0.10 or 1.1)
1079
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1080
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1081
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1082
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1083
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1084
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1085
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1086
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1087
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1088
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1089
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1090
+ refcount_bits=<num> - Width of a reference count entry in bits
1091
+ size=<size> - Virtual disk size
1092
1093
Note that not all of these options may be amendable.
1094
1095
Testing: amend -f qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2
1096
Creation options for 'qcow2':
1097
-size Virtual disk size
1098
-compat Compatibility level (0.10 or 1.1)
1099
-backing_file File name of a base image
1100
-backing_fmt Image format of the base image
1101
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1102
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1103
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1104
-encrypt.cipher-alg Name of encryption cipher algorithm
1105
-encrypt.cipher-mode Name of encryption cipher mode
1106
-encrypt.ivgen-alg Name of IV generator algorithm
1107
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1108
-encrypt.hash-alg Name of encryption hash algorithm
1109
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1110
-cluster_size qcow2 cluster size
1111
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1112
-lazy_refcounts Postpone refcount updates
1113
-refcount_bits Width of a reference count entry in bits
1114
+ backing_file=<str> - File name of a base image
1115
+ backing_fmt=<str> - Image format of the base image
1116
+ cluster_size=<size> - qcow2 cluster size
1117
+ compat=<str> - Compatibility level (0.10 or 1.1)
1118
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1119
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1120
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1121
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1122
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1123
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1124
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1125
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1126
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1127
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1128
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1129
+ refcount_bits=<num> - Width of a reference count entry in bits
1130
+ size=<size> - Virtual disk size
1131
1132
Note that not all of these options may be amendable.
1133
1134
Testing: amend -f qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2
1135
Creation options for 'qcow2':
1136
-size Virtual disk size
1137
-compat Compatibility level (0.10 or 1.1)
1138
-backing_file File name of a base image
1139
-backing_fmt Image format of the base image
1140
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1141
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1142
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1143
-encrypt.cipher-alg Name of encryption cipher algorithm
1144
-encrypt.cipher-mode Name of encryption cipher mode
1145
-encrypt.ivgen-alg Name of IV generator algorithm
1146
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1147
-encrypt.hash-alg Name of encryption hash algorithm
1148
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1149
-cluster_size qcow2 cluster size
1150
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1151
-lazy_refcounts Postpone refcount updates
1152
-refcount_bits Width of a reference count entry in bits
1153
+ backing_file=<str> - File name of a base image
1154
+ backing_fmt=<str> - Image format of the base image
1155
+ cluster_size=<size> - qcow2 cluster size
1156
+ compat=<str> - Compatibility level (0.10 or 1.1)
1157
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1158
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1159
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1160
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1161
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1162
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1163
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1164
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1165
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1166
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1167
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1168
+ refcount_bits=<num> - Width of a reference count entry in bits
1169
+ size=<size> - Virtual disk size
1170
1171
Note that not all of these options may be amendable.
1172
1173
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
1174
1175
Testing: amend -f qcow2 -o help
1176
Creation options for 'qcow2':
1177
-size Virtual disk size
1178
-compat Compatibility level (0.10 or 1.1)
1179
-backing_file File name of a base image
1180
-backing_fmt Image format of the base image
1181
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1182
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1183
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1184
-encrypt.cipher-alg Name of encryption cipher algorithm
1185
-encrypt.cipher-mode Name of encryption cipher mode
1186
-encrypt.ivgen-alg Name of IV generator algorithm
1187
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1188
-encrypt.hash-alg Name of encryption hash algorithm
1189
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1190
-cluster_size qcow2 cluster size
1191
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1192
-lazy_refcounts Postpone refcount updates
1193
-refcount_bits Width of a reference count entry in bits
1194
+ backing_file=<str> - File name of a base image
1195
+ backing_fmt=<str> - Image format of the base image
1196
+ cluster_size=<size> - qcow2 cluster size
1197
+ compat=<str> - Compatibility level (0.10 or 1.1)
1198
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1199
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1200
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1201
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1202
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1203
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1204
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1205
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1206
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1207
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1208
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1209
+ refcount_bits=<num> - Width of a reference count entry in bits
1210
+ size=<size> - Virtual disk size
1211
1212
Note that not all of these options may be amendable.
1213
1214
Testing: convert -o help
1215
Supported options:
1216
-size Virtual disk size
1217
+ size=<size> - Virtual disk size
1218
1219
Testing: amend -f bochs -o help
1220
qemu-img: Format driver 'bochs' does not support option amendment
43
--
1221
--
44
2.13.6
1222
2.19.1
45
1223
46
1224
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
libssh2 does not seem to offer real truncation support, so we can only
3
Following the example of qemu_opts_print_help(), indent all entries in
4
grow files -- but that is better than nothing.
4
the list of character devices.
5
5
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Message-id: 20180214204915.7980-4-mreitz@redhat.com
7
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
9
---
12
block/ssh.c | 24 ++++++++++++++++++++++++
10
chardev/char.c | 2 +-
13
1 file changed, 24 insertions(+)
11
1 file changed, 1 insertion(+), 1 deletion(-)
14
12
15
diff --git a/block/ssh.c b/block/ssh.c
13
diff --git a/chardev/char.c b/chardev/char.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/block/ssh.c
15
--- a/chardev/char.c
18
+++ b/block/ssh.c
16
+++ b/chardev/char.c
19
@@ -XXX,XX +XXX,XX @@ static int64_t ssh_getlength(BlockDriverState *bs)
17
@@ -XXX,XX +XXX,XX @@ help_string_append(const char *name, void *opaque)
20
return length;
18
{
19
GString *str = opaque;
20
21
- g_string_append_printf(str, "\n%s", name);
22
+ g_string_append_printf(str, "\n %s", name);
21
}
23
}
22
24
23
+static int ssh_truncate(BlockDriverState *bs, int64_t offset,
25
static const char *chardev_alias_translate(const char *name)
24
+ PreallocMode prealloc, Error **errp)
25
+{
26
+ BDRVSSHState *s = bs->opaque;
27
+
28
+ if (prealloc != PREALLOC_MODE_OFF) {
29
+ error_setg(errp, "Unsupported preallocation mode '%s'",
30
+ PreallocMode_str(prealloc));
31
+ return -ENOTSUP;
32
+ }
33
+
34
+ if (offset < s->attrs.filesize) {
35
+ error_setg(errp, "ssh driver does not support shrinking files");
36
+ return -ENOTSUP;
37
+ }
38
+
39
+ if (offset == s->attrs.filesize) {
40
+ return 0;
41
+ }
42
+
43
+ return ssh_grow_file(s, offset, errp);
44
+}
45
+
46
static BlockDriver bdrv_ssh = {
47
.format_name = "ssh",
48
.protocol_name = "ssh",
49
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_ssh = {
50
.bdrv_co_readv = ssh_co_readv,
51
.bdrv_co_writev = ssh_co_writev,
52
.bdrv_getlength = ssh_getlength,
53
+ .bdrv_truncate = ssh_truncate,
54
.bdrv_co_flush_to_disk = ssh_co_flush,
55
.create_opts = &ssh_create_opts,
56
};
57
--
26
--
58
2.13.6
27
2.19.1
59
28
60
29
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
We are gradually moving away from sector-based interfaces, towards
3
Just like in qemu_opts_print_help(), print the device name as a caption
4
byte-based. Update the parallels driver accordingly. Note that
4
instead of on every single line, indent all options, add angle brackets
5
the internal function block_status() is still sector-based, because
5
around types, and align the descriptions after 24 characters. Also,
6
it is still in use by other sector-based functions; but that's okay
6
separate the descriptions with " - " instead of putting them in
7
because request_alignment is 512 as a result of those functions.
7
parentheses, because that is what we do everywhere else. This does look
8
For now, no optimizations are added based on the mapping hint.
8
a bit funny here because basically all bits have the description
9
"on/off", but funny does not mean it is less readable.
9
10
10
Signed-off-by: Eric Blake <eblake@redhat.com>
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
12
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
12
Reviewed-by: Fam Zheng <famz@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
14
---
15
block/parallels.c | 22 +++++++++++++++-------
15
qdev-monitor.c | 13 +++++++++++--
16
1 file changed, 15 insertions(+), 7 deletions(-)
16
1 file changed, 11 insertions(+), 2 deletions(-)
17
17
18
diff --git a/block/parallels.c b/block/parallels.c
18
diff --git a/qdev-monitor.c b/qdev-monitor.c
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/parallels.c
20
--- a/qdev-monitor.c
21
+++ b/block/parallels.c
21
+++ b/qdev-monitor.c
22
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int parallels_co_flush_to_os(BlockDriverState *bs)
22
@@ -XXX,XX +XXX,XX @@ int qdev_device_help(QemuOpts *opts)
23
}
23
goto error;
24
25
26
-static int64_t coroutine_fn parallels_co_get_block_status(BlockDriverState *bs,
27
- int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file)
28
+static int coroutine_fn parallels_co_block_status(BlockDriverState *bs,
29
+ bool want_zero,
30
+ int64_t offset,
31
+ int64_t bytes,
32
+ int64_t *pnum,
33
+ int64_t *map,
34
+ BlockDriverState **file)
35
{
36
BDRVParallelsState *s = bs->opaque;
37
- int64_t offset;
38
+ int count;
39
40
+ assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
41
qemu_co_mutex_lock(&s->lock);
42
- offset = block_status(s, sector_num, nb_sectors, pnum);
43
+ offset = block_status(s, offset >> BDRV_SECTOR_BITS,
44
+ bytes >> BDRV_SECTOR_BITS, &count);
45
qemu_co_mutex_unlock(&s->lock);
46
47
+ *pnum = count * BDRV_SECTOR_SIZE;
48
if (offset < 0) {
49
return 0;
50
}
24
}
51
25
52
+ *map = offset * BDRV_SECTOR_SIZE;
26
+ if (prop_list) {
53
*file = bs->file->bs;
27
+ out_printf("%s options:\n", driver);
54
- return (offset << BDRV_SECTOR_BITS) |
28
+ } else {
55
- BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
29
+ out_printf("There are no options for %s.\n", driver);
56
+ return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
30
+ }
57
}
31
for (prop = prop_list; prop; prop = prop->next) {
58
32
- out_printf("%s.%s=%s", driver, prop->value->name, prop->value->type);
59
static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
33
+ int len;
60
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_parallels = {
34
+ out_printf(" %s=<%s>%n", prop->value->name, prop->value->type, &len);
61
.bdrv_open        = parallels_open,
35
if (prop->value->has_description) {
62
.bdrv_close        = parallels_close,
36
- out_printf(" (%s)\n", prop->value->description);
63
.bdrv_child_perm = bdrv_format_default_perms,
37
+ if (len < 24) {
64
- .bdrv_co_get_block_status = parallels_co_get_block_status,
38
+ out_printf("%*s", 24 - len, "");
65
+ .bdrv_co_block_status = parallels_co_block_status,
39
+ }
66
.bdrv_has_zero_init = bdrv_has_zero_init_1,
40
+ out_printf(" - %s\n", prop->value->description);
67
.bdrv_co_flush_to_os = parallels_co_flush_to_os,
41
} else {
68
.bdrv_co_readv = parallels_co_readv,
42
out_printf("\n");
43
}
69
--
44
--
70
2.13.6
45
2.19.1
71
46
72
47
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
At runtime (that is, during a future ssh_truncate()), the SSH session is
3
Just like in qemu_opts_print_help(), print the object name as a caption
4
non-blocking. However, ssh_truncate() (or rather, bdrv_truncate() in
4
instead of on every single line, indent all options, add angle brackets
5
general) is not a coroutine, so this resize operation needs to block.
5
around types, and align the descriptions after 24 characters.
6
6
7
For ssh_create(), that is fine, too; the session is never set to
7
Also, indent every object name in the list of available objects.
8
non-blocking anyway.
9
8
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Message-id: 20180214204915.7980-3-mreitz@redhat.com
10
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
12
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
12
---
16
block/ssh.c | 7 +++++++
13
vl.c | 13 ++++++++++---
17
1 file changed, 7 insertions(+)
14
1 file changed, 10 insertions(+), 3 deletions(-)
18
15
19
diff --git a/block/ssh.c b/block/ssh.c
16
diff --git a/vl.c b/vl.c
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/block/ssh.c
18
--- a/vl.c
22
+++ b/block/ssh.c
19
+++ b/vl.c
23
@@ -XXX,XX +XXX,XX @@ static int ssh_file_open(BlockDriverState *bs, QDict *options, int bdrv_flags,
20
@@ -XXX,XX +XXX,XX @@ static bool object_create_initial(const char *type, QemuOpts *opts)
24
return ret;
21
list = object_class_get_list_sorted(TYPE_USER_CREATABLE, false);
25
}
22
for (l = list; l != NULL; l = l->next) {
26
23
ObjectClass *oc = OBJECT_CLASS(l->data);
27
+/* Note: This is a blocking operation */
24
- printf("%s\n", object_class_get_name(oc));
28
static int ssh_grow_file(BDRVSSHState *s, int64_t offset, Error **errp)
25
+ printf(" %s\n", object_class_get_name(oc));
29
{
26
}
30
ssize_t ret;
27
g_slist_free(list);
31
char c[1] = { '\0' };
28
exit(0);
32
+ int was_blocking = libssh2_session_get_blocking(s->session);
29
@@ -XXX,XX +XXX,XX @@ static bool object_create_initial(const char *type, QemuOpts *opts)
33
30
}
34
/* offset must be strictly greater than the current size so we do
31
35
* not overwrite anything */
32
str = g_string_new(NULL);
36
assert(offset > 0 && offset > s->attrs.filesize);
33
- g_string_append_printf(str, "%s.%s=%s", type,
37
34
- prop->name, prop->type);
38
+ libssh2_session_set_blocking(s->session, 1);
35
+ g_string_append_printf(str, " %s=<%s>", prop->name, prop->type);
39
+
36
if (prop->description) {
40
libssh2_sftp_seek64(s->sftp_handle, offset - 1);
37
+ if (str->len < 24) {
41
ret = libssh2_sftp_write(s->sftp_handle, c, 1);
38
+ g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
42
+
39
+ }
43
+ libssh2_session_set_blocking(s->session, was_blocking);
40
g_string_append_printf(str, " - %s", prop->description);
44
+
41
}
45
if (ret < 0) {
42
g_ptr_array_add(array, g_string_free(str, false));
46
sftp_error_setg(errp, s, "Failed to grow file");
43
}
47
return -EIO;
44
g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
45
+ if (array->len > 0) {
46
+ printf("%s options:\n", type);
47
+ } else {
48
+ printf("There are no options for %s.\n", type);
49
+ }
50
for (i = 0; i < array->len; i++) {
51
printf("%s\n", (char *)array->pdata[i]);
52
}
48
--
53
--
49
2.13.6
54
2.19.1
50
55
51
56
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
If we ever want to offer even rudimentary truncation functionality for
3
There is no good reason why there should be a newline in this
4
ssh, we should put the respective code into a reusable function.
4
description, so remove it.
5
5
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Message-id: 20180214204915.7980-2-mreitz@redhat.com
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
9
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
10
---
12
block/ssh.c | 30 ++++++++++++++++++++++--------
11
vl.c | 2 +-
13
1 file changed, 22 insertions(+), 8 deletions(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
14
13
15
diff --git a/block/ssh.c b/block/ssh.c
14
diff --git a/vl.c b/vl.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/block/ssh.c
16
--- a/vl.c
18
+++ b/block/ssh.c
17
+++ b/vl.c
19
@@ -XXX,XX +XXX,XX @@ static int ssh_file_open(BlockDriverState *bs, QDict *options, int bdrv_flags,
18
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qemu_fw_cfg_opts = {
20
return ret;
19
}, {
21
}
20
.name = "file",
22
21
.type = QEMU_OPT_STRING,
23
+static int ssh_grow_file(BDRVSSHState *s, int64_t offset, Error **errp)
22
- .help = "Sets the name of the file from which\n"
24
+{
23
+ .help = "Sets the name of the file from which "
25
+ ssize_t ret;
24
"the fw_cfg blob will be loaded",
26
+ char c[1] = { '\0' };
25
}, {
27
+
26
.name = "string",
28
+ /* offset must be strictly greater than the current size so we do
29
+ * not overwrite anything */
30
+ assert(offset > 0 && offset > s->attrs.filesize);
31
+
32
+ libssh2_sftp_seek64(s->sftp_handle, offset - 1);
33
+ ret = libssh2_sftp_write(s->sftp_handle, c, 1);
34
+ if (ret < 0) {
35
+ sftp_error_setg(errp, s, "Failed to grow file");
36
+ return -EIO;
37
+ }
38
+
39
+ s->attrs.filesize = offset;
40
+ return 0;
41
+}
42
+
43
static QemuOptsList ssh_create_opts = {
44
.name = "ssh-create-opts",
45
.head = QTAILQ_HEAD_INITIALIZER(ssh_create_opts.head),
46
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn ssh_co_create_opts(const char *filename, QemuOpts *opts,
47
int64_t total_size = 0;
48
QDict *uri_options = NULL;
49
BDRVSSHState s;
50
- ssize_t r2;
51
- char c[1] = { '\0' };
52
53
ssh_state_init(&s);
54
55
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn ssh_co_create_opts(const char *filename, QemuOpts *opts,
56
}
57
58
if (total_size > 0) {
59
- libssh2_sftp_seek64(s.sftp_handle, total_size-1);
60
- r2 = libssh2_sftp_write(s.sftp_handle, c, 1);
61
- if (r2 < 0) {
62
- sftp_error_setg(errp, &s, "truncate failed");
63
- ret = -EINVAL;
64
+ ret = ssh_grow_file(&s, total_size, errp);
65
+ if (ret < 0) {
66
goto out;
67
}
68
- s.attrs.filesize = total_size;
69
}
70
71
ret = 0;
72
--
27
--
73
2.13.6
28
2.19.1
74
29
75
30
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Leonid Bloch <lbloch@janustech.com>
2
2
3
Rework the debug define so that we always get -Wformat checking,
3
If an expression is used to define DEFAULT_CLUSTER_SIZE, when compiled,
4
even when debugging is disabled.
4
it will be embedded as a literal expression in the binary (as the
5
default value) because it is stringified to mark the size of the default
6
value. Now this is fixed by using a defined number to define this value.
5
7
6
Signed-off-by: Eric Blake <eblake@redhat.com>
8
Signed-off-by: Leonid Bloch <lbloch@janustech.com>
7
Reviewed-by: Stefan Weil <sw@weilnetz.de>
9
Reviewed-by: Stefan Weil <sw@weilnetz.de>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Reviewed-by: Fam Zheng <famz@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
11
---
13
block/vdi.c | 12 +++++++++---
12
block/vdi.c | 4 ++--
14
1 file changed, 9 insertions(+), 3 deletions(-)
13
1 file changed, 2 insertions(+), 2 deletions(-)
15
14
16
diff --git a/block/vdi.c b/block/vdi.c
15
diff --git a/block/vdi.c b/block/vdi.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/block/vdi.c
17
--- a/block/vdi.c
19
+++ b/block/vdi.c
18
+++ b/block/vdi.c
20
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
21
#define DEFAULT_CLUSTER_SIZE (1 * MiB)
20
#define BLOCK_OPT_STATIC "static"
21
22
#define SECTOR_SIZE 512
23
-#define DEFAULT_CLUSTER_SIZE (1 * MiB)
24
+#define DEFAULT_CLUSTER_SIZE S_1MiB
22
25
23
#if defined(CONFIG_VDI_DEBUG)
26
#if defined(CONFIG_VDI_DEBUG)
24
-#define logout(fmt, ...) \
27
#define VDI_DEBUG 1
25
- fprintf(stderr, "vdi\t%-24s" fmt, __func__, ##__VA_ARGS__)
28
@@ -XXX,XX +XXX,XX @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
26
+#define VDI_DEBUG 1
29
goto fail;
27
#else
30
} else if (header.block_size != DEFAULT_CLUSTER_SIZE) {
28
-#define logout(fmt, ...) ((void)0)
31
error_setg(errp, "unsupported VDI image (block size %" PRIu32
29
+#define VDI_DEBUG 0
32
- " is not %" PRIu64 ")",
30
#endif
33
+ " is not %" PRIu32 ")",
31
34
header.block_size, DEFAULT_CLUSTER_SIZE);
32
+#define logout(fmt, ...) \
35
ret = -ENOTSUP;
33
+ do { \
36
goto fail;
34
+ if (VDI_DEBUG) { \
35
+ fprintf(stderr, "vdi\t%-24s" fmt, __func__, ##__VA_ARGS__); \
36
+ } \
37
+ } while (0)
38
+
39
/* Image signature. */
40
#define VDI_SIGNATURE 0xbeda107f
41
42
--
37
--
43
2.13.6
38
2.19.1
44
39
45
40
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Leonid Bloch <lbloch@janustech.com>
2
2
3
We are gradually moving away from sector-based interfaces, towards
3
The lookup table for power-of-two sizes was added in commit 540b8492618eb
4
byte-based. Update the null driver accordingly.
4
for the purpose of having convenient shortcuts for these sizes in cases
5
when the literal number has to be present at compile time, and
6
expressions as '(1 * KiB)' can not be used. One such case is the
7
stringification of sizes. Beyond that, it is convenient to use these
8
shortcuts for all power-of-two sizes, even if they don't have to be
9
literal numbers.
5
10
6
Signed-off-by: Eric Blake <eblake@redhat.com>
11
Despite its convenience, this table introduced 55 lines of "dumb" code,
7
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
12
the purpose and origin of which are obscure without reading the message
8
Reviewed-by: Fam Zheng <famz@redhat.com>
13
of the commit which introduced it. This patch fixes that by adding a
14
comment to the code itself with a brief explanation for the reasoning
15
behind this table. This comment includes the short AWK script that
16
generated the table, so that anyone who's interested could make sure
17
that the values in it are correct (otherwise these values look as if
18
they were typed manually).
19
20
Signed-off-by: Leonid Bloch <lbloch@janustech.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
22
---
11
block/null.c | 23 ++++++++++++-----------
23
include/qemu/units.h | 18 ++++++++++++++++++
12
1 file changed, 12 insertions(+), 11 deletions(-)
24
1 file changed, 18 insertions(+)
13
25
14
diff --git a/block/null.c b/block/null.c
26
diff --git a/include/qemu/units.h b/include/qemu/units.h
15
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
16
--- a/block/null.c
28
--- a/include/qemu/units.h
17
+++ b/block/null.c
29
+++ b/include/qemu/units.h
18
@@ -XXX,XX +XXX,XX @@ static int null_reopen_prepare(BDRVReopenState *reopen_state,
30
@@ -XXX,XX +XXX,XX @@
19
return 0;
31
#define PiB (INT64_C(1) << 50)
20
}
32
#define EiB (INT64_C(1) << 60)
21
33
22
-static int64_t coroutine_fn null_co_get_block_status(BlockDriverState *bs,
34
+/*
23
- int64_t sector_num,
35
+ * The following lookup table is intended to be used when a literal string of
24
- int nb_sectors, int *pnum,
36
+ * the number of bytes is required (for example if it needs to be stringified).
25
- BlockDriverState **file)
37
+ * It can also be used for generic shortcuts of power-of-two sizes.
26
+static int coroutine_fn null_co_block_status(BlockDriverState *bs,
38
+ * This table is generated using the AWK script below:
27
+ bool want_zero, int64_t offset,
39
+ *
28
+ int64_t bytes, int64_t *pnum,
40
+ * BEGIN {
29
+ int64_t *map,
41
+ * suffix="KMGTPE";
30
+ BlockDriverState **file)
42
+ * for(i=10; i<64; i++) {
31
{
43
+ * val=2**i;
32
BDRVNullState *s = bs->opaque;
44
+ * s=substr(suffix, int(i/10), 1);
33
- off_t start = sector_num * BDRV_SECTOR_SIZE;
45
+ * n=2**(i%10);
34
+ int ret = BDRV_BLOCK_OFFSET_VALID;
46
+ * pad=21-int(log(n)/log(10));
35
47
+ * printf("#define S_%d%siB %*d\n", n, s, pad, val);
36
- *pnum = nb_sectors;
48
+ * }
37
+ *pnum = bytes;
49
+ * }
38
+ *map = offset;
50
+ */
39
*file = bs;
51
+
40
52
#define S_1KiB 1024
41
if (s->read_zeroes) {
53
#define S_2KiB 2048
42
- return BDRV_BLOCK_OFFSET_VALID | start | BDRV_BLOCK_ZERO;
54
#define S_4KiB 4096
43
- } else {
44
- return BDRV_BLOCK_OFFSET_VALID | start;
45
+ ret |= BDRV_BLOCK_ZERO;
46
}
47
+ return ret;
48
}
49
50
static void null_refresh_filename(BlockDriverState *bs, QDict *opts)
51
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_null_co = {
52
.bdrv_co_flush_to_disk = null_co_flush,
53
.bdrv_reopen_prepare = null_reopen_prepare,
54
55
- .bdrv_co_get_block_status = null_co_get_block_status,
56
+ .bdrv_co_block_status = null_co_block_status,
57
58
.bdrv_refresh_filename = null_refresh_filename,
59
};
60
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_null_aio = {
61
.bdrv_aio_flush = null_aio_flush,
62
.bdrv_reopen_prepare = null_reopen_prepare,
63
64
- .bdrv_co_get_block_status = null_co_get_block_status,
65
+ .bdrv_co_block_status = null_co_block_status,
66
67
.bdrv_refresh_filename = null_refresh_filename,
68
};
69
--
55
--
70
2.13.6
56
2.19.1
71
57
72
58
diff view generated by jsdifflib