Skip to content

Commit

Permalink
Merge tag 'pull-block-2021-11-16' of https://gitlab.com/hreitz/qemu i…
Browse files Browse the repository at this point in the history
…nto staging

Block patches for 6.2.0-rc1:
- Fixes to image streaming job and block layer reconfiguration to make
  iotest 030 pass again
- docs: Deprecate incorrectly typed device_add arguments
- file-posix: Fix alignment after reopen changing O_DIRECT

# gpg: Signature made Tue 16 Nov 2021 01:57:03 PM CET
# gpg:                using RSA key CB62D7A0EE3829E45F004D34A1FA40D098019CDF
# gpg:                issuer "hreitz@redhat.com"
# gpg: Good signature from "Hanna Reitz <hreitz@redhat.com>" [marginal]
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: CB62 D7A0 EE38 29E4 5F00  4D34 A1FA 40D0 9801 9CDF

* tag 'pull-block-2021-11-16' of https://gitlab.com/hreitz/qemu:
  file-posix: Fix alignment after reopen changing O_DIRECT
  softmmu/qdev-monitor: fix use-after-free in qdev_set_id()
  docs: Deprecate incorrectly typed device_add arguments
  iotests/030: Unthrottle parallel jobs in reverse
  block: Let replace_child_noperm free children
  block: Let replace_child_tran keep indirect pointer
  transactions: Invoke clean() after everything else
  block: Restructure remove_file_or_backing_child()
  block: Pass BdrvChild ** to replace_child_noperm
  block: Drop detached child from ignore list
  block: Unite remove_empty_child and child_free
  block: Manipulate children list in .attach/.detach
  stream: Traverse graph after modification

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
rth7680 committed Nov 16, 2021
2 parents 9f0f846 + 5dbd0ce commit 871c71b
Show file tree
Hide file tree
Showing 9 changed files with 278 additions and 65 deletions.
233 changes: 177 additions & 56 deletions block.c

Large diffs are not rendered by default.

20 changes: 16 additions & 4 deletions block/file-posix.c
Expand Up @@ -167,6 +167,7 @@ typedef struct BDRVRawState {
int page_cache_inconsistent; /* errno from fdatasync failure */
bool has_fallocate;
bool needs_alignment;
bool force_alignment;
bool drop_cache;
bool check_cache_dropped;
struct {
Expand Down Expand Up @@ -351,6 +352,17 @@ static bool dio_byte_aligned(int fd)
return false;
}

static bool raw_needs_alignment(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;

if ((bs->open_flags & BDRV_O_NOCACHE) != 0 && !dio_byte_aligned(s->fd)) {
return true;
}

return s->force_alignment;
}

/* Check if read is allowed with given memory buffer and length.
*
* This function is used to check O_DIRECT memory buffer and request alignment.
Expand Down Expand Up @@ -728,9 +740,6 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,

s->has_discard = true;
s->has_write_zeroes = true;
if ((bs->open_flags & BDRV_O_NOCACHE) != 0 && !dio_byte_aligned(s->fd)) {
s->needs_alignment = true;
}

if (fstat(s->fd, &st) < 0) {
ret = -errno;
Expand Down Expand Up @@ -784,9 +793,10 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
* so QEMU makes sure all IO operations on the device are aligned
* to sector size, or else FreeBSD will reject them with EINVAL.
*/
s->needs_alignment = true;
s->force_alignment = true;
}
#endif
s->needs_alignment = raw_needs_alignment(bs);

#ifdef CONFIG_XFS
if (platform_test_xfs_fd(s->fd)) {
Expand Down Expand Up @@ -1251,7 +1261,9 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
BDRVRawState *s = bs->opaque;
struct stat st;

s->needs_alignment = raw_needs_alignment(bs);
raw_probe_alignment(bs, s->fd, errp);

bs->bl.min_mem_alignment = s->buf_align;
bs->bl.opt_mem_alignment = MAX(s->buf_align, qemu_real_host_page_size);

Expand Down
7 changes: 5 additions & 2 deletions block/stream.c
Expand Up @@ -54,15 +54,18 @@ static int stream_prepare(Job *job)
{
StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
BlockDriverState *unfiltered_bs = bdrv_skip_filters(s->target_bs);
BlockDriverState *base = bdrv_filter_or_cow_bs(s->above_base);
BlockDriverState *unfiltered_base = bdrv_skip_filters(base);
BlockDriverState *base;
BlockDriverState *unfiltered_base;
Error *local_err = NULL;
int ret = 0;

/* We should drop filter at this point, as filter hold the backing chain */
bdrv_cor_filter_drop(s->cor_filter_bs);
s->cor_filter_bs = NULL;

base = bdrv_filter_or_cow_bs(s->above_base);
unfiltered_base = bdrv_skip_filters(base);

if (bdrv_cow_child(unfiltered_bs)) {
const char *base_id = NULL, *base_fmt = NULL;
if (unfiltered_base) {
Expand Down
14 changes: 14 additions & 0 deletions docs/about/deprecated.rst
Expand Up @@ -250,6 +250,20 @@ options are removed in favor of using explicit ``blockdev-create`` and
``blockdev-add`` calls. See :doc:`/interop/live-block-operations` for
details.

Incorrectly typed ``device_add`` arguments (since 6.2)
''''''''''''''''''''''''''''''''''''''''''''''''''''''

Due to shortcomings in the internal implementation of ``device_add``, QEMU
incorrectly accepts certain invalid arguments: Any object or list arguments are
silently ignored. Other argument types are not checked, but an implicit
conversion happens, so that e.g. string values can be assigned to integer
device properties or vice versa.

This is a bug in QEMU that will be fixed in the future so that previously
accepted incorrect commands will return an error. Users should make sure that
all arguments passed to ``device_add`` are consistent with the documented
property types.

System accelerators
-------------------

Expand Down
3 changes: 3 additions & 0 deletions include/qemu/transactions.h
Expand Up @@ -31,6 +31,9 @@
* tran_create(), call your "prepare" functions on it, and finally call
* tran_abort() or tran_commit() to finalize the transaction by corresponding
* finalization actions in reverse order.
*
* The clean() functions registered by the drivers in a transaction are called
* last, after all abort() or commit() functions have been called.
*/

#ifndef QEMU_TRANSACTIONS_H
Expand Down
11 changes: 10 additions & 1 deletion tests/qemu-iotests/030
Expand Up @@ -251,7 +251,16 @@ class TestParallelOps(iotests.QMPTestCase):
speed=1024)
self.assert_qmp(result, 'return', {})

for job in pending_jobs:
# Do this in reverse: After unthrottling them, some jobs may finish
# before we have unthrottled all of them. This will drain their
# subgraph, and this will make jobs above them advance (despite those
# jobs on top being throttled). In the worst case, all jobs below the
# top one are finished before we can unthrottle it, and this makes it
# advance so far that it completes before we can unthrottle it - which
# results in an error.
# Starting from the top (i.e. in reverse) does not have this problem:
# When a job finishes, the ones below it are not advanced.
for job in reversed(pending_jobs):
result = self.vm.qmp('block-job-set-speed', device=job, speed=0)
self.assert_qmp(result, 'return', {})

Expand Down
29 changes: 29 additions & 0 deletions tests/qemu-iotests/142
Expand Up @@ -350,6 +350,35 @@ info block backing-file"

echo "$hmp_cmds" | run_qemu -drive "$files","$ids" | grep "Cache"

echo
echo "--- Alignment after changing O_DIRECT ---"
echo

# Directly test the protocol level: Can unaligned requests succeed even if
# O_DIRECT was only enabled through a reopen and vice versa?

# Ensure image size is a multiple of the sector size (required for O_DIRECT)
$QEMU_IMG create -f file "$TEST_IMG" 1M | _filter_img_create

# And write some data (not strictly necessary, but it feels better to actually
# have something to be read)
$QEMU_IO -f file -c 'write 0 4096' "$TEST_IMG" | _filter_qemu_io

$QEMU_IO --cache=writeback -f file $TEST_IMG <<EOF | _filter_qemu_io
read 42 42
reopen -o cache.direct=on
read 42 42
reopen -o cache.direct=off
read 42 42
EOF
$QEMU_IO --cache=none -f file $TEST_IMG <<EOF | _filter_qemu_io
read 42 42
reopen -o cache.direct=off
read 42 42
reopen -o cache.direct=on
read 42 42
EOF

# success, all done
echo "*** done"
rm -f $seq.full
Expand Down
18 changes: 18 additions & 0 deletions tests/qemu-iotests/142.out
Expand Up @@ -747,4 +747,22 @@ cache.no-flush=on on backing-file
Cache mode: writeback
Cache mode: writeback, direct
Cache mode: writeback, ignore flushes

--- Alignment after changing O_DIRECT ---

Formatting 'TEST_DIR/t.IMGFMT', fmt=file size=1048576
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 42/42 bytes at offset 42
42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 42/42 bytes at offset 42
42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 42/42 bytes at offset 42
42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 42/42 bytes at offset 42
42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 42/42 bytes at offset 42
42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 42/42 bytes at offset 42
42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
*** done
8 changes: 6 additions & 2 deletions util/transactions.c
Expand Up @@ -61,11 +61,13 @@ void tran_abort(Transaction *tran)
{
TransactionAction *act, *next;

QSLIST_FOREACH_SAFE(act, &tran->actions, entry, next) {
QSLIST_FOREACH(act, &tran->actions, entry) {
if (act->drv->abort) {
act->drv->abort(act->opaque);
}
}

QSLIST_FOREACH_SAFE(act, &tran->actions, entry, next) {
if (act->drv->clean) {
act->drv->clean(act->opaque);
}
Expand All @@ -80,11 +82,13 @@ void tran_commit(Transaction *tran)
{
TransactionAction *act, *next;

QSLIST_FOREACH_SAFE(act, &tran->actions, entry, next) {
QSLIST_FOREACH(act, &tran->actions, entry) {
if (act->drv->commit) {
act->drv->commit(act->opaque);
}
}

QSLIST_FOREACH_SAFE(act, &tran->actions, entry, next) {
if (act->drv->clean) {
act->drv->clean(act->opaque);
}
Expand Down

0 comments on commit 871c71b

Please sign in to comment.