1
The following changes since commit 36f87b4513373b3cd79c87c9197d17face95d4ac:
1
The following changes since commit 711c0418c8c1ce3a24346f058b001c4c5a2f0f81:
2
2
3
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.10-20170630' into staging (2017-06-30 11:58:49 +0100)
3
Merge remote-tracking branch 'remotes/philmd/tags/mips-20210702' into staging (2021-07-04 14:04:12 +0100)
4
4
5
are available in the git repository at:
5
are available in the Git repository at:
6
6
7
git://github.com/famz/qemu.git tags/block-pull-request
7
https://gitlab.com/stefanha/qemu.git tags/block-pull-request
8
8
9
for you to fetch changes up to c61e684e44272f2acb2bef34cf2aa234582a73a9:
9
for you to fetch changes up to 9f460c64e13897117f35ffb61f6f5e0102cabc70:
10
10
11
block: Exploit BDRV_BLOCK_EOF for larger zero blocks (2017-06-30 21:48:06 +0800)
11
block/io: Merge discard request alignments (2021-07-06 14:28:55 +0100)
12
13
----------------------------------------------------------------
14
Pull request
12
15
13
----------------------------------------------------------------
16
----------------------------------------------------------------
14
17
15
Hi Peter,
18
Akihiko Odaki (3):
19
block/file-posix: Optimize for macOS
20
block: Add backend_defaults property
21
block/io: Merge discard request alignments
16
22
17
Here are Eric Blake's enhancement to block layer API. Thanks!
23
Stefan Hajnoczi (2):
24
util/async: add a human-readable name to BHs for debugging
25
util/async: print leaked BH name when AioContext finalizes
18
26
19
----------------------------------------------------------------
27
include/block/aio.h | 31 ++++++++++++++++++++++---
20
28
include/hw/block/block.h | 3 +++
21
Eric Blake (2):
29
include/qemu/main-loop.h | 4 +++-
22
block: Add BDRV_BLOCK_EOF to bdrv_get_block_status()
30
block/file-posix.c | 27 ++++++++++++++++++++--
23
block: Exploit BDRV_BLOCK_EOF for larger zero blocks
31
block/io.c | 2 ++
24
32
hw/block/block.c | 42 ++++++++++++++++++++++++++++++----
25
block/io.c | 42 +++++++++++++++++++++++++++++++++---------
33
tests/unit/ptimer-test-stubs.c | 2 +-
26
include/block/block.h | 2 ++
34
util/async.c | 25 ++++++++++++++++----
27
tests/qemu-iotests/154 | 4 ----
35
util/main-loop.c | 4 ++--
28
tests/qemu-iotests/154.out | 12 ++++++------
36
tests/qemu-iotests/172.out | 38 ++++++++++++++++++++++++++++++
29
4 files changed, 41 insertions(+), 19 deletions(-)
37
10 files changed, 161 insertions(+), 17 deletions(-)
30
38
31
--
39
--
32
2.9.4
40
2.31.1
33
41
34
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
It can be difficult to debug issues with BHs in production environments.
2
Although BHs can usually be identified by looking up their ->cb()
3
function pointer, this requires debug information for the program. It is
4
also not possible to print human-readable diagnostics about BHs because
5
they have no identifier.
2
6
3
Just as the block layer already sets BDRV_BLOCK_ALLOCATED as a
7
This patch adds a name to each BH. The name is not unique per instance
4
shortcut for subsequent operations, there are also some optimizations
8
but differentiates between cb() functions, which is usually enough. It's
5
that are made easier if we can quickly tell that *pnum will advance
9
done by changing aio_bh_new() and friends to macros that stringify cb.
6
us to the end of a file, via a new BDRV_BLOCK_EOF which gets set
7
by the block layer.
8
10
9
This just plumbs up the new bit; subsequent patches will make use
11
The next patch will use the name field when reporting leaked BHs.
10
of it.
11
12
12
Signed-off-by: Eric Blake <eblake@redhat.com>
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Message-Id: <20170505021500.19315-2-eblake@redhat.com>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Message-Id: <20210414200247.917496-2-stefanha@redhat.com>
15
Signed-off-by: Fam Zheng <famz@redhat.com>
16
---
16
---
17
block/io.c | 15 +++++++++++----
17
include/block/aio.h | 31 ++++++++++++++++++++++++++++---
18
include/block/block.h | 2 ++
18
include/qemu/main-loop.h | 4 +++-
19
2 files changed, 13 insertions(+), 4 deletions(-)
19
tests/unit/ptimer-test-stubs.c | 2 +-
20
util/async.c | 9 +++++++--
21
util/main-loop.c | 4 ++--
22
5 files changed, 41 insertions(+), 9 deletions(-)
20
23
21
diff --git a/block/io.c b/block/io.c
24
diff --git a/include/block/aio.h b/include/block/aio.h
22
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
23
--- a/block/io.c
26
--- a/include/block/aio.h
24
+++ b/block/io.c
27
+++ b/include/block/aio.h
25
@@ -XXX,XX +XXX,XX @@ typedef struct BdrvCoGetBlockStatusData {
28
@@ -XXX,XX +XXX,XX @@ void aio_context_acquire(AioContext *ctx);
26
* Drivers not implementing the functionality are assumed to not support
29
/* Relinquish ownership of the AioContext. */
27
* backing files, hence all their sectors are reported as allocated.
30
void aio_context_release(AioContext *ctx);
31
32
+/**
33
+ * aio_bh_schedule_oneshot_full: Allocate a new bottom half structure that will
34
+ * run only once and as soon as possible.
35
+ *
36
+ * @name: A human-readable identifier for debugging purposes.
37
+ */
38
+void aio_bh_schedule_oneshot_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque,
39
+ const char *name);
40
+
41
/**
42
* aio_bh_schedule_oneshot: Allocate a new bottom half structure that will run
43
* only once and as soon as possible.
44
+ *
45
+ * A convenience wrapper for aio_bh_schedule_oneshot_full() that uses cb as the
46
+ * name string.
47
*/
48
-void aio_bh_schedule_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque);
49
+#define aio_bh_schedule_oneshot(ctx, cb, opaque) \
50
+ aio_bh_schedule_oneshot_full((ctx), (cb), (opaque), (stringify(cb)))
51
52
/**
53
- * aio_bh_new: Allocate a new bottom half structure.
54
+ * aio_bh_new_full: Allocate a new bottom half structure.
28
*
55
*
29
- * If 'sector_num' is beyond the end of the disk image the return value is 0
56
* Bottom halves are lightweight callbacks whose invocation is guaranteed
30
- * and 'pnum' is set to 0.
57
* to be wait-free, thread-safe and signal-safe. The #QEMUBH structure
31
+ * If 'sector_num' is beyond the end of the disk image the return value is
58
* is opaque and must be allocated prior to its use.
32
+ * BDRV_BLOCK_EOF and 'pnum' is set to 0.
59
+ *
33
*
60
+ * @name: A human-readable identifier for debugging purposes.
34
* 'pnum' is set to the number of sectors (including and immediately following
61
*/
35
* the specified sector) that are known to be in the same
62
-QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque);
36
* allocated/unallocated state.
63
+QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque,
37
*
64
+ const char *name);
38
* 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes
65
+
39
- * beyond the end of the disk image it will be clamped.
66
+/**
40
+ * beyond the end of the disk image it will be clamped; if 'pnum' is set to
67
+ * aio_bh_new: Allocate a new bottom half structure
41
+ * the end of the image, then the returned value will include BDRV_BLOCK_EOF.
68
+ *
42
*
69
+ * A convenience wrapper for aio_bh_new_full() that uses the cb as the name
43
* If returned value is positive and BDRV_BLOCK_OFFSET_VALID bit is set, 'file'
70
+ * string.
44
* points to the BDS which the sector range is allocated in.
71
+ */
45
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
72
+#define aio_bh_new(ctx, cb, opaque) \
46
73
+ aio_bh_new_full((ctx), (cb), (opaque), (stringify(cb)))
47
if (sector_num >= total_sectors) {
74
48
*pnum = 0;
75
/**
49
- return 0;
76
* aio_notify: Force processing of pending events.
50
+ return BDRV_BLOCK_EOF;
77
diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
51
}
78
index XXXXXXX..XXXXXXX 100644
52
79
--- a/include/qemu/main-loop.h
53
n = total_sectors - sector_num;
80
+++ b/include/qemu/main-loop.h
54
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
81
@@ -XXX,XX +XXX,XX @@ void qemu_cond_timedwait_iothread(QemuCond *cond, int ms);
55
if (!bs->drv->bdrv_co_get_block_status) {
82
56
*pnum = nb_sectors;
83
void qemu_fd_register(int fd);
57
ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED;
84
58
+ if (sector_num + nb_sectors == total_sectors) {
85
-QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque);
59
+ ret |= BDRV_BLOCK_EOF;
86
+#define qemu_bh_new(cb, opaque) \
60
+ }
87
+ qemu_bh_new_full((cb), (opaque), (stringify(cb)))
61
if (bs->drv->protocol_name) {
88
+QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name);
62
ret |= BDRV_BLOCK_OFFSET_VALID | (sector_num * BDRV_SECTOR_SIZE);
89
void qemu_bh_schedule_idle(QEMUBH *bh);
63
}
90
64
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
91
enum {
65
92
diff --git a/tests/unit/ptimer-test-stubs.c b/tests/unit/ptimer-test-stubs.c
66
out:
93
index XXXXXXX..XXXXXXX 100644
67
bdrv_dec_in_flight(bs);
94
--- a/tests/unit/ptimer-test-stubs.c
68
+ if (ret >= 0 && sector_num + *pnum == total_sectors) {
95
+++ b/tests/unit/ptimer-test-stubs.c
69
+ ret |= BDRV_BLOCK_EOF;
96
@@ -XXX,XX +XXX,XX @@ int64_t qemu_clock_deadline_ns_all(QEMUClockType type, int attr_mask)
70
+ }
97
return deadline;
71
return ret;
72
}
98
}
73
99
74
diff --git a/include/block/block.h b/include/block/block.h
100
-QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
101
+QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name)
102
{
103
QEMUBH *bh = g_new(QEMUBH, 1);
104
105
diff --git a/util/async.c b/util/async.c
75
index XXXXXXX..XXXXXXX 100644
106
index XXXXXXX..XXXXXXX 100644
76
--- a/include/block/block.h
107
--- a/util/async.c
77
+++ b/include/block/block.h
108
+++ b/util/async.c
78
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
109
@@ -XXX,XX +XXX,XX @@ enum {
79
* BDRV_BLOCK_OFFSET_VALID: an associated offset exists for accessing raw data
110
80
* BDRV_BLOCK_ALLOCATED: the content of the block is determined by this
111
struct QEMUBH {
81
* layer (short for DATA || ZERO), set by block layer
112
AioContext *ctx;
82
+ * BDRV_BLOCK_EOF: the returned pnum covers through end of file for this layer
113
+ const char *name;
83
*
114
QEMUBHFunc *cb;
84
* Internal flag:
115
void *opaque;
85
* BDRV_BLOCK_RAW: used internally to indicate that the request was
116
QSLIST_ENTRY(QEMUBH) next;
86
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
117
@@ -XXX,XX +XXX,XX @@ static QEMUBH *aio_bh_dequeue(BHList *head, unsigned *flags)
87
#define BDRV_BLOCK_OFFSET_VALID 0x04
118
return bh;
88
#define BDRV_BLOCK_RAW 0x08
119
}
89
#define BDRV_BLOCK_ALLOCATED 0x10
120
90
+#define BDRV_BLOCK_EOF 0x20
121
-void aio_bh_schedule_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque)
91
#define BDRV_BLOCK_OFFSET_MASK BDRV_SECTOR_MASK
122
+void aio_bh_schedule_oneshot_full(AioContext *ctx, QEMUBHFunc *cb,
92
123
+ void *opaque, const char *name)
93
typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
124
{
125
QEMUBH *bh;
126
bh = g_new(QEMUBH, 1);
127
@@ -XXX,XX +XXX,XX @@ void aio_bh_schedule_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque)
128
.ctx = ctx,
129
.cb = cb,
130
.opaque = opaque,
131
+ .name = name,
132
};
133
aio_bh_enqueue(bh, BH_SCHEDULED | BH_ONESHOT);
134
}
135
136
-QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque)
137
+QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque,
138
+ const char *name)
139
{
140
QEMUBH *bh;
141
bh = g_new(QEMUBH, 1);
142
@@ -XXX,XX +XXX,XX @@ QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque)
143
.ctx = ctx,
144
.cb = cb,
145
.opaque = opaque,
146
+ .name = name,
147
};
148
return bh;
149
}
150
diff --git a/util/main-loop.c b/util/main-loop.c
151
index XXXXXXX..XXXXXXX 100644
152
--- a/util/main-loop.c
153
+++ b/util/main-loop.c
154
@@ -XXX,XX +XXX,XX @@ void main_loop_wait(int nonblocking)
155
156
/* Functions to operate on the main QEMU AioContext. */
157
158
-QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
159
+QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name)
160
{
161
- return aio_bh_new(qemu_aio_context, cb, opaque);
162
+ return aio_bh_new_full(qemu_aio_context, cb, opaque, name);
163
}
164
165
/*
94
--
166
--
95
2.9.4
167
2.31.1
96
168
97
diff view generated by jsdifflib
New patch
1
BHs must be deleted before the AioContext is finalized. If not, it's a
2
bug and probably indicates that some part of the program still expects
3
the BH to run in the future. That can lead to memory leaks, inconsistent
4
state, or just hangs.
1
5
6
Unfortunately the assert(flags & BH_DELETED) call in aio_ctx_finalize()
7
is difficult to debug because the assertion failure contains no
8
information about the BH!
9
10
Use the QEMUBH name field added in the previous patch to show a useful
11
error when a leaked BH is detected.
12
13
Suggested-by: Eric Ernst <eric.g.ernst@gmail.com>
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Message-Id: <20210414200247.917496-3-stefanha@redhat.com>
16
---
17
util/async.c | 16 ++++++++++++++--
18
1 file changed, 14 insertions(+), 2 deletions(-)
19
20
diff --git a/util/async.c b/util/async.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/util/async.c
23
+++ b/util/async.c
24
@@ -XXX,XX +XXX,XX @@ aio_ctx_finalize(GSource *source)
25
assert(QSIMPLEQ_EMPTY(&ctx->bh_slice_list));
26
27
while ((bh = aio_bh_dequeue(&ctx->bh_list, &flags))) {
28
- /* qemu_bh_delete() must have been called on BHs in this AioContext */
29
- assert(flags & BH_DELETED);
30
+ /*
31
+ * qemu_bh_delete() must have been called on BHs in this AioContext. In
32
+ * many cases memory leaks, hangs, or inconsistent state occur when a
33
+ * BH is leaked because something still expects it to run.
34
+ *
35
+ * If you hit this, fix the lifecycle of the BH so that
36
+ * qemu_bh_delete() and any associated cleanup is called before the
37
+ * AioContext is finalized.
38
+ */
39
+ if (unlikely(!(flags & BH_DELETED))) {
40
+ fprintf(stderr, "%s: BH '%s' leaked, aborting...\n",
41
+ __func__, bh->name);
42
+ abort();
43
+ }
44
45
g_free(bh);
46
}
47
--
48
2.31.1
49
diff view generated by jsdifflib
New patch
1
From: Akihiko Odaki <akihiko.odaki@gmail.com>
1
2
3
This commit introduces "punch hole" operation and optimizes transfer
4
block size for macOS.
5
6
Thanks to Konstantin Nazarov for detailed analysis of a flaw in an
7
old version of this change:
8
https://gist.github.com/akihikodaki/87df4149e7ca87f18dc56807ec5a1bc5#gistcomment-3654667
9
10
Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com>
11
Message-id: 20210705130458.97642-1-akihiko.odaki@gmail.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
14
block/file-posix.c | 27 +++++++++++++++++++++++++--
15
1 file changed, 25 insertions(+), 2 deletions(-)
16
17
diff --git a/block/file-posix.c b/block/file-posix.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/file-posix.c
20
+++ b/block/file-posix.c
21
@@ -XXX,XX +XXX,XX @@
22
#if defined(HAVE_HOST_BLOCK_DEVICE)
23
#include <paths.h>
24
#include <sys/param.h>
25
+#include <sys/mount.h>
26
#include <IOKit/IOKitLib.h>
27
#include <IOKit/IOBSD.h>
28
#include <IOKit/storage/IOMediaBSDClient.h>
29
@@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
30
return;
31
}
32
33
+#if defined(__APPLE__) && (__MACH__)
34
+ struct statfs buf;
35
+
36
+ if (!fstatfs(s->fd, &buf)) {
37
+ bs->bl.opt_transfer = buf.f_iosize;
38
+ bs->bl.pdiscard_alignment = buf.f_bsize;
39
+ }
40
+#endif
41
+
42
if (bs->sg || S_ISBLK(st.st_mode)) {
43
int ret = hdev_get_max_hw_transfer(s->fd, &st);
44
45
@@ -XXX,XX +XXX,XX @@ out:
46
}
47
}
48
49
+#if defined(CONFIG_FALLOCATE) || defined(BLKZEROOUT) || defined(BLKDISCARD)
50
static int translate_err(int err)
51
{
52
if (err == -ENODEV || err == -ENOSYS || err == -EOPNOTSUPP ||
53
@@ -XXX,XX +XXX,XX @@ static int translate_err(int err)
54
}
55
return err;
56
}
57
+#endif
58
59
#ifdef CONFIG_FALLOCATE
60
static int do_fallocate(int fd, int mode, off_t offset, off_t len)
61
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_discard(void *opaque)
62
}
63
} while (errno == EINTR);
64
65
- ret = -errno;
66
+ ret = translate_err(-errno);
67
#endif
68
} else {
69
#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
70
ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
71
aiocb->aio_offset, aiocb->aio_nbytes);
72
+ ret = translate_err(-errno);
73
+#elif defined(__APPLE__) && (__MACH__)
74
+ fpunchhole_t fpunchhole;
75
+ fpunchhole.fp_flags = 0;
76
+ fpunchhole.reserved = 0;
77
+ fpunchhole.fp_offset = aiocb->aio_offset;
78
+ fpunchhole.fp_length = aiocb->aio_nbytes;
79
+ if (fcntl(s->fd, F_PUNCHHOLE, &fpunchhole) == -1) {
80
+ ret = errno == ENODEV ? -ENOTSUP : -errno;
81
+ } else {
82
+ ret = 0;
83
+ }
84
#endif
85
}
86
87
- ret = translate_err(ret);
88
if (ret == -ENOTSUP) {
89
s->has_discard = false;
90
}
91
--
92
2.31.1
93
diff view generated by jsdifflib
New patch
1
1
From: Akihiko Odaki <akihiko.odaki@gmail.com>
2
3
backend_defaults property allow users to control if default block
4
properties should be decided with backend information.
5
6
If it is off, any backend information will be discarded, which is
7
suitable if you plan to perform live migration to a different disk backend.
8
9
If it is on, a block device may utilize backend information more
10
aggressively.
11
12
By default, it is auto, which uses backend information for block
13
sizes and ignores the others, which is consistent with the older
14
versions.
15
16
Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com>
17
Message-id: 20210705130458.97642-2-akihiko.odaki@gmail.com
18
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
---
20
include/hw/block/block.h | 3 +++
21
hw/block/block.c | 42 ++++++++++++++++++++++++++++++++++----
22
tests/qemu-iotests/172.out | 38 ++++++++++++++++++++++++++++++++++
23
3 files changed, 79 insertions(+), 4 deletions(-)
24
25
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/block/block.h
28
+++ b/include/hw/block/block.h
29
@@ -XXX,XX +XXX,XX @@
30
31
typedef struct BlockConf {
32
BlockBackend *blk;
33
+ OnOffAuto backend_defaults;
34
uint32_t physical_block_size;
35
uint32_t logical_block_size;
36
uint32_t min_io_size;
37
@@ -XXX,XX +XXX,XX @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
38
}
39
40
#define DEFINE_BLOCK_PROPERTIES_BASE(_state, _conf) \
41
+ DEFINE_PROP_ON_OFF_AUTO("backend_defaults", _state, \
42
+ _conf.backend_defaults, ON_OFF_AUTO_AUTO), \
43
DEFINE_PROP_BLOCKSIZE("logical_block_size", _state, \
44
_conf.logical_block_size), \
45
DEFINE_PROP_BLOCKSIZE("physical_block_size", _state, \
46
diff --git a/hw/block/block.c b/hw/block/block.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/block/block.c
49
+++ b/hw/block/block.c
50
@@ -XXX,XX +XXX,XX @@ bool blkconf_blocksizes(BlockConf *conf, Error **errp)
51
{
52
BlockBackend *blk = conf->blk;
53
BlockSizes blocksizes;
54
- int backend_ret;
55
+ BlockDriverState *bs;
56
+ bool use_blocksizes;
57
+ bool use_bs;
58
+
59
+ switch (conf->backend_defaults) {
60
+ case ON_OFF_AUTO_AUTO:
61
+ use_blocksizes = !blk_probe_blocksizes(blk, &blocksizes);
62
+ use_bs = false;
63
+ break;
64
+
65
+ case ON_OFF_AUTO_ON:
66
+ use_blocksizes = !blk_probe_blocksizes(blk, &blocksizes);
67
+ bs = blk_bs(blk);
68
+ use_bs = bs;
69
+ break;
70
+
71
+ case ON_OFF_AUTO_OFF:
72
+ use_blocksizes = false;
73
+ use_bs = false;
74
+ break;
75
+
76
+ default:
77
+ abort();
78
+ }
79
80
- backend_ret = blk_probe_blocksizes(blk, &blocksizes);
81
/* fill in detected values if they are not defined via qemu command line */
82
if (!conf->physical_block_size) {
83
- if (!backend_ret) {
84
+ if (use_blocksizes) {
85
conf->physical_block_size = blocksizes.phys;
86
} else {
87
conf->physical_block_size = BDRV_SECTOR_SIZE;
88
}
89
}
90
if (!conf->logical_block_size) {
91
- if (!backend_ret) {
92
+ if (use_blocksizes) {
93
conf->logical_block_size = blocksizes.log;
94
} else {
95
conf->logical_block_size = BDRV_SECTOR_SIZE;
96
}
97
}
98
+ if (use_bs) {
99
+ if (!conf->opt_io_size) {
100
+ conf->opt_io_size = bs->bl.opt_transfer;
101
+ }
102
+ if (conf->discard_granularity == -1) {
103
+ if (bs->bl.pdiscard_alignment) {
104
+ conf->discard_granularity = bs->bl.pdiscard_alignment;
105
+ } else if (bs->bl.request_alignment != 1) {
106
+ conf->discard_granularity = bs->bl.request_alignment;
107
+ }
108
+ }
109
+ }
110
111
if (conf->logical_block_size > conf->physical_block_size) {
112
error_setg(errp,
113
diff --git a/tests/qemu-iotests/172.out b/tests/qemu-iotests/172.out
114
index XXXXXXX..XXXXXXX 100644
115
--- a/tests/qemu-iotests/172.out
116
+++ b/tests/qemu-iotests/172.out
117
@@ -XXX,XX +XXX,XX @@ Testing:
118
dev: floppy, id ""
119
unit = 0 (0x0)
120
drive = "floppy0"
121
+ backend_defaults = "auto"
122
logical_block_size = 512 (512 B)
123
physical_block_size = 512 (512 B)
124
min_io_size = 0 (0 B)
125
@@ -XXX,XX +XXX,XX @@ Testing: -fda TEST_DIR/t.qcow2
126
dev: floppy, id ""
127
unit = 0 (0x0)
128
drive = "floppy0"
129
+ backend_defaults = "auto"
130
logical_block_size = 512 (512 B)
131
physical_block_size = 512 (512 B)
132
min_io_size = 0 (0 B)
133
@@ -XXX,XX +XXX,XX @@ Testing: -fdb TEST_DIR/t.qcow2
134
dev: floppy, id ""
135
unit = 1 (0x1)
136
drive = "floppy1"
137
+ backend_defaults = "auto"
138
logical_block_size = 512 (512 B)
139
physical_block_size = 512 (512 B)
140
min_io_size = 0 (0 B)
141
@@ -XXX,XX +XXX,XX @@ Testing: -fdb TEST_DIR/t.qcow2
142
dev: floppy, id ""
143
unit = 0 (0x0)
144
drive = "floppy0"
145
+ backend_defaults = "auto"
146
logical_block_size = 512 (512 B)
147
physical_block_size = 512 (512 B)
148
min_io_size = 0 (0 B)
149
@@ -XXX,XX +XXX,XX @@ Testing: -fda TEST_DIR/t.qcow2 -fdb TEST_DIR/t.qcow2.2
150
dev: floppy, id ""
151
unit = 1 (0x1)
152
drive = "floppy1"
153
+ backend_defaults = "auto"
154
logical_block_size = 512 (512 B)
155
physical_block_size = 512 (512 B)
156
min_io_size = 0 (0 B)
157
@@ -XXX,XX +XXX,XX @@ Testing: -fda TEST_DIR/t.qcow2 -fdb TEST_DIR/t.qcow2.2
158
dev: floppy, id ""
159
unit = 0 (0x0)
160
drive = "floppy0"
161
+ backend_defaults = "auto"
162
logical_block_size = 512 (512 B)
163
physical_block_size = 512 (512 B)
164
min_io_size = 0 (0 B)
165
@@ -XXX,XX +XXX,XX @@ Testing: -fdb
166
dev: floppy, id ""
167
unit = 1 (0x1)
168
drive = "floppy1"
169
+ backend_defaults = "auto"
170
logical_block_size = 512 (512 B)
171
physical_block_size = 512 (512 B)
172
min_io_size = 0 (0 B)
173
@@ -XXX,XX +XXX,XX @@ Testing: -fdb
174
dev: floppy, id ""
175
unit = 0 (0x0)
176
drive = "floppy0"
177
+ backend_defaults = "auto"
178
logical_block_size = 512 (512 B)
179
physical_block_size = 512 (512 B)
180
min_io_size = 0 (0 B)
181
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2
182
dev: floppy, id ""
183
unit = 0 (0x0)
184
drive = "floppy0"
185
+ backend_defaults = "auto"
186
logical_block_size = 512 (512 B)
187
physical_block_size = 512 (512 B)
188
min_io_size = 0 (0 B)
189
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2,index=1
190
dev: floppy, id ""
191
unit = 1 (0x1)
192
drive = "floppy1"
193
+ backend_defaults = "auto"
194
logical_block_size = 512 (512 B)
195
physical_block_size = 512 (512 B)
196
min_io_size = 0 (0 B)
197
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2,index=1
198
dev: floppy, id ""
199
unit = 0 (0x0)
200
drive = "floppy0"
201
+ backend_defaults = "auto"
202
logical_block_size = 512 (512 B)
203
physical_block_size = 512 (512 B)
204
min_io_size = 0 (0 B)
205
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=floppy,file=TEST_DIR/t
206
dev: floppy, id ""
207
unit = 1 (0x1)
208
drive = "floppy1"
209
+ backend_defaults = "auto"
210
logical_block_size = 512 (512 B)
211
physical_block_size = 512 (512 B)
212
min_io_size = 0 (0 B)
213
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=floppy,file=TEST_DIR/t
214
dev: floppy, id ""
215
unit = 0 (0x0)
216
drive = "floppy0"
217
+ backend_defaults = "auto"
218
logical_block_size = 512 (512 B)
219
physical_block_size = 512 (512 B)
220
min_io_size = 0 (0 B)
221
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0
222
dev: floppy, id ""
223
unit = 0 (0x0)
224
drive = "none0"
225
+ backend_defaults = "auto"
226
logical_block_size = 512 (512 B)
227
physical_block_size = 512 (512 B)
228
min_io_size = 0 (0 B)
229
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,unit=1
230
dev: floppy, id ""
231
unit = 1 (0x1)
232
drive = "none0"
233
+ backend_defaults = "auto"
234
logical_block_size = 512 (512 B)
235
physical_block_size = 512 (512 B)
236
min_io_size = 0 (0 B)
237
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qco
238
dev: floppy, id ""
239
unit = 1 (0x1)
240
drive = "none1"
241
+ backend_defaults = "auto"
242
logical_block_size = 512 (512 B)
243
physical_block_size = 512 (512 B)
244
min_io_size = 0 (0 B)
245
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qco
246
dev: floppy, id ""
247
unit = 0 (0x0)
248
drive = "none0"
249
+ backend_defaults = "auto"
250
logical_block_size = 512 (512 B)
251
physical_block_size = 512 (512 B)
252
min_io_size = 0 (0 B)
253
@@ -XXX,XX +XXX,XX @@ Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
254
dev: floppy, id ""
255
unit = 1 (0x1)
256
drive = "none0"
257
+ backend_defaults = "auto"
258
logical_block_size = 512 (512 B)
259
physical_block_size = 512 (512 B)
260
min_io_size = 0 (0 B)
261
@@ -XXX,XX +XXX,XX @@ Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
262
dev: floppy, id ""
263
unit = 0 (0x0)
264
drive = "floppy0"
265
+ backend_defaults = "auto"
266
logical_block_size = 512 (512 B)
267
physical_block_size = 512 (512 B)
268
min_io_size = 0 (0 B)
269
@@ -XXX,XX +XXX,XX @@ Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
270
dev: floppy, id ""
271
unit = 1 (0x1)
272
drive = "none0"
273
+ backend_defaults = "auto"
274
logical_block_size = 512 (512 B)
275
physical_block_size = 512 (512 B)
276
min_io_size = 0 (0 B)
277
@@ -XXX,XX +XXX,XX @@ Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
278
dev: floppy, id ""
279
unit = 0 (0x0)
280
drive = "floppy0"
281
+ backend_defaults = "auto"
282
logical_block_size = 512 (512 B)
283
physical_block_size = 512 (512 B)
284
min_io_size = 0 (0 B)
285
@@ -XXX,XX +XXX,XX @@ Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
286
dev: floppy, id ""
287
unit = 0 (0x0)
288
drive = "none0"
289
+ backend_defaults = "auto"
290
logical_block_size = 512 (512 B)
291
physical_block_size = 512 (512 B)
292
min_io_size = 0 (0 B)
293
@@ -XXX,XX +XXX,XX @@ Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
294
dev: floppy, id ""
295
unit = 1 (0x1)
296
drive = "floppy1"
297
+ backend_defaults = "auto"
298
logical_block_size = 512 (512 B)
299
physical_block_size = 512 (512 B)
300
min_io_size = 0 (0 B)
301
@@ -XXX,XX +XXX,XX @@ Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
302
dev: floppy, id ""
303
unit = 0 (0x0)
304
drive = "none0"
305
+ backend_defaults = "auto"
306
logical_block_size = 512 (512 B)
307
physical_block_size = 512 (512 B)
308
min_io_size = 0 (0 B)
309
@@ -XXX,XX +XXX,XX @@ Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
310
dev: floppy, id ""
311
unit = 1 (0x1)
312
drive = "floppy1"
313
+ backend_defaults = "auto"
314
logical_block_size = 512 (512 B)
315
physical_block_size = 512 (512 B)
316
min_io_size = 0 (0 B)
317
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.q
318
dev: floppy, id ""
319
unit = 1 (0x1)
320
drive = "none0"
321
+ backend_defaults = "auto"
322
logical_block_size = 512 (512 B)
323
physical_block_size = 512 (512 B)
324
min_io_size = 0 (0 B)
325
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.q
326
dev: floppy, id ""
327
unit = 0 (0x0)
328
drive = "floppy0"
329
+ backend_defaults = "auto"
330
logical_block_size = 512 (512 B)
331
physical_block_size = 512 (512 B)
332
min_io_size = 0 (0 B)
333
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.q
334
dev: floppy, id ""
335
unit = 1 (0x1)
336
drive = "none0"
337
+ backend_defaults = "auto"
338
logical_block_size = 512 (512 B)
339
physical_block_size = 512 (512 B)
340
min_io_size = 0 (0 B)
341
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.q
342
dev: floppy, id ""
343
unit = 0 (0x0)
344
drive = "floppy0"
345
+ backend_defaults = "auto"
346
logical_block_size = 512 (512 B)
347
physical_block_size = 512 (512 B)
348
min_io_size = 0 (0 B)
349
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -global floppy.drive=none0 -device
350
dev: floppy, id ""
351
unit = 0 (0x0)
352
drive = "none0"
353
+ backend_defaults = "auto"
354
logical_block_size = 512 (512 B)
355
physical_block_size = 512 (512 B)
356
min_io_size = 0 (0 B)
357
@@ -XXX,XX +XXX,XX @@ Testing: -device floppy
358
dev: floppy, id ""
359
unit = 0 (0x0)
360
drive = ""
361
+ backend_defaults = "auto"
362
logical_block_size = 512 (512 B)
363
physical_block_size = 512 (512 B)
364
min_io_size = 0 (0 B)
365
@@ -XXX,XX +XXX,XX @@ Testing: -device floppy,drive-type=120
366
dev: floppy, id ""
367
unit = 0 (0x0)
368
drive = ""
369
+ backend_defaults = "auto"
370
logical_block_size = 512 (512 B)
371
physical_block_size = 512 (512 B)
372
min_io_size = 0 (0 B)
373
@@ -XXX,XX +XXX,XX @@ Testing: -device floppy,drive-type=144
374
dev: floppy, id ""
375
unit = 0 (0x0)
376
drive = ""
377
+ backend_defaults = "auto"
378
logical_block_size = 512 (512 B)
379
physical_block_size = 512 (512 B)
380
min_io_size = 0 (0 B)
381
@@ -XXX,XX +XXX,XX @@ Testing: -device floppy,drive-type=288
382
dev: floppy, id ""
383
unit = 0 (0x0)
384
drive = ""
385
+ backend_defaults = "auto"
386
logical_block_size = 512 (512 B)
387
physical_block_size = 512 (512 B)
388
min_io_size = 0 (0 B)
389
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,drive-t
390
dev: floppy, id ""
391
unit = 0 (0x0)
392
drive = "none0"
393
+ backend_defaults = "auto"
394
logical_block_size = 512 (512 B)
395
physical_block_size = 512 (512 B)
396
min_io_size = 0 (0 B)
397
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,drive-t
398
dev: floppy, id ""
399
unit = 0 (0x0)
400
drive = "none0"
401
+ backend_defaults = "auto"
402
logical_block_size = 512 (512 B)
403
physical_block_size = 512 (512 B)
404
min_io_size = 0 (0 B)
405
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,logical
406
dev: floppy, id ""
407
unit = 0 (0x0)
408
drive = "none0"
409
+ backend_defaults = "auto"
410
logical_block_size = 512 (512 B)
411
physical_block_size = 512 (512 B)
412
min_io_size = 0 (0 B)
413
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,physica
414
dev: floppy, id ""
415
unit = 0 (0x0)
416
drive = "none0"
417
+ backend_defaults = "auto"
418
logical_block_size = 512 (512 B)
419
physical_block_size = 512 (512 B)
420
min_io_size = 0 (0 B)
421
--
422
2.31.1
423
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Akihiko Odaki <akihiko.odaki@gmail.com>
2
2
3
When we have a BDS with unallocated clusters, but asking the status
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com>
4
of its underlying bs->file or backing layer encounters an end-of-file
4
Message-id: 20210705130458.97642-3-akihiko.odaki@gmail.com
5
condition, we know that the rest of the unallocated area will read as
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
6
zeroes. However, pre-patch, this required two separate calls to
7
bdrv_get_block_status(), as the first call stops at the point where
8
the underlying file ends. Thanks to BDRV_BLOCK_EOF, we can now widen
9
the results of the primary status if the secondary status already
10
includes BDRV_BLOCK_ZERO.
11
12
In turn, this fixes a TODO mentioned in iotest 154, where we can now
13
see that all sectors in a partial cluster at the end of a file read
14
as zero when coupling the shorter backing file's status along with our
15
knowledge that the remaining sectors came from an unallocated cluster.
16
17
Also, note that the loop in bdrv_co_get_block_status_above() had an
18
inefficent exit: in cases where the active layer sets BDRV_BLOCK_ZERO
19
but does NOT set BDRV_BLOCK_ALLOCATED (namely, where we know we read
20
zeroes merely because our unallocated clusters lie beyond the backing
21
file's shorter length), we still ended up probing the backing layer
22
even though we already had a good answer.
23
24
Signed-off-by: Eric Blake <eblake@redhat.com>
25
Message-Id: <20170505021500.19315-3-eblake@redhat.com>
26
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
27
Signed-off-by: Fam Zheng <famz@redhat.com>
28
---
6
---
29
block/io.c | 27 ++++++++++++++++++++++-----
7
block/io.c | 2 ++
30
tests/qemu-iotests/154 | 4 ----
8
1 file changed, 2 insertions(+)
31
tests/qemu-iotests/154.out | 12 ++++++------
32
3 files changed, 28 insertions(+), 15 deletions(-)
33
9
34
diff --git a/block/io.c b/block/io.c
10
diff --git a/block/io.c b/block/io.c
35
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
36
--- a/block/io.c
12
--- a/block/io.c
37
+++ b/block/io.c
13
+++ b/block/io.c
38
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
14
@@ -XXX,XX +XXX,XX @@ void bdrv_parent_drained_begin_single(BdrvChild *c, bool poll)
39
/* Ignore errors. This is just providing extra information, it
15
40
* is useful but not necessary.
16
static void bdrv_merge_limits(BlockLimits *dst, const BlockLimits *src)
41
*/
42
- if (!file_pnum) {
43
- /* !file_pnum indicates an offset at or beyond the EOF; it is
44
- * perfectly valid for the format block driver to point to such
45
- * offsets, so catch it and mark everything as zero */
46
+ if (ret2 & BDRV_BLOCK_EOF &&
47
+ (!file_pnum || ret2 & BDRV_BLOCK_ZERO)) {
48
+ /*
49
+ * It is valid for the format block driver to read
50
+ * beyond the end of the underlying file's current
51
+ * size; such areas read as zero.
52
+ */
53
ret |= BDRV_BLOCK_ZERO;
54
} else {
55
/* Limit request to the range reported by the protocol driver */
56
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn bdrv_co_get_block_status_above(BlockDriverState *bs,
57
{
17
{
58
BlockDriverState *p;
18
+ dst->pdiscard_alignment = MAX(dst->pdiscard_alignment,
59
int64_t ret = 0;
19
+ src->pdiscard_alignment);
60
+ bool first = true;
20
dst->opt_transfer = MAX(dst->opt_transfer, src->opt_transfer);
61
21
dst->max_transfer = MIN_NON_ZERO(dst->max_transfer, src->max_transfer);
62
assert(bs != base);
22
dst->max_hw_transfer = MIN_NON_ZERO(dst->max_hw_transfer,
63
for (p = bs; p != base; p = backing_bs(p)) {
64
ret = bdrv_co_get_block_status(p, sector_num, nb_sectors, pnum, file);
65
- if (ret < 0 || ret & BDRV_BLOCK_ALLOCATED) {
66
+ if (ret < 0) {
67
+ break;
68
+ }
69
+ if (ret & BDRV_BLOCK_ZERO && ret & BDRV_BLOCK_EOF && !first) {
70
+ /*
71
+ * Reading beyond the end of the file continues to read
72
+ * zeroes, but we can only widen the result to the
73
+ * unallocated length we learned from an earlier
74
+ * iteration.
75
+ */
76
+ *pnum = nb_sectors;
77
+ }
78
+ if (ret & (BDRV_BLOCK_ZERO | BDRV_BLOCK_DATA)) {
79
break;
80
}
81
/* [sector_num, pnum] unallocated on this layer, which could be only
82
* the first part of [sector_num, nb_sectors]. */
83
nb_sectors = MIN(nb_sectors, *pnum);
84
+ first = false;
85
}
86
return ret;
87
}
88
diff --git a/tests/qemu-iotests/154 b/tests/qemu-iotests/154
89
index XXXXXXX..XXXXXXX 100755
90
--- a/tests/qemu-iotests/154
91
+++ b/tests/qemu-iotests/154
92
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "alloc $size 2048" "$TEST_IMG" | _filter_qemu_io
93
$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
94
95
# Repeat with backing file holding unallocated cluster.
96
-# TODO: Note that this forces an allocation, because we aren't yet able to
97
-# quickly detect that reads beyond EOF of the backing file are always zero
98
CLUSTER_SIZE=2048 TEST_IMG="$TEST_IMG.base" _make_test_img $((size + 1024))
99
100
# Write at the front: sector-wise, the request is:
101
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "alloc $size 2048" "$TEST_IMG" | _filter_qemu_io
102
$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
103
104
# Repeat with backing file holding zero'd cluster
105
-# TODO: Note that this forces an allocation, because we aren't yet able to
106
-# quickly detect that reads beyond EOF of the backing file are always zero
107
$QEMU_IO -c "write -z $size 512" "$TEST_IMG.base" | _filter_qemu_io
108
109
# Write at the front: sector-wise, the request is:
110
diff --git a/tests/qemu-iotests/154.out b/tests/qemu-iotests/154.out
111
index XXXXXXX..XXXXXXX 100644
112
--- a/tests/qemu-iotests/154.out
113
+++ b/tests/qemu-iotests/154.out
114
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 134217728
115
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
116
2048/2048 bytes allocated at offset 128 MiB
117
[{ "start": 0, "length": 134217728, "depth": 1, "zero": true, "data": false},
118
-{ "start": 134217728, "length": 2048, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
119
+{ "start": 134217728, "length": 2048, "depth": 0, "zero": true, "data": false}]
120
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134219776 backing_file=TEST_DIR/t.IMGFMT.base
121
wrote 512/512 bytes at offset 134219264
122
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
123
2048/2048 bytes allocated at offset 128 MiB
124
[{ "start": 0, "length": 134217728, "depth": 1, "zero": true, "data": false},
125
-{ "start": 134217728, "length": 2048, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
126
+{ "start": 134217728, "length": 2048, "depth": 0, "zero": true, "data": false}]
127
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134219776 backing_file=TEST_DIR/t.IMGFMT.base
128
wrote 1024/1024 bytes at offset 134218240
129
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
130
2048/2048 bytes allocated at offset 128 MiB
131
[{ "start": 0, "length": 134217728, "depth": 1, "zero": true, "data": false},
132
-{ "start": 134217728, "length": 2048, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
133
+{ "start": 134217728, "length": 2048, "depth": 0, "zero": true, "data": false}]
134
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134219776 backing_file=TEST_DIR/t.IMGFMT.base
135
wrote 2048/2048 bytes at offset 134217728
136
2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
137
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 134217728
138
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
139
2048/2048 bytes allocated at offset 128 MiB
140
[{ "start": 0, "length": 134217728, "depth": 1, "zero": true, "data": false},
141
-{ "start": 134217728, "length": 2048, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
142
+{ "start": 134217728, "length": 2048, "depth": 0, "zero": true, "data": false}]
143
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134219776 backing_file=TEST_DIR/t.IMGFMT.base
144
wrote 512/512 bytes at offset 134219264
145
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
146
2048/2048 bytes allocated at offset 128 MiB
147
[{ "start": 0, "length": 134217728, "depth": 1, "zero": true, "data": false},
148
-{ "start": 134217728, "length": 2048, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
149
+{ "start": 134217728, "length": 2048, "depth": 0, "zero": true, "data": false}]
150
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134219776 backing_file=TEST_DIR/t.IMGFMT.base
151
wrote 1024/1024 bytes at offset 134218240
152
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
153
2048/2048 bytes allocated at offset 128 MiB
154
[{ "start": 0, "length": 134217728, "depth": 1, "zero": true, "data": false},
155
-{ "start": 134217728, "length": 2048, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
156
+{ "start": 134217728, "length": 2048, "depth": 0, "zero": true, "data": false}]
157
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134219776 backing_file=TEST_DIR/t.IMGFMT.base
158
wrote 2048/2048 bytes at offset 134217728
159
2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
160
--
23
--
161
2.9.4
24
2.31.1
162
25
163
diff view generated by jsdifflib