1
The following changes since commit 23919ddfd56135cad3cb468a8f54d5a595f024f4:
1
The following changes since commit c1eb2ddf0f8075faddc5f7c3d39feae3e8e9d6b4:
2
2
3
Merge remote-tracking branch 'remotes/aperard/tags/pull-xen-20190827' into staging (2019-08-27 15:52:36 +0100)
3
Update version for v8.0.0 release (2023-04-19 17:27:13 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/XanClic/qemu.git tags/pull-block-2019-08-27
7
https://gitlab.com/stefanha/qemu.git tags/block-pull-request
8
8
9
for you to fetch changes up to bb043c056cffcc2f3ce88bfdaf2e76e455c09e2c:
9
for you to fetch changes up to 36e5e9b22abe56aa00ca067851555ad8127a7966:
10
10
11
iotests: Unify cache mode quoting (2019-08-27 19:48:44 +0200)
11
tracing: install trace events file only if necessary (2023-04-20 07:39:43 -0400)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block patches:
14
Pull request
15
- qemu-io now accepts a file to read a write pattern from
15
16
- Ensure that raw files have their first block allocated so we can probe
16
Sam Li's zoned storage work and fixes I collected during the 8.0 freeze.
17
the O_DIRECT alignment if necessary
18
- Various fixes
19
17
20
----------------------------------------------------------------
18
----------------------------------------------------------------
21
Denis Plotnikov (1):
22
qemu-io: add pattern file for write command
23
19
24
Max Reitz (7):
20
Carlos Santos (1):
25
iotests: Fix _filter_img_create()
21
tracing: install trace events file only if necessary
26
vmdk: Use bdrv_dirname() for relative extent paths
27
iotests: Keep testing broken relative extent paths
28
vmdk: Reject invalid compressed writes
29
iotests: Disable broken streamOptimized tests
30
iotests: Disable 110 for vmdk.twoGbMaxExtentSparse
31
iotests: Disable 126 for flat vmdk subformats
32
22
33
Nir Soffer (3):
23
Philippe Mathieu-Daudé (1):
34
block: posix: Always allocate the first block
24
block/dmg: Declare a type definition for DMG uncompress function
35
iotests: Test allocate_first_block() with O_DIRECT
36
iotests: Unify cache mode quoting
37
25
38
Stefan Hajnoczi (1):
26
Sam Li (17):
39
file-posix: fix request_alignment typo
27
block/block-common: add zoned device structs
28
block/file-posix: introduce helper functions for sysfs attributes
29
block/block-backend: add block layer APIs resembling Linux
30
ZonedBlockDevice ioctls
31
block/raw-format: add zone operations to pass through requests
32
block: add zoned BlockDriver check to block layer
33
iotests: test new zone operations
34
block: add some trace events for new block layer APIs
35
docs/zoned-storage: add zoned device documentation
36
file-posix: add tracking of the zone write pointers
37
block: introduce zone append write for zoned devices
38
qemu-iotests: test zone append operation
39
block: add some trace events for zone append
40
include: update virtio_blk headers to v6.3-rc1
41
virtio-blk: add zoned storage emulation for zoned devices
42
block: add accounting for zone append operation
43
virtio-blk: add some trace events for zoned emulation
44
docs/zoned-storage:add zoned emulation use case
40
45
41
Thomas Huth (2):
46
Thomas De Schampheleire (1):
42
iotests: Check for enabled drivers before testing them
47
tracetool: use relative paths for '#line' preprocessor directives
43
tests/check-block: Skip iotests when sanitizers are enabled
44
48
45
Vladimir Sementsov-Ogievskiy (1):
49
docs/devel/index-api.rst | 1 +
46
block: fix permission update in bdrv_replace_node
50
docs/devel/zoned-storage.rst | 62 ++
47
51
qapi/block-core.json | 68 +-
48
block.c | 5 +-
52
qapi/block.json | 4 +
49
block/file-posix.c | 53 +++++++++-
53
meson.build | 4 +
50
block/vmdk.c | 64 ++++++++----
54
block/dmg.h | 8 +-
51
qemu-io-cmds.c | 99 +++++++++++++++++--
55
include/block/accounting.h | 1 +
52
tests/check-block.sh | 5 +
56
include/block/block-common.h | 57 ++
53
tests/qemu-iotests/002 | 1 +
57
include/block/block-io.h | 13 +
54
tests/qemu-iotests/003 | 1 +
58
include/block/block_int-common.h | 37 +
55
tests/qemu-iotests/005 | 3 +-
59
include/block/raw-aio.h | 8 +-
56
tests/qemu-iotests/009 | 1 +
60
include/standard-headers/drm/drm_fourcc.h | 12 +
57
tests/qemu-iotests/010 | 1 +
61
include/standard-headers/linux/ethtool.h | 48 +-
58
tests/qemu-iotests/011 | 1 +
62
include/standard-headers/linux/fuse.h | 45 +-
59
tests/qemu-iotests/017 | 3 +-
63
include/standard-headers/linux/pci_regs.h | 1 +
60
tests/qemu-iotests/018 | 3 +-
64
include/standard-headers/linux/vhost_types.h | 2 +
61
tests/qemu-iotests/019 | 3 +-
65
include/standard-headers/linux/virtio_blk.h | 105 +++
62
tests/qemu-iotests/020 | 3 +-
66
include/sysemu/block-backend-io.h | 27 +
63
tests/qemu-iotests/026 | 4 +-
67
linux-headers/asm-arm64/kvm.h | 1 +
64
tests/qemu-iotests/027 | 1 +
68
linux-headers/asm-x86/kvm.h | 34 +-
65
tests/qemu-iotests/032 | 1 +
69
linux-headers/linux/kvm.h | 9 +
66
tests/qemu-iotests/033 | 1 +
70
linux-headers/linux/vfio.h | 15 +-
67
tests/qemu-iotests/034 | 3 +-
71
linux-headers/linux/vhost.h | 8 +
68
tests/qemu-iotests/037 | 3 +-
72
block.c | 19 +
69
tests/qemu-iotests/039 | 4 +-
73
block/block-backend.c | 193 ++++++
70
tests/qemu-iotests/052 | 2 +-
74
block/dmg.c | 7 +-
71
tests/qemu-iotests/059 | 34 ++++++-
75
block/file-posix.c | 677 +++++++++++++++++--
72
tests/qemu-iotests/059.out | 26 +++--
76
block/io.c | 68 ++
73
tests/qemu-iotests/063 | 3 +-
77
block/io_uring.c | 4 +
74
tests/qemu-iotests/071 | 1 +
78
block/linux-aio.c | 3 +
75
tests/qemu-iotests/072 | 1 +
79
block/qapi-sysemu.c | 11 +
76
tests/qemu-iotests/081 | 4 +-
80
block/qapi.c | 18 +
77
tests/qemu-iotests/091 | 4 +-
81
block/raw-format.c | 26 +
78
tests/qemu-iotests/099 | 1 +
82
hw/block/virtio-blk-common.c | 2 +
79
tests/qemu-iotests/105 | 3 +-
83
hw/block/virtio-blk.c | 405 +++++++++++
80
tests/qemu-iotests/110 | 3 +-
84
hw/virtio/virtio-qmp.c | 2 +
81
tests/qemu-iotests/120 | 1 +
85
qemu-io-cmds.c | 224 ++++++
82
tests/qemu-iotests/126 | 2 +
86
block/trace-events | 4 +
83
tests/qemu-iotests/{150.out => 150.out.qcow2} | 0
87
docs/system/qemu-block-drivers.rst.inc | 6 +
84
tests/qemu-iotests/150.out.raw | 12 +++
88
hw/block/trace-events | 7 +
85
tests/qemu-iotests/162 | 4 +-
89
scripts/tracetool/backend/ftrace.py | 4 +-
86
tests/qemu-iotests/175 | 47 +++++++--
90
scripts/tracetool/backend/log.py | 4 +-
87
tests/qemu-iotests/175.out | 16 ++-
91
scripts/tracetool/backend/syslog.py | 4 +-
88
tests/qemu-iotests/178.out.qcow2 | 4 +-
92
tests/qemu-iotests/tests/zoned | 105 +++
89
tests/qemu-iotests/184 | 1 +
93
tests/qemu-iotests/tests/zoned.out | 69 ++
90
tests/qemu-iotests/186 | 1 +
94
trace/meson.build | 2 +-
91
tests/qemu-iotests/197 | 1 +
95
46 files changed, 2353 insertions(+), 81 deletions(-)
92
tests/qemu-iotests/215 | 1 +
96
create mode 100644 docs/devel/zoned-storage.rst
93
tests/qemu-iotests/221.out | 12 ++-
97
create mode 100755 tests/qemu-iotests/tests/zoned
94
tests/qemu-iotests/251 | 1 +
98
create mode 100644 tests/qemu-iotests/tests/zoned.out
95
tests/qemu-iotests/253.out | 12 ++-
96
tests/qemu-iotests/common.filter | 4 +-
97
tests/qemu-iotests/common.rc | 14 +++
98
50 files changed, 391 insertions(+), 87 deletions(-)
99
rename tests/qemu-iotests/{150.out => 150.out.qcow2} (100%)
100
create mode 100644 tests/qemu-iotests/150.out.raw
101
99
102
--
100
--
103
2.21.0
101
2.39.2
104
102
105
103
diff view generated by jsdifflib
1
From: Nir Soffer <nirsof@gmail.com>
1
From: Sam Li <faithilikerun@gmail.com>
2
2
3
Quoting cache mode is not needed, and most tests use unquoted values.
3
Signed-off-by: Sam Li <faithilikerun@gmail.com>
4
Unify all test to use the same style.
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Reviewed-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
6
Reviewed-by: Hannes Reinecke <hare@suse.de>
7
Reviewed-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
8
Acked-by: Kevin Wolf <kwolf@redhat.com>
9
Message-id: 20230324090605.28361-2-faithilikerun@gmail.com
10
[Adjust commit message prefix as suggested by Philippe Mathieu-Daudé
11
<philmd@linaro.org>.
12
--Stefan]
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
---
15
include/block/block-common.h | 43 ++++++++++++++++++++++++++++++++++++
16
1 file changed, 43 insertions(+)
5
17
6
Message-id: 20190827173432.7656-1-nsoffer@redhat.com
18
diff --git a/include/block/block-common.h b/include/block/block-common.h
7
Signed-off-by: Nir Soffer <nsoffer@redhat.com>
19
index XXXXXXX..XXXXXXX 100644
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
20
--- a/include/block/block-common.h
9
---
21
+++ b/include/block/block-common.h
10
tests/qemu-iotests/026 | 4 ++--
22
@@ -XXX,XX +XXX,XX @@ typedef struct BlockDriver BlockDriver;
11
tests/qemu-iotests/039 | 4 ++--
23
typedef struct BdrvChild BdrvChild;
12
tests/qemu-iotests/052 | 2 +-
24
typedef struct BdrvChildClass BdrvChildClass;
13
tests/qemu-iotests/091 | 4 ++--
25
14
4 files changed, 7 insertions(+), 7 deletions(-)
26
+typedef enum BlockZoneOp {
15
27
+ BLK_ZO_OPEN,
16
diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026
28
+ BLK_ZO_CLOSE,
17
index XXXXXXX..XXXXXXX 100755
29
+ BLK_ZO_FINISH,
18
--- a/tests/qemu-iotests/026
30
+ BLK_ZO_RESET,
19
+++ b/tests/qemu-iotests/026
31
+} BlockZoneOp;
20
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
32
+
21
# Currently only qcow2 supports rebasing
33
+typedef enum BlockZoneModel {
22
_supported_fmt qcow2
34
+ BLK_Z_NONE = 0x0, /* Regular block device */
23
_supported_proto file
35
+ BLK_Z_HM = 0x1, /* Host-managed zoned block device */
24
-_default_cache_mode "writethrough"
36
+ BLK_Z_HA = 0x2, /* Host-aware zoned block device */
25
-_supported_cache_modes "writethrough" "none"
37
+} BlockZoneModel;
26
+_default_cache_mode writethrough
38
+
27
+_supported_cache_modes writethrough none
39
+typedef enum BlockZoneState {
28
# The refcount table tests expect a certain minimum width for refcount entries
40
+ BLK_ZS_NOT_WP = 0x0,
29
# (so that the refcount table actually needs to grow); that minimum is 16 bits,
41
+ BLK_ZS_EMPTY = 0x1,
30
# being the default refcount entry width.
42
+ BLK_ZS_IOPEN = 0x2,
31
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
43
+ BLK_ZS_EOPEN = 0x3,
32
index XXXXXXX..XXXXXXX 100755
44
+ BLK_ZS_CLOSED = 0x4,
33
--- a/tests/qemu-iotests/039
45
+ BLK_ZS_RDONLY = 0xD,
34
+++ b/tests/qemu-iotests/039
46
+ BLK_ZS_FULL = 0xE,
35
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
47
+ BLK_ZS_OFFLINE = 0xF,
36
_supported_fmt qcow2
48
+} BlockZoneState;
37
_supported_proto file
49
+
38
_supported_os Linux
50
+typedef enum BlockZoneType {
39
-_default_cache_mode "writethrough"
51
+ BLK_ZT_CONV = 0x1, /* Conventional random writes supported */
40
-_supported_cache_modes "writethrough"
52
+ BLK_ZT_SWR = 0x2, /* Sequential writes required */
41
+_default_cache_mode writethrough
53
+ BLK_ZT_SWP = 0x3, /* Sequential writes preferred */
42
+_supported_cache_modes writethrough
54
+} BlockZoneType;
43
55
+
44
size=128M
56
+/*
45
57
+ * Zone descriptor data structure.
46
diff --git a/tests/qemu-iotests/052 b/tests/qemu-iotests/052
58
+ * Provides information on a zone with all position and size values in bytes.
47
index XXXXXXX..XXXXXXX 100755
59
+ */
48
--- a/tests/qemu-iotests/052
60
+typedef struct BlockZoneDescriptor {
49
+++ b/tests/qemu-iotests/052
61
+ uint64_t start;
50
@@ -XXX,XX +XXX,XX @@ _supported_fmt generic
62
+ uint64_t length;
51
_supported_proto file
63
+ uint64_t cap;
52
64
+ uint64_t wp;
53
# Don't do O_DIRECT on tmpfs
65
+ BlockZoneType type;
54
-_supported_cache_modes "writeback" "writethrough" "unsafe"
66
+ BlockZoneState state;
55
+_supported_cache_modes writeback writethrough unsafe
67
+} BlockZoneDescriptor;
56
68
+
57
size=128M
69
typedef struct BlockDriverInfo {
58
_make_test_img $size
70
/* in bytes, 0 if irrelevant */
59
diff --git a/tests/qemu-iotests/091 b/tests/qemu-iotests/091
71
int cluster_size;
60
index XXXXXXX..XXXXXXX 100755
61
--- a/tests/qemu-iotests/091
62
+++ b/tests/qemu-iotests/091
63
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
64
_supported_fmt qcow2
65
_supported_proto file
66
_supported_os Linux
67
-_default_cache_mode "none"
68
-_supported_cache_modes "writethrough" "none" "writeback"
69
+_default_cache_mode none
70
+_supported_cache_modes writethrough none writeback
71
72
size=1G
73
74
--
72
--
75
2.21.0
73
2.39.2
76
74
77
75
diff view generated by jsdifflib
1
From: Nir Soffer <nirsof@gmail.com>
1
From: Sam Li <faithilikerun@gmail.com>
2
2
3
Using block_resize we can test allocate_first_block() with file
3
Use get_sysfs_str_val() to get the string value of device
4
descriptor opened with O_DIRECT, ensuring that it works for any size
4
zoned model. Then get_sysfs_zoned_model() can convert it to
5
larger than 4096 bytes.
5
BlockZoneModel type of QEMU.
6
6
7
Testing smaller sizes is tricky as the result depends on the filesystem
7
Use get_sysfs_long_val() to get the long value of zoned device
8
used for testing. For example on NFS any size will work since O_DIRECT
8
information.
9
does not require any alignment.
9
10
10
Signed-off-by: Sam Li <faithilikerun@gmail.com>
11
Signed-off-by: Nir Soffer <nsoffer@redhat.com>
11
Reviewed-by: Hannes Reinecke <hare@suse.de>
12
Reviewed-by: Max Reitz <mreitz@redhat.com>
12
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Message-id: 20190827010528.8818-3-nsoffer@redhat.com
13
Reviewed-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
Reviewed-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
15
Acked-by: Kevin Wolf <kwolf@redhat.com>
16
Message-id: 20230324090605.28361-3-faithilikerun@gmail.com
17
[Adjust commit message prefix as suggested by Philippe Mathieu-Daudé
18
<philmd@linaro.org>.
19
--Stefan]
20
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
---
21
---
16
tests/qemu-iotests/175 | 28 ++++++++++++++++++++++++++++
22
include/block/block_int-common.h | 3 +
17
tests/qemu-iotests/175.out | 8 ++++++++
23
block/file-posix.c | 130 ++++++++++++++++++++++---------
18
2 files changed, 36 insertions(+)
24
2 files changed, 95 insertions(+), 38 deletions(-)
19
25
20
diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
26
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
21
index XXXXXXX..XXXXXXX 100755
27
index XXXXXXX..XXXXXXX 100644
22
--- a/tests/qemu-iotests/175
28
--- a/include/block/block_int-common.h
23
+++ b/tests/qemu-iotests/175
29
+++ b/include/block/block_int-common.h
24
@@ -XXX,XX +XXX,XX @@ _filter_blocks()
30
@@ -XXX,XX +XXX,XX @@ typedef struct BlockLimits {
25
-e "s/blocks=$((extra_blocks + img_size / 512))\\(\$\\|[^0-9]\\)/max allocation/"
31
* an explicit monitor command to load the disk inside the guest).
32
*/
33
bool has_variable_length;
34
+
35
+ /* device zone model */
36
+ BlockZoneModel zoned;
37
} BlockLimits;
38
39
typedef struct BdrvOpBlocker BdrvOpBlocker;
40
diff --git a/block/file-posix.c b/block/file-posix.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/block/file-posix.c
43
+++ b/block/file-posix.c
44
@@ -XXX,XX +XXX,XX @@ static int hdev_get_max_hw_transfer(int fd, struct stat *st)
45
#endif
26
}
46
}
27
47
28
+# Resize image using block_resize.
48
-static int hdev_get_max_segments(int fd, struct stat *st)
29
+# Parameter 1: image path
49
+/*
30
+# Parameter 2: new size
50
+ * Get a sysfs attribute value as character string.
31
+_block_resize()
51
+ */
52
+static int get_sysfs_str_val(struct stat *st, const char *attribute,
53
+ char **val) {
54
+#ifdef CONFIG_LINUX
55
+ g_autofree char *sysfspath = NULL;
56
+ int ret;
57
+ size_t len;
58
+
59
+ if (!S_ISBLK(st->st_mode)) {
60
+ return -ENOTSUP;
61
+ }
62
+
63
+ sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/%s",
64
+ major(st->st_rdev), minor(st->st_rdev),
65
+ attribute);
66
+ ret = g_file_get_contents(sysfspath, val, &len, NULL);
67
+ if (ret == -1) {
68
+ return -ENOENT;
69
+ }
70
+
71
+ /* The file is ended with '\n' */
72
+ char *p;
73
+ p = *val;
74
+ if (*(p + len - 1) == '\n') {
75
+ *(p + len - 1) = '\0';
76
+ }
77
+ return ret;
78
+#else
79
+ return -ENOTSUP;
80
+#endif
81
+}
82
+
83
+static int get_sysfs_zoned_model(struct stat *st, BlockZoneModel *zoned)
32
+{
84
+{
33
+ local path=$1
85
+ g_autofree char *val = NULL;
34
+ local size=$2
86
+ int ret;
35
+
87
+
36
+ $QEMU -qmp stdio -nographic -nodefaults \
88
+ ret = get_sysfs_str_val(st, "zoned", &val);
37
+ -blockdev file,node-name=file,filename=$path,cache.direct=on \
89
+ if (ret < 0) {
38
+ <<EOF
90
+ return ret;
39
+{'execute': 'qmp_capabilities'}
91
+ }
40
+{'execute': 'block_resize', 'arguments': {'node-name': 'file', 'size': $size}}
92
+
41
+{'execute': 'quit'}
93
+ if (strcmp(val, "host-managed") == 0) {
42
+EOF
94
+ *zoned = BLK_Z_HM;
95
+ } else if (strcmp(val, "host-aware") == 0) {
96
+ *zoned = BLK_Z_HA;
97
+ } else if (strcmp(val, "none") == 0) {
98
+ *zoned = BLK_Z_NONE;
99
+ } else {
100
+ return -ENOTSUP;
101
+ }
102
+ return 0;
43
+}
103
+}
44
+
104
+
45
# get standard environment, filters and checks
105
+/*
46
. ./common.rc
106
+ * Get a sysfs attribute value as a long integer.
47
. ./common.filter
107
+ */
48
@@ -XXX,XX +XXX,XX @@ _supported_fmt raw
108
+static long get_sysfs_long_val(struct stat *st, const char *attribute)
49
_supported_proto file
109
{
50
_supported_os Linux
110
#ifdef CONFIG_LINUX
51
111
- char buf[32];
52
+_default_cache_mode none
112
+ g_autofree char *str = NULL;
53
+_supported_cache_modes none directsync
113
const char *end;
54
+
114
- char *sysfspath = NULL;
55
size=$((1 * 1024 * 1024))
115
+ long val;
56
116
+ int ret;
57
touch "$TEST_DIR/empty"
117
+
58
@@ -XXX,XX +XXX,XX @@ for mode in off full falloc; do
118
+ ret = get_sysfs_str_val(st, attribute, &str);
59
stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size
119
+ if (ret < 0) {
60
done
120
+ return ret;
61
121
+ }
62
+for new_size in 4096 1048576; do
122
+
63
+ echo
123
+ /* The file is ended with '\n', pass 'end' to accept that. */
64
+ echo "== resize empty image with block_resize =="
124
+ ret = qemu_strtol(str, &end, 10, &val);
65
+ _make_test_img 0 | _filter_imgfmt
125
+ if (ret == 0 && end && *end == '\0') {
66
+ _block_resize $TEST_IMG $new_size >/dev/null
126
+ ret = val;
67
+ stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $new_size
127
+ }
68
+done
128
+ return ret;
69
+
129
+#else
70
# success, all done
130
+ return -ENOTSUP;
71
echo "*** done"
131
+#endif
72
rm -f $seq.full
132
+}
73
diff --git a/tests/qemu-iotests/175.out b/tests/qemu-iotests/175.out
133
+
74
index XXXXXXX..XXXXXXX 100644
134
+static int hdev_get_max_segments(int fd, struct stat *st)
75
--- a/tests/qemu-iotests/175.out
135
+{
76
+++ b/tests/qemu-iotests/175.out
136
+#ifdef CONFIG_LINUX
77
@@ -XXX,XX +XXX,XX @@ size=1048576, max allocation
137
int ret;
78
== creating image with preallocation falloc ==
138
- int sysfd = -1;
79
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=falloc
139
- long max_segments;
80
size=1048576, max allocation
140
81
+
141
if (S_ISCHR(st->st_mode)) {
82
+== resize empty image with block_resize ==
142
if (ioctl(fd, SG_GET_SG_TABLESIZE, &ret) == 0) {
83
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0
143
@@ -XXX,XX +XXX,XX @@ static int hdev_get_max_segments(int fd, struct stat *st)
84
+size=4096, min allocation
144
}
85
+
145
return -ENOTSUP;
86
+== resize empty image with block_resize ==
146
}
87
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0
147
-
88
+size=1048576, min allocation
148
- if (!S_ISBLK(st->st_mode)) {
89
*** done
149
- return -ENOTSUP;
150
- }
151
-
152
- sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/max_segments",
153
- major(st->st_rdev), minor(st->st_rdev));
154
- sysfd = open(sysfspath, O_RDONLY);
155
- if (sysfd == -1) {
156
- ret = -errno;
157
- goto out;
158
- }
159
- ret = RETRY_ON_EINTR(read(sysfd, buf, sizeof(buf) - 1));
160
- if (ret < 0) {
161
- ret = -errno;
162
- goto out;
163
- } else if (ret == 0) {
164
- ret = -EIO;
165
- goto out;
166
- }
167
- buf[ret] = 0;
168
- /* The file is ended with '\n', pass 'end' to accept that. */
169
- ret = qemu_strtol(buf, &end, 10, &max_segments);
170
- if (ret == 0 && end && *end == '\n') {
171
- ret = max_segments;
172
- }
173
-
174
-out:
175
- if (sysfd != -1) {
176
- close(sysfd);
177
- }
178
- g_free(sysfspath);
179
- return ret;
180
+ return get_sysfs_long_val(st, "max_segments");
181
#else
182
return -ENOTSUP;
183
#endif
184
@@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
185
{
186
BDRVRawState *s = bs->opaque;
187
struct stat st;
188
+ int ret;
189
+ BlockZoneModel zoned;
190
191
s->needs_alignment = raw_needs_alignment(bs);
192
raw_probe_alignment(bs, s->fd, errp);
193
@@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
194
bs->bl.max_hw_iov = ret;
195
}
196
}
197
+
198
+ ret = get_sysfs_zoned_model(&st, &zoned);
199
+ if (ret < 0) {
200
+ zoned = BLK_Z_NONE;
201
+ }
202
+ bs->bl.zoned = zoned;
203
}
204
205
static int check_for_dasd(int fd)
90
--
206
--
91
2.21.0
207
2.39.2
92
208
93
209
diff view generated by jsdifflib
1
From: Nir Soffer <nirsof@gmail.com>
1
From: Sam Li <faithilikerun@gmail.com>
2
2
3
When creating an image with preallocation "off" or "falloc", the first
3
Add zoned device option to host_device BlockDriver. It will be presented only
4
block of the image is typically not allocated. When using Gluster
4
for zoned host block devices. By adding zone management operations to the
5
storage backed by XFS filesystem, reading this block using direct I/O
5
host_block_device BlockDriver, users can use the new block layer APIs
6
succeeds regardless of request length, fooling alignment detection.
6
including Report Zone and four zone management operations
7
(open, close, finish, reset, reset_all).
7
8
8
In this case we fallback to a safe value (4096) instead of the optimal
9
Qemu-io uses the new APIs to perform zoned storage commands of the device:
9
value (512), which may lead to unneeded data copying when aligning
10
zone_report(zrp), zone_open(zo), zone_close(zc), zone_reset(zrs),
10
requests. Allocating the first block avoids the fallback.
11
zone_finish(zf).
11
12
12
Since we allocate the first block even with preallocation=off, we no
13
For example, to test zone_report, use following command:
13
longer create images with zero disk size:
14
$ ./build/qemu-io --image-opts -n driver=host_device, filename=/dev/nullb0
15
-c "zrp offset nr_zones"
14
16
15
$ ./qemu-img create -f raw test.raw 1g
17
Signed-off-by: Sam Li <faithilikerun@gmail.com>
16
Formatting 'test.raw', fmt=raw size=1073741824
18
Reviewed-by: Hannes Reinecke <hare@suse.de>
19
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
20
Reviewed-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
21
Acked-by: Kevin Wolf <kwolf@redhat.com>
22
Message-id: 20230324090605.28361-4-faithilikerun@gmail.com
23
[Adjust commit message prefix as suggested by Philippe Mathieu-Daudé
24
<philmd@linaro.org> and remove spurious ret = -errno in
25
raw_co_zone_mgmt().
26
--Stefan]
27
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
28
---
29
meson.build | 4 +
30
include/block/block-io.h | 9 +
31
include/block/block_int-common.h | 21 ++
32
include/block/raw-aio.h | 6 +-
33
include/sysemu/block-backend-io.h | 18 ++
34
block/block-backend.c | 133 +++++++++++++
35
block/file-posix.c | 306 +++++++++++++++++++++++++++++-
36
block/io.c | 41 ++++
37
qemu-io-cmds.c | 149 +++++++++++++++
38
9 files changed, 684 insertions(+), 3 deletions(-)
17
39
18
$ ls -lhs test.raw
40
diff --git a/meson.build b/meson.build
19
4.0K -rw-r--r--. 1 nsoffer nsoffer 1.0G Aug 16 23:48 test.raw
41
index XXXXXXX..XXXXXXX 100644
20
42
--- a/meson.build
21
And converting the image requires additional cluster:
43
+++ b/meson.build
22
44
@@ -XXX,XX +XXX,XX @@ config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
23
$ ./qemu-img measure -f raw -O qcow2 test.raw
45
# has_header
24
required size: 458752
46
config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
25
fully allocated size: 1074135040
47
config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
26
48
+config_host_data.set('CONFIG_BLKZONED', cc.has_header('linux/blkzoned.h'))
27
When using format like vmdk with multiple files per image, we allocate
49
config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
28
one block per file:
50
config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
29
51
config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
30
$ ./qemu-img create -f vmdk -o subformat=twoGbMaxExtentFlat test.vmdk 4g
52
@@ -XXX,XX +XXX,XX @@ config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
31
Formatting 'test.vmdk', fmt=vmdk size=4294967296 compat6=off hwversion=undefined subformat=twoGbMaxExtentFlat
53
config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
32
54
cc.has_member('struct stat', 'st_atim',
33
$ ls -lhs test*.vmdk
55
prefix: '#include <sys/stat.h>'))
34
4.0K -rw-r--r--. 1 nsoffer nsoffer 2.0G Aug 27 03:23 test-f001.vmdk
56
+config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY',
35
4.0K -rw-r--r--. 1 nsoffer nsoffer 2.0G Aug 27 03:23 test-f002.vmdk
57
+ cc.has_member('struct blk_zone', 'capacity',
36
4.0K -rw-r--r--. 1 nsoffer nsoffer 353 Aug 27 03:23 test.vmdk
58
+ prefix: '#include <linux/blkzoned.h>'))
37
59
38
I did quick performance test for copying disks with qemu-img convert to
60
# has_type
39
new raw target image to Gluster storage with sector size of 512 bytes:
61
config_host_data.set('CONFIG_IOVEC',
40
62
diff --git a/include/block/block-io.h b/include/block/block-io.h
41
for i in $(seq 10); do
63
index XXXXXXX..XXXXXXX 100644
42
rm -f dst.raw
64
--- a/include/block/block-io.h
43
sleep 10
65
+++ b/include/block/block-io.h
44
time ./qemu-img convert -f raw -O raw -t none -T none src.raw dst.raw
66
@@ -XXX,XX +XXX,XX @@ int coroutine_fn GRAPH_RDLOCK bdrv_co_flush(BlockDriverState *bs);
45
done
67
int coroutine_fn GRAPH_RDLOCK bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
46
68
int64_t bytes);
47
Here is a table comparing the total time spent:
69
48
70
+/* Report zone information of zone block device. */
49
Type Before(s) After(s) Diff(%)
71
+int coroutine_fn GRAPH_RDLOCK bdrv_co_zone_report(BlockDriverState *bs,
50
---------------------------------------
72
+ int64_t offset,
51
real 530.028 469.123 -11.4
73
+ unsigned int *nr_zones,
52
user 17.204 10.768 -37.4
74
+ BlockZoneDescriptor *zones);
53
sys 17.881 7.011 -60.7
75
+int coroutine_fn GRAPH_RDLOCK bdrv_co_zone_mgmt(BlockDriverState *bs,
54
76
+ BlockZoneOp op,
55
We can see very clear improvement in CPU usage.
77
+ int64_t offset, int64_t len);
56
78
+
57
Signed-off-by: Nir Soffer <nsoffer@redhat.com>
79
bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs);
58
Message-id: 20190827010528.8818-2-nsoffer@redhat.com
80
int bdrv_block_status(BlockDriverState *bs, int64_t offset,
59
Reviewed-by: Max Reitz <mreitz@redhat.com>
81
int64_t bytes, int64_t *pnum, int64_t *map,
60
Signed-off-by: Max Reitz <mreitz@redhat.com>
82
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
61
---
83
index XXXXXXX..XXXXXXX 100644
62
block/file-posix.c | 51 +++++++++++++++++++
84
--- a/include/block/block_int-common.h
63
tests/qemu-iotests/059.out | 2 +-
85
+++ b/include/block/block_int-common.h
64
tests/qemu-iotests/{150.out => 150.out.qcow2} | 0
86
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
65
tests/qemu-iotests/150.out.raw | 12 +++++
87
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_load_vmstate)(
66
tests/qemu-iotests/175 | 19 ++++---
88
BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
67
tests/qemu-iotests/175.out | 8 +--
89
68
tests/qemu-iotests/178.out.qcow2 | 4 +-
90
+ int coroutine_fn (*bdrv_co_zone_report)(BlockDriverState *bs,
69
tests/qemu-iotests/221.out | 12 +++--
91
+ int64_t offset, unsigned int *nr_zones,
70
tests/qemu-iotests/253.out | 12 +++--
92
+ BlockZoneDescriptor *zones);
71
9 files changed, 99 insertions(+), 21 deletions(-)
93
+ int coroutine_fn (*bdrv_co_zone_mgmt)(BlockDriverState *bs, BlockZoneOp op,
72
rename tests/qemu-iotests/{150.out => 150.out.qcow2} (100%)
94
+ int64_t offset, int64_t len);
73
create mode 100644 tests/qemu-iotests/150.out.raw
95
+
74
96
/* removable device specific */
97
bool coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_is_inserted)(
98
BlockDriverState *bs);
99
@@ -XXX,XX +XXX,XX @@ typedef struct BlockLimits {
100
101
/* device zone model */
102
BlockZoneModel zoned;
103
+
104
+ /* zone size expressed in bytes */
105
+ uint32_t zone_size;
106
+
107
+ /* total number of zones */
108
+ uint32_t nr_zones;
109
+
110
+ /* maximum sectors of a zone append write operation */
111
+ int64_t max_append_sectors;
112
+
113
+ /* maximum number of open zones */
114
+ int64_t max_open_zones;
115
+
116
+ /* maximum number of active zones */
117
+ int64_t max_active_zones;
118
} BlockLimits;
119
120
typedef struct BdrvOpBlocker BdrvOpBlocker;
121
diff --git a/include/block/raw-aio.h b/include/block/raw-aio.h
122
index XXXXXXX..XXXXXXX 100644
123
--- a/include/block/raw-aio.h
124
+++ b/include/block/raw-aio.h
125
@@ -XXX,XX +XXX,XX @@
126
#define QEMU_AIO_WRITE_ZEROES 0x0020
127
#define QEMU_AIO_COPY_RANGE 0x0040
128
#define QEMU_AIO_TRUNCATE 0x0080
129
+#define QEMU_AIO_ZONE_REPORT 0x0100
130
+#define QEMU_AIO_ZONE_MGMT 0x0200
131
#define QEMU_AIO_TYPE_MASK \
132
(QEMU_AIO_READ | \
133
QEMU_AIO_WRITE | \
134
@@ -XXX,XX +XXX,XX @@
135
QEMU_AIO_DISCARD | \
136
QEMU_AIO_WRITE_ZEROES | \
137
QEMU_AIO_COPY_RANGE | \
138
- QEMU_AIO_TRUNCATE)
139
+ QEMU_AIO_TRUNCATE | \
140
+ QEMU_AIO_ZONE_REPORT | \
141
+ QEMU_AIO_ZONE_MGMT)
142
143
/* AIO flags */
144
#define QEMU_AIO_MISALIGNED 0x1000
145
diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h
146
index XXXXXXX..XXXXXXX 100644
147
--- a/include/sysemu/block-backend-io.h
148
+++ b/include/sysemu/block-backend-io.h
149
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
150
BlockCompletionFunc *cb, void *opaque);
151
BlockAIOCB *blk_aio_flush(BlockBackend *blk,
152
BlockCompletionFunc *cb, void *opaque);
153
+BlockAIOCB *blk_aio_zone_report(BlockBackend *blk, int64_t offset,
154
+ unsigned int *nr_zones,
155
+ BlockZoneDescriptor *zones,
156
+ BlockCompletionFunc *cb, void *opaque);
157
+BlockAIOCB *blk_aio_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
158
+ int64_t offset, int64_t len,
159
+ BlockCompletionFunc *cb, void *opaque);
160
BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes,
161
BlockCompletionFunc *cb, void *opaque);
162
void blk_aio_cancel_async(BlockAIOCB *acb);
163
@@ -XXX,XX +XXX,XX @@ int co_wrapper_mixed blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
164
int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
165
int64_t bytes, BdrvRequestFlags flags);
166
167
+int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
168
+ unsigned int *nr_zones,
169
+ BlockZoneDescriptor *zones);
170
+int co_wrapper_mixed blk_zone_report(BlockBackend *blk, int64_t offset,
171
+ unsigned int *nr_zones,
172
+ BlockZoneDescriptor *zones);
173
+int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
174
+ int64_t offset, int64_t len);
175
+int co_wrapper_mixed blk_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
176
+ int64_t offset, int64_t len);
177
+
178
int co_wrapper_mixed blk_pdiscard(BlockBackend *blk, int64_t offset,
179
int64_t bytes);
180
int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset,
181
diff --git a/block/block-backend.c b/block/block-backend.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/block/block-backend.c
184
+++ b/block/block-backend.c
185
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_flush(BlockBackend *blk)
186
return ret;
187
}
188
189
+static void coroutine_fn blk_aio_zone_report_entry(void *opaque)
190
+{
191
+ BlkAioEmAIOCB *acb = opaque;
192
+ BlkRwCo *rwco = &acb->rwco;
193
+
194
+ rwco->ret = blk_co_zone_report(rwco->blk, rwco->offset,
195
+ (unsigned int*)acb->bytes,rwco->iobuf);
196
+ blk_aio_complete(acb);
197
+}
198
+
199
+BlockAIOCB *blk_aio_zone_report(BlockBackend *blk, int64_t offset,
200
+ unsigned int *nr_zones,
201
+ BlockZoneDescriptor *zones,
202
+ BlockCompletionFunc *cb, void *opaque)
203
+{
204
+ BlkAioEmAIOCB *acb;
205
+ Coroutine *co;
206
+ IO_CODE();
207
+
208
+ blk_inc_in_flight(blk);
209
+ acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque);
210
+ acb->rwco = (BlkRwCo) {
211
+ .blk = blk,
212
+ .offset = offset,
213
+ .iobuf = zones,
214
+ .ret = NOT_DONE,
215
+ };
216
+ acb->bytes = (int64_t)nr_zones,
217
+ acb->has_returned = false;
218
+
219
+ co = qemu_coroutine_create(blk_aio_zone_report_entry, acb);
220
+ aio_co_enter(blk_get_aio_context(blk), co);
221
+
222
+ acb->has_returned = true;
223
+ if (acb->rwco.ret != NOT_DONE) {
224
+ replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
225
+ blk_aio_complete_bh, acb);
226
+ }
227
+
228
+ return &acb->common;
229
+}
230
+
231
+static void coroutine_fn blk_aio_zone_mgmt_entry(void *opaque)
232
+{
233
+ BlkAioEmAIOCB *acb = opaque;
234
+ BlkRwCo *rwco = &acb->rwco;
235
+
236
+ rwco->ret = blk_co_zone_mgmt(rwco->blk, (BlockZoneOp)rwco->iobuf,
237
+ rwco->offset, acb->bytes);
238
+ blk_aio_complete(acb);
239
+}
240
+
241
+BlockAIOCB *blk_aio_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
242
+ int64_t offset, int64_t len,
243
+ BlockCompletionFunc *cb, void *opaque) {
244
+ BlkAioEmAIOCB *acb;
245
+ Coroutine *co;
246
+ IO_CODE();
247
+
248
+ blk_inc_in_flight(blk);
249
+ acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque);
250
+ acb->rwco = (BlkRwCo) {
251
+ .blk = blk,
252
+ .offset = offset,
253
+ .iobuf = (void *)op,
254
+ .ret = NOT_DONE,
255
+ };
256
+ acb->bytes = len;
257
+ acb->has_returned = false;
258
+
259
+ co = qemu_coroutine_create(blk_aio_zone_mgmt_entry, acb);
260
+ aio_co_enter(blk_get_aio_context(blk), co);
261
+
262
+ acb->has_returned = true;
263
+ if (acb->rwco.ret != NOT_DONE) {
264
+ replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
265
+ blk_aio_complete_bh, acb);
266
+ }
267
+
268
+ return &acb->common;
269
+}
270
+
271
+/*
272
+ * Send a zone_report command.
273
+ * offset is a byte offset from the start of the device. No alignment
274
+ * required for offset.
275
+ * nr_zones represents IN maximum and OUT actual.
276
+ */
277
+int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
278
+ unsigned int *nr_zones,
279
+ BlockZoneDescriptor *zones)
280
+{
281
+ int ret;
282
+ IO_CODE();
283
+
284
+ blk_inc_in_flight(blk); /* increase before waiting */
285
+ blk_wait_while_drained(blk);
286
+ if (!blk_is_available(blk)) {
287
+ blk_dec_in_flight(blk);
288
+ return -ENOMEDIUM;
289
+ }
290
+ ret = bdrv_co_zone_report(blk_bs(blk), offset, nr_zones, zones);
291
+ blk_dec_in_flight(blk);
292
+ return ret;
293
+}
294
+
295
+/*
296
+ * Send a zone_management command.
297
+ * op is the zone operation;
298
+ * offset is the byte offset from the start of the zoned device;
299
+ * len is the maximum number of bytes the command should operate on. It
300
+ * should be aligned with the device zone size.
301
+ */
302
+int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
303
+ int64_t offset, int64_t len)
304
+{
305
+ int ret;
306
+ IO_CODE();
307
+
308
+ blk_inc_in_flight(blk);
309
+ blk_wait_while_drained(blk);
310
+
311
+ ret = blk_check_byte_request(blk, offset, len);
312
+ if (ret < 0) {
313
+ blk_dec_in_flight(blk);
314
+ return ret;
315
+ }
316
+
317
+ ret = bdrv_co_zone_mgmt(blk_bs(blk), op, offset, len);
318
+ blk_dec_in_flight(blk);
319
+ return ret;
320
+}
321
+
322
void blk_drain(BlockBackend *blk)
323
{
324
BlockDriverState *bs = blk_bs(blk);
75
diff --git a/block/file-posix.c b/block/file-posix.c
325
diff --git a/block/file-posix.c b/block/file-posix.c
76
index XXXXXXX..XXXXXXX 100644
326
index XXXXXXX..XXXXXXX 100644
77
--- a/block/file-posix.c
327
--- a/block/file-posix.c
78
+++ b/block/file-posix.c
328
+++ b/block/file-posix.c
79
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_discard(void *opaque)
329
@@ -XXX,XX +XXX,XX @@
80
return ret;
330
#include <sys/param.h>
331
#include <sys/syscall.h>
332
#include <sys/vfs.h>
333
+#if defined(CONFIG_BLKZONED)
334
+#include <linux/blkzoned.h>
335
+#endif
336
#include <linux/cdrom.h>
337
#include <linux/fd.h>
338
#include <linux/fs.h>
339
@@ -XXX,XX +XXX,XX @@ typedef struct RawPosixAIOData {
340
PreallocMode prealloc;
341
Error **errp;
342
} truncate;
343
+ struct {
344
+ unsigned int *nr_zones;
345
+ BlockZoneDescriptor *zones;
346
+ } zone_report;
347
+ struct {
348
+ unsigned long op;
349
+ } zone_mgmt;
350
};
351
} RawPosixAIOData;
352
353
@@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
354
zoned = BLK_Z_NONE;
355
}
356
bs->bl.zoned = zoned;
357
+ if (zoned != BLK_Z_NONE) {
358
+ /*
359
+ * The zoned device must at least have zone size and nr_zones fields.
360
+ */
361
+ ret = get_sysfs_long_val(&st, "chunk_sectors");
362
+ if (ret < 0) {
363
+ error_setg_errno(errp, -ret, "Unable to read chunk_sectors "
364
+ "sysfs attribute");
365
+ goto out;
366
+ } else if (!ret) {
367
+ error_setg(errp, "Read 0 from chunk_sectors sysfs attribute");
368
+ goto out;
369
+ }
370
+ bs->bl.zone_size = ret << BDRV_SECTOR_BITS;
371
+
372
+ ret = get_sysfs_long_val(&st, "nr_zones");
373
+ if (ret < 0) {
374
+ error_setg_errno(errp, -ret, "Unable to read nr_zones "
375
+ "sysfs attribute");
376
+ goto out;
377
+ } else if (!ret) {
378
+ error_setg(errp, "Read 0 from nr_zones sysfs attribute");
379
+ goto out;
380
+ }
381
+ bs->bl.nr_zones = ret;
382
+
383
+ ret = get_sysfs_long_val(&st, "zone_append_max_bytes");
384
+ if (ret > 0) {
385
+ bs->bl.max_append_sectors = ret >> BDRV_SECTOR_BITS;
386
+ }
387
+
388
+ ret = get_sysfs_long_val(&st, "max_open_zones");
389
+ if (ret >= 0) {
390
+ bs->bl.max_open_zones = ret;
391
+ }
392
+
393
+ ret = get_sysfs_long_val(&st, "max_active_zones");
394
+ if (ret >= 0) {
395
+ bs->bl.max_active_zones = ret;
396
+ }
397
+ return;
398
+ }
399
+out:
400
+ bs->bl.zoned = BLK_Z_NONE;
81
}
401
}
82
402
403
static int check_for_dasd(int fd)
404
@@ -XXX,XX +XXX,XX @@ static int hdev_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz)
405
BDRVRawState *s = bs->opaque;
406
int ret;
407
408
- /* If DASD, get blocksizes */
409
+ /* If DASD or zoned devices, get blocksizes */
410
if (check_for_dasd(s->fd) < 0) {
411
- return -ENOTSUP;
412
+ /* zoned devices are not DASD */
413
+ if (bs->bl.zoned == BLK_Z_NONE) {
414
+ return -ENOTSUP;
415
+ }
416
}
417
ret = probe_logical_blocksize(s->fd, &bsz->log);
418
if (ret < 0) {
419
@@ -XXX,XX +XXX,XX @@ static off_t copy_file_range(int in_fd, off_t *in_off, int out_fd,
420
}
421
#endif
422
83
+/*
423
+/*
84
+ * Help alignment probing by allocating the first block.
424
+ * parse_zone - Fill a zone descriptor
85
+ *
86
+ * When reading with direct I/O from unallocated area on Gluster backed by XFS,
87
+ * reading succeeds regardless of request length. In this case we fallback to
88
+ * safe alignment which is not optimal. Allocating the first block avoids this
89
+ * fallback.
90
+ *
91
+ * fd may be opened with O_DIRECT, but we don't know the buffer alignment or
92
+ * request alignment, so we use safe values.
93
+ *
94
+ * Returns: 0 on success, -errno on failure. Since this is an optimization,
95
+ * caller may ignore failures.
96
+ */
425
+ */
97
+static int allocate_first_block(int fd, size_t max_size)
426
+#if defined(CONFIG_BLKZONED)
98
+{
427
+static inline int parse_zone(struct BlockZoneDescriptor *zone,
99
+ size_t write_size = (max_size < MAX_BLOCKSIZE)
428
+ const struct blk_zone *blkz) {
100
+ ? BDRV_SECTOR_SIZE
429
+ zone->start = blkz->start << BDRV_SECTOR_BITS;
101
+ : MAX_BLOCKSIZE;
430
+ zone->length = blkz->len << BDRV_SECTOR_BITS;
102
+ size_t max_align = MAX(MAX_BLOCKSIZE, getpagesize());
431
+ zone->wp = blkz->wp << BDRV_SECTOR_BITS;
103
+ void *buf;
432
+
104
+ ssize_t n;
433
+#ifdef HAVE_BLK_ZONE_REP_CAPACITY
434
+ zone->cap = blkz->capacity << BDRV_SECTOR_BITS;
435
+#else
436
+ zone->cap = blkz->len << BDRV_SECTOR_BITS;
437
+#endif
438
+
439
+ switch (blkz->type) {
440
+ case BLK_ZONE_TYPE_SEQWRITE_REQ:
441
+ zone->type = BLK_ZT_SWR;
442
+ break;
443
+ case BLK_ZONE_TYPE_SEQWRITE_PREF:
444
+ zone->type = BLK_ZT_SWP;
445
+ break;
446
+ case BLK_ZONE_TYPE_CONVENTIONAL:
447
+ zone->type = BLK_ZT_CONV;
448
+ break;
449
+ default:
450
+ error_report("Unsupported zone type: 0x%x", blkz->type);
451
+ return -ENOTSUP;
452
+ }
453
+
454
+ switch (blkz->cond) {
455
+ case BLK_ZONE_COND_NOT_WP:
456
+ zone->state = BLK_ZS_NOT_WP;
457
+ break;
458
+ case BLK_ZONE_COND_EMPTY:
459
+ zone->state = BLK_ZS_EMPTY;
460
+ break;
461
+ case BLK_ZONE_COND_IMP_OPEN:
462
+ zone->state = BLK_ZS_IOPEN;
463
+ break;
464
+ case BLK_ZONE_COND_EXP_OPEN:
465
+ zone->state = BLK_ZS_EOPEN;
466
+ break;
467
+ case BLK_ZONE_COND_CLOSED:
468
+ zone->state = BLK_ZS_CLOSED;
469
+ break;
470
+ case BLK_ZONE_COND_READONLY:
471
+ zone->state = BLK_ZS_RDONLY;
472
+ break;
473
+ case BLK_ZONE_COND_FULL:
474
+ zone->state = BLK_ZS_FULL;
475
+ break;
476
+ case BLK_ZONE_COND_OFFLINE:
477
+ zone->state = BLK_ZS_OFFLINE;
478
+ break;
479
+ default:
480
+ error_report("Unsupported zone state: 0x%x", blkz->cond);
481
+ return -ENOTSUP;
482
+ }
483
+ return 0;
484
+}
485
+#endif
486
+
487
+#if defined(CONFIG_BLKZONED)
488
+static int handle_aiocb_zone_report(void *opaque)
489
+{
490
+ RawPosixAIOData *aiocb = opaque;
491
+ int fd = aiocb->aio_fildes;
492
+ unsigned int *nr_zones = aiocb->zone_report.nr_zones;
493
+ BlockZoneDescriptor *zones = aiocb->zone_report.zones;
494
+ /* zoned block devices use 512-byte sectors */
495
+ uint64_t sector = aiocb->aio_offset / 512;
496
+
497
+ struct blk_zone *blkz;
498
+ size_t rep_size;
499
+ unsigned int nrz;
500
+ int ret, n = 0, i = 0;
501
+
502
+ nrz = *nr_zones;
503
+ rep_size = sizeof(struct blk_zone_report) + nrz * sizeof(struct blk_zone);
504
+ g_autofree struct blk_zone_report *rep = NULL;
505
+ rep = g_malloc(rep_size);
506
+
507
+ blkz = (struct blk_zone *)(rep + 1);
508
+ while (n < nrz) {
509
+ memset(rep, 0, rep_size);
510
+ rep->sector = sector;
511
+ rep->nr_zones = nrz - n;
512
+
513
+ do {
514
+ ret = ioctl(fd, BLKREPORTZONE, rep);
515
+ } while (ret != 0 && errno == EINTR);
516
+ if (ret != 0) {
517
+ error_report("%d: ioctl BLKREPORTZONE at %" PRId64 " failed %d",
518
+ fd, sector, errno);
519
+ return -errno;
520
+ }
521
+
522
+ if (!rep->nr_zones) {
523
+ break;
524
+ }
525
+
526
+ for (i = 0; i < rep->nr_zones; i++, n++) {
527
+ ret = parse_zone(&zones[n], &blkz[i]);
528
+ if (ret != 0) {
529
+ return ret;
530
+ }
531
+
532
+ /* The next report should start after the last zone reported */
533
+ sector = blkz[i].start + blkz[i].len;
534
+ }
535
+ }
536
+
537
+ *nr_zones = n;
538
+ return 0;
539
+}
540
+#endif
541
+
542
+#if defined(CONFIG_BLKZONED)
543
+static int handle_aiocb_zone_mgmt(void *opaque)
544
+{
545
+ RawPosixAIOData *aiocb = opaque;
546
+ int fd = aiocb->aio_fildes;
547
+ uint64_t sector = aiocb->aio_offset / 512;
548
+ int64_t nr_sectors = aiocb->aio_nbytes / 512;
549
+ struct blk_zone_range range;
105
+ int ret;
550
+ int ret;
106
+
551
+
107
+ buf = qemu_memalign(max_align, write_size);
552
+ /* Execute the operation */
108
+ memset(buf, 0, write_size);
553
+ range.sector = sector;
109
+
554
+ range.nr_sectors = nr_sectors;
110
+ do {
555
+ do {
111
+ n = pwrite(fd, buf, write_size, 0);
556
+ ret = ioctl(fd, aiocb->zone_mgmt.op, &range);
112
+ } while (n == -1 && errno == EINTR);
557
+ } while (ret != 0 && errno == EINTR);
113
+
558
+
114
+ ret = (n == -1) ? -errno : 0;
115
+
116
+ qemu_vfree(buf);
117
+ return ret;
559
+ return ret;
118
+}
560
+}
119
+
561
+#endif
120
static int handle_aiocb_truncate(void *opaque)
562
+
563
static int handle_aiocb_copy_range(void *opaque)
121
{
564
{
122
RawPosixAIOData *aiocb = opaque;
565
RawPosixAIOData *aiocb = opaque;
123
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_truncate(void *opaque)
566
@@ -XXX,XX +XXX,XX @@ static void raw_account_discard(BDRVRawState *s, uint64_t nbytes, int ret)
124
/* posix_fallocate() doesn't set errno. */
567
}
125
error_setg_errno(errp, -result,
568
}
126
"Could not preallocate new data");
569
127
+ } else if (current_length == 0) {
570
+/*
128
+ /*
571
+ * zone report - Get a zone block device's information in the form
129
+ * posix_fallocate() uses fallocate() if the filesystem
572
+ * of an array of zone descriptors.
130
+ * supports it, or fallback to manually writing zeroes. If
573
+ * zones is an array of zone descriptors to hold zone information on reply;
131
+ * fallocate() was used, unaligned reads from the fallocated
574
+ * offset can be any byte within the entire size of the device;
132
+ * area in raw_probe_alignment() will succeed, hence we need to
575
+ * nr_zones is the maxium number of sectors the command should operate on.
133
+ * allocate the first block.
576
+ */
134
+ *
577
+#if defined(CONFIG_BLKZONED)
135
+ * Optimize future alignment probing; ignore failures.
578
+static int coroutine_fn raw_co_zone_report(BlockDriverState *bs, int64_t offset,
136
+ */
579
+ unsigned int *nr_zones,
137
+ allocate_first_block(fd, offset);
580
+ BlockZoneDescriptor *zones) {
138
}
581
+ BDRVRawState *s = bs->opaque;
139
} else {
582
+ RawPosixAIOData acb = (RawPosixAIOData) {
140
result = 0;
583
+ .bs = bs,
141
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_truncate(void *opaque)
584
+ .aio_fildes = s->fd,
142
if (ftruncate(fd, offset) != 0) {
585
+ .aio_type = QEMU_AIO_ZONE_REPORT,
143
result = -errno;
586
+ .aio_offset = offset,
144
error_setg_errno(errp, -result, "Could not resize file");
587
+ .zone_report = {
145
+ } else if (current_length == 0 && offset > current_length) {
588
+ .nr_zones = nr_zones,
146
+ /* Optimize future alignment probing; ignore failures. */
589
+ .zones = zones,
147
+ allocate_first_block(fd, offset);
590
+ },
148
}
591
+ };
149
return result;
592
+
150
default:
593
+ return raw_thread_pool_submit(bs, handle_aiocb_zone_report, &acb);
151
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
594
+}
595
+#endif
596
+
597
+/*
598
+ * zone management operations - Execute an operation on a zone
599
+ */
600
+#if defined(CONFIG_BLKZONED)
601
+static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
602
+ int64_t offset, int64_t len) {
603
+ BDRVRawState *s = bs->opaque;
604
+ RawPosixAIOData acb;
605
+ int64_t zone_size, zone_size_mask;
606
+ const char *op_name;
607
+ unsigned long zo;
608
+ int ret;
609
+ int64_t capacity = bs->total_sectors << BDRV_SECTOR_BITS;
610
+
611
+ zone_size = bs->bl.zone_size;
612
+ zone_size_mask = zone_size - 1;
613
+ if (offset & zone_size_mask) {
614
+ error_report("sector offset %" PRId64 " is not aligned to zone size "
615
+ "%" PRId64 "", offset / 512, zone_size / 512);
616
+ return -EINVAL;
617
+ }
618
+
619
+ if (((offset + len) < capacity && len & zone_size_mask) ||
620
+ offset + len > capacity) {
621
+ error_report("number of sectors %" PRId64 " is not aligned to zone size"
622
+ " %" PRId64 "", len / 512, zone_size / 512);
623
+ return -EINVAL;
624
+ }
625
+
626
+ switch (op) {
627
+ case BLK_ZO_OPEN:
628
+ op_name = "BLKOPENZONE";
629
+ zo = BLKOPENZONE;
630
+ break;
631
+ case BLK_ZO_CLOSE:
632
+ op_name = "BLKCLOSEZONE";
633
+ zo = BLKCLOSEZONE;
634
+ break;
635
+ case BLK_ZO_FINISH:
636
+ op_name = "BLKFINISHZONE";
637
+ zo = BLKFINISHZONE;
638
+ break;
639
+ case BLK_ZO_RESET:
640
+ op_name = "BLKRESETZONE";
641
+ zo = BLKRESETZONE;
642
+ break;
643
+ default:
644
+ error_report("Unsupported zone op: 0x%x", op);
645
+ return -ENOTSUP;
646
+ }
647
+
648
+ acb = (RawPosixAIOData) {
649
+ .bs = bs,
650
+ .aio_fildes = s->fd,
651
+ .aio_type = QEMU_AIO_ZONE_MGMT,
652
+ .aio_offset = offset,
653
+ .aio_nbytes = len,
654
+ .zone_mgmt = {
655
+ .op = zo,
656
+ },
657
+ };
658
+
659
+ ret = raw_thread_pool_submit(bs, handle_aiocb_zone_mgmt, &acb);
660
+ if (ret != 0) {
661
+ error_report("ioctl %s failed %d", op_name, ret);
662
+ }
663
+
664
+ return ret;
665
+}
666
+#endif
667
+
668
static coroutine_fn int
669
raw_do_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes,
670
bool blkdev)
671
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = {
672
#ifdef __linux__
673
.bdrv_co_ioctl = hdev_co_ioctl,
674
#endif
675
+
676
+ /* zoned device */
677
+#if defined(CONFIG_BLKZONED)
678
+ /* zone management operations */
679
+ .bdrv_co_zone_report = raw_co_zone_report,
680
+ .bdrv_co_zone_mgmt = raw_co_zone_mgmt,
681
+#endif
682
};
683
684
#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
685
diff --git a/block/io.c b/block/io.c
152
index XXXXXXX..XXXXXXX 100644
686
index XXXXXXX..XXXXXXX 100644
153
--- a/tests/qemu-iotests/059.out
687
--- a/block/io.c
154
+++ b/tests/qemu-iotests/059.out
688
+++ b/block/io.c
155
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000 subformat=twoGbMax
689
@@ -XXX,XX +XXX,XX @@ out:
156
image: TEST_DIR/t.vmdk
690
return co.ret;
157
file format: vmdk
691
}
158
virtual size: 0.977 TiB (1073741824000 bytes)
692
159
-disk size: 16 KiB
693
+int coroutine_fn bdrv_co_zone_report(BlockDriverState *bs, int64_t offset,
160
+disk size: 1.97 MiB
694
+ unsigned int *nr_zones,
161
Format specific information:
695
+ BlockZoneDescriptor *zones)
162
cid: XXXXXXXX
696
+{
163
parent cid: XXXXXXXX
697
+ BlockDriver *drv = bs->drv;
164
diff --git a/tests/qemu-iotests/150.out b/tests/qemu-iotests/150.out.qcow2
698
+ CoroutineIOCompletion co = {
165
similarity index 100%
699
+ .coroutine = qemu_coroutine_self(),
166
rename from tests/qemu-iotests/150.out
700
+ };
167
rename to tests/qemu-iotests/150.out.qcow2
701
+ IO_CODE();
168
diff --git a/tests/qemu-iotests/150.out.raw b/tests/qemu-iotests/150.out.raw
702
+
169
new file mode 100644
703
+ bdrv_inc_in_flight(bs);
170
index XXXXXXX..XXXXXXX
704
+ if (!drv || !drv->bdrv_co_zone_report || bs->bl.zoned == BLK_Z_NONE) {
171
--- /dev/null
705
+ co.ret = -ENOTSUP;
172
+++ b/tests/qemu-iotests/150.out.raw
706
+ goto out;
173
@@ -XXX,XX +XXX,XX @@
707
+ }
174
+QA output created by 150
708
+ co.ret = drv->bdrv_co_zone_report(bs, offset, nr_zones, zones);
175
+
709
+out:
176
+=== Mapping sparse conversion ===
710
+ bdrv_dec_in_flight(bs);
177
+
711
+ return co.ret;
178
+Offset Length File
712
+}
179
+0 0x1000 TEST_DIR/t.IMGFMT
713
+
180
+
714
+int coroutine_fn bdrv_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
181
+=== Mapping non-sparse conversion ===
715
+ int64_t offset, int64_t len)
182
+
716
+{
183
+Offset Length File
717
+ BlockDriver *drv = bs->drv;
184
+0 0x100000 TEST_DIR/t.IMGFMT
718
+ CoroutineIOCompletion co = {
185
+*** done
719
+ .coroutine = qemu_coroutine_self(),
186
diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
720
+ };
187
index XXXXXXX..XXXXXXX 100755
721
+ IO_CODE();
188
--- a/tests/qemu-iotests/175
722
+
189
+++ b/tests/qemu-iotests/175
723
+ bdrv_inc_in_flight(bs);
190
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
724
+ if (!drv || !drv->bdrv_co_zone_mgmt || bs->bl.zoned == BLK_Z_NONE) {
191
# the file size. This function hides the resulting difference in the
725
+ co.ret = -ENOTSUP;
192
# stat -c '%b' output.
726
+ goto out;
193
# Parameter 1: Number of blocks an empty file occupies
727
+ }
194
-# Parameter 2: Image size in bytes
728
+ co.ret = drv->bdrv_co_zone_mgmt(bs, op, offset, len);
195
+# Parameter 2: Minimal number of blocks in an image
729
+out:
196
+# Parameter 3: Image size in bytes
730
+ bdrv_dec_in_flight(bs);
197
_filter_blocks()
731
+ return co.ret;
732
+}
733
+
734
void *qemu_blockalign(BlockDriverState *bs, size_t size)
198
{
735
{
199
extra_blocks=$1
736
IO_CODE();
200
- img_size=$2
737
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
201
+ min_blocks=$2
202
+ img_size=$3
203
204
- sed -e "s/blocks=$extra_blocks\\(\$\\|[^0-9]\\)/nothing allocated/" \
205
- -e "s/blocks=$((extra_blocks + img_size / 512))\\(\$\\|[^0-9]\\)/everything allocated/"
206
+ sed -e "s/blocks=$min_blocks\\(\$\\|[^0-9]\\)/min allocation/" \
207
+ -e "s/blocks=$((extra_blocks + img_size / 512))\\(\$\\|[^0-9]\\)/max allocation/"
208
}
209
210
# get standard environment, filters and checks
211
@@ -XXX,XX +XXX,XX @@ size=$((1 * 1024 * 1024))
212
touch "$TEST_DIR/empty"
213
extra_blocks=$(stat -c '%b' "$TEST_DIR/empty")
214
215
+# We always write the first byte; check how many blocks this filesystem
216
+# allocates to match empty image alloation.
217
+printf "\0" > "$TEST_DIR/empty"
218
+min_blocks=$(stat -c '%b' "$TEST_DIR/empty")
219
+
220
echo
221
echo "== creating image with default preallocation =="
222
_make_test_img $size | _filter_imgfmt
223
-stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $size
224
+stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size
225
226
for mode in off full falloc; do
227
echo
228
echo "== creating image with preallocation $mode =="
229
IMGOPTS=preallocation=$mode _make_test_img $size | _filter_imgfmt
230
- stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $size
231
+ stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size
232
done
233
234
# success, all done
235
diff --git a/tests/qemu-iotests/175.out b/tests/qemu-iotests/175.out
236
index XXXXXXX..XXXXXXX 100644
738
index XXXXXXX..XXXXXXX 100644
237
--- a/tests/qemu-iotests/175.out
739
--- a/qemu-io-cmds.c
238
+++ b/tests/qemu-iotests/175.out
740
+++ b/qemu-io-cmds.c
239
@@ -XXX,XX +XXX,XX @@ QA output created by 175
741
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t flush_cmd = {
240
742
.oneline = "flush all in-core file state to disk",
241
== creating image with default preallocation ==
743
};
242
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
744
243
-size=1048576, nothing allocated
745
+static inline int64_t tosector(int64_t bytes)
244
+size=1048576, min allocation
746
+{
245
747
+ return bytes >> BDRV_SECTOR_BITS;
246
== creating image with preallocation off ==
748
+}
247
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=off
749
+
248
-size=1048576, nothing allocated
750
+static int zone_report_f(BlockBackend *blk, int argc, char **argv)
249
+size=1048576, min allocation
751
+{
250
752
+ int ret;
251
== creating image with preallocation full ==
753
+ int64_t offset;
252
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=full
754
+ unsigned int nr_zones;
253
-size=1048576, everything allocated
755
+
254
+size=1048576, max allocation
756
+ ++optind;
255
757
+ offset = cvtnum(argv[optind]);
256
== creating image with preallocation falloc ==
758
+ ++optind;
257
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=falloc
759
+ nr_zones = cvtnum(argv[optind]);
258
-size=1048576, everything allocated
760
+
259
+size=1048576, max allocation
761
+ g_autofree BlockZoneDescriptor *zones = NULL;
260
*** done
762
+ zones = g_new(BlockZoneDescriptor, nr_zones);
261
diff --git a/tests/qemu-iotests/178.out.qcow2 b/tests/qemu-iotests/178.out.qcow2
763
+ ret = blk_zone_report(blk, offset, &nr_zones, zones);
262
index XXXXXXX..XXXXXXX 100644
764
+ if (ret < 0) {
263
--- a/tests/qemu-iotests/178.out.qcow2
765
+ printf("zone report failed: %s\n", strerror(-ret));
264
+++ b/tests/qemu-iotests/178.out.qcow2
766
+ } else {
265
@@ -XXX,XX +XXX,XX @@ converted image file size in bytes: 196608
767
+ for (int i = 0; i < nr_zones; ++i) {
266
== raw input image with data (human) ==
768
+ printf("start: 0x%" PRIx64 ", len 0x%" PRIx64 ", "
267
769
+ "cap"" 0x%" PRIx64 ", wptr 0x%" PRIx64 ", "
268
Formatting 'TEST_DIR/t.qcow2', fmt=IMGFMT size=1073741824
770
+ "zcond:%u, [type: %u]\n",
269
-required size: 393216
771
+ tosector(zones[i].start), tosector(zones[i].length),
270
+required size: 458752
772
+ tosector(zones[i].cap), tosector(zones[i].wp),
271
fully allocated size: 1074135040
773
+ zones[i].state, zones[i].type);
272
wrote 512/512 bytes at offset 512
774
+ }
273
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
775
+ }
274
@@ -XXX,XX +XXX,XX @@ converted image file size in bytes: 196608
776
+ return ret;
275
777
+}
276
Formatting 'TEST_DIR/t.qcow2', fmt=IMGFMT size=1073741824
778
+
277
{
779
+static const cmdinfo_t zone_report_cmd = {
278
- "required": 393216,
780
+ .name = "zone_report",
279
+ "required": 458752,
781
+ .altname = "zrp",
280
"fully-allocated": 1074135040
782
+ .cfunc = zone_report_f,
281
}
783
+ .argmin = 2,
282
wrote 512/512 bytes at offset 512
784
+ .argmax = 2,
283
diff --git a/tests/qemu-iotests/221.out b/tests/qemu-iotests/221.out
785
+ .args = "offset number",
284
index XXXXXXX..XXXXXXX 100644
786
+ .oneline = "report zone information",
285
--- a/tests/qemu-iotests/221.out
787
+};
286
+++ b/tests/qemu-iotests/221.out
788
+
287
@@ -XXX,XX +XXX,XX @@ QA output created by 221
789
+static int zone_open_f(BlockBackend *blk, int argc, char **argv)
288
=== Check mapping of unaligned raw image ===
790
+{
289
791
+ int ret;
290
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65537
792
+ int64_t offset, len;
291
-[{ "start": 0, "length": 66048, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
793
+ ++optind;
292
-[{ "start": 0, "length": 66048, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
794
+ offset = cvtnum(argv[optind]);
293
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
795
+ ++optind;
294
+{ "start": 4096, "length": 61952, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
796
+ len = cvtnum(argv[optind]);
295
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
797
+ ret = blk_zone_mgmt(blk, BLK_ZO_OPEN, offset, len);
296
+{ "start": 4096, "length": 61952, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
798
+ if (ret < 0) {
297
wrote 1/1 bytes at offset 65536
799
+ printf("zone open failed: %s\n", strerror(-ret));
298
1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
800
+ }
299
-[{ "start": 0, "length": 65536, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
801
+ return ret;
300
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
802
+}
301
+{ "start": 4096, "length": 61440, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
803
+
302
{ "start": 65536, "length": 1, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
804
+static const cmdinfo_t zone_open_cmd = {
303
{ "start": 65537, "length": 511, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
805
+ .name = "zone_open",
304
-[{ "start": 0, "length": 65536, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
806
+ .altname = "zo",
305
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
807
+ .cfunc = zone_open_f,
306
+{ "start": 4096, "length": 61440, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
808
+ .argmin = 2,
307
{ "start": 65536, "length": 1, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
809
+ .argmax = 2,
308
{ "start": 65537, "length": 511, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
810
+ .args = "offset len",
309
*** done
811
+ .oneline = "explicit open a range of zones in zone block device",
310
diff --git a/tests/qemu-iotests/253.out b/tests/qemu-iotests/253.out
812
+};
311
index XXXXXXX..XXXXXXX 100644
813
+
312
--- a/tests/qemu-iotests/253.out
814
+static int zone_close_f(BlockBackend *blk, int argc, char **argv)
313
+++ b/tests/qemu-iotests/253.out
815
+{
314
@@ -XXX,XX +XXX,XX @@ QA output created by 253
816
+ int ret;
315
=== Check mapping of unaligned raw image ===
817
+ int64_t offset, len;
316
818
+ ++optind;
317
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048575
819
+ offset = cvtnum(argv[optind]);
318
-[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
820
+ ++optind;
319
-[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
821
+ len = cvtnum(argv[optind]);
320
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
822
+ ret = blk_zone_mgmt(blk, BLK_ZO_CLOSE, offset, len);
321
+{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
823
+ if (ret < 0) {
322
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
824
+ printf("zone close failed: %s\n", strerror(-ret));
323
+{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
825
+ }
324
wrote 65535/65535 bytes at offset 983040
826
+ return ret;
325
63.999 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
827
+}
326
-[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
828
+
327
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
829
+static const cmdinfo_t zone_close_cmd = {
328
+{ "start": 4096, "length": 978944, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
830
+ .name = "zone_close",
329
{ "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
831
+ .altname = "zc",
330
-[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
832
+ .cfunc = zone_close_f,
331
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
833
+ .argmin = 2,
332
+{ "start": 4096, "length": 978944, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
834
+ .argmax = 2,
333
{ "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
835
+ .args = "offset len",
334
*** done
836
+ .oneline = "close a range of zones in zone block device",
837
+};
838
+
839
+static int zone_finish_f(BlockBackend *blk, int argc, char **argv)
840
+{
841
+ int ret;
842
+ int64_t offset, len;
843
+ ++optind;
844
+ offset = cvtnum(argv[optind]);
845
+ ++optind;
846
+ len = cvtnum(argv[optind]);
847
+ ret = blk_zone_mgmt(blk, BLK_ZO_FINISH, offset, len);
848
+ if (ret < 0) {
849
+ printf("zone finish failed: %s\n", strerror(-ret));
850
+ }
851
+ return ret;
852
+}
853
+
854
+static const cmdinfo_t zone_finish_cmd = {
855
+ .name = "zone_finish",
856
+ .altname = "zf",
857
+ .cfunc = zone_finish_f,
858
+ .argmin = 2,
859
+ .argmax = 2,
860
+ .args = "offset len",
861
+ .oneline = "finish a range of zones in zone block device",
862
+};
863
+
864
+static int zone_reset_f(BlockBackend *blk, int argc, char **argv)
865
+{
866
+ int ret;
867
+ int64_t offset, len;
868
+ ++optind;
869
+ offset = cvtnum(argv[optind]);
870
+ ++optind;
871
+ len = cvtnum(argv[optind]);
872
+ ret = blk_zone_mgmt(blk, BLK_ZO_RESET, offset, len);
873
+ if (ret < 0) {
874
+ printf("zone reset failed: %s\n", strerror(-ret));
875
+ }
876
+ return ret;
877
+}
878
+
879
+static const cmdinfo_t zone_reset_cmd = {
880
+ .name = "zone_reset",
881
+ .altname = "zrs",
882
+ .cfunc = zone_reset_f,
883
+ .argmin = 2,
884
+ .argmax = 2,
885
+ .args = "offset len",
886
+ .oneline = "reset a zone write pointer in zone block device",
887
+};
888
+
889
static int truncate_f(BlockBackend *blk, int argc, char **argv);
890
static const cmdinfo_t truncate_cmd = {
891
.name = "truncate",
892
@@ -XXX,XX +XXX,XX @@ static void __attribute((constructor)) init_qemuio_commands(void)
893
qemuio_add_command(&aio_write_cmd);
894
qemuio_add_command(&aio_flush_cmd);
895
qemuio_add_command(&flush_cmd);
896
+ qemuio_add_command(&zone_report_cmd);
897
+ qemuio_add_command(&zone_open_cmd);
898
+ qemuio_add_command(&zone_close_cmd);
899
+ qemuio_add_command(&zone_finish_cmd);
900
+ qemuio_add_command(&zone_reset_cmd);
901
qemuio_add_command(&truncate_cmd);
902
qemuio_add_command(&length_cmd);
903
qemuio_add_command(&info_cmd);
335
--
904
--
336
2.21.0
905
2.39.2
337
906
338
907
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Sam Li <faithilikerun@gmail.com>
2
2
3
It is possible to enable only a subset of the block drivers with the
3
raw-format driver usually sits on top of file-posix driver. It needs to
4
"--block-drv-rw-whitelist" option of the "configure" script. All other
4
pass through requests of zone commands.
5
drivers are marked as unusable (or only included as read-only with the
6
"--block-drv-ro-whitelist" option). If an iotest is now using such a
7
disabled block driver, it is failing - which is bad, since at least the
8
tests in the "auto" group should be able to deal with this situation.
9
Thus let's introduce a "_require_drivers" function that can be used by
10
the shell tests to check for the availability of certain drivers first,
11
and marks the test as "not run" if one of the drivers is missing.
12
5
13
This patch mainly targets the test in the "auto" group which should
6
Signed-off-by: Sam Li <faithilikerun@gmail.com>
14
never fail in such a case, but also improves some of the other tests
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
15
along the way. Note that we also assume that the "qcow2" and "file"
8
Reviewed-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
16
drivers are always available - otherwise it does not make sense to
9
Reviewed-by: Hannes Reinecke <hare@suse.de>
17
run "make check-block" at all (which only tests with qcow2 by default).
10
Reviewed-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
11
Acked-by: Kevin Wolf <kwolf@redhat.com>
12
Message-id: 20230324090605.28361-5-faithilikerun@gmail.com
13
[Adjust commit message prefix as suggested by Philippe Mathieu-Daudé
14
<philmd@linaro.org>.
15
--Stefan]
16
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
17
---
18
block/raw-format.c | 17 +++++++++++++++++
19
1 file changed, 17 insertions(+)
18
20
19
Signed-off-by: Thomas Huth <thuth@redhat.com>
21
diff --git a/block/raw-format.c b/block/raw-format.c
20
Message-id: 20190823133552.11680-1-thuth@redhat.com
22
index XXXXXXX..XXXXXXX 100644
21
Signed-off-by: Max Reitz <mreitz@redhat.com>
23
--- a/block/raw-format.c
22
---
24
+++ b/block/raw-format.c
23
tests/qemu-iotests/071 | 1 +
25
@@ -XXX,XX +XXX,XX @@ raw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
24
tests/qemu-iotests/081 | 4 +---
26
return bdrv_co_pdiscard(bs->file, offset, bytes);
25
tests/qemu-iotests/099 | 1 +
26
tests/qemu-iotests/120 | 1 +
27
tests/qemu-iotests/162 | 4 +---
28
tests/qemu-iotests/184 | 1 +
29
tests/qemu-iotests/186 | 1 +
30
tests/qemu-iotests/common.rc | 14 ++++++++++++++
31
8 files changed, 21 insertions(+), 6 deletions(-)
32
33
diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071
34
index XXXXXXX..XXXXXXX 100755
35
--- a/tests/qemu-iotests/071
36
+++ b/tests/qemu-iotests/071
37
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
38
39
_supported_fmt qcow2
40
_supported_proto file
41
+_require_drivers blkdebug blkverify
42
43
do_run_qemu()
44
{
45
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
46
index XXXXXXX..XXXXXXX 100755
47
--- a/tests/qemu-iotests/081
48
+++ b/tests/qemu-iotests/081
49
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
50
_supported_fmt raw
51
_supported_proto file
52
_supported_os Linux
53
+_require_drivers quorum
54
55
do_run_qemu()
56
{
57
@@ -XXX,XX +XXX,XX @@ run_qemu()
58
| _filter_qemu_io | _filter_generated_node_ids
59
}
27
}
60
28
61
-test_quorum=$($QEMU_IMG --help|grep quorum)
29
+static int coroutine_fn GRAPH_RDLOCK
62
-[ "$test_quorum" = "" ] && _supported_fmt quorum
30
+raw_co_zone_report(BlockDriverState *bs, int64_t offset,
63
-
31
+ unsigned int *nr_zones,
64
quorum="driver=raw,file.driver=quorum,file.vote-threshold=2"
32
+ BlockZoneDescriptor *zones)
65
quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw"
66
quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw"
67
diff --git a/tests/qemu-iotests/099 b/tests/qemu-iotests/099
68
index XXXXXXX..XXXXXXX 100755
69
--- a/tests/qemu-iotests/099
70
+++ b/tests/qemu-iotests/099
71
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
72
_supported_fmt qcow qcow2 qed vdi vhdx vmdk vpc
73
_supported_proto file
74
_supported_os Linux
75
+_require_drivers blkdebug blkverify
76
_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
77
"subformat=twoGbMaxExtentSparse"
78
79
diff --git a/tests/qemu-iotests/120 b/tests/qemu-iotests/120
80
index XXXXXXX..XXXXXXX 100755
81
--- a/tests/qemu-iotests/120
82
+++ b/tests/qemu-iotests/120
83
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
84
_supported_fmt generic
85
_supported_proto file
86
_unsupported_fmt luks
87
+_require_drivers raw
88
89
_make_test_img 64M
90
91
diff --git a/tests/qemu-iotests/162 b/tests/qemu-iotests/162
92
index XXXXXXX..XXXXXXX 100755
93
--- a/tests/qemu-iotests/162
94
+++ b/tests/qemu-iotests/162
95
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
96
. ./common.filter
97
98
_supported_fmt generic
99
-
100
-test_ssh=$($QEMU_IMG --help | grep '^Supported formats:.* ssh\( \|$\)')
101
-[ "$test_ssh" = "" ] && _notrun "ssh support required"
102
+_require_drivers ssh
103
104
echo
105
echo '=== NBD ==='
106
diff --git a/tests/qemu-iotests/184 b/tests/qemu-iotests/184
107
index XXXXXXX..XXXXXXX 100755
108
--- a/tests/qemu-iotests/184
109
+++ b/tests/qemu-iotests/184
110
@@ -XXX,XX +XXX,XX @@ trap "exit \$status" 0 1 2 3 15
111
. ./common.filter
112
113
_supported_os Linux
114
+_require_drivers throttle
115
116
do_run_qemu()
117
{
118
diff --git a/tests/qemu-iotests/186 b/tests/qemu-iotests/186
119
index XXXXXXX..XXXXXXX 100755
120
--- a/tests/qemu-iotests/186
121
+++ b/tests/qemu-iotests/186
122
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
123
124
_supported_fmt qcow2
125
_supported_proto file
126
+_require_drivers null-co
127
128
if [ "$QEMU_DEFAULT_MACHINE" != "pc" ]; then
129
_notrun "Requires a PC machine"
130
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
131
index XXXXXXX..XXXXXXX 100644
132
--- a/tests/qemu-iotests/common.rc
133
+++ b/tests/qemu-iotests/common.rc
134
@@ -XXX,XX +XXX,XX @@ _require_command()
135
[ -x "$c" ] || _notrun "$1 utility required, skipped this test"
136
}
137
138
+# Check that a set of drivers has been whitelisted in the QEMU binary
139
+#
140
+_require_drivers()
141
+{
33
+{
142
+ available=$($QEMU -drive format=help | \
34
+ return bdrv_co_zone_report(bs->file->bs, offset, nr_zones, zones);
143
+ sed -e '/Supported formats:/!d' -e 's/Supported formats://')
144
+ for driver
145
+ do
146
+ if ! echo "$available" | grep -q " $driver\( \|$\)"; then
147
+ _notrun "$driver not available"
148
+ fi
149
+ done
150
+}
35
+}
151
+
36
+
152
# make sure this script returns success
37
+static int coroutine_fn GRAPH_RDLOCK
153
true
38
+raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
39
+ int64_t offset, int64_t len)
40
+{
41
+ return bdrv_co_zone_mgmt(bs->file->bs, op, offset, len);
42
+}
43
+
44
static int64_t coroutine_fn GRAPH_RDLOCK
45
raw_co_getlength(BlockDriverState *bs)
46
{
47
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_raw = {
48
.bdrv_co_pwritev = &raw_co_pwritev,
49
.bdrv_co_pwrite_zeroes = &raw_co_pwrite_zeroes,
50
.bdrv_co_pdiscard = &raw_co_pdiscard,
51
+ .bdrv_co_zone_report = &raw_co_zone_report,
52
+ .bdrv_co_zone_mgmt = &raw_co_zone_mgmt,
53
.bdrv_co_block_status = &raw_co_block_status,
54
.bdrv_co_copy_range_from = &raw_co_copy_range_from,
55
.bdrv_co_copy_range_to = &raw_co_copy_range_to,
154
--
56
--
155
2.21.0
57
2.39.2
156
58
157
59
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Sam Li <faithilikerun@gmail.com>
2
2
3
It's wrong to OR shared permissions. It may lead to crash on further
3
Putting zoned/non-zoned BlockDrivers on top of each other is not
4
permission updates.
4
allowed.
5
Also, no needs to consider previously calculated permissions, as at
6
this point we already bind all new parents and bdrv_get_cumulative_perm
7
result is enough. So fix the bug by just set permissions by
8
bdrv_get_cumulative_perm result.
9
5
10
Bug was introduced in long ago 234ac1a9025, in 2.9.
6
Signed-off-by: Sam Li <faithilikerun@gmail.com>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Reviewed-by: Hannes Reinecke <hare@suse.de>
9
Reviewed-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
10
Acked-by: Kevin Wolf <kwolf@redhat.com>
11
Message-id: 20230324090605.28361-6-faithilikerun@gmail.com
12
[Adjust commit message prefix as suggested by Philippe Mathieu-Daudé
13
<philmd@linaro.org> and clarify that the check is about zoned
14
BlockDrivers.
15
--Stefan]
16
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
17
---
18
include/block/block_int-common.h | 5 +++++
19
block.c | 19 +++++++++++++++++++
20
block/file-posix.c | 12 ++++++++++++
21
block/raw-format.c | 1 +
22
4 files changed, 37 insertions(+)
11
23
12
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
24
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
13
Message-id: 20190824100740.61635-1-vsementsov@virtuozzo.com
25
index XXXXXXX..XXXXXXX 100644
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
26
--- a/include/block/block_int-common.h
15
---
27
+++ b/include/block/block_int-common.h
16
block.c | 5 ++---
28
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
17
1 file changed, 2 insertions(+), 3 deletions(-)
29
*/
18
30
bool is_format;
31
32
+ /*
33
+ * Set to true if the BlockDriver supports zoned children.
34
+ */
35
+ bool supports_zoned_children;
36
+
37
/*
38
* Drivers not implementing bdrv_parse_filename nor bdrv_open should have
39
* this field set to true, except ones that are defined only by their
19
diff --git a/block.c b/block.c
40
diff --git a/block.c b/block.c
20
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
21
--- a/block.c
42
--- a/block.c
22
+++ b/block.c
43
+++ b/block.c
23
@@ -XXX,XX +XXX,XX @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
44
@@ -XXX,XX +XXX,XX @@ void bdrv_add_child(BlockDriverState *parent_bs, BlockDriverState *child_bs,
24
{
45
return;
25
BdrvChild *c, *next;
26
GSList *list = NULL, *p;
27
- uint64_t old_perm, old_shared;
28
uint64_t perm = 0, shared = BLK_PERM_ALL;
29
int ret;
30
31
@@ -XXX,XX +XXX,XX @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
32
bdrv_unref(from);
33
}
46
}
34
47
35
- bdrv_get_cumulative_perm(to, &old_perm, &old_shared);
48
+ /*
36
- bdrv_set_perm(to, old_perm | perm, old_shared | shared);
49
+ * Non-zoned block drivers do not follow zoned storage constraints
37
+ bdrv_get_cumulative_perm(to, &perm, &shared);
50
+ * (i.e. sequential writes to zones). Refuse mixing zoned and non-zoned
38
+ bdrv_set_perm(to, perm, shared);
51
+ * drivers in a graph.
39
52
+ */
40
out:
53
+ if (!parent_bs->drv->supports_zoned_children &&
41
g_slist_free(list);
54
+ child_bs->bl.zoned == BLK_Z_HM) {
55
+ /*
56
+ * The host-aware model allows zoned storage constraints and random
57
+ * write. Allow mixing host-aware and non-zoned drivers. Using
58
+ * host-aware device as a regular device.
59
+ */
60
+ error_setg(errp, "Cannot add a %s child to a %s parent",
61
+ child_bs->bl.zoned == BLK_Z_HM ? "zoned" : "non-zoned",
62
+ parent_bs->drv->supports_zoned_children ?
63
+ "support zoned children" : "not support zoned children");
64
+ return;
65
+ }
66
+
67
if (!QLIST_EMPTY(&child_bs->parents)) {
68
error_setg(errp, "The node %s already has a parent",
69
child_bs->node_name);
70
diff --git a/block/file-posix.c b/block/file-posix.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/block/file-posix.c
73
+++ b/block/file-posix.c
74
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
75
goto fail;
76
}
77
}
78
+#ifdef CONFIG_BLKZONED
79
+ /*
80
+ * The kernel page cache does not reliably work for writes to SWR zones
81
+ * of zoned block device because it can not guarantee the order of writes.
82
+ */
83
+ if ((bs->bl.zoned != BLK_Z_NONE) &&
84
+ (!(s->open_flags & O_DIRECT))) {
85
+ error_setg(errp, "The driver supports zoned devices, and it requires "
86
+ "cache.direct=on, which was not specified.");
87
+ return -EINVAL; /* No host kernel page cache */
88
+ }
89
+#endif
90
91
if (S_ISBLK(st.st_mode)) {
92
#ifdef __linux__
93
diff --git a/block/raw-format.c b/block/raw-format.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/block/raw-format.c
96
+++ b/block/raw-format.c
97
@@ -XXX,XX +XXX,XX @@ static void raw_child_perm(BlockDriverState *bs, BdrvChild *c,
98
BlockDriver bdrv_raw = {
99
.format_name = "raw",
100
.instance_size = sizeof(BDRVRawState),
101
+ .supports_zoned_children = true,
102
.bdrv_probe = &raw_probe,
103
.bdrv_reopen_prepare = &raw_reopen_prepare,
104
.bdrv_reopen_commit = &raw_reopen_commit,
42
--
105
--
43
2.21.0
106
2.39.2
44
107
45
108
diff view generated by jsdifflib
1
We had a test for a case where relative extent paths did not work, but
1
From: Sam Li <faithilikerun@gmail.com>
2
unfortunately we just fixed the underlying problem, so it works now.
3
This patch adds a new test case that still fails.
4
2
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
The new block layer APIs of zoned block devices can be tested by:
6
Reviewed-by: John Snow <jsnow@redhat.com>
4
$ tests/qemu-iotests/check zoned
7
Message-id: 20190815153638.4600-4-mreitz@redhat.com
5
Run each zone operation on a newly created null_blk device
8
Reviewed-by: John Snow <jsnow@redhat.com>
6
and see whether it outputs the same zone information.
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
8
Signed-off-by: Sam Li <faithilikerun@gmail.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Acked-by: Kevin Wolf <kwolf@redhat.com>
11
Message-id: 20230324090605.28361-7-faithilikerun@gmail.com
12
[Adjust commit message prefix as suggested by Philippe Mathieu-Daudé
13
<philmd@linaro.org>.
14
--Stefan]
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
---
16
---
11
tests/qemu-iotests/059 | 27 +++++++++++++++++++++++++++
17
tests/qemu-iotests/tests/zoned | 89 ++++++++++++++++++++++++++++++
12
tests/qemu-iotests/059.out | 4 ++++
18
tests/qemu-iotests/tests/zoned.out | 53 ++++++++++++++++++
13
2 files changed, 31 insertions(+)
19
2 files changed, 142 insertions(+)
20
create mode 100755 tests/qemu-iotests/tests/zoned
21
create mode 100644 tests/qemu-iotests/tests/zoned.out
14
22
15
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
23
diff --git a/tests/qemu-iotests/tests/zoned b/tests/qemu-iotests/tests/zoned
16
index XXXXXXX..XXXXXXX 100755
24
new file mode 100755
17
--- a/tests/qemu-iotests/059
25
index XXXXXXX..XXXXXXX
18
+++ b/tests/qemu-iotests/059
26
--- /dev/null
19
@@ -XXX,XX +XXX,XX @@ $QEMU_IMG convert -f qcow2 -O vmdk -o subformat=streamOptimized "$TEST_IMG.qcow2
27
+++ b/tests/qemu-iotests/tests/zoned
20
28
@@ -XXX,XX +XXX,XX @@
21
echo
29
+#!/usr/bin/env bash
22
echo "=== Testing monolithicFlat with internally generated JSON file name ==="
30
+#
31
+# Test zone management operations.
32
+#
23
+
33
+
24
+echo '--- blkdebug ---'
34
+seq="$(basename $0)"
25
# Should work, because bdrv_dirname() works fine with blkdebug
35
+echo "QA output created by $seq"
26
IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
36
+status=1 # failure is the default!
27
$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" \
28
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TE
29
| _filter_testdir | _filter_imgfmt | _filter_img_info
30
_cleanup_test_img
31
32
+echo '--- quorum ---'
33
+# Should not work, because bdrv_dirname() does not work with quorum
34
+IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
35
+cp "$TEST_IMG" "$TEST_IMG.orig"
36
+
37
+
37
+filename="json:{
38
+_cleanup()
38
+ \"driver\": \"$IMGFMT\",
39
+{
39
+ \"file\": {
40
+ _cleanup_test_img
40
+ \"driver\": \"quorum\",
41
+ sudo -n rmmod null_blk
41
+ \"children\": [ {
42
+}
42
+ \"driver\": \"file\",
43
+trap "_cleanup; exit \$status" 0 1 2 3 15
43
+ \"filename\": \"$TEST_IMG\"
44
+ }, {
45
+ \"driver\": \"file\",
46
+ \"filename\": \"$TEST_IMG.orig\"
47
+ } ],
48
+ \"vote-threshold\": 1
49
+ } }"
50
+
44
+
51
+filename=$(echo "$filename" | tr '\n' ' ' | sed -e 's/\s\+/ /g')
45
+# get standard environment, filters and checks
52
+$QEMU_IMG info "$filename" 2>&1 \
46
+. ../common.rc
53
+ | sed -e "s/'json:[^']*'/\$QUORUM_FILE/g" \
47
+. ../common.filter
54
+ | _filter_testdir | _filter_imgfmt | _filter_img_info
48
+. ../common.qemu
49
+
50
+# This test only runs on Linux hosts with raw image files.
51
+_supported_fmt raw
52
+_supported_proto file
53
+_supported_os Linux
54
+
55
+sudo -n true || \
56
+ _notrun 'Password-less sudo required'
57
+
58
+IMG="--image-opts -n driver=host_device,filename=/dev/nullb0"
59
+QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
60
+
61
+echo "Testing a null_blk device:"
62
+echo "case 1: if the operations work"
63
+sudo -n modprobe null_blk nr_devices=1 zoned=1
64
+sudo -n chmod 0666 /dev/nullb0
65
+
66
+echo "(1) report the first zone:"
67
+$QEMU_IO $IMG -c "zrp 0 1"
68
+echo
69
+echo "report the first 10 zones"
70
+$QEMU_IO $IMG -c "zrp 0 10"
71
+echo
72
+echo "report the last zone:"
73
+$QEMU_IO $IMG -c "zrp 0x3e70000000 2" # 0x3e70000000 / 512 = 0x1f380000
74
+echo
75
+echo
76
+echo "(2) opening the first zone"
77
+$QEMU_IO $IMG -c "zo 0 268435456" # 268435456 / 512 = 524288
78
+echo "report after:"
79
+$QEMU_IO $IMG -c "zrp 0 1"
80
+echo
81
+echo "opening the second zone"
82
+$QEMU_IO $IMG -c "zo 268435456 268435456" #
83
+echo "report after:"
84
+$QEMU_IO $IMG -c "zrp 268435456 1"
85
+echo
86
+echo "opening the last zone"
87
+$QEMU_IO $IMG -c "zo 0x3e70000000 268435456"
88
+echo "report after:"
89
+$QEMU_IO $IMG -c "zrp 0x3e70000000 2"
90
+echo
91
+echo
92
+echo "(3) closing the first zone"
93
+$QEMU_IO $IMG -c "zc 0 268435456"
94
+echo "report after:"
95
+$QEMU_IO $IMG -c "zrp 0 1"
96
+echo
97
+echo "closing the last zone"
98
+$QEMU_IO $IMG -c "zc 0x3e70000000 268435456"
99
+echo "report after:"
100
+$QEMU_IO $IMG -c "zrp 0x3e70000000 2"
101
+echo
102
+echo
103
+echo "(4) finishing the second zone"
104
+$QEMU_IO $IMG -c "zf 268435456 268435456"
105
+echo "After finishing a zone:"
106
+$QEMU_IO $IMG -c "zrp 268435456 1"
107
+echo
108
+echo
109
+echo "(5) resetting the second zone"
110
+$QEMU_IO $IMG -c "zrs 268435456 268435456"
111
+echo "After resetting a zone:"
112
+$QEMU_IO $IMG -c "zrp 268435456 1"
113
+
114
+# success, all done
115
+echo "*** done"
116
+rm -f $seq.full
117
+status=0
118
diff --git a/tests/qemu-iotests/tests/zoned.out b/tests/qemu-iotests/tests/zoned.out
119
new file mode 100644
120
index XXXXXXX..XXXXXXX
121
--- /dev/null
122
+++ b/tests/qemu-iotests/tests/zoned.out
123
@@ -XXX,XX +XXX,XX @@
124
+QA output created by zoned
125
+Testing a null_blk device:
126
+case 1: if the operations work
127
+(1) report the first zone:
128
+start: 0x0, len 0x80000, cap 0x80000, wptr 0x0, zcond:1, [type: 2]
129
+
130
+report the first 10 zones
131
+start: 0x0, len 0x80000, cap 0x80000, wptr 0x0, zcond:1, [type: 2]
132
+start: 0x80000, len 0x80000, cap 0x80000, wptr 0x80000, zcond:1, [type: 2]
133
+start: 0x100000, len 0x80000, cap 0x80000, wptr 0x100000, zcond:1, [type: 2]
134
+start: 0x180000, len 0x80000, cap 0x80000, wptr 0x180000, zcond:1, [type: 2]
135
+start: 0x200000, len 0x80000, cap 0x80000, wptr 0x200000, zcond:1, [type: 2]
136
+start: 0x280000, len 0x80000, cap 0x80000, wptr 0x280000, zcond:1, [type: 2]
137
+start: 0x300000, len 0x80000, cap 0x80000, wptr 0x300000, zcond:1, [type: 2]
138
+start: 0x380000, len 0x80000, cap 0x80000, wptr 0x380000, zcond:1, [type: 2]
139
+start: 0x400000, len 0x80000, cap 0x80000, wptr 0x400000, zcond:1, [type: 2]
140
+start: 0x480000, len 0x80000, cap 0x80000, wptr 0x480000, zcond:1, [type: 2]
141
+
142
+report the last zone:
143
+start: 0x1f380000, len 0x80000, cap 0x80000, wptr 0x1f380000, zcond:1, [type: 2]
55
+
144
+
56
+
145
+
57
echo
146
+(2) opening the first zone
58
echo "=== Testing version 3 ==="
147
+report after:
59
_use_sample_img iotest-version3.vmdk.bz2
148
+start: 0x0, len 0x80000, cap 0x80000, wptr 0x0, zcond:3, [type: 2]
60
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
149
+
61
index XXXXXXX..XXXXXXX 100644
150
+opening the second zone
62
--- a/tests/qemu-iotests/059.out
151
+report after:
63
+++ b/tests/qemu-iotests/059.out
152
+start: 0x80000, len 0x80000, cap 0x80000, wptr 0x80000, zcond:3, [type: 2]
64
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 10240
153
+
65
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
154
+opening the last zone
66
155
+report after:
67
=== Testing monolithicFlat with internally generated JSON file name ===
156
+start: 0x1f380000, len 0x80000, cap 0x80000, wptr 0x1f380000, zcond:3, [type: 2]
68
+--- blkdebug ---
157
+
69
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
158
+
70
format name: IMGFMT
159
+(3) closing the first zone
71
cluster size: 0 bytes
160
+report after:
72
vm state offset: 0 bytes
161
+start: 0x0, len 0x80000, cap 0x80000, wptr 0x0, zcond:1, [type: 2]
73
+--- quorum ---
162
+
74
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
163
+closing the last zone
75
+qemu-img: Could not open $QUORUM_FILE: Cannot use relative paths with VMDK descriptor file $QUORUM_FILE: Cannot generate a base directory for quorum nodes
164
+report after:
76
165
+start: 0x1f380000, len 0x80000, cap 0x80000, wptr 0x1f380000, zcond:1, [type: 2]
77
=== Testing version 3 ===
166
+
78
image: TEST_DIR/iotest-version3.IMGFMT
167
+
168
+(4) finishing the second zone
169
+After finishing a zone:
170
+start: 0x80000, len 0x80000, cap 0x80000, wptr 0x100000, zcond:14, [type: 2]
171
+
172
+
173
+(5) resetting the second zone
174
+After resetting a zone:
175
+start: 0x80000, len 0x80000, cap 0x80000, wptr 0x80000, zcond:1, [type: 2]
176
+*** done
79
--
177
--
80
2.21.0
178
2.39.2
81
179
82
180
diff view generated by jsdifflib
New patch
1
From: Sam Li <faithilikerun@gmail.com>
1
2
3
Signed-off-by: Sam Li <faithilikerun@gmail.com>
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Reviewed-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
6
Acked-by: Kevin Wolf <kwolf@redhat.com>
7
Message-id: 20230324090605.28361-8-faithilikerun@gmail.com
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
---
10
block/file-posix.c | 3 +++
11
block/trace-events | 2 ++
12
2 files changed, 5 insertions(+)
13
14
diff --git a/block/file-posix.c b/block/file-posix.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/file-posix.c
17
+++ b/block/file-posix.c
18
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_zone_report(BlockDriverState *bs, int64_t offset,
19
},
20
};
21
22
+ trace_zbd_zone_report(bs, *nr_zones, offset >> BDRV_SECTOR_BITS);
23
return raw_thread_pool_submit(bs, handle_aiocb_zone_report, &acb);
24
}
25
#endif
26
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
27
},
28
};
29
30
+ trace_zbd_zone_mgmt(bs, op_name, offset >> BDRV_SECTOR_BITS,
31
+ len >> BDRV_SECTOR_BITS);
32
ret = raw_thread_pool_submit(bs, handle_aiocb_zone_mgmt, &acb);
33
if (ret != 0) {
34
error_report("ioctl %s failed %d", op_name, ret);
35
diff --git a/block/trace-events b/block/trace-events
36
index XXXXXXX..XXXXXXX 100644
37
--- a/block/trace-events
38
+++ b/block/trace-events
39
@@ -XXX,XX +XXX,XX @@ file_FindEjectableOpticalMedia(const char *media) "Matching using %s"
40
file_setup_cdrom(const char *partition) "Using %s as optical disc"
41
file_hdev_is_sg(int type, int version) "SG device found: type=%d, version=%d"
42
file_flush_fdatasync_failed(int err) "errno %d"
43
+zbd_zone_report(void *bs, unsigned int nr_zones, int64_t sector) "bs %p report %d zones starting at sector offset 0x%" PRIx64 ""
44
+zbd_zone_mgmt(void *bs, const char *op_name, int64_t sector, int64_t len) "bs %p %s starts at sector offset 0x%" PRIx64 " over a range of 0x%" PRIx64 " sectors"
45
46
# ssh.c
47
sftp_error(const char *op, const char *ssh_err, int ssh_err_code, int sftp_err_code) "%s failed: %s (libssh error code: %d, sftp error code: %d)"
48
--
49
2.39.2
diff view generated by jsdifflib
1
The error message for the test case where we have a quorum node for
1
From: Sam Li <faithilikerun@gmail.com>
2
which no directory name can be generated is different: For
3
twoGbMaxExtentSparse, it complains that it cannot open the extent file.
4
For other (sub)formats, it just notes that it cannot determine the
5
backing file path. Both are fine, but just disable twoGbMaxExtentSparse
6
for simplicity's sake.
7
2
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
Add the documentation about the zoned device support to virtio-blk
9
Reviewed-by: John Snow <jsnow@redhat.com>
4
emulation.
10
Message-id: 20190815153638.4600-7-mreitz@redhat.com
5
11
Reviewed-by: John Snow <jsnow@redhat.com>
6
Signed-off-by: Sam Li <faithilikerun@gmail.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Reviewed-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
9
Reviewed-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
10
Acked-by: Kevin Wolf <kwolf@redhat.com>
11
Message-id: 20230324090605.28361-9-faithilikerun@gmail.com
12
[Add index-api.rst to fix "zoned-storage.rst:document isn't included in
13
any toctree" error.
14
--Stefan]
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
16
---
14
tests/qemu-iotests/110 | 3 ++-
17
docs/devel/index-api.rst | 1 +
15
1 file changed, 2 insertions(+), 1 deletion(-)
18
docs/devel/zoned-storage.rst | 43 ++++++++++++++++++++++++++
19
docs/system/qemu-block-drivers.rst.inc | 6 ++++
20
3 files changed, 50 insertions(+)
21
create mode 100644 docs/devel/zoned-storage.rst
16
22
17
diff --git a/tests/qemu-iotests/110 b/tests/qemu-iotests/110
23
diff --git a/docs/devel/index-api.rst b/docs/devel/index-api.rst
18
index XXXXXXX..XXXXXXX 100755
24
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qemu-iotests/110
25
--- a/docs/devel/index-api.rst
20
+++ b/tests/qemu-iotests/110
26
+++ b/docs/devel/index-api.rst
21
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
27
@@ -XXX,XX +XXX,XX @@ generated from in-code annotations to function prototypes.
22
# Any format supporting backing files
28
memory
23
_supported_fmt qed qcow qcow2 vmdk
29
modules
24
_supported_proto file
30
ui
25
-_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
31
+ zoned-storage
26
+_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
32
diff --git a/docs/devel/zoned-storage.rst b/docs/devel/zoned-storage.rst
27
+ "subformat=twoGbMaxExtentSparse"
33
new file mode 100644
28
34
index XXXXXXX..XXXXXXX
29
TEST_IMG_REL=$(basename "$TEST_IMG")
35
--- /dev/null
36
+++ b/docs/devel/zoned-storage.rst
37
@@ -XXX,XX +XXX,XX @@
38
+=============
39
+zoned-storage
40
+=============
41
+
42
+Zoned Block Devices (ZBDs) divide the LBA space into block regions called zones
43
+that are larger than the LBA size. They can only allow sequential writes, which
44
+can reduce write amplification in SSDs, and potentially lead to higher
45
+throughput and increased capacity. More details about ZBDs can be found at:
46
+
47
+https://zonedstorage.io/docs/introduction/zoned-storage
48
+
49
+1. Block layer APIs for zoned storage
50
+-------------------------------------
51
+QEMU block layer supports three zoned storage models:
52
+- BLK_Z_HM: The host-managed zoned model only allows sequential writes access
53
+to zones. It supports ZBD-specific I/O commands that can be used by a host to
54
+manage the zones of a device.
55
+- BLK_Z_HA: The host-aware zoned model allows random write operations in
56
+zones, making it backward compatible with regular block devices.
57
+- BLK_Z_NONE: The non-zoned model has no zones support. It includes both
58
+regular and drive-managed ZBD devices. ZBD-specific I/O commands are not
59
+supported.
60
+
61
+The block device information resides inside BlockDriverState. QEMU uses
62
+BlockLimits struct(BlockDriverState::bl) that is continuously accessed by the
63
+block layer while processing I/O requests. A BlockBackend has a root pointer to
64
+a BlockDriverState graph(for example, raw format on top of file-posix). The
65
+zoned storage information can be propagated from the leaf BlockDriverState all
66
+the way up to the BlockBackend. If the zoned storage model in file-posix is
67
+set to BLK_Z_HM, then block drivers will declare support for zoned host device.
68
+
69
+The block layer APIs support commands needed for zoned storage devices,
70
+including report zones, four zone operations, and zone append.
71
+
72
+2. Emulating zoned storage controllers
73
+--------------------------------------
74
+When the BlockBackend's BlockLimits model reports a zoned storage device, users
75
+like the virtio-blk emulation or the qemu-io-cmds.c utility can use block layer
76
+APIs for zoned storage emulation or testing.
77
+
78
+For example, to test zone_report on a null_blk device using qemu-io is:
79
+$ path/to/qemu-io --image-opts -n driver=host_device,filename=/dev/nullb0
80
+-c "zrp offset nr_zones"
81
diff --git a/docs/system/qemu-block-drivers.rst.inc b/docs/system/qemu-block-drivers.rst.inc
82
index XXXXXXX..XXXXXXX 100644
83
--- a/docs/system/qemu-block-drivers.rst.inc
84
+++ b/docs/system/qemu-block-drivers.rst.inc
85
@@ -XXX,XX +XXX,XX @@ Hard disks
86
you may corrupt your host data (use the ``-snapshot`` command
87
line option or modify the device permissions accordingly).
88
89
+Zoned block devices
90
+ Zoned block devices can be passed through to the guest if the emulated storage
91
+ controller supports zoned storage. Use ``--blockdev host_device,
92
+ node-name=drive0,filename=/dev/nullb0,cache.direct=on`` to pass through
93
+ ``/dev/nullb0`` as ``drive0``.
94
+
95
Windows
96
^^^^^^^
30
97
31
--
98
--
32
2.21.0
99
2.39.2
33
34
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
The sanitizers (especially the address sanitizer from Clang) are
3
Introduce the BdrvDmgUncompressFunc type defintion. To emphasis
4
sometimes printing out warnings or false positives - this spoils
4
dmg_uncompress_bz2 and dmg_uncompress_lzfse are pointer to functions,
5
the output of the iotests, causing some of the tests to fail.
5
declare them using this new typedef.
6
Thus let's skip the automatic iotests during "make check" when the
7
user configured QEMU with --enable-sanitizers.
8
6
9
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20190823084203.29734-1-thuth@redhat.com
8
Message-id: 20230320152610.32052-1-philmd@linaro.org
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
10
---
13
tests/check-block.sh | 5 +++++
11
block/dmg.h | 8 ++++----
14
1 file changed, 5 insertions(+)
12
block/dmg.c | 7 ++-----
13
2 files changed, 6 insertions(+), 9 deletions(-)
15
14
16
diff --git a/tests/check-block.sh b/tests/check-block.sh
15
diff --git a/block/dmg.h b/block/dmg.h
17
index XXXXXXX..XXXXXXX 100755
16
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/check-block.sh
17
--- a/block/dmg.h
19
+++ b/tests/check-block.sh
18
+++ b/block/dmg.h
20
@@ -XXX,XX +XXX,XX @@ if grep -q "TARGET_GPROF=y" *-softmmu/config-target.mak 2>/dev/null ; then
19
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVDMGState {
21
exit 0
20
z_stream zstream;
22
fi
21
} BDRVDMGState;
23
22
24
+if grep -q "CFLAGS.*-fsanitize" config-host.mak 2>/dev/null ; then
23
-extern int (*dmg_uncompress_bz2)(char *next_in, unsigned int avail_in,
25
+ echo "Sanitizers are enabled ==> Not running the qemu-iotests."
24
- char *next_out, unsigned int avail_out);
26
+ exit 0
25
+typedef int BdrvDmgUncompressFunc(char *next_in, unsigned int avail_in,
27
+fi
26
+ char *next_out, unsigned int avail_out);
28
+
27
29
if [ -z "$(find . -name 'qemu-system-*' -print)" ]; then
28
-extern int (*dmg_uncompress_lzfse)(char *next_in, unsigned int avail_in,
30
echo "No qemu-system binary available ==> Not running the qemu-iotests."
29
- char *next_out, unsigned int avail_out);
31
exit 0
30
+extern BdrvDmgUncompressFunc *dmg_uncompress_bz2;
31
+extern BdrvDmgUncompressFunc *dmg_uncompress_lzfse;
32
33
#endif
34
diff --git a/block/dmg.c b/block/dmg.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/block/dmg.c
37
+++ b/block/dmg.c
38
@@ -XXX,XX +XXX,XX @@
39
#include "qemu/memalign.h"
40
#include "dmg.h"
41
42
-int (*dmg_uncompress_bz2)(char *next_in, unsigned int avail_in,
43
- char *next_out, unsigned int avail_out);
44
-
45
-int (*dmg_uncompress_lzfse)(char *next_in, unsigned int avail_in,
46
- char *next_out, unsigned int avail_out);
47
+BdrvDmgUncompressFunc *dmg_uncompress_bz2;
48
+BdrvDmgUncompressFunc *dmg_uncompress_lzfse;
49
50
enum {
51
/* Limit chunk sizes to prevent unreasonable amounts of memory being used
32
--
52
--
33
2.21.0
53
2.39.2
34
54
35
55
diff view generated by jsdifflib
New patch
1
From: Thomas De Schampheleire <thomas.de_schampheleire@nokia.com>
1
2
3
The event filename is an absolute path. Convert it to a relative path when
4
writing '#line' directives, to preserve reproducibility of the generated
5
output when different base paths are used.
6
7
Signed-off-by: Thomas De Schampheleire <thomas.de_schampheleire@nokia.com>
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-Id: <20230406080045.21696-1-thomas.de_schampheleire@nokia.com>
10
---
11
scripts/tracetool/backend/ftrace.py | 4 +++-
12
scripts/tracetool/backend/log.py | 4 +++-
13
scripts/tracetool/backend/syslog.py | 4 +++-
14
3 files changed, 9 insertions(+), 3 deletions(-)
15
16
diff --git a/scripts/tracetool/backend/ftrace.py b/scripts/tracetool/backend/ftrace.py
17
index XXXXXXX..XXXXXXX 100644
18
--- a/scripts/tracetool/backend/ftrace.py
19
+++ b/scripts/tracetool/backend/ftrace.py
20
@@ -XXX,XX +XXX,XX @@
21
__email__ = "stefanha@redhat.com"
22
23
24
+import os.path
25
+
26
from tracetool import out
27
28
29
@@ -XXX,XX +XXX,XX @@ def generate_h(event, group):
30
args=event.args,
31
event_id="TRACE_" + event.name.upper(),
32
event_lineno=event.lineno,
33
- event_filename=event.filename,
34
+ event_filename=os.path.relpath(event.filename),
35
fmt=event.fmt.rstrip("\n"),
36
argnames=argnames)
37
38
diff --git a/scripts/tracetool/backend/log.py b/scripts/tracetool/backend/log.py
39
index XXXXXXX..XXXXXXX 100644
40
--- a/scripts/tracetool/backend/log.py
41
+++ b/scripts/tracetool/backend/log.py
42
@@ -XXX,XX +XXX,XX @@
43
__email__ = "stefanha@redhat.com"
44
45
46
+import os.path
47
+
48
from tracetool import out
49
50
51
@@ -XXX,XX +XXX,XX @@ def generate_h(event, group):
52
' }',
53
cond=cond,
54
event_lineno=event.lineno,
55
- event_filename=event.filename,
56
+ event_filename=os.path.relpath(event.filename),
57
name=event.name,
58
fmt=event.fmt.rstrip("\n"),
59
argnames=argnames)
60
diff --git a/scripts/tracetool/backend/syslog.py b/scripts/tracetool/backend/syslog.py
61
index XXXXXXX..XXXXXXX 100644
62
--- a/scripts/tracetool/backend/syslog.py
63
+++ b/scripts/tracetool/backend/syslog.py
64
@@ -XXX,XX +XXX,XX @@
65
__email__ = "stefanha@redhat.com"
66
67
68
+import os.path
69
+
70
from tracetool import out
71
72
73
@@ -XXX,XX +XXX,XX @@ def generate_h(event, group):
74
' }',
75
cond=cond,
76
event_lineno=event.lineno,
77
- event_filename=event.filename,
78
+ event_filename=os.path.relpath(event.filename),
79
name=event.name,
80
fmt=event.fmt.rstrip("\n"),
81
argnames=argnames)
82
--
83
2.39.2
diff view generated by jsdifflib
1
This makes iotest 033 pass with e.g. subformat=monolithicFlat. It also
1
From: Sam Li <faithilikerun@gmail.com>
2
turns a former error in 059 into success.
3
2
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
Since Linux doesn't have a user API to issue zone append operations to
5
Message-id: 20190815153638.4600-3-mreitz@redhat.com
4
zoned devices from user space, the file-posix driver is modified to add
6
Reviewed-by: John Snow <jsnow@redhat.com>
5
zone append emulation using regular writes. To do this, the file-posix
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
driver tracks the wp location of all zones of the device. It uses an
7
array of uint64_t. The most significant bit of each wp location indicates
8
if the zone type is conventional zones.
9
10
The zones wp can be changed due to the following operations issued:
11
- zone reset: change the wp to the start offset of that zone
12
- zone finish: change to the end location of that zone
13
- write to a zone
14
- zone append
15
16
Signed-off-by: Sam Li <faithilikerun@gmail.com>
17
Message-id: 20230407081657.17947-2-faithilikerun@gmail.com
18
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
---
19
---
9
block/vmdk.c | 54 ++++++++++++++++++++++++--------------
20
include/block/block-common.h | 14 +++
10
tests/qemu-iotests/059 | 7 +++--
21
include/block/block_int-common.h | 5 +
11
tests/qemu-iotests/059.out | 4 ++-
22
block/file-posix.c | 173 ++++++++++++++++++++++++++++++-
12
3 files changed, 42 insertions(+), 23 deletions(-)
23
3 files changed, 189 insertions(+), 3 deletions(-)
13
24
14
diff --git a/block/vmdk.c b/block/vmdk.c
25
diff --git a/include/block/block-common.h b/include/block/block-common.h
15
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
16
--- a/block/vmdk.c
27
--- a/include/block/block-common.h
17
+++ b/block/vmdk.c
28
+++ b/include/block/block-common.h
18
@@ -XXX,XX +XXX,XX @@ static const char *next_line(const char *s)
29
@@ -XXX,XX +XXX,XX @@ typedef struct BlockZoneDescriptor {
30
BlockZoneState state;
31
} BlockZoneDescriptor;
32
33
+/*
34
+ * Track write pointers of a zone in bytes.
35
+ */
36
+typedef struct BlockZoneWps {
37
+ CoMutex colock;
38
+ uint64_t wp[];
39
+} BlockZoneWps;
40
+
41
typedef struct BlockDriverInfo {
42
/* in bytes, 0 if irrelevant */
43
int cluster_size;
44
@@ -XXX,XX +XXX,XX @@ typedef enum {
45
#define BDRV_SECTOR_BITS 9
46
#define BDRV_SECTOR_SIZE (1ULL << BDRV_SECTOR_BITS)
47
48
+/*
49
+ * Get the first most significant bit of wp. If it is zero, then
50
+ * the zone type is SWR.
51
+ */
52
+#define BDRV_ZT_IS_CONV(wp) (wp & (1ULL << 63))
53
+
54
#define BDRV_REQUEST_MAX_SECTORS MIN_CONST(SIZE_MAX >> BDRV_SECTOR_BITS, \
55
INT_MAX >> BDRV_SECTOR_BITS)
56
#define BDRV_REQUEST_MAX_BYTES (BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS)
57
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/include/block/block_int-common.h
60
+++ b/include/block/block_int-common.h
61
@@ -XXX,XX +XXX,XX @@ typedef struct BlockLimits {
62
63
/* maximum number of active zones */
64
int64_t max_active_zones;
65
+
66
+ int64_t write_granularity;
67
} BlockLimits;
68
69
typedef struct BdrvOpBlocker BdrvOpBlocker;
70
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
71
CoMutex bsc_modify_lock;
72
/* Always non-NULL, but must only be dereferenced under an RCU read guard */
73
BdrvBlockStatusCache *block_status_cache;
74
+
75
+ /* array of write pointers' location of each zone in the zoned device. */
76
+ BlockZoneWps *wps;
77
};
78
79
struct BlockBackendRootState {
80
diff --git a/block/file-posix.c b/block/file-posix.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/block/file-posix.c
83
+++ b/block/file-posix.c
84
@@ -XXX,XX +XXX,XX @@ static int hdev_get_max_segments(int fd, struct stat *st)
85
#endif
19
}
86
}
20
87
21
static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
88
+#if defined(CONFIG_BLKZONED)
22
- const char *desc_file_path, QDict *options,
89
+/*
23
- Error **errp)
90
+ * If the reset_all flag is true, then the wps of zone whose state is
24
+ QDict *options, Error **errp)
91
+ * not readonly or offline should be all reset to the start sector.
25
{
92
+ * Else, take the real wp of the device.
26
int ret;
93
+ */
27
int matches;
94
+static int get_zones_wp(BlockDriverState *bs, int fd, int64_t offset,
28
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
95
+ unsigned int nrz, bool reset_all)
29
const char *p, *np;
96
+{
30
int64_t sectors = 0;
97
+ struct blk_zone *blkz;
31
int64_t flat_offset;
98
+ size_t rep_size;
32
+ char *desc_file_dir = NULL;
99
+ uint64_t sector = offset >> BDRV_SECTOR_BITS;
33
char *extent_path;
100
+ BlockZoneWps *wps = bs->wps;
34
BdrvChild *extent_file;
101
+ int j = offset / bs->bl.zone_size;
35
BDRVVmdkState *s = bs->opaque;
102
+ int ret, n = 0, i = 0;
36
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
103
+ rep_size = sizeof(struct blk_zone_report) + nrz * sizeof(struct blk_zone);
37
continue;
104
+ g_autofree struct blk_zone_report *rep = NULL;
38
}
105
+
39
106
+ rep = g_malloc(rep_size);
40
- if (!path_is_absolute(fname) && !path_has_protocol(fname) &&
107
+ blkz = (struct blk_zone *)(rep + 1);
41
- !desc_file_path[0])
108
+ while (n < nrz) {
42
- {
109
+ memset(rep, 0, rep_size);
43
- bdrv_refresh_filename(bs->file->bs);
110
+ rep->sector = sector;
44
- error_setg(errp, "Cannot use relative extent paths with VMDK "
111
+ rep->nr_zones = nrz - n;
45
- "descriptor file '%s'", bs->file->bs->filename);
112
+
46
- return -EINVAL;
113
+ do {
47
- }
114
+ ret = ioctl(fd, BLKREPORTZONE, rep);
48
+ if (path_is_absolute(fname)) {
115
+ } while (ret != 0 && errno == EINTR);
49
+ extent_path = g_strdup(fname);
116
+ if (ret != 0) {
50
+ } else {
117
+ error_report("%d: ioctl BLKREPORTZONE at %" PRId64 " failed %d",
51
+ if (!desc_file_dir) {
118
+ fd, offset, errno);
52
+ desc_file_dir = bdrv_dirname(bs->file->bs, errp);
119
+ return -errno;
53
+ if (!desc_file_dir) {
120
+ }
54
+ bdrv_refresh_filename(bs->file->bs);
121
+
55
+ error_prepend(errp, "Cannot use relative paths with VMDK "
122
+ if (!rep->nr_zones) {
56
+ "descriptor file '%s': ",
123
+ break;
57
+ bs->file->bs->filename);
124
+ }
58
+ ret = -EINVAL;
125
+
59
+ goto out;
126
+ for (i = 0; i < rep->nr_zones; ++i, ++n, ++j) {
127
+ /*
128
+ * The wp tracking cares only about sequential writes required and
129
+ * sequential write preferred zones so that the wp can advance to
130
+ * the right location.
131
+ * Use the most significant bit of the wp location to indicate the
132
+ * zone type: 0 for SWR/SWP zones and 1 for conventional zones.
133
+ */
134
+ if (blkz[i].type == BLK_ZONE_TYPE_CONVENTIONAL) {
135
+ wps->wp[j] |= 1ULL << 63;
136
+ } else {
137
+ switch(blkz[i].cond) {
138
+ case BLK_ZONE_COND_FULL:
139
+ case BLK_ZONE_COND_READONLY:
140
+ /* Zone not writable */
141
+ wps->wp[j] = (blkz[i].start + blkz[i].len) << BDRV_SECTOR_BITS;
142
+ break;
143
+ case BLK_ZONE_COND_OFFLINE:
144
+ /* Zone not writable nor readable */
145
+ wps->wp[j] = (blkz[i].start) << BDRV_SECTOR_BITS;
146
+ break;
147
+ default:
148
+ if (reset_all) {
149
+ wps->wp[j] = blkz[i].start << BDRV_SECTOR_BITS;
150
+ } else {
151
+ wps->wp[j] = blkz[i].wp << BDRV_SECTOR_BITS;
152
+ }
153
+ break;
60
+ }
154
+ }
61
+ }
155
+ }
62
156
+ }
63
- extent_path = path_combine(desc_file_path, fname);
157
+ sector = blkz[i - 1].start + blkz[i - 1].len;
64
+ extent_path = g_strconcat(desc_file_dir, fname, NULL);
158
+ }
65
+ }
159
+
66
160
+ return 0;
67
ret = snprintf(extent_opt_prefix, 32, "extents.%d", s->num_extents);
161
+}
68
assert(ret < 32);
162
+
69
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
163
+static void update_zones_wp(BlockDriverState *bs, int fd, int64_t offset,
70
g_free(extent_path);
164
+ unsigned int nrz)
71
if (local_err) {
165
+{
72
error_propagate(errp, local_err);
166
+ if (get_zones_wp(bs, fd, offset, nrz, 0) < 0) {
73
- return -EINVAL;
167
+ error_report("update zone wp failed");
74
+ ret = -EINVAL;
168
+ }
75
+ goto out;
169
+}
170
+#endif
171
+
172
static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
173
{
174
BDRVRawState *s = bs->opaque;
175
@@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
176
if (ret >= 0) {
177
bs->bl.max_active_zones = ret;
76
}
178
}
77
179
+
78
/* save to extents array */
180
+ ret = get_sysfs_long_val(&st, "physical_block_size");
79
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
181
+ if (ret >= 0) {
80
0, 0, 0, 0, 0, &extent, errp);
182
+ bs->bl.write_granularity = ret;
81
if (ret < 0) {
183
+ }
82
bdrv_unref_child(bs, extent_file);
184
+
83
- return ret;
185
+ /* The refresh_limits() function can be called multiple times. */
84
+ goto out;
186
+ g_free(bs->wps);
85
}
187
+ bs->wps = g_malloc(sizeof(BlockZoneWps) +
86
extent->flat_start_offset = flat_offset << 9;
188
+ sizeof(int64_t) * bs->bl.nr_zones);
87
} else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) {
189
+ ret = get_zones_wp(bs, s->fd, 0, bs->bl.nr_zones, 0);
88
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
190
+ if (ret < 0) {
89
g_free(buf);
191
+ error_setg_errno(errp, -ret, "report wps failed");
90
if (ret) {
192
+ bs->wps = NULL;
91
bdrv_unref_child(bs, extent_file);
193
+ return;
92
- return ret;
194
+ }
93
+ goto out;
195
+ qemu_co_mutex_init(&bs->wps->colock);
94
}
196
return;
95
extent = &s->extents[s->num_extents - 1];
197
}
96
} else if (!strcmp(type, "SESPARSE")) {
198
out:
97
ret = vmdk_open_se_sparse(bs, extent_file, bs->open_flags, errp);
199
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset,
98
if (ret) {
200
{
99
bdrv_unref_child(bs, extent_file);
201
BDRVRawState *s = bs->opaque;
100
- return ret;
202
RawPosixAIOData acb;
101
+ goto out;
203
+ int ret;
102
}
204
103
extent = &s->extents[s->num_extents - 1];
205
if (fd_open(bs) < 0)
104
} else {
206
return -EIO;
105
error_setg(errp, "Unsupported extent type '%s'", type);
207
+#if defined(CONFIG_BLKZONED)
106
bdrv_unref_child(bs, extent_file);
208
+ if (type & QEMU_AIO_WRITE && bs->wps) {
107
- return -ENOTSUP;
209
+ qemu_co_mutex_lock(&bs->wps->colock);
108
+ ret = -ENOTSUP;
210
+ }
109
+ goto out;
211
+#endif
110
}
212
111
extent->type = g_strdup(type);
213
/*
112
}
214
* When using O_DIRECT, the request must be aligned to be able to use
113
- return 0;
215
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset,
114
+
216
} else if (s->use_linux_io_uring) {
115
+ ret = 0;
217
LuringState *aio = aio_get_linux_io_uring(bdrv_get_aio_context(bs));
116
+ goto out;
218
assert(qiov->size == bytes);
117
219
- return luring_co_submit(bs, aio, s->fd, offset, qiov, type);
118
invalid:
220
+ ret = luring_co_submit(bs, aio, s->fd, offset, qiov, type);
119
np = next_line(p);
221
+ goto out;
120
@@ -XXX,XX +XXX,XX @@ invalid:
222
#endif
121
np--;
223
#ifdef CONFIG_LINUX_AIO
122
}
224
} else if (s->use_linux_aio) {
123
error_setg(errp, "Invalid extent line: %.*s", (int)(np - p), p);
225
LinuxAioState *aio = aio_get_linux_aio(bdrv_get_aio_context(bs));
124
- return -EINVAL;
226
assert(qiov->size == bytes);
125
+ ret = -EINVAL;
227
- return laio_co_submit(bs, aio, s->fd, offset, qiov, type,
228
+ ret = laio_co_submit(bs, aio, s->fd, offset, qiov, type,
229
s->aio_max_batch);
230
+ goto out;
231
#endif
232
}
233
234
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset,
235
};
236
237
assert(qiov->size == bytes);
238
- return raw_thread_pool_submit(bs, handle_aiocb_rw, &acb);
239
+ ret = raw_thread_pool_submit(bs, handle_aiocb_rw, &acb);
126
+
240
+
127
+out:
241
+out:
128
+ g_free(desc_file_dir);
242
+#if defined(CONFIG_BLKZONED)
243
+ BlockZoneWps *wps = bs->wps;
244
+ if (ret == 0) {
245
+ if (type & QEMU_AIO_WRITE && wps && bs->bl.zone_size) {
246
+ uint64_t *wp = &wps->wp[offset / bs->bl.zone_size];
247
+ if (!BDRV_ZT_IS_CONV(*wp)) {
248
+ /* Advance the wp if needed */
249
+ if (offset + bytes > *wp) {
250
+ *wp = offset + bytes;
251
+ }
252
+ }
253
+ }
254
+ } else {
255
+ if (type & QEMU_AIO_WRITE) {
256
+ update_zones_wp(bs, s->fd, 0, 1);
257
+ }
258
+ }
259
+
260
+ if (type & QEMU_AIO_WRITE && wps) {
261
+ qemu_co_mutex_unlock(&wps->colock);
262
+ }
263
+#endif
129
+ return ret;
264
+ return ret;
130
}
265
}
131
266
132
static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
267
static int coroutine_fn raw_co_preadv(BlockDriverState *bs, int64_t offset,
133
@@ -XXX,XX +XXX,XX @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
268
@@ -XXX,XX +XXX,XX @@ static void raw_close(BlockDriverState *bs)
134
}
269
BDRVRawState *s = bs->opaque;
135
s->create_type = g_strdup(ct);
270
136
s->desc_offset = 0;
271
if (s->fd >= 0) {
137
- ret = vmdk_parse_extents(buf, bs, bs->file->bs->exact_filename, options,
272
+#if defined(CONFIG_BLKZONED)
138
- errp);
273
+ g_free(bs->wps);
139
+ ret = vmdk_parse_extents(buf, bs, options, errp);
274
+#endif
140
exit:
275
qemu_close(s->fd);
276
s->fd = -1;
277
}
278
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
279
const char *op_name;
280
unsigned long zo;
281
int ret;
282
+ BlockZoneWps *wps = bs->wps;
283
int64_t capacity = bs->total_sectors << BDRV_SECTOR_BITS;
284
285
zone_size = bs->bl.zone_size;
286
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
287
return -EINVAL;
288
}
289
290
+ QEMU_LOCK_GUARD(&wps->colock);
291
+ uint32_t i = offset / bs->bl.zone_size;
292
+ uint32_t nrz = len / bs->bl.zone_size;
293
+ uint64_t *wp = &wps->wp[i];
294
+ if (BDRV_ZT_IS_CONV(*wp) && len != capacity) {
295
+ error_report("zone mgmt operations are not allowed for conventional zones");
296
+ return -EIO;
297
+ }
298
+
299
switch (op) {
300
case BLK_ZO_OPEN:
301
op_name = "BLKOPENZONE";
302
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
303
len >> BDRV_SECTOR_BITS);
304
ret = raw_thread_pool_submit(bs, handle_aiocb_zone_mgmt, &acb);
305
if (ret != 0) {
306
+ update_zones_wp(bs, s->fd, offset, i);
307
error_report("ioctl %s failed %d", op_name, ret);
308
+ return ret;
309
+ }
310
+
311
+ if (zo == BLKRESETZONE && len == capacity) {
312
+ ret = get_zones_wp(bs, s->fd, 0, bs->bl.nr_zones, 1);
313
+ if (ret < 0) {
314
+ error_report("reporting single wp failed");
315
+ return ret;
316
+ }
317
+ } else if (zo == BLKRESETZONE) {
318
+ for (int j = 0; j < nrz; ++j) {
319
+ wp[j] = offset + j * zone_size;
320
+ }
321
+ } else if (zo == BLKFINISHZONE) {
322
+ for (int j = 0; j < nrz; ++j) {
323
+ /* The zoned device allows the last zone smaller that the
324
+ * zone size. */
325
+ wp[j] = MIN(offset + (j + 1) * zone_size, offset + len);
326
+ }
327
}
328
141
return ret;
329
return ret;
142
}
143
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
144
index XXXXXXX..XXXXXXX 100755
145
--- a/tests/qemu-iotests/059
146
+++ b/tests/qemu-iotests/059
147
@@ -XXX,XX +XXX,XX @@ $QEMU_IMG convert -f qcow2 -O vmdk -o subformat=streamOptimized "$TEST_IMG.qcow2
148
149
echo
150
echo "=== Testing monolithicFlat with internally generated JSON file name ==="
151
+# Should work, because bdrv_dirname() works fine with blkdebug
152
IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
153
-$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" 2>&1 \
154
- | _filter_testdir | _filter_imgfmt
155
+$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" \
156
+ -c info \
157
+ 2>&1 \
158
+ | _filter_testdir | _filter_imgfmt | _filter_img_info
159
_cleanup_test_img
160
161
echo
162
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
163
index XXXXXXX..XXXXXXX 100644
164
--- a/tests/qemu-iotests/059.out
165
+++ b/tests/qemu-iotests/059.out
166
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 10240
167
168
=== Testing monolithicFlat with internally generated JSON file name ===
169
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
170
-qemu-io: can't open: Cannot use relative extent paths with VMDK descriptor file 'json:{"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "read_aio"}'
171
+format name: IMGFMT
172
+cluster size: 0 bytes
173
+vm state offset: 0 bytes
174
175
=== Testing version 3 ===
176
image: TEST_DIR/iotest-version3.IMGFMT
177
--
330
--
178
2.21.0
331
2.39.2
179
180
diff view generated by jsdifflib
New patch
1
From: Sam Li <faithilikerun@gmail.com>
1
2
3
A zone append command is a write operation that specifies the first
4
logical block of a zone as the write position. When writing to a zoned
5
block device using zone append, the byte offset of the call may point at
6
any position within the zone to which the data is being appended. Upon
7
completion the device will respond with the position where the data has
8
been written in the zone.
9
10
Signed-off-by: Sam Li <faithilikerun@gmail.com>
11
Reviewed-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
12
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Message-id: 20230407081657.17947-3-faithilikerun@gmail.com
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
---
16
include/block/block-io.h | 4 +++
17
include/block/block_int-common.h | 3 ++
18
include/block/raw-aio.h | 4 ++-
19
include/sysemu/block-backend-io.h | 9 +++++
20
block/block-backend.c | 60 +++++++++++++++++++++++++++++++
21
block/file-posix.c | 58 ++++++++++++++++++++++++++----
22
block/io.c | 27 ++++++++++++++
23
block/io_uring.c | 4 +++
24
block/linux-aio.c | 3 ++
25
block/raw-format.c | 8 +++++
26
10 files changed, 172 insertions(+), 8 deletions(-)
27
28
diff --git a/include/block/block-io.h b/include/block/block-io.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/block/block-io.h
31
+++ b/include/block/block-io.h
32
@@ -XXX,XX +XXX,XX @@ int coroutine_fn GRAPH_RDLOCK bdrv_co_zone_report(BlockDriverState *bs,
33
int coroutine_fn GRAPH_RDLOCK bdrv_co_zone_mgmt(BlockDriverState *bs,
34
BlockZoneOp op,
35
int64_t offset, int64_t len);
36
+int coroutine_fn GRAPH_RDLOCK bdrv_co_zone_append(BlockDriverState *bs,
37
+ int64_t *offset,
38
+ QEMUIOVector *qiov,
39
+ BdrvRequestFlags flags);
40
41
bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs);
42
int bdrv_block_status(BlockDriverState *bs, int64_t offset,
43
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/include/block/block_int-common.h
46
+++ b/include/block/block_int-common.h
47
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
48
BlockZoneDescriptor *zones);
49
int coroutine_fn (*bdrv_co_zone_mgmt)(BlockDriverState *bs, BlockZoneOp op,
50
int64_t offset, int64_t len);
51
+ int coroutine_fn (*bdrv_co_zone_append)(BlockDriverState *bs,
52
+ int64_t *offset, QEMUIOVector *qiov,
53
+ BdrvRequestFlags flags);
54
55
/* removable device specific */
56
bool coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_is_inserted)(
57
diff --git a/include/block/raw-aio.h b/include/block/raw-aio.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/include/block/raw-aio.h
60
+++ b/include/block/raw-aio.h
61
@@ -XXX,XX +XXX,XX @@
62
#define QEMU_AIO_TRUNCATE 0x0080
63
#define QEMU_AIO_ZONE_REPORT 0x0100
64
#define QEMU_AIO_ZONE_MGMT 0x0200
65
+#define QEMU_AIO_ZONE_APPEND 0x0400
66
#define QEMU_AIO_TYPE_MASK \
67
(QEMU_AIO_READ | \
68
QEMU_AIO_WRITE | \
69
@@ -XXX,XX +XXX,XX @@
70
QEMU_AIO_COPY_RANGE | \
71
QEMU_AIO_TRUNCATE | \
72
QEMU_AIO_ZONE_REPORT | \
73
- QEMU_AIO_ZONE_MGMT)
74
+ QEMU_AIO_ZONE_MGMT | \
75
+ QEMU_AIO_ZONE_APPEND)
76
77
/* AIO flags */
78
#define QEMU_AIO_MISALIGNED 0x1000
79
diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h
80
index XXXXXXX..XXXXXXX 100644
81
--- a/include/sysemu/block-backend-io.h
82
+++ b/include/sysemu/block-backend-io.h
83
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_zone_report(BlockBackend *blk, int64_t offset,
84
BlockAIOCB *blk_aio_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
85
int64_t offset, int64_t len,
86
BlockCompletionFunc *cb, void *opaque);
87
+BlockAIOCB *blk_aio_zone_append(BlockBackend *blk, int64_t *offset,
88
+ QEMUIOVector *qiov, BdrvRequestFlags flags,
89
+ BlockCompletionFunc *cb, void *opaque);
90
BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes,
91
BlockCompletionFunc *cb, void *opaque);
92
void blk_aio_cancel_async(BlockAIOCB *acb);
93
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
94
int64_t offset, int64_t len);
95
int co_wrapper_mixed blk_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
96
int64_t offset, int64_t len);
97
+int coroutine_fn blk_co_zone_append(BlockBackend *blk, int64_t *offset,
98
+ QEMUIOVector *qiov,
99
+ BdrvRequestFlags flags);
100
+int co_wrapper_mixed blk_zone_append(BlockBackend *blk, int64_t *offset,
101
+ QEMUIOVector *qiov,
102
+ BdrvRequestFlags flags);
103
104
int co_wrapper_mixed blk_pdiscard(BlockBackend *blk, int64_t offset,
105
int64_t bytes);
106
diff --git a/block/block-backend.c b/block/block-backend.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/block/block-backend.c
109
+++ b/block/block-backend.c
110
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
111
return &acb->common;
112
}
113
114
+static void coroutine_fn blk_aio_zone_append_entry(void *opaque)
115
+{
116
+ BlkAioEmAIOCB *acb = opaque;
117
+ BlkRwCo *rwco = &acb->rwco;
118
+
119
+ rwco->ret = blk_co_zone_append(rwco->blk, (int64_t *)acb->bytes,
120
+ rwco->iobuf, rwco->flags);
121
+ blk_aio_complete(acb);
122
+}
123
+
124
+BlockAIOCB *blk_aio_zone_append(BlockBackend *blk, int64_t *offset,
125
+ QEMUIOVector *qiov, BdrvRequestFlags flags,
126
+ BlockCompletionFunc *cb, void *opaque) {
127
+ BlkAioEmAIOCB *acb;
128
+ Coroutine *co;
129
+ IO_CODE();
130
+
131
+ blk_inc_in_flight(blk);
132
+ acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque);
133
+ acb->rwco = (BlkRwCo) {
134
+ .blk = blk,
135
+ .ret = NOT_DONE,
136
+ .flags = flags,
137
+ .iobuf = qiov,
138
+ };
139
+ acb->bytes = (int64_t)offset;
140
+ acb->has_returned = false;
141
+
142
+ co = qemu_coroutine_create(blk_aio_zone_append_entry, acb);
143
+ aio_co_enter(blk_get_aio_context(blk), co);
144
+ acb->has_returned = true;
145
+ if (acb->rwco.ret != NOT_DONE) {
146
+ replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
147
+ blk_aio_complete_bh, acb);
148
+ }
149
+
150
+ return &acb->common;
151
+}
152
+
153
/*
154
* Send a zone_report command.
155
* offset is a byte offset from the start of the device. No alignment
156
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
157
return ret;
158
}
159
160
+/*
161
+ * Send a zone_append command.
162
+ */
163
+int coroutine_fn blk_co_zone_append(BlockBackend *blk, int64_t *offset,
164
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
165
+{
166
+ int ret;
167
+ IO_CODE();
168
+
169
+ blk_inc_in_flight(blk);
170
+ blk_wait_while_drained(blk);
171
+ if (!blk_is_available(blk)) {
172
+ blk_dec_in_flight(blk);
173
+ return -ENOMEDIUM;
174
+ }
175
+
176
+ ret = bdrv_co_zone_append(blk_bs(blk), offset, qiov, flags);
177
+ blk_dec_in_flight(blk);
178
+ return ret;
179
+}
180
+
181
void blk_drain(BlockBackend *blk)
182
{
183
BlockDriverState *bs = blk_bs(blk);
184
diff --git a/block/file-posix.c b/block/file-posix.c
185
index XXXXXXX..XXXXXXX 100644
186
--- a/block/file-posix.c
187
+++ b/block/file-posix.c
188
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVRawState {
189
bool has_write_zeroes:1;
190
bool use_linux_aio:1;
191
bool use_linux_io_uring:1;
192
+ int64_t *offset; /* offset of zone append operation */
193
int page_cache_inconsistent; /* errno from fdatasync failure */
194
bool has_fallocate;
195
bool needs_alignment;
196
@@ -XXX,XX +XXX,XX @@ static ssize_t handle_aiocb_rw_vector(RawPosixAIOData *aiocb)
197
ssize_t len;
198
199
len = RETRY_ON_EINTR(
200
- (aiocb->aio_type & QEMU_AIO_WRITE) ?
201
+ (aiocb->aio_type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) ?
202
qemu_pwritev(aiocb->aio_fildes,
203
aiocb->io.iov,
204
aiocb->io.niov,
205
@@ -XXX,XX +XXX,XX @@ static ssize_t handle_aiocb_rw_linear(RawPosixAIOData *aiocb, char *buf)
206
ssize_t len;
207
208
while (offset < aiocb->aio_nbytes) {
209
- if (aiocb->aio_type & QEMU_AIO_WRITE) {
210
+ if (aiocb->aio_type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) {
211
len = pwrite(aiocb->aio_fildes,
212
(const char *)buf + offset,
213
aiocb->aio_nbytes - offset,
214
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_rw(void *opaque)
215
}
216
217
nbytes = handle_aiocb_rw_linear(aiocb, buf);
218
- if (!(aiocb->aio_type & QEMU_AIO_WRITE)) {
219
+ if (!(aiocb->aio_type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND))) {
220
char *p = buf;
221
size_t count = aiocb->aio_nbytes, copy;
222
int i;
223
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset,
224
if (fd_open(bs) < 0)
225
return -EIO;
226
#if defined(CONFIG_BLKZONED)
227
- if (type & QEMU_AIO_WRITE && bs->wps) {
228
+ if ((type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) && bs->wps) {
229
qemu_co_mutex_lock(&bs->wps->colock);
230
+ if (type & QEMU_AIO_ZONE_APPEND && bs->bl.zone_size) {
231
+ int index = offset / bs->bl.zone_size;
232
+ offset = bs->wps->wp[index];
233
+ }
234
}
235
#endif
236
237
@@ -XXX,XX +XXX,XX @@ out:
238
#if defined(CONFIG_BLKZONED)
239
BlockZoneWps *wps = bs->wps;
240
if (ret == 0) {
241
- if (type & QEMU_AIO_WRITE && wps && bs->bl.zone_size) {
242
+ if ((type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND))
243
+ && wps && bs->bl.zone_size) {
244
uint64_t *wp = &wps->wp[offset / bs->bl.zone_size];
245
if (!BDRV_ZT_IS_CONV(*wp)) {
246
+ if (type & QEMU_AIO_ZONE_APPEND) {
247
+ *s->offset = *wp;
248
+ }
249
/* Advance the wp if needed */
250
if (offset + bytes > *wp) {
251
*wp = offset + bytes;
252
@@ -XXX,XX +XXX,XX @@ out:
253
}
254
}
255
} else {
256
- if (type & QEMU_AIO_WRITE) {
257
+ if (type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) {
258
update_zones_wp(bs, s->fd, 0, 1);
259
}
260
}
261
262
- if (type & QEMU_AIO_WRITE && wps) {
263
+ if ((type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) && wps) {
264
qemu_co_mutex_unlock(&wps->colock);
265
}
266
#endif
267
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
268
}
269
#endif
270
271
+#if defined(CONFIG_BLKZONED)
272
+static int coroutine_fn raw_co_zone_append(BlockDriverState *bs,
273
+ int64_t *offset,
274
+ QEMUIOVector *qiov,
275
+ BdrvRequestFlags flags) {
276
+ assert(flags == 0);
277
+ int64_t zone_size_mask = bs->bl.zone_size - 1;
278
+ int64_t iov_len = 0;
279
+ int64_t len = 0;
280
+ BDRVRawState *s = bs->opaque;
281
+ s->offset = offset;
282
+
283
+ if (*offset & zone_size_mask) {
284
+ error_report("sector offset %" PRId64 " is not aligned to zone size "
285
+ "%" PRId32 "", *offset / 512, bs->bl.zone_size / 512);
286
+ return -EINVAL;
287
+ }
288
+
289
+ int64_t wg = bs->bl.write_granularity;
290
+ int64_t wg_mask = wg - 1;
291
+ for (int i = 0; i < qiov->niov; i++) {
292
+ iov_len = qiov->iov[i].iov_len;
293
+ if (iov_len & wg_mask) {
294
+ error_report("len of IOVector[%d] %" PRId64 " is not aligned to "
295
+ "block size %" PRId64 "", i, iov_len, wg);
296
+ return -EINVAL;
297
+ }
298
+ len += iov_len;
299
+ }
300
+
301
+ return raw_co_prw(bs, *offset, len, qiov, QEMU_AIO_ZONE_APPEND);
302
+}
303
+#endif
304
+
305
static coroutine_fn int
306
raw_do_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes,
307
bool blkdev)
308
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = {
309
/* zone management operations */
310
.bdrv_co_zone_report = raw_co_zone_report,
311
.bdrv_co_zone_mgmt = raw_co_zone_mgmt,
312
+ .bdrv_co_zone_append = raw_co_zone_append,
313
#endif
314
};
315
316
diff --git a/block/io.c b/block/io.c
317
index XXXXXXX..XXXXXXX 100644
318
--- a/block/io.c
319
+++ b/block/io.c
320
@@ -XXX,XX +XXX,XX @@ out:
321
return co.ret;
322
}
323
324
+int coroutine_fn bdrv_co_zone_append(BlockDriverState *bs, int64_t *offset,
325
+ QEMUIOVector *qiov,
326
+ BdrvRequestFlags flags)
327
+{
328
+ int ret;
329
+ BlockDriver *drv = bs->drv;
330
+ CoroutineIOCompletion co = {
331
+ .coroutine = qemu_coroutine_self(),
332
+ };
333
+ IO_CODE();
334
+
335
+ ret = bdrv_check_qiov_request(*offset, qiov->size, qiov, 0, NULL);
336
+ if (ret < 0) {
337
+ return ret;
338
+ }
339
+
340
+ bdrv_inc_in_flight(bs);
341
+ if (!drv || !drv->bdrv_co_zone_append || bs->bl.zoned == BLK_Z_NONE) {
342
+ co.ret = -ENOTSUP;
343
+ goto out;
344
+ }
345
+ co.ret = drv->bdrv_co_zone_append(bs, offset, qiov, flags);
346
+out:
347
+ bdrv_dec_in_flight(bs);
348
+ return co.ret;
349
+}
350
+
351
void *qemu_blockalign(BlockDriverState *bs, size_t size)
352
{
353
IO_CODE();
354
diff --git a/block/io_uring.c b/block/io_uring.c
355
index XXXXXXX..XXXXXXX 100644
356
--- a/block/io_uring.c
357
+++ b/block/io_uring.c
358
@@ -XXX,XX +XXX,XX @@ static int luring_do_submit(int fd, LuringAIOCB *luringcb, LuringState *s,
359
io_uring_prep_writev(sqes, fd, luringcb->qiov->iov,
360
luringcb->qiov->niov, offset);
361
break;
362
+ case QEMU_AIO_ZONE_APPEND:
363
+ io_uring_prep_writev(sqes, fd, luringcb->qiov->iov,
364
+ luringcb->qiov->niov, offset);
365
+ break;
366
case QEMU_AIO_READ:
367
io_uring_prep_readv(sqes, fd, luringcb->qiov->iov,
368
luringcb->qiov->niov, offset);
369
diff --git a/block/linux-aio.c b/block/linux-aio.c
370
index XXXXXXX..XXXXXXX 100644
371
--- a/block/linux-aio.c
372
+++ b/block/linux-aio.c
373
@@ -XXX,XX +XXX,XX @@ static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
374
case QEMU_AIO_WRITE:
375
io_prep_pwritev(iocbs, fd, qiov->iov, qiov->niov, offset);
376
break;
377
+ case QEMU_AIO_ZONE_APPEND:
378
+ io_prep_pwritev(iocbs, fd, qiov->iov, qiov->niov, offset);
379
+ break;
380
case QEMU_AIO_READ:
381
io_prep_preadv(iocbs, fd, qiov->iov, qiov->niov, offset);
382
break;
383
diff --git a/block/raw-format.c b/block/raw-format.c
384
index XXXXXXX..XXXXXXX 100644
385
--- a/block/raw-format.c
386
+++ b/block/raw-format.c
387
@@ -XXX,XX +XXX,XX @@ raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
388
return bdrv_co_zone_mgmt(bs->file->bs, op, offset, len);
389
}
390
391
+static int coroutine_fn GRAPH_RDLOCK
392
+raw_co_zone_append(BlockDriverState *bs,int64_t *offset, QEMUIOVector *qiov,
393
+ BdrvRequestFlags flags)
394
+{
395
+ return bdrv_co_zone_append(bs->file->bs, offset, qiov, flags);
396
+}
397
+
398
static int64_t coroutine_fn GRAPH_RDLOCK
399
raw_co_getlength(BlockDriverState *bs)
400
{
401
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_raw = {
402
.bdrv_co_pdiscard = &raw_co_pdiscard,
403
.bdrv_co_zone_report = &raw_co_zone_report,
404
.bdrv_co_zone_mgmt = &raw_co_zone_mgmt,
405
+ .bdrv_co_zone_append = &raw_co_zone_append,
406
.bdrv_co_block_status = &raw_co_block_status,
407
.bdrv_co_copy_range_from = &raw_co_copy_range_from,
408
.bdrv_co_copy_range_to = &raw_co_copy_range_to,
409
--
410
2.39.2
diff view generated by jsdifflib
1
From: Denis Plotnikov <dplotnikov@virtuozzo.com>
1
From: Sam Li <faithilikerun@gmail.com>
2
2
3
The patch allows to provide a pattern file for write
3
The patch tests zone append writes by reporting the zone wp after
4
command. There was no similar ability before.
4
the completion of the call. "zap -p" option can print the sector
5
offset value after completion, which should be the start sector
6
where the append write begins.
5
7
6
Signed-off-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
8
Signed-off-by: Sam Li <faithilikerun@gmail.com>
7
Message-id: 20190820164616.4072-1-dplotnikov@virtuozzo.com
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Message-id: 20230407081657.17947-4-faithilikerun@gmail.com
9
[mreitz: Keep optstring in alphabetical order]
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
12
---
12
qemu-io-cmds.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++---
13
qemu-io-cmds.c | 75 ++++++++++++++++++++++++++++++
13
1 file changed, 93 insertions(+), 6 deletions(-)
14
tests/qemu-iotests/tests/zoned | 16 +++++++
15
tests/qemu-iotests/tests/zoned.out | 16 +++++++
16
3 files changed, 107 insertions(+)
14
17
15
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
18
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/qemu-io-cmds.c
20
--- a/qemu-io-cmds.c
18
+++ b/qemu-io-cmds.c
21
+++ b/qemu-io-cmds.c
19
@@ -XXX,XX +XXX,XX @@ static void qemu_io_free(void *p)
22
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t zone_reset_cmd = {
20
qemu_vfree(p);
23
.oneline = "reset a zone write pointer in zone block device",
21
}
24
};
22
25
23
+/*
26
+static int do_aio_zone_append(BlockBackend *blk, QEMUIOVector *qiov,
24
+ * qemu_io_alloc_from_file()
27
+ int64_t *offset, int flags, int *total)
25
+ *
26
+ * Allocates the buffer and populates it with the content of the given file
27
+ * up to @len bytes. If the file length is less than @len, then the buffer
28
+ * is populated with the file content cyclically.
29
+ *
30
+ * @blk - the block backend where the buffer content is going to be written to
31
+ * @len - the buffer length
32
+ * @file_name - the file to read the content from
33
+ *
34
+ * Returns: the buffer pointer on success
35
+ * NULL on error
36
+ */
37
+static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
38
+ const char *file_name)
39
+{
28
+{
40
+ char *buf, *buf_origin;
29
+ int async_ret = NOT_DONE;
41
+ FILE *f = fopen(file_name, "r");
42
+ int pattern_len;
43
+
30
+
44
+ if (!f) {
31
+ blk_aio_zone_append(blk, offset, qiov, flags, aio_rw_done, &async_ret);
45
+ perror(file_name);
32
+ while (async_ret == NOT_DONE) {
46
+ return NULL;
33
+ main_loop_wait(false);
47
+ }
34
+ }
48
+
35
+
49
+ if (qemuio_misalign) {
36
+ *total = qiov->size;
50
+ len += MISALIGN_OFFSET;
37
+ return async_ret < 0 ? async_ret : 1;
38
+}
39
+
40
+static int zone_append_f(BlockBackend *blk, int argc, char **argv)
41
+{
42
+ int ret;
43
+ bool pflag = false;
44
+ int flags = 0;
45
+ int total = 0;
46
+ int64_t offset;
47
+ char *buf;
48
+ int c, nr_iov;
49
+ int pattern = 0xcd;
50
+ QEMUIOVector qiov;
51
+
52
+ if (optind > argc - 3) {
53
+ return -EINVAL;
51
+ }
54
+ }
52
+
55
+
53
+ buf_origin = buf = blk_blockalign(blk, len);
56
+ if ((c = getopt(argc, argv, "p")) != -1) {
54
+
57
+ pflag = true;
55
+ if (qemuio_misalign) {
56
+ buf_origin += MISALIGN_OFFSET;
57
+ buf += MISALIGN_OFFSET;
58
+ len -= MISALIGN_OFFSET;
59
+ }
58
+ }
60
+
59
+
61
+ pattern_len = fread(buf_origin, 1, len, f);
60
+ offset = cvtnum(argv[optind]);
62
+
61
+ if (offset < 0) {
63
+ if (ferror(f)) {
62
+ print_cvtnum_err(offset, argv[optind]);
64
+ perror(file_name);
63
+ return offset;
65
+ goto error;
64
+ }
65
+ optind++;
66
+ nr_iov = argc - optind;
67
+ buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern,
68
+ flags & BDRV_REQ_REGISTERED_BUF);
69
+ if (buf == NULL) {
70
+ return -EINVAL;
71
+ }
72
+ ret = do_aio_zone_append(blk, &qiov, &offset, flags, &total);
73
+ if (ret < 0) {
74
+ printf("zone append failed: %s\n", strerror(-ret));
75
+ goto out;
66
+ }
76
+ }
67
+
77
+
68
+ if (pattern_len == 0) {
78
+ if (pflag) {
69
+ fprintf(stderr, "%s: file is empty\n", file_name);
79
+ printf("After zap done, the append sector is 0x%" PRIx64 "\n",
70
+ goto error;
80
+ tosector(offset));
71
+ }
81
+ }
72
+
82
+
73
+ fclose(f);
83
+out:
74
+
84
+ qemu_io_free(blk, buf, qiov.size,
75
+ if (len > pattern_len) {
85
+ flags & BDRV_REQ_REGISTERED_BUF);
76
+ len -= pattern_len;
86
+ qemu_iovec_destroy(&qiov);
77
+ buf += pattern_len;
87
+ return ret;
78
+
79
+ while (len > 0) {
80
+ size_t len_to_copy = MIN(pattern_len, len);
81
+
82
+ memcpy(buf, buf_origin, len_to_copy);
83
+
84
+ len -= len_to_copy;
85
+ buf += len_to_copy;
86
+ }
87
+ }
88
+
89
+ return buf_origin;
90
+
91
+error:
92
+ qemu_io_free(buf_origin);
93
+ return NULL;
94
+}
88
+}
95
+
89
+
96
static void dump_buffer(const void *buffer, int64_t offset, int64_t len)
90
+static const cmdinfo_t zone_append_cmd = {
97
{
91
+ .name = "zone_append",
98
uint64_t i;
92
+ .altname = "zap",
99
@@ -XXX,XX +XXX,XX @@ static void write_help(void)
93
+ .cfunc = zone_append_f,
100
" -n, -- with -z, don't allow slow fallback\n"
94
+ .argmin = 3,
101
" -p, -- ignored for backwards compatibility\n"
95
+ .argmax = 4,
102
" -P, -- use different pattern to fill file\n"
96
+ .args = "offset len [len..]",
103
+" -s, -- use a pattern file to fill the write buffer\n"
97
+ .oneline = "append write a number of bytes at a specified offset",
104
" -C, -- report statistics in a machine parsable format\n"
98
+};
105
" -q, -- quiet mode, do not show I/O statistics\n"
99
+
106
" -u, -- with -z, allow unmapping\n"
100
static int truncate_f(BlockBackend *blk, int argc, char **argv);
107
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t write_cmd = {
101
static const cmdinfo_t truncate_cmd = {
108
.perm = BLK_PERM_WRITE,
102
.name = "truncate",
109
.argmin = 2,
103
@@ -XXX,XX +XXX,XX @@ static void __attribute((constructor)) init_qemuio_commands(void)
110
.argmax = -1,
104
qemuio_add_command(&zone_close_cmd);
111
- .args = "[-bcCfnquz] [-P pattern] off len",
105
qemuio_add_command(&zone_finish_cmd);
112
+ .args = "[-bcCfnquz] [-P pattern | -s source_file] off len",
106
qemuio_add_command(&zone_reset_cmd);
113
.oneline = "writes a number of bytes at a specified offset",
107
+ qemuio_add_command(&zone_append_cmd);
114
.help = write_help,
108
qemuio_add_command(&truncate_cmd);
115
};
109
qemuio_add_command(&length_cmd);
116
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
110
qemuio_add_command(&info_cmd);
117
{
111
diff --git a/tests/qemu-iotests/tests/zoned b/tests/qemu-iotests/tests/zoned
118
struct timespec t1, t2;
112
index XXXXXXX..XXXXXXX 100755
119
bool Cflag = false, qflag = false, bflag = false;
113
--- a/tests/qemu-iotests/tests/zoned
120
- bool Pflag = false, zflag = false, cflag = false;
114
+++ b/tests/qemu-iotests/tests/zoned
121
+ bool Pflag = false, zflag = false, cflag = false, sflag = false;
115
@@ -XXX,XX +XXX,XX @@ echo "(5) resetting the second zone"
122
int flags = 0;
116
$QEMU_IO $IMG -c "zrs 268435456 268435456"
123
int c, cnt, ret;
117
echo "After resetting a zone:"
124
char *buf = NULL;
118
$QEMU_IO $IMG -c "zrp 268435456 1"
125
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
119
+echo
126
/* Some compilers get confused and warn if this is not initialized. */
120
+echo
127
int64_t total = 0;
121
+echo "(6) append write" # the physical block size of the device is 4096
128
int pattern = 0xcd;
122
+$QEMU_IO $IMG -c "zrp 0 1"
129
+ const char *file_name = NULL;
123
+$QEMU_IO $IMG -c "zap -p 0 0x1000 0x2000"
130
124
+echo "After appending the first zone firstly:"
131
- while ((c = getopt(argc, argv, "bcCfnpP:quz")) != -1) {
125
+$QEMU_IO $IMG -c "zrp 0 1"
132
+ while ((c = getopt(argc, argv, "bcCfnpP:qs:uz")) != -1) {
126
+$QEMU_IO $IMG -c "zap -p 0 0x1000 0x2000"
133
switch (c) {
127
+echo "After appending the first zone secondly:"
134
case 'b':
128
+$QEMU_IO $IMG -c "zrp 0 1"
135
bflag = true;
129
+$QEMU_IO $IMG -c "zap -p 268435456 0x1000 0x2000"
136
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
130
+echo "After appending the second zone firstly:"
137
case 'q':
131
+$QEMU_IO $IMG -c "zrp 268435456 1"
138
qflag = true;
132
+$QEMU_IO $IMG -c "zap -p 268435456 0x1000 0x2000"
139
break;
133
+echo "After appending the second zone secondly:"
140
+ case 's':
134
+$QEMU_IO $IMG -c "zrp 268435456 1"
141
+ sflag = true;
135
142
+ file_name = optarg;
136
# success, all done
143
+ break;
137
echo "*** done"
144
case 'u':
138
diff --git a/tests/qemu-iotests/tests/zoned.out b/tests/qemu-iotests/tests/zoned.out
145
flags |= BDRV_REQ_MAY_UNMAP;
139
index XXXXXXX..XXXXXXX 100644
146
break;
140
--- a/tests/qemu-iotests/tests/zoned.out
147
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
141
+++ b/tests/qemu-iotests/tests/zoned.out
148
return -EINVAL;
142
@@ -XXX,XX +XXX,XX @@ start: 0x80000, len 0x80000, cap 0x80000, wptr 0x100000, zcond:14, [type: 2]
149
}
143
(5) resetting the second zone
150
144
After resetting a zone:
151
- if (zflag && Pflag) {
145
start: 0x80000, len 0x80000, cap 0x80000, wptr 0x80000, zcond:1, [type: 2]
152
- printf("-z and -P cannot be specified at the same time\n");
146
+
153
+ if (zflag + Pflag + sflag > 1) {
147
+
154
+ printf("Only one of -z, -P, and -s "
148
+(6) append write
155
+ "can be specified at the same time\n");
149
+start: 0x0, len 0x80000, cap 0x80000, wptr 0x0, zcond:1, [type: 2]
156
return -EINVAL;
150
+After zap done, the append sector is 0x0
157
}
151
+After appending the first zone firstly:
158
152
+start: 0x0, len 0x80000, cap 0x80000, wptr 0x18, zcond:2, [type: 2]
159
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
153
+After zap done, the append sector is 0x18
160
}
154
+After appending the first zone secondly:
161
155
+start: 0x0, len 0x80000, cap 0x80000, wptr 0x30, zcond:2, [type: 2]
162
if (!zflag) {
156
+After zap done, the append sector is 0x80000
163
- buf = qemu_io_alloc(blk, count, pattern);
157
+After appending the second zone firstly:
164
+ if (sflag) {
158
+start: 0x80000, len 0x80000, cap 0x80000, wptr 0x80018, zcond:2, [type: 2]
165
+ buf = qemu_io_alloc_from_file(blk, count, file_name);
159
+After zap done, the append sector is 0x80018
166
+ if (!buf) {
160
+After appending the second zone secondly:
167
+ return -EINVAL;
161
+start: 0x80000, len 0x80000, cap 0x80000, wptr 0x80030, zcond:2, [type: 2]
168
+ }
162
*** done
169
+ } else {
170
+ buf = qemu_io_alloc(blk, count, pattern);
171
+ }
172
}
173
174
clock_gettime(CLOCK_MONOTONIC, &t1);
175
--
163
--
176
2.21.0
164
2.39.2
177
178
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
From: Sam Li <faithilikerun@gmail.com>
2
2
3
Fixes: a6b257a08e3d72219f03e461a52152672fec0612
3
Signed-off-by: Sam Li <faithilikerun@gmail.com>
4
("file-posix: Handle undetectable alignment")
4
Reviewed-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
5
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Message-id: 20230407081657.17947-5-faithilikerun@gmail.com
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Message-id: 20190827101328.4062-1-stefanha@redhat.com
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
8
---
10
block/file-posix.c | 2 +-
9
block/file-posix.c | 3 +++
11
1 file changed, 1 insertion(+), 1 deletion(-)
10
block/trace-events | 2 ++
11
2 files changed, 5 insertions(+)
12
12
13
diff --git a/block/file-posix.c b/block/file-posix.c
13
diff --git a/block/file-posix.c b/block/file-posix.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/file-posix.c
15
--- a/block/file-posix.c
16
+++ b/block/file-posix.c
16
+++ b/block/file-posix.c
17
@@ -XXX,XX +XXX,XX @@ static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp)
17
@@ -XXX,XX +XXX,XX @@ out:
18
for (i = 0; i < ARRAY_SIZE(alignments); i++) {
18
if (!BDRV_ZT_IS_CONV(*wp)) {
19
align = alignments[i];
19
if (type & QEMU_AIO_ZONE_APPEND) {
20
if (raw_is_io_aligned(fd, buf + align, max_align)) {
20
*s->offset = *wp;
21
- /* Fallback to request_aligment. */
21
+ trace_zbd_zone_append_complete(bs, *s->offset
22
+ /* Fallback to request_alignment. */
22
+ >> BDRV_SECTOR_BITS);
23
s->buf_align = (align != 1) ? align : bs->bl.request_alignment;
23
}
24
break;
24
/* Advance the wp if needed */
25
}
25
if (offset + bytes > *wp) {
26
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_zone_append(BlockDriverState *bs,
27
len += iov_len;
28
}
29
30
+ trace_zbd_zone_append(bs, *offset >> BDRV_SECTOR_BITS);
31
return raw_co_prw(bs, *offset, len, qiov, QEMU_AIO_ZONE_APPEND);
32
}
33
#endif
34
diff --git a/block/trace-events b/block/trace-events
35
index XXXXXXX..XXXXXXX 100644
36
--- a/block/trace-events
37
+++ b/block/trace-events
38
@@ -XXX,XX +XXX,XX @@ file_hdev_is_sg(int type, int version) "SG device found: type=%d, version=%d"
39
file_flush_fdatasync_failed(int err) "errno %d"
40
zbd_zone_report(void *bs, unsigned int nr_zones, int64_t sector) "bs %p report %d zones starting at sector offset 0x%" PRIx64 ""
41
zbd_zone_mgmt(void *bs, const char *op_name, int64_t sector, int64_t len) "bs %p %s starts at sector offset 0x%" PRIx64 " over a range of 0x%" PRIx64 " sectors"
42
+zbd_zone_append(void *bs, int64_t sector) "bs %p append at sector offset 0x%" PRIx64 ""
43
+zbd_zone_append_complete(void *bs, int64_t sector) "bs %p returns append sector 0x%" PRIx64 ""
44
45
# ssh.c
46
sftp_error(const char *op, const char *ssh_err, int ssh_err_code, int sftp_err_code) "%s failed: %s (libssh error code: %d, sftp error code: %d)"
26
--
47
--
27
2.21.0
48
2.39.2
28
29
diff view generated by jsdifflib
New patch
1
From: Sam Li <faithilikerun@gmail.com>
1
2
3
Use scripts/update-linux-headers.sh to update headers to 6.3-rc1.
4
5
Signed-off-by: Sam Li <faithilikerun@gmail.com>
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Reviewed-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
8
Message-id: 20230407082528.18841-2-faithilikerun@gmail.com
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
---
11
include/standard-headers/drm/drm_fourcc.h | 12 +++
12
include/standard-headers/linux/ethtool.h | 48 ++++++++-
13
include/standard-headers/linux/fuse.h | 45 +++++++-
14
include/standard-headers/linux/pci_regs.h | 1 +
15
include/standard-headers/linux/vhost_types.h | 2 +
16
include/standard-headers/linux/virtio_blk.h | 105 +++++++++++++++++++
17
linux-headers/asm-arm64/kvm.h | 1 +
18
linux-headers/asm-x86/kvm.h | 34 +++++-
19
linux-headers/linux/kvm.h | 9 ++
20
linux-headers/linux/vfio.h | 15 +--
21
linux-headers/linux/vhost.h | 8 ++
22
11 files changed, 270 insertions(+), 10 deletions(-)
23
24
diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/standard-headers/drm/drm_fourcc.h
27
+++ b/include/standard-headers/drm/drm_fourcc.h
28
@@ -XXX,XX +XXX,XX @@ extern "C" {
29
*
30
* The authoritative list of format modifier codes is found in
31
* `include/uapi/drm/drm_fourcc.h`
32
+ *
33
+ * Open Source User Waiver
34
+ * -----------------------
35
+ *
36
+ * Because this is the authoritative source for pixel formats and modifiers
37
+ * referenced by GL, Vulkan extensions and other standards and hence used both
38
+ * by open source and closed source driver stacks, the usual requirement for an
39
+ * upstream in-kernel or open source userspace user does not apply.
40
+ *
41
+ * To ensure, as much as feasible, compatibility across stacks and avoid
42
+ * confusion with incompatible enumerations stakeholders for all relevant driver
43
+ * stacks should approve additions.
44
*/
45
46
#define fourcc_code(a, b, c, d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
47
diff --git a/include/standard-headers/linux/ethtool.h b/include/standard-headers/linux/ethtool.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/include/standard-headers/linux/ethtool.h
50
+++ b/include/standard-headers/linux/ethtool.h
51
@@ -XXX,XX +XXX,XX @@ enum ethtool_stringset {
52
    ETH_SS_COUNT
53
};
54
55
+/**
56
+ * enum ethtool_mac_stats_src - source of ethtool MAC statistics
57
+ * @ETHTOOL_MAC_STATS_SRC_AGGREGATE:
58
+ *    if device supports a MAC merge layer, this retrieves the aggregate
59
+ *    statistics of the eMAC and pMAC. Otherwise, it retrieves just the
60
+ *    statistics of the single (express) MAC.
61
+ * @ETHTOOL_MAC_STATS_SRC_EMAC:
62
+ *    if device supports a MM layer, this retrieves the eMAC statistics.
63
+ *    Otherwise, it retrieves the statistics of the single (express) MAC.
64
+ * @ETHTOOL_MAC_STATS_SRC_PMAC:
65
+ *    if device supports a MM layer, this retrieves the pMAC statistics.
66
+ */
67
+enum ethtool_mac_stats_src {
68
+    ETHTOOL_MAC_STATS_SRC_AGGREGATE,
69
+    ETHTOOL_MAC_STATS_SRC_EMAC,
70
+    ETHTOOL_MAC_STATS_SRC_PMAC,
71
+};
72
+
73
/**
74
* enum ethtool_module_power_mode_policy - plug-in module power mode policy
75
* @ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH: Module is always in high power mode.
76
@@ -XXX,XX +XXX,XX @@ enum ethtool_podl_pse_pw_d_status {
77
    ETHTOOL_PODL_PSE_PW_D_STATUS_ERROR,
78
};
79
80
+/**
81
+ * enum ethtool_mm_verify_status - status of MAC Merge Verify function
82
+ * @ETHTOOL_MM_VERIFY_STATUS_UNKNOWN:
83
+ *    verification status is unknown
84
+ * @ETHTOOL_MM_VERIFY_STATUS_INITIAL:
85
+ *    the 802.3 Verify State diagram is in the state INIT_VERIFICATION
86
+ * @ETHTOOL_MM_VERIFY_STATUS_VERIFYING:
87
+ *    the Verify State diagram is in the state VERIFICATION_IDLE,
88
+ *    SEND_VERIFY or WAIT_FOR_RESPONSE
89
+ * @ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED:
90
+ *    indicates that the Verify State diagram is in the state VERIFIED
91
+ * @ETHTOOL_MM_VERIFY_STATUS_FAILED:
92
+ *    the Verify State diagram is in the state VERIFY_FAIL
93
+ * @ETHTOOL_MM_VERIFY_STATUS_DISABLED:
94
+ *    verification of preemption operation is disabled
95
+ */
96
+enum ethtool_mm_verify_status {
97
+    ETHTOOL_MM_VERIFY_STATUS_UNKNOWN,
98
+    ETHTOOL_MM_VERIFY_STATUS_INITIAL,
99
+    ETHTOOL_MM_VERIFY_STATUS_VERIFYING,
100
+    ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED,
101
+    ETHTOOL_MM_VERIFY_STATUS_FAILED,
102
+    ETHTOOL_MM_VERIFY_STATUS_DISABLED,
103
+};
104
+
105
/**
106
* struct ethtool_gstrings - string set for data tagging
107
* @cmd: Command number = %ETHTOOL_GSTRINGS
108
@@ -XXX,XX +XXX,XX @@ struct ethtool_rxnfc {
109
        uint32_t            rule_cnt;
110
        uint32_t            rss_context;
111
    };
112
-    uint32_t                rule_locs[0];
113
+    uint32_t                rule_locs[];
114
};
115
116
117
@@ -XXX,XX +XXX,XX @@ enum ethtool_link_mode_bit_indices {
118
    ETHTOOL_LINK_MODE_800000baseDR8_2_Full_BIT     = 96,
119
    ETHTOOL_LINK_MODE_800000baseSR8_Full_BIT     = 97,
120
    ETHTOOL_LINK_MODE_800000baseVR8_Full_BIT     = 98,
121
+    ETHTOOL_LINK_MODE_10baseT1S_Full_BIT         = 99,
122
+    ETHTOOL_LINK_MODE_10baseT1S_Half_BIT         = 100,
123
+    ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT     = 101,
124
125
    /* must be last entry */
126
    __ETHTOOL_LINK_MODE_MASK_NBITS
127
diff --git a/include/standard-headers/linux/fuse.h b/include/standard-headers/linux/fuse.h
128
index XXXXXXX..XXXXXXX 100644
129
--- a/include/standard-headers/linux/fuse.h
130
+++ b/include/standard-headers/linux/fuse.h
131
@@ -XXX,XX +XXX,XX @@
132
* 7.38
133
* - add FUSE_EXPIRE_ONLY flag to fuse_notify_inval_entry
134
* - add FOPEN_PARALLEL_DIRECT_WRITES
135
+ * - add total_extlen to fuse_in_header
136
+ * - add FUSE_MAX_NR_SECCTX
137
+ * - add extension header
138
+ * - add FUSE_EXT_GROUPS
139
+ * - add FUSE_CREATE_SUPP_GROUP
140
*/
141
142
#ifndef _LINUX_FUSE_H
143
@@ -XXX,XX +XXX,XX @@ struct fuse_file_lock {
144
* FUSE_SECURITY_CTX:    add security context to create, mkdir, symlink, and
145
*            mknod
146
* FUSE_HAS_INODE_DAX: use per inode DAX
147
+ * FUSE_CREATE_SUPP_GROUP: add supplementary group info to create, mkdir,
148
+ *            symlink and mknod (single group that matches parent)
149
*/
150
#define FUSE_ASYNC_READ        (1 << 0)
151
#define FUSE_POSIX_LOCKS    (1 << 1)
152
@@ -XXX,XX +XXX,XX @@ struct fuse_file_lock {
153
/* bits 32..63 get shifted down 32 bits into the flags2 field */
154
#define FUSE_SECURITY_CTX    (1ULL << 32)
155
#define FUSE_HAS_INODE_DAX    (1ULL << 33)
156
+#define FUSE_CREATE_SUPP_GROUP    (1ULL << 34)
157
158
/**
159
* CUSE INIT request/reply flags
160
@@ -XXX,XX +XXX,XX @@ struct fuse_file_lock {
161
*/
162
#define FUSE_EXPIRE_ONLY        (1 << 0)
163
164
+/**
165
+ * extension type
166
+ * FUSE_MAX_NR_SECCTX: maximum value of &fuse_secctx_header.nr_secctx
167
+ * FUSE_EXT_GROUPS: &fuse_supp_groups extension
168
+ */
169
+enum fuse_ext_type {
170
+    /* Types 0..31 are reserved for fuse_secctx_header */
171
+    FUSE_MAX_NR_SECCTX    = 31,
172
+    FUSE_EXT_GROUPS        = 32,
173
+};
174
+
175
enum fuse_opcode {
176
    FUSE_LOOKUP        = 1,
177
    FUSE_FORGET        = 2, /* no reply */
178
@@ -XXX,XX +XXX,XX @@ struct fuse_in_header {
179
    uint32_t    uid;
180
    uint32_t    gid;
181
    uint32_t    pid;
182
-    uint32_t    padding;
183
+    uint16_t    total_extlen; /* length of extensions in 8byte units */
184
+    uint16_t    padding;
185
};
186
187
struct fuse_out_header {
188
@@ -XXX,XX +XXX,XX @@ struct fuse_secctx_header {
189
    uint32_t    nr_secctx;
190
};
191
192
+/**
193
+ * struct fuse_ext_header - extension header
194
+ * @size: total size of this extension including this header
195
+ * @type: type of extension
196
+ *
197
+ * This is made compatible with fuse_secctx_header by using type values >
198
+ * FUSE_MAX_NR_SECCTX
199
+ */
200
+struct fuse_ext_header {
201
+    uint32_t    size;
202
+    uint32_t    type;
203
+};
204
+
205
+/**
206
+ * struct fuse_supp_groups - Supplementary group extension
207
+ * @nr_groups: number of supplementary groups
208
+ * @groups: flexible array of group IDs
209
+ */
210
+struct fuse_supp_groups {
211
+    uint32_t    nr_groups;
212
+    uint32_t    groups[];
213
+};
214
+
215
#endif /* _LINUX_FUSE_H */
216
diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h
217
index XXXXXXX..XXXXXXX 100644
218
--- a/include/standard-headers/linux/pci_regs.h
219
+++ b/include/standard-headers/linux/pci_regs.h
220
@@ -XXX,XX +XXX,XX @@
221
#define PCI_EXP_LNKCTL2_TX_MARGIN    0x0380 /* Transmit Margin */
222
#define PCI_EXP_LNKCTL2_HASD        0x0020 /* HW Autonomous Speed Disable */
223
#define PCI_EXP_LNKSTA2        0x32    /* Link Status 2 */
224
+#define PCI_EXP_LNKSTA2_FLIT        0x0400 /* Flit Mode Status */
225
#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2    0x32    /* end of v2 EPs w/ link */
226
#define PCI_EXP_SLTCAP2        0x34    /* Slot Capabilities 2 */
227
#define PCI_EXP_SLTCAP2_IBPD    0x00000001 /* In-band PD Disable Supported */
228
diff --git a/include/standard-headers/linux/vhost_types.h b/include/standard-headers/linux/vhost_types.h
229
index XXXXXXX..XXXXXXX 100644
230
--- a/include/standard-headers/linux/vhost_types.h
231
+++ b/include/standard-headers/linux/vhost_types.h
232
@@ -XXX,XX +XXX,XX @@ struct vhost_vdpa_iova_range {
233
#define VHOST_BACKEND_F_IOTLB_ASID 0x3
234
/* Device can be suspended */
235
#define VHOST_BACKEND_F_SUSPEND 0x4
236
+/* Device can be resumed */
237
+#define VHOST_BACKEND_F_RESUME 0x5
238
239
#endif
240
diff --git a/include/standard-headers/linux/virtio_blk.h b/include/standard-headers/linux/virtio_blk.h
241
index XXXXXXX..XXXXXXX 100644
242
--- a/include/standard-headers/linux/virtio_blk.h
243
+++ b/include/standard-headers/linux/virtio_blk.h
244
@@ -XXX,XX +XXX,XX @@
245
#define VIRTIO_BLK_F_DISCARD    13    /* DISCARD is supported */
246
#define VIRTIO_BLK_F_WRITE_ZEROES    14    /* WRITE ZEROES is supported */
247
#define VIRTIO_BLK_F_SECURE_ERASE    16 /* Secure Erase is supported */
248
+#define VIRTIO_BLK_F_ZONED        17    /* Zoned block device */
249
250
/* Legacy feature bits */
251
#ifndef VIRTIO_BLK_NO_LEGACY
252
@@ -XXX,XX +XXX,XX @@ struct virtio_blk_config {
253
    /* Secure erase commands must be aligned to this number of sectors. */
254
    __virtio32 secure_erase_sector_alignment;
255
256
+    /* Zoned block device characteristics (if VIRTIO_BLK_F_ZONED) */
257
+    struct virtio_blk_zoned_characteristics {
258
+        uint32_t zone_sectors;
259
+        uint32_t max_open_zones;
260
+        uint32_t max_active_zones;
261
+        uint32_t max_append_sectors;
262
+        uint32_t write_granularity;
263
+        uint8_t model;
264
+        uint8_t unused2[3];
265
+    } zoned;
266
} QEMU_PACKED;
267
268
/*
269
@@ -XXX,XX +XXX,XX @@ struct virtio_blk_config {
270
/* Secure erase command */
271
#define VIRTIO_BLK_T_SECURE_ERASE    14
272
273
+/* Zone append command */
274
+#define VIRTIO_BLK_T_ZONE_APPEND 15
275
+
276
+/* Report zones command */
277
+#define VIRTIO_BLK_T_ZONE_REPORT 16
278
+
279
+/* Open zone command */
280
+#define VIRTIO_BLK_T_ZONE_OPEN 18
281
+
282
+/* Close zone command */
283
+#define VIRTIO_BLK_T_ZONE_CLOSE 20
284
+
285
+/* Finish zone command */
286
+#define VIRTIO_BLK_T_ZONE_FINISH 22
287
+
288
+/* Reset zone command */
289
+#define VIRTIO_BLK_T_ZONE_RESET 24
290
+
291
+/* Reset All zones command */
292
+#define VIRTIO_BLK_T_ZONE_RESET_ALL 26
293
+
294
#ifndef VIRTIO_BLK_NO_LEGACY
295
/* Barrier before this op. */
296
#define VIRTIO_BLK_T_BARRIER    0x80000000
297
@@ -XXX,XX +XXX,XX @@ struct virtio_blk_outhdr {
298
    __virtio64 sector;
299
};
300
301
+/*
302
+ * Supported zoned device models.
303
+ */
304
+
305
+/* Regular block device */
306
+#define VIRTIO_BLK_Z_NONE 0
307
+/* Host-managed zoned device */
308
+#define VIRTIO_BLK_Z_HM 1
309
+/* Host-aware zoned device */
310
+#define VIRTIO_BLK_Z_HA 2
311
+
312
+/*
313
+ * Zone descriptor. A part of VIRTIO_BLK_T_ZONE_REPORT command reply.
314
+ */
315
+struct virtio_blk_zone_descriptor {
316
+    /* Zone capacity */
317
+    uint64_t z_cap;
318
+    /* The starting sector of the zone */
319
+    uint64_t z_start;
320
+    /* Zone write pointer position in sectors */
321
+    uint64_t z_wp;
322
+    /* Zone type */
323
+    uint8_t z_type;
324
+    /* Zone state */
325
+    uint8_t z_state;
326
+    uint8_t reserved[38];
327
+};
328
+
329
+struct virtio_blk_zone_report {
330
+    uint64_t nr_zones;
331
+    uint8_t reserved[56];
332
+    struct virtio_blk_zone_descriptor zones[];
333
+};
334
+
335
+/*
336
+ * Supported zone types.
337
+ */
338
+
339
+/* Conventional zone */
340
+#define VIRTIO_BLK_ZT_CONV 1
341
+/* Sequential Write Required zone */
342
+#define VIRTIO_BLK_ZT_SWR 2
343
+/* Sequential Write Preferred zone */
344
+#define VIRTIO_BLK_ZT_SWP 3
345
+
346
+/*
347
+ * Zone states that are available for zones of all types.
348
+ */
349
+
350
+/* Not a write pointer (conventional zones only) */
351
+#define VIRTIO_BLK_ZS_NOT_WP 0
352
+/* Empty */
353
+#define VIRTIO_BLK_ZS_EMPTY 1
354
+/* Implicitly Open */
355
+#define VIRTIO_BLK_ZS_IOPEN 2
356
+/* Explicitly Open */
357
+#define VIRTIO_BLK_ZS_EOPEN 3
358
+/* Closed */
359
+#define VIRTIO_BLK_ZS_CLOSED 4
360
+/* Read-Only */
361
+#define VIRTIO_BLK_ZS_RDONLY 13
362
+/* Full */
363
+#define VIRTIO_BLK_ZS_FULL 14
364
+/* Offline */
365
+#define VIRTIO_BLK_ZS_OFFLINE 15
366
+
367
/* Unmap this range (only valid for write zeroes command) */
368
#define VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP    0x00000001
369
370
@@ -XXX,XX +XXX,XX @@ struct virtio_scsi_inhdr {
371
#define VIRTIO_BLK_S_OK        0
372
#define VIRTIO_BLK_S_IOERR    1
373
#define VIRTIO_BLK_S_UNSUPP    2
374
+
375
+/* Error codes that are specific to zoned block devices */
376
+#define VIRTIO_BLK_S_ZONE_INVALID_CMD 3
377
+#define VIRTIO_BLK_S_ZONE_UNALIGNED_WP 4
378
+#define VIRTIO_BLK_S_ZONE_OPEN_RESOURCE 5
379
+#define VIRTIO_BLK_S_ZONE_ACTIVE_RESOURCE 6
380
+
381
#endif /* _LINUX_VIRTIO_BLK_H */
382
diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h
383
index XXXXXXX..XXXXXXX 100644
384
--- a/linux-headers/asm-arm64/kvm.h
385
+++ b/linux-headers/asm-arm64/kvm.h
386
@@ -XXX,XX +XXX,XX @@ struct kvm_regs {
387
#define KVM_ARM_VCPU_SVE        4 /* enable SVE for this CPU */
388
#define KVM_ARM_VCPU_PTRAUTH_ADDRESS    5 /* VCPU uses address authentication */
389
#define KVM_ARM_VCPU_PTRAUTH_GENERIC    6 /* VCPU uses generic authentication */
390
+#define KVM_ARM_VCPU_HAS_EL2        7 /* Support nested virtualization */
391
392
struct kvm_vcpu_init {
393
    __u32 target;
394
diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h
395
index XXXXXXX..XXXXXXX 100644
396
--- a/linux-headers/asm-x86/kvm.h
397
+++ b/linux-headers/asm-x86/kvm.h
398
@@ -XXX,XX +XXX,XX @@
399
400
#include <linux/types.h>
401
#include <linux/ioctl.h>
402
+#include <linux/stddef.h>
403
404
#define KVM_PIO_PAGE_OFFSET 1
405
#define KVM_COALESCED_MMIO_PAGE_OFFSET 2
406
@@ -XXX,XX +XXX,XX @@ struct kvm_nested_state {
407
     * KVM_{GET,PUT}_NESTED_STATE ioctl values.
408
     */
409
    union {
410
-        struct kvm_vmx_nested_state_data vmx[0];
411
-        struct kvm_svm_nested_state_data svm[0];
412
+        __DECLARE_FLEX_ARRAY(struct kvm_vmx_nested_state_data, vmx);
413
+        __DECLARE_FLEX_ARRAY(struct kvm_svm_nested_state_data, svm);
414
    } data;
415
};
416
417
@@ -XXX,XX +XXX,XX @@ struct kvm_pmu_event_filter {
418
#define KVM_PMU_EVENT_ALLOW 0
419
#define KVM_PMU_EVENT_DENY 1
420
421
+#define KVM_PMU_EVENT_FLAG_MASKED_EVENTS BIT(0)
422
+#define KVM_PMU_EVENT_FLAGS_VALID_MASK (KVM_PMU_EVENT_FLAG_MASKED_EVENTS)
423
+
424
+/*
425
+ * Masked event layout.
426
+ * Bits Description
427
+ * ---- -----------
428
+ * 7:0 event select (low bits)
429
+ * 15:8 umask match
430
+ * 31:16 unused
431
+ * 35:32 event select (high bits)
432
+ * 36:54 unused
433
+ * 55 exclude bit
434
+ * 63:56 umask mask
435
+ */
436
+
437
+#define KVM_PMU_ENCODE_MASKED_ENTRY(event_select, mask, match, exclude) \
438
+    (((event_select) & 0xFFULL) | (((event_select) & 0XF00ULL) << 24) | \
439
+    (((mask) & 0xFFULL) << 56) | \
440
+    (((match) & 0xFFULL) << 8) | \
441
+    ((__u64)(!!(exclude)) << 55))
442
+
443
+#define KVM_PMU_MASKED_ENTRY_EVENT_SELECT \
444
+    (GENMASK_ULL(7, 0) | GENMASK_ULL(35, 32))
445
+#define KVM_PMU_MASKED_ENTRY_UMASK_MASK        (GENMASK_ULL(63, 56))
446
+#define KVM_PMU_MASKED_ENTRY_UMASK_MATCH    (GENMASK_ULL(15, 8))
447
+#define KVM_PMU_MASKED_ENTRY_EXCLUDE        (BIT_ULL(55))
448
+#define KVM_PMU_MASKED_ENTRY_UMASK_MASK_SHIFT    (56)
449
+
450
/* for KVM_{GET,SET,HAS}_DEVICE_ATTR */
451
#define KVM_VCPU_TSC_CTRL 0 /* control group for the timestamp counter (TSC) */
452
#define KVM_VCPU_TSC_OFFSET 0 /* attribute for the TSC offset */
453
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
454
index XXXXXXX..XXXXXXX 100644
455
--- a/linux-headers/linux/kvm.h
456
+++ b/linux-headers/linux/kvm.h
457
@@ -XXX,XX +XXX,XX @@ struct kvm_s390_mem_op {
458
        struct {
459
            __u8 ar;    /* the access register number */
460
            __u8 key;    /* access key, ignored if flag unset */
461
+            __u8 pad1[6];    /* ignored */
462
+            __u64 old_addr;    /* ignored if cmpxchg flag unset */
463
        };
464
        __u32 sida_offset; /* offset into the sida */
465
        __u8 reserved[32]; /* ignored */
466
@@ -XXX,XX +XXX,XX @@ struct kvm_s390_mem_op {
467
#define KVM_S390_MEMOP_SIDA_WRITE    3
468
#define KVM_S390_MEMOP_ABSOLUTE_READ    4
469
#define KVM_S390_MEMOP_ABSOLUTE_WRITE    5
470
+#define KVM_S390_MEMOP_ABSOLUTE_CMPXCHG    6
471
+
472
/* flags for kvm_s390_mem_op->flags */
473
#define KVM_S390_MEMOP_F_CHECK_ONLY        (1ULL << 0)
474
#define KVM_S390_MEMOP_F_INJECT_EXCEPTION    (1ULL << 1)
475
#define KVM_S390_MEMOP_F_SKEY_PROTECTION    (1ULL << 2)
476
477
+/* flags specifying extension support via KVM_CAP_S390_MEM_OP_EXTENSION */
478
+#define KVM_S390_MEMOP_EXTENSION_CAP_BASE    (1 << 0)
479
+#define KVM_S390_MEMOP_EXTENSION_CAP_CMPXCHG    (1 << 1)
480
+
481
/* for KVM_INTERRUPT */
482
struct kvm_interrupt {
483
    /* in */
484
@@ -XXX,XX +XXX,XX @@ struct kvm_ppc_resize_hpt {
485
#define KVM_CAP_DIRTY_LOG_RING_ACQ_REL 223
486
#define KVM_CAP_S390_PROTECTED_ASYNC_DISABLE 224
487
#define KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP 225
488
+#define KVM_CAP_PMU_EVENT_MASKED_EVENTS 226
489
490
#ifdef KVM_CAP_IRQ_ROUTING
491
492
diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
493
index XXXXXXX..XXXXXXX 100644
494
--- a/linux-headers/linux/vfio.h
495
+++ b/linux-headers/linux/vfio.h
496
@@ -XXX,XX +XXX,XX @@
497
/* Supports VFIO_DMA_UNMAP_FLAG_ALL */
498
#define VFIO_UNMAP_ALL            9
499
500
-/* Supports the vaddr flag for DMA map and unmap */
501
+/*
502
+ * Supports the vaddr flag for DMA map and unmap. Not supported for mediated
503
+ * devices, so this capability is subject to change as groups are added or
504
+ * removed.
505
+ */
506
#define VFIO_UPDATE_VADDR        10
507
508
/*
509
@@ -XXX,XX +XXX,XX @@ struct vfio_iommu_type1_info_dma_avail {
510
* Map process virtual addresses to IO virtual addresses using the
511
* provided struct vfio_dma_map. Caller sets argsz. READ &/ WRITE required.
512
*
513
- * If flags & VFIO_DMA_MAP_FLAG_VADDR, update the base vaddr for iova, and
514
- * unblock translation of host virtual addresses in the iova range. The vaddr
515
+ * If flags & VFIO_DMA_MAP_FLAG_VADDR, update the base vaddr for iova. The vaddr
516
* must have previously been invalidated with VFIO_DMA_UNMAP_FLAG_VADDR. To
517
* maintain memory consistency within the user application, the updated vaddr
518
* must address the same memory object as originally mapped. Failure to do so
519
@@ -XXX,XX +XXX,XX @@ struct vfio_bitmap {
520
* must be 0. This cannot be combined with the get-dirty-bitmap flag.
521
*
522
* If flags & VFIO_DMA_UNMAP_FLAG_VADDR, do not unmap, but invalidate host
523
- * virtual addresses in the iova range. Tasks that attempt to translate an
524
- * iova's vaddr will block. DMA to already-mapped pages continues. This
525
- * cannot be combined with the get-dirty-bitmap flag.
526
+ * virtual addresses in the iova range. DMA to already-mapped pages continues.
527
+ * Groups may not be added to the container while any addresses are invalid.
528
+ * This cannot be combined with the get-dirty-bitmap flag.
529
*/
530
struct vfio_iommu_type1_dma_unmap {
531
    __u32    argsz;
532
diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
533
index XXXXXXX..XXXXXXX 100644
534
--- a/linux-headers/linux/vhost.h
535
+++ b/linux-headers/linux/vhost.h
536
@@ -XXX,XX +XXX,XX @@
537
*/
538
#define VHOST_VDPA_SUSPEND        _IO(VHOST_VIRTIO, 0x7D)
539
540
+/* Resume a device so it can resume processing virtqueue requests
541
+ *
542
+ * After the return of this ioctl the device will have restored all the
543
+ * necessary states and it is fully operational to continue processing the
544
+ * virtqueue descriptors.
545
+ */
546
+#define VHOST_VDPA_RESUME        _IO(VHOST_VIRTIO, 0x7E)
547
+
548
#endif
549
--
550
2.39.2
diff view generated by jsdifflib
New patch
1
From: Sam Li <faithilikerun@gmail.com>
1
2
3
This patch extends virtio-blk emulation to handle zoned device commands
4
by calling the new block layer APIs to perform zoned device I/O on
5
behalf of the guest. It supports Report Zone, four zone oparations (open,
6
close, finish, reset), and Append Zone.
7
8
The VIRTIO_BLK_F_ZONED feature bit will only be set if the host does
9
support zoned block devices. Regular block devices(conventional zones)
10
will not be set.
11
12
The guest os can use blktests, fio to test those commands on zoned devices.
13
Furthermore, using zonefs to test zone append write is also supported.
14
15
Signed-off-by: Sam Li <faithilikerun@gmail.com>
16
Message-id: 20230407082528.18841-3-faithilikerun@gmail.com
17
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
18
---
19
hw/block/virtio-blk-common.c | 2 +
20
hw/block/virtio-blk.c | 389 +++++++++++++++++++++++++++++++++++
21
hw/virtio/virtio-qmp.c | 2 +
22
3 files changed, 393 insertions(+)
23
24
diff --git a/hw/block/virtio-blk-common.c b/hw/block/virtio-blk-common.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/block/virtio-blk-common.c
27
+++ b/hw/block/virtio-blk-common.c
28
@@ -XXX,XX +XXX,XX @@ static const VirtIOFeature feature_sizes[] = {
29
.end = endof(struct virtio_blk_config, discard_sector_alignment)},
30
{.flags = 1ULL << VIRTIO_BLK_F_WRITE_ZEROES,
31
.end = endof(struct virtio_blk_config, write_zeroes_may_unmap)},
32
+ {.flags = 1ULL << VIRTIO_BLK_F_ZONED,
33
+ .end = endof(struct virtio_blk_config, zoned)},
34
{}
35
};
36
37
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/block/virtio-blk.c
40
+++ b/hw/block/virtio-blk.c
41
@@ -XXX,XX +XXX,XX @@
42
#include "qemu/module.h"
43
#include "qemu/error-report.h"
44
#include "qemu/main-loop.h"
45
+#include "block/block_int.h"
46
#include "trace.h"
47
#include "hw/block/block.h"
48
#include "hw/qdev-properties.h"
49
@@ -XXX,XX +XXX,XX @@ err:
50
return err_status;
51
}
52
53
+typedef struct ZoneCmdData {
54
+ VirtIOBlockReq *req;
55
+ struct iovec *in_iov;
56
+ unsigned in_num;
57
+ union {
58
+ struct {
59
+ unsigned int nr_zones;
60
+ BlockZoneDescriptor *zones;
61
+ } zone_report_data;
62
+ struct {
63
+ int64_t offset;
64
+ } zone_append_data;
65
+ };
66
+} ZoneCmdData;
67
+
68
+/*
69
+ * check zoned_request: error checking before issuing requests. If all checks
70
+ * passed, return true.
71
+ * append: true if only zone append requests issued.
72
+ */
73
+static bool check_zoned_request(VirtIOBlock *s, int64_t offset, int64_t len,
74
+ bool append, uint8_t *status) {
75
+ BlockDriverState *bs = blk_bs(s->blk);
76
+ int index;
77
+
78
+ if (!virtio_has_feature(s->host_features, VIRTIO_BLK_F_ZONED)) {
79
+ *status = VIRTIO_BLK_S_UNSUPP;
80
+ return false;
81
+ }
82
+
83
+ if (offset < 0 || len < 0 || len > (bs->total_sectors << BDRV_SECTOR_BITS)
84
+ || offset > (bs->total_sectors << BDRV_SECTOR_BITS) - len) {
85
+ *status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
86
+ return false;
87
+ }
88
+
89
+ if (append) {
90
+ if (bs->bl.write_granularity) {
91
+ if ((offset % bs->bl.write_granularity) != 0) {
92
+ *status = VIRTIO_BLK_S_ZONE_UNALIGNED_WP;
93
+ return false;
94
+ }
95
+ }
96
+
97
+ index = offset / bs->bl.zone_size;
98
+ if (BDRV_ZT_IS_CONV(bs->wps->wp[index])) {
99
+ *status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
100
+ return false;
101
+ }
102
+
103
+ if (len / 512 > bs->bl.max_append_sectors) {
104
+ if (bs->bl.max_append_sectors == 0) {
105
+ *status = VIRTIO_BLK_S_UNSUPP;
106
+ } else {
107
+ *status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
108
+ }
109
+ return false;
110
+ }
111
+ }
112
+ return true;
113
+}
114
+
115
+static void virtio_blk_zone_report_complete(void *opaque, int ret)
116
+{
117
+ ZoneCmdData *data = opaque;
118
+ VirtIOBlockReq *req = data->req;
119
+ VirtIOBlock *s = req->dev;
120
+ VirtIODevice *vdev = VIRTIO_DEVICE(req->dev);
121
+ struct iovec *in_iov = data->in_iov;
122
+ unsigned in_num = data->in_num;
123
+ int64_t zrp_size, n, j = 0;
124
+ int64_t nz = data->zone_report_data.nr_zones;
125
+ int8_t err_status = VIRTIO_BLK_S_OK;
126
+
127
+ if (ret) {
128
+ err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
129
+ goto out;
130
+ }
131
+
132
+ struct virtio_blk_zone_report zrp_hdr = (struct virtio_blk_zone_report) {
133
+ .nr_zones = cpu_to_le64(nz),
134
+ };
135
+ zrp_size = sizeof(struct virtio_blk_zone_report)
136
+ + sizeof(struct virtio_blk_zone_descriptor) * nz;
137
+ n = iov_from_buf(in_iov, in_num, 0, &zrp_hdr, sizeof(zrp_hdr));
138
+ if (n != sizeof(zrp_hdr)) {
139
+ virtio_error(vdev, "Driver provided input buffer that is too small!");
140
+ err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
141
+ goto out;
142
+ }
143
+
144
+ for (size_t i = sizeof(zrp_hdr); i < zrp_size;
145
+ i += sizeof(struct virtio_blk_zone_descriptor), ++j) {
146
+ struct virtio_blk_zone_descriptor desc =
147
+ (struct virtio_blk_zone_descriptor) {
148
+ .z_start = cpu_to_le64(data->zone_report_data.zones[j].start
149
+ >> BDRV_SECTOR_BITS),
150
+ .z_cap = cpu_to_le64(data->zone_report_data.zones[j].cap
151
+ >> BDRV_SECTOR_BITS),
152
+ .z_wp = cpu_to_le64(data->zone_report_data.zones[j].wp
153
+ >> BDRV_SECTOR_BITS),
154
+ };
155
+
156
+ switch (data->zone_report_data.zones[j].type) {
157
+ case BLK_ZT_CONV:
158
+ desc.z_type = VIRTIO_BLK_ZT_CONV;
159
+ break;
160
+ case BLK_ZT_SWR:
161
+ desc.z_type = VIRTIO_BLK_ZT_SWR;
162
+ break;
163
+ case BLK_ZT_SWP:
164
+ desc.z_type = VIRTIO_BLK_ZT_SWP;
165
+ break;
166
+ default:
167
+ g_assert_not_reached();
168
+ }
169
+
170
+ switch (data->zone_report_data.zones[j].state) {
171
+ case BLK_ZS_RDONLY:
172
+ desc.z_state = VIRTIO_BLK_ZS_RDONLY;
173
+ break;
174
+ case BLK_ZS_OFFLINE:
175
+ desc.z_state = VIRTIO_BLK_ZS_OFFLINE;
176
+ break;
177
+ case BLK_ZS_EMPTY:
178
+ desc.z_state = VIRTIO_BLK_ZS_EMPTY;
179
+ break;
180
+ case BLK_ZS_CLOSED:
181
+ desc.z_state = VIRTIO_BLK_ZS_CLOSED;
182
+ break;
183
+ case BLK_ZS_FULL:
184
+ desc.z_state = VIRTIO_BLK_ZS_FULL;
185
+ break;
186
+ case BLK_ZS_EOPEN:
187
+ desc.z_state = VIRTIO_BLK_ZS_EOPEN;
188
+ break;
189
+ case BLK_ZS_IOPEN:
190
+ desc.z_state = VIRTIO_BLK_ZS_IOPEN;
191
+ break;
192
+ case BLK_ZS_NOT_WP:
193
+ desc.z_state = VIRTIO_BLK_ZS_NOT_WP;
194
+ break;
195
+ default:
196
+ g_assert_not_reached();
197
+ }
198
+
199
+ /* TODO: it takes O(n^2) time complexity. Optimizations required. */
200
+ n = iov_from_buf(in_iov, in_num, i, &desc, sizeof(desc));
201
+ if (n != sizeof(desc)) {
202
+ virtio_error(vdev, "Driver provided input buffer "
203
+ "for descriptors that is too small!");
204
+ err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
205
+ }
206
+ }
207
+
208
+out:
209
+ aio_context_acquire(blk_get_aio_context(s->conf.conf.blk));
210
+ virtio_blk_req_complete(req, err_status);
211
+ virtio_blk_free_request(req);
212
+ aio_context_release(blk_get_aio_context(s->conf.conf.blk));
213
+ g_free(data->zone_report_data.zones);
214
+ g_free(data);
215
+}
216
+
217
+static void virtio_blk_handle_zone_report(VirtIOBlockReq *req,
218
+ struct iovec *in_iov,
219
+ unsigned in_num)
220
+{
221
+ VirtIOBlock *s = req->dev;
222
+ VirtIODevice *vdev = VIRTIO_DEVICE(s);
223
+ unsigned int nr_zones;
224
+ ZoneCmdData *data;
225
+ int64_t zone_size, offset;
226
+ uint8_t err_status;
227
+
228
+ if (req->in_len < sizeof(struct virtio_blk_inhdr) +
229
+ sizeof(struct virtio_blk_zone_report) +
230
+ sizeof(struct virtio_blk_zone_descriptor)) {
231
+ virtio_error(vdev, "in buffer too small for zone report");
232
+ return;
233
+ }
234
+
235
+ /* start byte offset of the zone report */
236
+ offset = virtio_ldq_p(vdev, &req->out.sector) << BDRV_SECTOR_BITS;
237
+ if (!check_zoned_request(s, offset, 0, false, &err_status)) {
238
+ goto out;
239
+ }
240
+ nr_zones = (req->in_len - sizeof(struct virtio_blk_inhdr) -
241
+ sizeof(struct virtio_blk_zone_report)) /
242
+ sizeof(struct virtio_blk_zone_descriptor);
243
+
244
+ zone_size = sizeof(BlockZoneDescriptor) * nr_zones;
245
+ data = g_malloc(sizeof(ZoneCmdData));
246
+ data->req = req;
247
+ data->in_iov = in_iov;
248
+ data->in_num = in_num;
249
+ data->zone_report_data.nr_zones = nr_zones;
250
+ data->zone_report_data.zones = g_malloc(zone_size),
251
+
252
+ blk_aio_zone_report(s->blk, offset, &data->zone_report_data.nr_zones,
253
+ data->zone_report_data.zones,
254
+ virtio_blk_zone_report_complete, data);
255
+ return;
256
+out:
257
+ virtio_blk_req_complete(req, err_status);
258
+ virtio_blk_free_request(req);
259
+}
260
+
261
+static void virtio_blk_zone_mgmt_complete(void *opaque, int ret)
262
+{
263
+ VirtIOBlockReq *req = opaque;
264
+ VirtIOBlock *s = req->dev;
265
+ int8_t err_status = VIRTIO_BLK_S_OK;
266
+
267
+ if (ret) {
268
+ err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
269
+ }
270
+
271
+ aio_context_acquire(blk_get_aio_context(s->conf.conf.blk));
272
+ virtio_blk_req_complete(req, err_status);
273
+ virtio_blk_free_request(req);
274
+ aio_context_release(blk_get_aio_context(s->conf.conf.blk));
275
+}
276
+
277
+static int virtio_blk_handle_zone_mgmt(VirtIOBlockReq *req, BlockZoneOp op)
278
+{
279
+ VirtIOBlock *s = req->dev;
280
+ VirtIODevice *vdev = VIRTIO_DEVICE(s);
281
+ BlockDriverState *bs = blk_bs(s->blk);
282
+ int64_t offset = virtio_ldq_p(vdev, &req->out.sector) << BDRV_SECTOR_BITS;
283
+ uint64_t len;
284
+ uint64_t capacity = bs->total_sectors << BDRV_SECTOR_BITS;
285
+ uint8_t err_status = VIRTIO_BLK_S_OK;
286
+
287
+ uint32_t type = virtio_ldl_p(vdev, &req->out.type);
288
+ if (type == VIRTIO_BLK_T_ZONE_RESET_ALL) {
289
+ /* Entire drive capacity */
290
+ offset = 0;
291
+ len = capacity;
292
+ } else {
293
+ if (bs->bl.zone_size > capacity - offset) {
294
+ /* The zoned device allows the last smaller zone. */
295
+ len = capacity - bs->bl.zone_size * (bs->bl.nr_zones - 1);
296
+ } else {
297
+ len = bs->bl.zone_size;
298
+ }
299
+ }
300
+
301
+ if (!check_zoned_request(s, offset, len, false, &err_status)) {
302
+ goto out;
303
+ }
304
+
305
+ blk_aio_zone_mgmt(s->blk, op, offset, len,
306
+ virtio_blk_zone_mgmt_complete, req);
307
+
308
+ return 0;
309
+out:
310
+ virtio_blk_req_complete(req, err_status);
311
+ virtio_blk_free_request(req);
312
+ return err_status;
313
+}
314
+
315
+static void virtio_blk_zone_append_complete(void *opaque, int ret)
316
+{
317
+ ZoneCmdData *data = opaque;
318
+ VirtIOBlockReq *req = data->req;
319
+ VirtIOBlock *s = req->dev;
320
+ VirtIODevice *vdev = VIRTIO_DEVICE(req->dev);
321
+ int64_t append_sector, n;
322
+ uint8_t err_status = VIRTIO_BLK_S_OK;
323
+
324
+ if (ret) {
325
+ err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
326
+ goto out;
327
+ }
328
+
329
+ virtio_stq_p(vdev, &append_sector,
330
+ data->zone_append_data.offset >> BDRV_SECTOR_BITS);
331
+ n = iov_from_buf(data->in_iov, data->in_num, 0, &append_sector,
332
+ sizeof(append_sector));
333
+ if (n != sizeof(append_sector)) {
334
+ virtio_error(vdev, "Driver provided input buffer less than size of "
335
+ "append_sector");
336
+ err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
337
+ goto out;
338
+ }
339
+
340
+out:
341
+ aio_context_acquire(blk_get_aio_context(s->conf.conf.blk));
342
+ virtio_blk_req_complete(req, err_status);
343
+ virtio_blk_free_request(req);
344
+ aio_context_release(blk_get_aio_context(s->conf.conf.blk));
345
+ g_free(data);
346
+}
347
+
348
+static int virtio_blk_handle_zone_append(VirtIOBlockReq *req,
349
+ struct iovec *out_iov,
350
+ struct iovec *in_iov,
351
+ uint64_t out_num,
352
+ unsigned in_num) {
353
+ VirtIOBlock *s = req->dev;
354
+ VirtIODevice *vdev = VIRTIO_DEVICE(s);
355
+ uint8_t err_status = VIRTIO_BLK_S_OK;
356
+
357
+ int64_t offset = virtio_ldq_p(vdev, &req->out.sector) << BDRV_SECTOR_BITS;
358
+ int64_t len = iov_size(out_iov, out_num);
359
+
360
+ if (!check_zoned_request(s, offset, len, true, &err_status)) {
361
+ goto out;
362
+ }
363
+
364
+ ZoneCmdData *data = g_malloc(sizeof(ZoneCmdData));
365
+ data->req = req;
366
+ data->in_iov = in_iov;
367
+ data->in_num = in_num;
368
+ data->zone_append_data.offset = offset;
369
+ qemu_iovec_init_external(&req->qiov, out_iov, out_num);
370
+ blk_aio_zone_append(s->blk, &data->zone_append_data.offset, &req->qiov, 0,
371
+ virtio_blk_zone_append_complete, data);
372
+ return 0;
373
+
374
+out:
375
+ aio_context_acquire(blk_get_aio_context(s->conf.conf.blk));
376
+ virtio_blk_req_complete(req, err_status);
377
+ virtio_blk_free_request(req);
378
+ aio_context_release(blk_get_aio_context(s->conf.conf.blk));
379
+ return err_status;
380
+}
381
+
382
static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
383
{
384
uint32_t type;
385
@@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
386
case VIRTIO_BLK_T_FLUSH:
387
virtio_blk_handle_flush(req, mrb);
388
break;
389
+ case VIRTIO_BLK_T_ZONE_REPORT:
390
+ virtio_blk_handle_zone_report(req, in_iov, in_num);
391
+ break;
392
+ case VIRTIO_BLK_T_ZONE_OPEN:
393
+ virtio_blk_handle_zone_mgmt(req, BLK_ZO_OPEN);
394
+ break;
395
+ case VIRTIO_BLK_T_ZONE_CLOSE:
396
+ virtio_blk_handle_zone_mgmt(req, BLK_ZO_CLOSE);
397
+ break;
398
+ case VIRTIO_BLK_T_ZONE_FINISH:
399
+ virtio_blk_handle_zone_mgmt(req, BLK_ZO_FINISH);
400
+ break;
401
+ case VIRTIO_BLK_T_ZONE_RESET:
402
+ virtio_blk_handle_zone_mgmt(req, BLK_ZO_RESET);
403
+ break;
404
+ case VIRTIO_BLK_T_ZONE_RESET_ALL:
405
+ virtio_blk_handle_zone_mgmt(req, BLK_ZO_RESET);
406
+ break;
407
case VIRTIO_BLK_T_SCSI_CMD:
408
virtio_blk_handle_scsi(req);
409
break;
410
@@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
411
virtio_blk_free_request(req);
412
break;
413
}
414
+ case VIRTIO_BLK_T_ZONE_APPEND & ~VIRTIO_BLK_T_OUT:
415
+ /*
416
+ * Passing out_iov/out_num and in_iov/in_num is not safe
417
+ * to access req->elem.out_sg directly because it may be
418
+ * modified by virtio_blk_handle_request().
419
+ */
420
+ virtio_blk_handle_zone_append(req, out_iov, in_iov, out_num, in_num);
421
+ break;
422
/*
423
* VIRTIO_BLK_T_DISCARD and VIRTIO_BLK_T_WRITE_ZEROES are defined with
424
* VIRTIO_BLK_T_OUT flag set. We masked this flag in the switch statement,
425
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
426
{
427
VirtIOBlock *s = VIRTIO_BLK(vdev);
428
BlockConf *conf = &s->conf.conf;
429
+ BlockDriverState *bs = blk_bs(s->blk);
430
struct virtio_blk_config blkcfg;
431
uint64_t capacity;
432
int64_t length;
433
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
434
blkcfg.write_zeroes_may_unmap = 1;
435
virtio_stl_p(vdev, &blkcfg.max_write_zeroes_seg, 1);
436
}
437
+ if (bs->bl.zoned != BLK_Z_NONE) {
438
+ switch (bs->bl.zoned) {
439
+ case BLK_Z_HM:
440
+ blkcfg.zoned.model = VIRTIO_BLK_Z_HM;
441
+ break;
442
+ case BLK_Z_HA:
443
+ blkcfg.zoned.model = VIRTIO_BLK_Z_HA;
444
+ break;
445
+ default:
446
+ g_assert_not_reached();
447
+ }
448
+
449
+ virtio_stl_p(vdev, &blkcfg.zoned.zone_sectors,
450
+ bs->bl.zone_size / 512);
451
+ virtio_stl_p(vdev, &blkcfg.zoned.max_active_zones,
452
+ bs->bl.max_active_zones);
453
+ virtio_stl_p(vdev, &blkcfg.zoned.max_open_zones,
454
+ bs->bl.max_open_zones);
455
+ virtio_stl_p(vdev, &blkcfg.zoned.write_granularity, blk_size);
456
+ virtio_stl_p(vdev, &blkcfg.zoned.max_append_sectors,
457
+ bs->bl.max_append_sectors);
458
+ } else {
459
+ blkcfg.zoned.model = VIRTIO_BLK_Z_NONE;
460
+ }
461
memcpy(config, &blkcfg, s->config_size);
462
}
463
464
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
465
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
466
VirtIOBlock *s = VIRTIO_BLK(dev);
467
VirtIOBlkConf *conf = &s->conf;
468
+ BlockDriverState *bs = blk_bs(conf->conf.blk);
469
Error *err = NULL;
470
unsigned i;
471
472
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
473
return;
474
}
475
476
+ if (bs->bl.zoned != BLK_Z_NONE) {
477
+ virtio_add_feature(&s->host_features, VIRTIO_BLK_F_ZONED);
478
+ if (bs->bl.zoned == BLK_Z_HM) {
479
+ virtio_clear_feature(&s->host_features, VIRTIO_BLK_F_DISCARD);
480
+ }
481
+ }
482
+
483
if (virtio_has_feature(s->host_features, VIRTIO_BLK_F_DISCARD) &&
484
(!conf->max_discard_sectors ||
485
conf->max_discard_sectors > BDRV_REQUEST_MAX_SECTORS)) {
486
diff --git a/hw/virtio/virtio-qmp.c b/hw/virtio/virtio-qmp.c
487
index XXXXXXX..XXXXXXX 100644
488
--- a/hw/virtio/virtio-qmp.c
489
+++ b/hw/virtio/virtio-qmp.c
490
@@ -XXX,XX +XXX,XX @@ static const qmp_virtio_feature_map_t virtio_blk_feature_map[] = {
491
"VIRTIO_BLK_F_DISCARD: Discard command supported"),
492
FEATURE_ENTRY(VIRTIO_BLK_F_WRITE_ZEROES, \
493
"VIRTIO_BLK_F_WRITE_ZEROES: Write zeroes command supported"),
494
+ FEATURE_ENTRY(VIRTIO_BLK_F_ZONED, \
495
+ "VIRTIO_BLK_F_ZONED: Zoned block devices"),
496
#ifndef VIRTIO_BLK_NO_LEGACY
497
FEATURE_ENTRY(VIRTIO_BLK_F_BARRIER, \
498
"VIRTIO_BLK_F_BARRIER: Request barriers supported"),
499
--
500
2.39.2
diff view generated by jsdifflib
1
iotest 126 requires backing file support, which flat vmdks cannot offer.
1
From: Sam Li <faithilikerun@gmail.com>
2
Skip this test for such subformats.
3
2
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
Taking account of the new zone append write operation for zoned devices,
5
Message-id: 20190815153638.4600-8-mreitz@redhat.com
4
BLOCK_ACCT_ZONE_APPEND enum is introduced as other I/O request type (read,
6
Reviewed-by: John Snow <jsnow@redhat.com>
5
write, flush).
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
7
Signed-off-by: Sam Li <faithilikerun@gmail.com>
8
Message-id: 20230407082528.18841-4-faithilikerun@gmail.com
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
---
10
---
9
tests/qemu-iotests/126 | 2 ++
11
qapi/block-core.json | 68 ++++++++++++++++++++++++++++++++------
10
1 file changed, 2 insertions(+)
12
qapi/block.json | 4 +++
13
include/block/accounting.h | 1 +
14
block/qapi-sysemu.c | 11 ++++++
15
block/qapi.c | 18 ++++++++++
16
hw/block/virtio-blk.c | 4 +++
17
6 files changed, 95 insertions(+), 11 deletions(-)
11
18
12
diff --git a/tests/qemu-iotests/126 b/tests/qemu-iotests/126
19
diff --git a/qapi/block-core.json b/qapi/block-core.json
13
index XXXXXXX..XXXXXXX 100755
20
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/qemu-iotests/126
21
--- a/qapi/block-core.json
15
+++ b/tests/qemu-iotests/126
22
+++ b/qapi/block-core.json
16
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
23
@@ -XXX,XX +XXX,XX @@
17
24
# @min_wr_latency_ns: Minimum latency of write operations in the
18
# Needs backing file support
25
# defined interval, in nanoseconds.
19
_supported_fmt qcow qcow2 qed vmdk
26
#
20
+_unsupported_imgopts "subformat=monolithicFlat" \
27
+# @min_zone_append_latency_ns: Minimum latency of zone append operations
21
+ "subformat=twoGbMaxExtentFlat"
28
+# in the defined interval, in nanoseconds
22
# This is the default protocol (and we want to test the difference between
29
+# (since 8.1)
23
# colons which separate a protocol prefix from the rest and colons which are
30
+#
24
# just part of the filename, so we cannot test protocols which require a prefix)
31
# @min_flush_latency_ns: Minimum latency of flush operations in the
32
# defined interval, in nanoseconds.
33
#
34
@@ -XXX,XX +XXX,XX @@
35
# @max_wr_latency_ns: Maximum latency of write operations in the
36
# defined interval, in nanoseconds.
37
#
38
+# @max_zone_append_latency_ns: Maximum latency of zone append operations
39
+# in the defined interval, in nanoseconds
40
+# (since 8.1)
41
+#
42
# @max_flush_latency_ns: Maximum latency of flush operations in the
43
# defined interval, in nanoseconds.
44
#
45
@@ -XXX,XX +XXX,XX @@
46
# @avg_wr_latency_ns: Average latency of write operations in the
47
# defined interval, in nanoseconds.
48
#
49
+# @avg_zone_append_latency_ns: Average latency of zone append operations
50
+# in the defined interval, in nanoseconds
51
+# (since 8.1)
52
+#
53
# @avg_flush_latency_ns: Average latency of flush operations in the
54
# defined interval, in nanoseconds.
55
#
56
@@ -XXX,XX +XXX,XX @@
57
# @avg_wr_queue_depth: Average number of pending write operations
58
# in the defined interval.
59
#
60
+# @avg_zone_append_queue_depth: Average number of pending zone append
61
+# operations in the defined interval
62
+# (since 8.1).
63
+#
64
# Since: 2.5
65
##
66
{ 'struct': 'BlockDeviceTimedStats',
67
'data': { 'interval_length': 'int', 'min_rd_latency_ns': 'int',
68
'max_rd_latency_ns': 'int', 'avg_rd_latency_ns': 'int',
69
'min_wr_latency_ns': 'int', 'max_wr_latency_ns': 'int',
70
- 'avg_wr_latency_ns': 'int', 'min_flush_latency_ns': 'int',
71
- 'max_flush_latency_ns': 'int', 'avg_flush_latency_ns': 'int',
72
- 'avg_rd_queue_depth': 'number', 'avg_wr_queue_depth': 'number' } }
73
+ 'avg_wr_latency_ns': 'int', 'min_zone_append_latency_ns': 'int',
74
+ 'max_zone_append_latency_ns': 'int',
75
+ 'avg_zone_append_latency_ns': 'int',
76
+ 'min_flush_latency_ns': 'int', 'max_flush_latency_ns': 'int',
77
+ 'avg_flush_latency_ns': 'int', 'avg_rd_queue_depth': 'number',
78
+ 'avg_wr_queue_depth': 'number',
79
+ 'avg_zone_append_queue_depth': 'number' } }
80
81
##
82
# @BlockDeviceStats:
83
@@ -XXX,XX +XXX,XX @@
84
#
85
# @wr_bytes: The number of bytes written by the device.
86
#
87
+# @zone_append_bytes: The number of bytes appended by the zoned devices
88
+# (since 8.1)
89
+#
90
# @unmap_bytes: The number of bytes unmapped by the device (Since 4.2)
91
#
92
# @rd_operations: The number of read operations performed by the device.
93
#
94
# @wr_operations: The number of write operations performed by the device.
95
#
96
+# @zone_append_operations: The number of zone append operations performed
97
+# by the zoned devices (since 8.1)
98
+#
99
# @flush_operations: The number of cache flush operations performed by the
100
# device (since 0.15)
101
#
102
@@ -XXX,XX +XXX,XX @@
103
#
104
# @wr_total_time_ns: Total time spent on writes in nanoseconds (since 0.15).
105
#
106
+# @zone_append_total_time_ns: Total time spent on zone append writes
107
+# in nanoseconds (since 8.1)
108
+#
109
# @flush_total_time_ns: Total time spent on cache flushes in nanoseconds
110
# (since 0.15).
111
#
112
@@ -XXX,XX +XXX,XX @@
113
# @wr_merged: Number of write requests that have been merged into another
114
# request (Since 2.3).
115
#
116
+# @zone_append_merged: Number of zone append requests that have been merged
117
+# into another request (since 8.1)
118
+#
119
# @unmap_merged: Number of unmap requests that have been merged into another
120
# request (Since 4.2)
121
#
122
@@ -XXX,XX +XXX,XX @@
123
# @failed_wr_operations: The number of failed write operations
124
# performed by the device (Since 2.5)
125
#
126
+# @failed_zone_append_operations: The number of failed zone append write
127
+# operations performed by the zoned devices
128
+# (since 8.1)
129
+#
130
# @failed_flush_operations: The number of failed flush operations
131
# performed by the device (Since 2.5)
132
#
133
@@ -XXX,XX +XXX,XX @@
134
# @invalid_wr_operations: The number of invalid write operations
135
# performed by the device (Since 2.5)
136
#
137
+# @invalid_zone_append_operations: The number of invalid zone append operations
138
+# performed by the zoned device (since 8.1)
139
+#
140
# @invalid_flush_operations: The number of invalid flush operations
141
# performed by the device (Since 2.5)
142
#
143
@@ -XXX,XX +XXX,XX @@
144
#
145
# @wr_latency_histogram: @BlockLatencyHistogramInfo. (Since 4.0)
146
#
147
+# @zone_append_latency_histogram: @BlockLatencyHistogramInfo. (since 8.1)
148
+#
149
# @flush_latency_histogram: @BlockLatencyHistogramInfo. (Since 4.0)
150
#
151
# Since: 0.14
152
##
153
{ 'struct': 'BlockDeviceStats',
154
- 'data': {'rd_bytes': 'int', 'wr_bytes': 'int', 'unmap_bytes' : 'int',
155
- 'rd_operations': 'int', 'wr_operations': 'int',
156
+ 'data': {'rd_bytes': 'int', 'wr_bytes': 'int', 'zone_append_bytes': 'int',
157
+ 'unmap_bytes' : 'int', 'rd_operations': 'int',
158
+ 'wr_operations': 'int', 'zone_append_operations': 'int',
159
'flush_operations': 'int', 'unmap_operations': 'int',
160
'rd_total_time_ns': 'int', 'wr_total_time_ns': 'int',
161
- 'flush_total_time_ns': 'int', 'unmap_total_time_ns': 'int',
162
- 'wr_highest_offset': 'int',
163
- 'rd_merged': 'int', 'wr_merged': 'int', 'unmap_merged': 'int',
164
- '*idle_time_ns': 'int',
165
+ 'zone_append_total_time_ns': 'int', 'flush_total_time_ns': 'int',
166
+ 'unmap_total_time_ns': 'int', 'wr_highest_offset': 'int',
167
+ 'rd_merged': 'int', 'wr_merged': 'int', 'zone_append_merged': 'int',
168
+ 'unmap_merged': 'int', '*idle_time_ns': 'int',
169
'failed_rd_operations': 'int', 'failed_wr_operations': 'int',
170
- 'failed_flush_operations': 'int', 'failed_unmap_operations': 'int',
171
- 'invalid_rd_operations': 'int', 'invalid_wr_operations': 'int',
172
+ 'failed_zone_append_operations': 'int',
173
+ 'failed_flush_operations': 'int',
174
+ 'failed_unmap_operations': 'int', 'invalid_rd_operations': 'int',
175
+ 'invalid_wr_operations': 'int',
176
+ 'invalid_zone_append_operations': 'int',
177
'invalid_flush_operations': 'int', 'invalid_unmap_operations': 'int',
178
'account_invalid': 'bool', 'account_failed': 'bool',
179
'timed_stats': ['BlockDeviceTimedStats'],
180
'*rd_latency_histogram': 'BlockLatencyHistogramInfo',
181
'*wr_latency_histogram': 'BlockLatencyHistogramInfo',
182
+ '*zone_append_latency_histogram': 'BlockLatencyHistogramInfo',
183
'*flush_latency_histogram': 'BlockLatencyHistogramInfo' } }
184
185
##
186
diff --git a/qapi/block.json b/qapi/block.json
187
index XXXXXXX..XXXXXXX 100644
188
--- a/qapi/block.json
189
+++ b/qapi/block.json
190
@@ -XXX,XX +XXX,XX @@
191
# @boundaries-write: list of interval boundary values for write latency
192
# histogram.
193
#
194
+# @boundaries-zap: list of interval boundary values for zone append write
195
+# latency histogram.
196
+#
197
# @boundaries-flush: list of interval boundary values for flush latency
198
# histogram.
199
#
200
@@ -XXX,XX +XXX,XX @@
201
'*boundaries': ['uint64'],
202
'*boundaries-read': ['uint64'],
203
'*boundaries-write': ['uint64'],
204
+ '*boundaries-zap': ['uint64'],
205
'*boundaries-flush': ['uint64'] },
206
'allow-preconfig': true }
207
diff --git a/include/block/accounting.h b/include/block/accounting.h
208
index XXXXXXX..XXXXXXX 100644
209
--- a/include/block/accounting.h
210
+++ b/include/block/accounting.h
211
@@ -XXX,XX +XXX,XX @@ enum BlockAcctType {
212
BLOCK_ACCT_READ,
213
BLOCK_ACCT_WRITE,
214
BLOCK_ACCT_FLUSH,
215
+ BLOCK_ACCT_ZONE_APPEND,
216
BLOCK_ACCT_UNMAP,
217
BLOCK_MAX_IOTYPE,
218
};
219
diff --git a/block/qapi-sysemu.c b/block/qapi-sysemu.c
220
index XXXXXXX..XXXXXXX 100644
221
--- a/block/qapi-sysemu.c
222
+++ b/block/qapi-sysemu.c
223
@@ -XXX,XX +XXX,XX @@ void qmp_block_latency_histogram_set(
224
bool has_boundaries, uint64List *boundaries,
225
bool has_boundaries_read, uint64List *boundaries_read,
226
bool has_boundaries_write, uint64List *boundaries_write,
227
+ bool has_boundaries_append, uint64List *boundaries_append,
228
bool has_boundaries_flush, uint64List *boundaries_flush,
229
Error **errp)
230
{
231
@@ -XXX,XX +XXX,XX @@ void qmp_block_latency_histogram_set(
232
}
233
}
234
235
+ if (has_boundaries || has_boundaries_append) {
236
+ ret = block_latency_histogram_set(
237
+ stats, BLOCK_ACCT_ZONE_APPEND,
238
+ has_boundaries_append ? boundaries_append : boundaries);
239
+ if (ret) {
240
+ error_setg(errp, "Device '%s' set append write boundaries fail", id);
241
+ return;
242
+ }
243
+ }
244
+
245
if (has_boundaries || has_boundaries_flush) {
246
ret = block_latency_histogram_set(
247
stats, BLOCK_ACCT_FLUSH,
248
diff --git a/block/qapi.c b/block/qapi.c
249
index XXXXXXX..XXXXXXX 100644
250
--- a/block/qapi.c
251
+++ b/block/qapi.c
252
@@ -XXX,XX +XXX,XX @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
253
254
ds->rd_bytes = stats->nr_bytes[BLOCK_ACCT_READ];
255
ds->wr_bytes = stats->nr_bytes[BLOCK_ACCT_WRITE];
256
+ ds->zone_append_bytes = stats->nr_bytes[BLOCK_ACCT_ZONE_APPEND];
257
ds->unmap_bytes = stats->nr_bytes[BLOCK_ACCT_UNMAP];
258
ds->rd_operations = stats->nr_ops[BLOCK_ACCT_READ];
259
ds->wr_operations = stats->nr_ops[BLOCK_ACCT_WRITE];
260
+ ds->zone_append_operations = stats->nr_ops[BLOCK_ACCT_ZONE_APPEND];
261
ds->unmap_operations = stats->nr_ops[BLOCK_ACCT_UNMAP];
262
263
ds->failed_rd_operations = stats->failed_ops[BLOCK_ACCT_READ];
264
ds->failed_wr_operations = stats->failed_ops[BLOCK_ACCT_WRITE];
265
+ ds->failed_zone_append_operations =
266
+ stats->failed_ops[BLOCK_ACCT_ZONE_APPEND];
267
ds->failed_flush_operations = stats->failed_ops[BLOCK_ACCT_FLUSH];
268
ds->failed_unmap_operations = stats->failed_ops[BLOCK_ACCT_UNMAP];
269
270
ds->invalid_rd_operations = stats->invalid_ops[BLOCK_ACCT_READ];
271
ds->invalid_wr_operations = stats->invalid_ops[BLOCK_ACCT_WRITE];
272
+ ds->invalid_zone_append_operations =
273
+ stats->invalid_ops[BLOCK_ACCT_ZONE_APPEND];
274
ds->invalid_flush_operations =
275
stats->invalid_ops[BLOCK_ACCT_FLUSH];
276
ds->invalid_unmap_operations = stats->invalid_ops[BLOCK_ACCT_UNMAP];
277
278
ds->rd_merged = stats->merged[BLOCK_ACCT_READ];
279
ds->wr_merged = stats->merged[BLOCK_ACCT_WRITE];
280
+ ds->zone_append_merged = stats->merged[BLOCK_ACCT_ZONE_APPEND];
281
ds->unmap_merged = stats->merged[BLOCK_ACCT_UNMAP];
282
ds->flush_operations = stats->nr_ops[BLOCK_ACCT_FLUSH];
283
ds->wr_total_time_ns = stats->total_time_ns[BLOCK_ACCT_WRITE];
284
+ ds->zone_append_total_time_ns =
285
+ stats->total_time_ns[BLOCK_ACCT_ZONE_APPEND];
286
ds->rd_total_time_ns = stats->total_time_ns[BLOCK_ACCT_READ];
287
ds->flush_total_time_ns = stats->total_time_ns[BLOCK_ACCT_FLUSH];
288
ds->unmap_total_time_ns = stats->total_time_ns[BLOCK_ACCT_UNMAP];
289
@@ -XXX,XX +XXX,XX @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
290
291
TimedAverage *rd = &ts->latency[BLOCK_ACCT_READ];
292
TimedAverage *wr = &ts->latency[BLOCK_ACCT_WRITE];
293
+ TimedAverage *zap = &ts->latency[BLOCK_ACCT_ZONE_APPEND];
294
TimedAverage *fl = &ts->latency[BLOCK_ACCT_FLUSH];
295
296
dev_stats->interval_length = ts->interval_length;
297
@@ -XXX,XX +XXX,XX @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
298
dev_stats->max_wr_latency_ns = timed_average_max(wr);
299
dev_stats->avg_wr_latency_ns = timed_average_avg(wr);
300
301
+ dev_stats->min_zone_append_latency_ns = timed_average_min(zap);
302
+ dev_stats->max_zone_append_latency_ns = timed_average_max(zap);
303
+ dev_stats->avg_zone_append_latency_ns = timed_average_avg(zap);
304
+
305
dev_stats->min_flush_latency_ns = timed_average_min(fl);
306
dev_stats->max_flush_latency_ns = timed_average_max(fl);
307
dev_stats->avg_flush_latency_ns = timed_average_avg(fl);
308
@@ -XXX,XX +XXX,XX @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
309
block_acct_queue_depth(ts, BLOCK_ACCT_READ);
310
dev_stats->avg_wr_queue_depth =
311
block_acct_queue_depth(ts, BLOCK_ACCT_WRITE);
312
+ dev_stats->avg_zone_append_queue_depth =
313
+ block_acct_queue_depth(ts, BLOCK_ACCT_ZONE_APPEND);
314
315
QAPI_LIST_PREPEND(ds->timed_stats, dev_stats);
316
}
317
@@ -XXX,XX +XXX,XX @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
318
= bdrv_latency_histogram_stats(&hgram[BLOCK_ACCT_READ]);
319
ds->wr_latency_histogram
320
= bdrv_latency_histogram_stats(&hgram[BLOCK_ACCT_WRITE]);
321
+ ds->zone_append_latency_histogram
322
+ = bdrv_latency_histogram_stats(&hgram[BLOCK_ACCT_ZONE_APPEND]);
323
ds->flush_latency_histogram
324
= bdrv_latency_histogram_stats(&hgram[BLOCK_ACCT_FLUSH]);
325
}
326
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
327
index XXXXXXX..XXXXXXX 100644
328
--- a/hw/block/virtio-blk.c
329
+++ b/hw/block/virtio-blk.c
330
@@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_zone_append(VirtIOBlockReq *req,
331
data->in_num = in_num;
332
data->zone_append_data.offset = offset;
333
qemu_iovec_init_external(&req->qiov, out_iov, out_num);
334
+
335
+ block_acct_start(blk_get_stats(s->blk), &req->acct, len,
336
+ BLOCK_ACCT_ZONE_APPEND);
337
+
338
blk_aio_zone_append(s->blk, &data->zone_append_data.offset, &req->qiov, 0,
339
virtio_blk_zone_append_complete, data);
340
return 0;
25
--
341
--
26
2.21.0
342
2.39.2
27
28
diff view generated by jsdifflib
1
streamOptimized does not support writes that do not span exactly one
1
From: Sam Li <faithilikerun@gmail.com>
2
cluster. Furthermore, it cannot rewrite already allocated clusters.
3
As such, many iotests do not work with it. Disable them.
4
2
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
Signed-off-by: Sam Li <faithilikerun@gmail.com>
6
Message-id: 20190815153638.4600-6-mreitz@redhat.com
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Reviewed-by: John Snow <jsnow@redhat.com>
5
Message-id: 20230407082528.18841-5-faithilikerun@gmail.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
---
7
---
10
tests/qemu-iotests/002 | 1 +
8
hw/block/virtio-blk.c | 12 ++++++++++++
11
tests/qemu-iotests/003 | 1 +
9
hw/block/trace-events | 7 +++++++
12
tests/qemu-iotests/005 | 3 ++-
10
2 files changed, 19 insertions(+)
13
tests/qemu-iotests/009 | 1 +
14
tests/qemu-iotests/010 | 1 +
15
tests/qemu-iotests/011 | 1 +
16
tests/qemu-iotests/017 | 3 ++-
17
tests/qemu-iotests/018 | 3 ++-
18
tests/qemu-iotests/019 | 3 ++-
19
tests/qemu-iotests/020 | 3 ++-
20
tests/qemu-iotests/027 | 1 +
21
tests/qemu-iotests/032 | 1 +
22
tests/qemu-iotests/033 | 1 +
23
tests/qemu-iotests/034 | 3 ++-
24
tests/qemu-iotests/037 | 3 ++-
25
tests/qemu-iotests/063 | 3 ++-
26
tests/qemu-iotests/072 | 1 +
27
tests/qemu-iotests/105 | 3 ++-
28
tests/qemu-iotests/197 | 1 +
29
tests/qemu-iotests/215 | 1 +
30
tests/qemu-iotests/251 | 1 +
31
21 files changed, 30 insertions(+), 9 deletions(-)
32
11
33
diff --git a/tests/qemu-iotests/002 b/tests/qemu-iotests/002
12
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
34
index XXXXXXX..XXXXXXX 100755
13
index XXXXXXX..XXXXXXX 100644
35
--- a/tests/qemu-iotests/002
14
--- a/hw/block/virtio-blk.c
36
+++ b/tests/qemu-iotests/002
15
+++ b/hw/block/virtio-blk.c
37
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
16
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_zone_report_complete(void *opaque, int ret)
38
17
int64_t nz = data->zone_report_data.nr_zones;
39
_supported_fmt generic
18
int8_t err_status = VIRTIO_BLK_S_OK;
40
_supported_proto generic
19
41
+_unsupported_imgopts "subformat=streamOptimized"
20
+ trace_virtio_blk_zone_report_complete(vdev, req, nz, ret);
42
21
if (ret) {
43
22
err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
44
size=128M
23
goto out;
45
diff --git a/tests/qemu-iotests/003 b/tests/qemu-iotests/003
24
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_handle_zone_report(VirtIOBlockReq *req,
46
index XXXXXXX..XXXXXXX 100755
25
nr_zones = (req->in_len - sizeof(struct virtio_blk_inhdr) -
47
--- a/tests/qemu-iotests/003
26
sizeof(struct virtio_blk_zone_report)) /
48
+++ b/tests/qemu-iotests/003
27
sizeof(struct virtio_blk_zone_descriptor);
49
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
28
+ trace_virtio_blk_handle_zone_report(vdev, req,
50
29
+ offset >> BDRV_SECTOR_BITS, nr_zones);
51
_supported_fmt generic
30
52
_supported_proto generic
31
zone_size = sizeof(BlockZoneDescriptor) * nr_zones;
53
+_unsupported_imgopts "subformat=streamOptimized"
32
data = g_malloc(sizeof(ZoneCmdData));
54
33
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_zone_mgmt_complete(void *opaque, int ret)
55
size=128M
34
{
56
offset=67M
35
VirtIOBlockReq *req = opaque;
57
diff --git a/tests/qemu-iotests/005 b/tests/qemu-iotests/005
36
VirtIOBlock *s = req->dev;
58
index XXXXXXX..XXXXXXX 100755
37
+ VirtIODevice *vdev = VIRTIO_DEVICE(s);
59
--- a/tests/qemu-iotests/005
38
int8_t err_status = VIRTIO_BLK_S_OK;
60
+++ b/tests/qemu-iotests/005
39
+ trace_virtio_blk_zone_mgmt_complete(vdev, req,ret);
61
@@ -XXX,XX +XXX,XX @@ _supported_fmt generic
40
62
_supported_proto generic
41
if (ret) {
63
_supported_os Linux
42
err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
64
_unsupported_imgopts "subformat=twoGbMaxExtentFlat" \
43
@@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_zone_mgmt(VirtIOBlockReq *req, BlockZoneOp op)
65
- "subformat=twoGbMaxExtentSparse"
44
/* Entire drive capacity */
66
+ "subformat=twoGbMaxExtentSparse" \
45
offset = 0;
67
+ "subformat=streamOptimized"
46
len = capacity;
68
47
+ trace_virtio_blk_handle_zone_reset_all(vdev, req, 0,
69
# vpc is limited to 127GB, so we can't test it here
48
+ bs->total_sectors);
70
if [ "$IMGFMT" = "vpc" ]; then
49
} else {
71
diff --git a/tests/qemu-iotests/009 b/tests/qemu-iotests/009
50
if (bs->bl.zone_size > capacity - offset) {
72
index XXXXXXX..XXXXXXX 100755
51
/* The zoned device allows the last smaller zone. */
73
--- a/tests/qemu-iotests/009
52
@@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_zone_mgmt(VirtIOBlockReq *req, BlockZoneOp op)
74
+++ b/tests/qemu-iotests/009
53
} else {
75
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
54
len = bs->bl.zone_size;
76
55
}
77
_supported_fmt generic
56
+ trace_virtio_blk_handle_zone_mgmt(vdev, req, op,
78
_supported_proto generic
57
+ offset >> BDRV_SECTOR_BITS,
79
+_unsupported_imgopts "subformat=streamOptimized"
58
+ len >> BDRV_SECTOR_BITS);
80
59
}
81
60
82
size=6G
61
if (!check_zoned_request(s, offset, len, false, &err_status)) {
83
diff --git a/tests/qemu-iotests/010 b/tests/qemu-iotests/010
62
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_zone_append_complete(void *opaque, int ret)
84
index XXXXXXX..XXXXXXX 100755
63
err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
85
--- a/tests/qemu-iotests/010
64
goto out;
86
+++ b/tests/qemu-iotests/010
65
}
87
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
66
+ trace_virtio_blk_zone_append_complete(vdev, req, append_sector, ret);
88
67
89
_supported_fmt generic
68
out:
90
_supported_proto generic
69
aio_context_acquire(blk_get_aio_context(s->conf.conf.blk));
91
+_unsupported_imgopts "subformat=streamOptimized"
70
@@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_zone_append(VirtIOBlockReq *req,
92
71
int64_t offset = virtio_ldq_p(vdev, &req->out.sector) << BDRV_SECTOR_BITS;
93
72
int64_t len = iov_size(out_iov, out_num);
94
size=6G
73
95
diff --git a/tests/qemu-iotests/011 b/tests/qemu-iotests/011
74
+ trace_virtio_blk_handle_zone_append(vdev, req, offset >> BDRV_SECTOR_BITS);
96
index XXXXXXX..XXXXXXX 100755
75
if (!check_zoned_request(s, offset, len, true, &err_status)) {
97
--- a/tests/qemu-iotests/011
76
goto out;
98
+++ b/tests/qemu-iotests/011
77
}
99
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
78
diff --git a/hw/block/trace-events b/hw/block/trace-events
100
79
index XXXXXXX..XXXXXXX 100644
101
_supported_fmt generic
80
--- a/hw/block/trace-events
102
_supported_proto generic
81
+++ b/hw/block/trace-events
103
+_unsupported_imgopts "subformat=streamOptimized"
82
@@ -XXX,XX +XXX,XX @@ pflash_write_unknown(const char *name, uint8_t cmd) "%s: unknown command 0x%02x"
104
83
# virtio-blk.c
105
84
virtio_blk_req_complete(void *vdev, void *req, int status) "vdev %p req %p status %d"
106
size=6G
85
virtio_blk_rw_complete(void *vdev, void *req, int ret) "vdev %p req %p ret %d"
107
diff --git a/tests/qemu-iotests/017 b/tests/qemu-iotests/017
86
+virtio_blk_zone_report_complete(void *vdev, void *req, unsigned int nr_zones, int ret) "vdev %p req %p nr_zones %u ret %d"
108
index XXXXXXX..XXXXXXX 100755
87
+virtio_blk_zone_mgmt_complete(void *vdev, void *req, int ret) "vdev %p req %p ret %d"
109
--- a/tests/qemu-iotests/017
88
+virtio_blk_zone_append_complete(void *vdev, void *req, int64_t sector, int ret) "vdev %p req %p, append sector 0x%" PRIx64 " ret %d"
110
+++ b/tests/qemu-iotests/017
89
virtio_blk_handle_write(void *vdev, void *req, uint64_t sector, size_t nsectors) "vdev %p req %p sector %"PRIu64" nsectors %zu"
111
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
90
virtio_blk_handle_read(void *vdev, void *req, uint64_t sector, size_t nsectors) "vdev %p req %p sector %"PRIu64" nsectors %zu"
112
_supported_fmt qcow qcow2 vmdk qed
91
virtio_blk_submit_multireq(void *vdev, void *mrb, int start, int num_reqs, uint64_t offset, size_t size, bool is_write) "vdev %p mrb %p start %d num_reqs %d offset %"PRIu64" size %zu is_write %d"
113
_supported_proto generic
92
+virtio_blk_handle_zone_report(void *vdev, void *req, int64_t sector, unsigned int nr_zones) "vdev %p req %p sector 0x%" PRIx64 " nr_zones %u"
114
_unsupported_proto vxhs
93
+virtio_blk_handle_zone_mgmt(void *vdev, void *req, uint8_t op, int64_t sector, int64_t len) "vdev %p req %p op 0x%x sector 0x%" PRIx64 " len 0x%" PRIx64 ""
115
-_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
94
+virtio_blk_handle_zone_reset_all(void *vdev, void *req, int64_t sector, int64_t len) "vdev %p req %p sector 0x%" PRIx64 " cap 0x%" PRIx64 ""
116
+_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
95
+virtio_blk_handle_zone_append(void *vdev, void *req, int64_t sector) "vdev %p req %p, append sector 0x%" PRIx64 ""
117
+ "subformat=streamOptimized"
96
118
97
# hd-geometry.c
119
TEST_OFFSETS="0 4294967296"
98
hd_geometry_lchs_guess(void *blk, int cyls, int heads, int secs) "blk %p LCHS %d %d %d"
120
121
diff --git a/tests/qemu-iotests/018 b/tests/qemu-iotests/018
122
index XXXXXXX..XXXXXXX 100755
123
--- a/tests/qemu-iotests/018
124
+++ b/tests/qemu-iotests/018
125
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
126
_supported_fmt qcow qcow2 vmdk qed
127
_supported_proto file
128
_supported_os Linux
129
-_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
130
+_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
131
+ "streamOptimized"
132
133
TEST_OFFSETS="0 4294967296"
134
135
diff --git a/tests/qemu-iotests/019 b/tests/qemu-iotests/019
136
index XXXXXXX..XXXXXXX 100755
137
--- a/tests/qemu-iotests/019
138
+++ b/tests/qemu-iotests/019
139
@@ -XXX,XX +XXX,XX @@ _supported_proto file
140
_supported_os Linux
141
_unsupported_imgopts "subformat=monolithicFlat" \
142
"subformat=twoGbMaxExtentFlat" \
143
- "subformat=twoGbMaxExtentSparse"
144
+ "subformat=twoGbMaxExtentSparse" \
145
+ "subformat=streamOptimized"
146
147
TEST_OFFSETS="0 4294967296"
148
CLUSTER_SIZE=65536
149
diff --git a/tests/qemu-iotests/020 b/tests/qemu-iotests/020
150
index XXXXXXX..XXXXXXX 100755
151
--- a/tests/qemu-iotests/020
152
+++ b/tests/qemu-iotests/020
153
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow qcow2 vmdk qed
154
_supported_proto file
155
_unsupported_imgopts "subformat=monolithicFlat" \
156
"subformat=twoGbMaxExtentFlat" \
157
- "subformat=twoGbMaxExtentSparse"
158
+ "subformat=twoGbMaxExtentSparse" \
159
+ "subformat=streamOptimized"
160
161
TEST_OFFSETS="0 4294967296"
162
163
diff --git a/tests/qemu-iotests/027 b/tests/qemu-iotests/027
164
index XXXXXXX..XXXXXXX 100755
165
--- a/tests/qemu-iotests/027
166
+++ b/tests/qemu-iotests/027
167
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
168
169
_supported_fmt vmdk qcow qcow2 qed
170
_supported_proto generic
171
+_unsupported_imgopts "subformat=streamOptimized"
172
173
174
size=128M
175
diff --git a/tests/qemu-iotests/032 b/tests/qemu-iotests/032
176
index XXXXXXX..XXXXXXX 100755
177
--- a/tests/qemu-iotests/032
178
+++ b/tests/qemu-iotests/032
179
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
180
# This works for any image format (though unlikely to segfault for raw)
181
_supported_fmt generic
182
_supported_proto generic
183
+_unsupported_imgopts "subformat=streamOptimized"
184
185
echo
186
echo === Prepare image ===
187
diff --git a/tests/qemu-iotests/033 b/tests/qemu-iotests/033
188
index XXXXXXX..XXXXXXX 100755
189
--- a/tests/qemu-iotests/033
190
+++ b/tests/qemu-iotests/033
191
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
192
193
_supported_fmt generic
194
_supported_proto generic
195
+_unsupported_imgopts "subformat=streamOptimized"
196
197
198
size=128M
199
diff --git a/tests/qemu-iotests/034 b/tests/qemu-iotests/034
200
index XXXXXXX..XXXXXXX 100755
201
--- a/tests/qemu-iotests/034
202
+++ b/tests/qemu-iotests/034
203
@@ -XXX,XX +XXX,XX @@ _supported_proto file
204
_supported_os Linux
205
_unsupported_imgopts "subformat=monolithicFlat" \
206
"subformat=twoGbMaxExtentFlat" \
207
- "subformat=twoGbMaxExtentSparse"
208
+ "subformat=twoGbMaxExtentSparse" \
209
+ "subformat=streamOptimized"
210
211
CLUSTER_SIZE=4k
212
size=128M
213
diff --git a/tests/qemu-iotests/037 b/tests/qemu-iotests/037
214
index XXXXXXX..XXXXXXX 100755
215
--- a/tests/qemu-iotests/037
216
+++ b/tests/qemu-iotests/037
217
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow qcow2 vmdk qed
218
_supported_proto file
219
_unsupported_imgopts "subformat=monolithicFlat" \
220
"subformat=twoGbMaxExtentFlat" \
221
- "subformat=twoGbMaxExtentSparse"
222
+ "subformat=twoGbMaxExtentSparse" \
223
+ "subformat=streamOptimized"
224
225
CLUSTER_SIZE=4k
226
size=128M
227
diff --git a/tests/qemu-iotests/063 b/tests/qemu-iotests/063
228
index XXXXXXX..XXXXXXX 100755
229
--- a/tests/qemu-iotests/063
230
+++ b/tests/qemu-iotests/063
231
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow qcow2 vmdk qed raw
232
_supported_proto file
233
_unsupported_imgopts "subformat=monolithicFlat" \
234
"subformat=twoGbMaxExtentFlat" \
235
- "subformat=twoGbMaxExtentSparse"
236
+ "subformat=twoGbMaxExtentSparse" \
237
+ "subformat=streamOptimized"
238
239
_make_test_img 4M
240
241
diff --git a/tests/qemu-iotests/072 b/tests/qemu-iotests/072
242
index XXXXXXX..XXXXXXX 100755
243
--- a/tests/qemu-iotests/072
244
+++ b/tests/qemu-iotests/072
245
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
246
247
_supported_fmt vpc vmdk vhdx vdi qed qcow2 qcow
248
_supported_proto file
249
+_unsupported_imgopts "subformat=streamOptimized"
250
251
IMG_SIZE=64M
252
253
diff --git a/tests/qemu-iotests/105 b/tests/qemu-iotests/105
254
index XXXXXXX..XXXXXXX 100755
255
--- a/tests/qemu-iotests/105
256
+++ b/tests/qemu-iotests/105
257
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
258
_supported_fmt qcow2 vmdk vhdx qed
259
_supported_proto generic
260
_unsupported_imgopts "subformat=twoGbMaxExtentFlat" \
261
- "subformat=twoGbMaxExtentSparse"
262
+ "subformat=twoGbMaxExtentSparse" \
263
+ "subformat=streamOptimized"
264
265
echo
266
echo "creating large image"
267
diff --git a/tests/qemu-iotests/197 b/tests/qemu-iotests/197
268
index XXXXXXX..XXXXXXX 100755
269
--- a/tests/qemu-iotests/197
270
+++ b/tests/qemu-iotests/197
271
@@ -XXX,XX +XXX,XX @@ _supported_fmt generic
272
_supported_proto generic
273
# LUKS support may be possible, but it complicates things.
274
_unsupported_fmt luks
275
+_unsupported_imgopts "subformat=streamOptimized"
276
277
echo
278
echo '=== Copy-on-read ==='
279
diff --git a/tests/qemu-iotests/215 b/tests/qemu-iotests/215
280
index XXXXXXX..XXXXXXX 100755
281
--- a/tests/qemu-iotests/215
282
+++ b/tests/qemu-iotests/215
283
@@ -XXX,XX +XXX,XX @@ _supported_fmt generic
284
_supported_proto generic
285
# LUKS support may be possible, but it complicates things.
286
_unsupported_fmt luks
287
+_unsupported_imgopts "subformat=streamOptimized"
288
289
echo
290
echo '=== Copy-on-read ==='
291
diff --git a/tests/qemu-iotests/251 b/tests/qemu-iotests/251
292
index XXXXXXX..XXXXXXX 100755
293
--- a/tests/qemu-iotests/251
294
+++ b/tests/qemu-iotests/251
295
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
296
_supported_fmt generic
297
_supported_proto file
298
_supported_os Linux
299
+_unsupported_imgopts "subformat=streamOptimized"
300
301
if [ "$IMGOPTSSYNTAX" = "true" ]; then
302
# We use json:{} filenames here, so we cannot work with additional options.
303
--
99
--
304
2.21.0
100
2.39.2
305
306
diff view generated by jsdifflib
1
Compressed writes generally have to write full clusters, not just in
1
From: Sam Li <faithilikerun@gmail.com>
2
theory but also in practice when it comes to vmdk's streamOptimized
3
subformat. It currently is just silently broken for writes with
4
non-zero in-cluster offsets:
5
2
6
$ qemu-img create -f vmdk -o subformat=streamOptimized foo.vmdk 1M
3
Add the documentation about the example of using virtio-blk driver
7
$ qemu-io -c 'write 4k 4k' -c 'read 4k 4k' foo.vmdk
4
to pass the zoned block devices through to the guest.
8
wrote 4096/4096 bytes at offset 4096
9
4 KiB, 1 ops; 00.01 sec (443.724 KiB/sec and 110.9309 ops/sec)
10
read failed: Invalid argument
11
5
12
(The technical reason is that vmdk_write_extent() just writes the
6
Signed-off-by: Sam Li <faithilikerun@gmail.com>
13
incomplete compressed data actually to offset 4k. When reading the
7
Message-id: 20230407082528.18841-6-faithilikerun@gmail.com
14
data, vmdk_read_extent() looks at offset 0 and finds the compressed data
8
[Fix Sphinx indentation error by turning command-lines into
15
size to be 0, because that is what it reads from there. This yields an
9
pre-formatted text.
16
error.)
10
--Stefan]
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
docs/devel/zoned-storage.rst | 25 ++++++++++++++++++++++---
14
1 file changed, 22 insertions(+), 3 deletions(-)
17
15
18
For incomplete writes with zero in-cluster offsets, the error path when
16
diff --git a/docs/devel/zoned-storage.rst b/docs/devel/zoned-storage.rst
19
reading the rest of the cluster is a bit different, but the result is
20
the same:
21
22
$ qemu-img create -f vmdk -o subformat=streamOptimized foo.vmdk 1M
23
$ qemu-io -c 'write 0k 4k' -c 'read 4k 4k' foo.vmdk
24
wrote 4096/4096 bytes at offset 0
25
4 KiB, 1 ops; 00.01 sec (362.641 KiB/sec and 90.6603 ops/sec)
26
read failed: Invalid argument
27
28
(Here, vmdk_read_extent() finds the data and then sees that the
29
uncompressed data is short.)
30
31
It is better to reject invalid writes than to make the user believe they
32
might have succeeded and then fail when trying to read it back.
33
34
Signed-off-by: Max Reitz <mreitz@redhat.com>
35
Reviewed-by: John Snow <jsnow@redhat.com>
36
Message-id: 20190815153638.4600-5-mreitz@redhat.com
37
Reviewed-by: John Snow <jsnow@redhat.com>
38
Signed-off-by: Max Reitz <mreitz@redhat.com>
39
---
40
block/vmdk.c | 10 ++++++++++
41
1 file changed, 10 insertions(+)
42
43
diff --git a/block/vmdk.c b/block/vmdk.c
44
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
45
--- a/block/vmdk.c
18
--- a/docs/devel/zoned-storage.rst
46
+++ b/block/vmdk.c
19
+++ b/docs/devel/zoned-storage.rst
47
@@ -XXX,XX +XXX,XX @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
20
@@ -XXX,XX +XXX,XX @@ When the BlockBackend's BlockLimits model reports a zoned storage device, users
48
if (extent->compressed) {
21
like the virtio-blk emulation or the qemu-io-cmds.c utility can use block layer
49
void *compressed_data;
22
APIs for zoned storage emulation or testing.
50
23
51
+ /* Only whole clusters */
24
-For example, to test zone_report on a null_blk device using qemu-io is:
52
+ if (offset_in_cluster ||
25
-$ path/to/qemu-io --image-opts -n driver=host_device,filename=/dev/nullb0
53
+ n_bytes > (extent->cluster_sectors * SECTOR_SIZE) ||
26
--c "zrp offset nr_zones"
54
+ (n_bytes < (extent->cluster_sectors * SECTOR_SIZE) &&
27
+For example, to test zone_report on a null_blk device using qemu-io is::
55
+ offset + n_bytes != extent->end_sector * SECTOR_SIZE))
56
+ {
57
+ ret = -EINVAL;
58
+ goto out;
59
+ }
60
+
28
+
61
if (!extent->has_marker) {
29
+ $ path/to/qemu-io --image-opts -n driver=host_device,filename=/dev/nullb0 -c "zrp offset nr_zones"
62
ret = -EINVAL;
30
+
63
goto out;
31
+To expose the host's zoned block device through virtio-blk, the command line
32
+can be (includes the -device parameter)::
33
+
34
+ -blockdev node-name=drive0,driver=host_device,filename=/dev/nullb0,cache.direct=on \
35
+ -device virtio-blk-pci,drive=drive0
36
+
37
+Or only use the -drive parameter::
38
+
39
+ -driver driver=host_device,file=/dev/nullb0,if=virtio,cache.direct=on
40
+
41
+Additionally, QEMU has several ways of supporting zoned storage, including:
42
+(1) Using virtio-scsi: --device scsi-block allows for the passing through of
43
+SCSI ZBC devices, enabling the attachment of ZBC or ZAC HDDs to QEMU.
44
+(2) PCI device pass-through: While NVMe ZNS emulation is available for testing
45
+purposes, it cannot yet pass through a zoned device from the host. To pass on
46
+the NVMe ZNS device to the guest, use VFIO PCI pass the entire NVMe PCI adapter
47
+through to the guest. Likewise, an HDD HBA can be passed on to QEMU all HDDs
48
+attached to the HBA.
64
--
49
--
65
2.21.0
50
2.39.2
66
67
diff view generated by jsdifflib
1
fe646693acc changed qemu-img create's output so that it no longer prints
1
From: Carlos Santos <casantos@redhat.com>
2
single quotes around parameter values. The subformat and adapter_type
3
filters in _filter_img_create() have never been adapted to that change.
4
2
5
Fixes: fe646693acc13ac48b98435d14149ab04dc597bc
3
It is not useful when configuring with --enable-trace-backends=nop.
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
7
Reviewed-by: John Snow <jsnow@redhat.com>
5
Signed-off-by: Carlos Santos <casantos@redhat.com>
8
Message-id: 20190815153638.4600-2-mreitz@redhat.com
6
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Reviewed-by: John Snow <jsnow@redhat.com>
7
Message-Id: <20230408010410.281263-1-casantos@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
8
---
12
tests/qemu-iotests/059.out | 16 ++++++++--------
9
trace/meson.build | 2 +-
13
tests/qemu-iotests/common.filter | 4 ++--
10
1 file changed, 1 insertion(+), 1 deletion(-)
14
2 files changed, 10 insertions(+), 10 deletions(-)
15
11
16
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
12
diff --git a/trace/meson.build b/trace/meson.build
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/qemu-iotests/059.out
14
--- a/trace/meson.build
19
+++ b/tests/qemu-iotests/059.out
15
+++ b/trace/meson.build
20
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
16
@@ -XXX,XX +XXX,XX @@ trace_events_all = custom_target('trace-events-all',
21
qemu-io: can't open device TEST_DIR/t.vmdk: L1 size too big
17
input: trace_events_files,
22
18
command: [ 'cat', '@INPUT@' ],
23
=== Testing monolithicFlat creation and opening ===
19
capture: true,
24
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicFlat
20
- install: true,
25
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648
21
+ install: get_option('trace_backends') != [ 'nop' ],
26
image: TEST_DIR/t.IMGFMT
22
install_dir: qemu_datadir)
27
file format: IMGFMT
23
28
virtual size: 2 GiB (2147483648 bytes)
24
if 'ust' in get_option('trace_backends')
29
30
=== Testing monolithicFlat with zeroed_grain ===
31
qemu-img: TEST_DIR/t.IMGFMT: Flat image can't enable zeroed grain
32
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicFlat
33
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648
34
35
=== Testing big twoGbMaxExtentFlat ===
36
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000 subformat=twoGbMaxExtentFlat
37
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000
38
image: TEST_DIR/t.vmdk
39
file format: vmdk
40
virtual size: 0.977 TiB (1073741824000 bytes)
41
@@ -XXX,XX +XXX,XX @@ Format specific information:
42
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Invalid extent line: RW 12582912 VMFS "dummy.IMGFMT" 1
43
44
=== Testing truncated sparse ===
45
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=107374182400 subformat=monolithicSparse
46
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=107374182400
47
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': File truncated, expecting at least 13172736 bytes
48
49
=== Converting to streamOptimized from image with small cluster size===
50
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 10240
51
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
52
53
=== Testing monolithicFlat with internally generated JSON file name ===
54
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 subformat=monolithicFlat
55
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
56
qemu-io: can't open: Cannot use relative extent paths with VMDK descriptor file 'json:{"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "read_aio"}'
57
58
=== Testing version 3 ===
59
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 64931328
60
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
61
62
=== Testing 4TB monolithicFlat creation and IO ===
63
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4398046511104 subformat=monolithicFlat
64
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4398046511104
65
image: TEST_DIR/t.IMGFMT
66
file format: IMGFMT
67
virtual size: 4 TiB (4398046511104 bytes)
68
@@ -XXX,XX +XXX,XX @@ read 1024/1024 bytes at offset 966367641600
69
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
70
71
=== Testing qemu-img map on extents ===
72
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544 subformat=monolithicSparse
73
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544
74
wrote 1024/1024 bytes at offset 65024
75
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
76
wrote 1024/1024 bytes at offset 2147483136
77
@@ -XXX,XX +XXX,XX @@ Offset Length Mapped to File
78
0 0x20000 0x3f0000 TEST_DIR/t.vmdk
79
0x7fff0000 0x20000 0x410000 TEST_DIR/t.vmdk
80
0x140000000 0x10000 0x430000 TEST_DIR/t.vmdk
81
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544 subformat=twoGbMaxExtentSparse
82
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544
83
wrote 1024/1024 bytes at offset 65024
84
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
85
wrote 1024/1024 bytes at offset 2147483136
86
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
87
index XXXXXXX..XXXXXXX 100644
88
--- a/tests/qemu-iotests/common.filter
89
+++ b/tests/qemu-iotests/common.filter
90
@@ -XXX,XX +XXX,XX @@ _filter_img_create()
91
-e "s# compat6=\\(on\\|off\\)##g" \
92
-e "s# static=\\(on\\|off\\)##g" \
93
-e "s# zeroed_grain=\\(on\\|off\\)##g" \
94
- -e "s# subformat='[^']*'##g" \
95
- -e "s# adapter_type='[^']*'##g" \
96
+ -e "s# subformat=[^ ]*##g" \
97
+ -e "s# adapter_type=[^ ]*##g" \
98
-e "s# hwversion=[^ ]*##g" \
99
-e "s# lazy_refcounts=\\(on\\|off\\)##g" \
100
-e "s# block_size=[0-9]\\+##g" \
101
--
25
--
102
2.21.0
26
2.39.2
103
104
diff view generated by jsdifflib