2012-09-27 19:29:13 +02:00
|
|
|
/*
|
|
|
|
* Live block commit
|
|
|
|
*
|
|
|
|
* Copyright Red Hat, Inc. 2012
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Jeff Cody <jcody@redhat.com>
|
|
|
|
* Based on stream.c by Stefan Hajnoczi
|
|
|
|
*
|
|
|
|
* This work is licensed under the terms of the GNU LGPL, version 2 or later.
|
|
|
|
* See the COPYING.LIB file in the top-level directory.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2016-01-18 19:01:42 +01:00
|
|
|
#include "qemu/osdep.h"
|
2017-03-09 11:49:16 +01:00
|
|
|
#include "qemu/cutils.h"
|
2012-09-27 19:29:13 +02:00
|
|
|
#include "trace.h"
|
2012-12-17 18:19:44 +01:00
|
|
|
#include "block/block_int.h"
|
2016-10-27 18:07:00 +02:00
|
|
|
#include "block/blockjob_int.h"
|
include/qemu/osdep.h: Don't include qapi/error.h
Commit 57cb38b included qapi/error.h into qemu/osdep.h to get the
Error typedef. Since then, we've moved to include qemu/osdep.h
everywhere. Its file comment explains: "To avoid getting into
possible circular include dependencies, this file should not include
any other QEMU headers, with the exceptions of config-host.h,
compiler.h, os-posix.h and os-win32.h, all of which are doing a
similar job to this file and are under similar constraints."
qapi/error.h doesn't do a similar job, and it doesn't adhere to
similar constraints: it includes qapi-types.h. That's in excess of
100KiB of crap most .c files don't actually need.
Add the typedef to qemu/typedefs.h, and include that instead of
qapi/error.h. Include qapi/error.h in .c files that need it and don't
get it now. Include qapi-types.h in qom/object.h for uint16List.
Update scripts/clean-includes accordingly. Update it further to match
reality: replace config.h by config-target.h, add sysemu/os-posix.h,
sysemu/os-win32.h. Update the list of includes in the qemu/osdep.h
comment quoted above similarly.
This reduces the number of objects depending on qapi/error.h from "all
of them" to less than a third. Unfortunately, the number depending on
qapi-types.h shrinks only a little. More work is needed for that one.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
[Fix compilation without the spice devel packages. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2016-03-14 09:01:28 +01:00
|
|
|
#include "qapi/error.h"
|
2012-09-27 19:29:13 +02:00
|
|
|
#include "qemu/ratelimit.h"
|
2022-02-26 19:07:23 +01:00
|
|
|
#include "qemu/memalign.h"
|
2015-10-19 17:53:22 +02:00
|
|
|
#include "sysemu/block-backend.h"
|
2012-09-27 19:29:13 +02:00
|
|
|
|
|
|
|
enum {
|
|
|
|
/*
|
|
|
|
* Size of data buffer for populating the image file. This should be large
|
|
|
|
* enough to process multiple clusters in a single call, so that populating
|
|
|
|
* contiguous regions of the image is efficient.
|
|
|
|
*/
|
|
|
|
COMMIT_BUFFER_SIZE = 512 * 1024, /* in bytes */
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct CommitBlockJob {
|
|
|
|
BlockJob common;
|
2017-01-16 16:22:34 +01:00
|
|
|
BlockDriverState *commit_top_bs;
|
2016-04-14 13:09:53 +02:00
|
|
|
BlockBackend *top;
|
|
|
|
BlockBackend *base;
|
2018-09-06 15:02:13 +02:00
|
|
|
BlockDriverState *base_bs;
|
2019-06-12 17:47:37 +02:00
|
|
|
BlockDriverState *base_overlay;
|
2012-09-28 17:22:55 +02:00
|
|
|
BlockdevOnError on_error;
|
2018-11-12 15:00:35 +01:00
|
|
|
bool base_read_only;
|
2019-03-12 17:48:41 +01:00
|
|
|
bool chain_frozen;
|
block: extend block-commit to accept a string for the backing file
On some image chains, QEMU may not always be able to resolve the
filenames properly, when updating the backing file of an image
after a block commit.
For instance, certain relative pathnames may fail, or drives may
have been specified originally by file descriptor (e.g. /dev/fd/???),
or a relative protocol pathname may have been used.
In these instances, QEMU may lack the information to be able to make
the correct choice, but the user or management layer most likely does
have that knowledge.
With this extension to the block-commit api, the user is able to change
the backing file of the overlay image as part of the block-commit
operation.
This allows the change to be 'safe', in the sense that if the attempt
to write the overlay image metadata fails, then the block-commit
operation returns failure, without disrupting the guest.
If the commit top is the active layer, then specifying the backing
file string will be treated as an error (there is no overlay image
to modify in that case).
If a backing file string is not specified in the command, the backing
file string to use is determined in the same manner as it was
previously.
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-25 21:40:10 +02:00
|
|
|
char *backing_file_str;
|
2012-09-27 19:29:13 +02:00
|
|
|
} CommitBlockJob;
|
|
|
|
|
2018-09-06 15:02:13 +02:00
|
|
|
static int commit_prepare(Job *job)
|
2012-09-27 19:29:13 +02:00
|
|
|
{
|
2018-04-17 16:41:17 +02:00
|
|
|
CommitBlockJob *s = container_of(job, CommitBlockJob, common.job);
|
2017-06-02 23:04:55 +02:00
|
|
|
|
2019-03-12 17:48:41 +01:00
|
|
|
bdrv_unfreeze_backing_chain(s->commit_top_bs, s->base_bs);
|
|
|
|
s->chain_frozen = false;
|
|
|
|
|
2017-01-16 16:22:34 +01:00
|
|
|
/* Remove base node parent that still uses BLK_PERM_WRITE/RESIZE before
|
|
|
|
* the normal backing chain can be restored. */
|
|
|
|
blk_unref(s->base);
|
2018-09-06 15:02:13 +02:00
|
|
|
s->base = NULL;
|
|
|
|
|
|
|
|
/* FIXME: bdrv_drop_intermediate treats total failures and partial failures
|
|
|
|
* identically. Further work is needed to disambiguate these cases. */
|
|
|
|
return bdrv_drop_intermediate(s->commit_top_bs, s->base_bs,
|
|
|
|
s->backing_file_str);
|
|
|
|
}
|
2014-10-21 13:03:59 +02:00
|
|
|
|
2018-09-06 15:02:13 +02:00
|
|
|
static void commit_abort(Job *job)
|
|
|
|
{
|
|
|
|
CommitBlockJob *s = container_of(job, CommitBlockJob, common.job);
|
|
|
|
BlockDriverState *top_bs = blk_bs(s->top);
|
|
|
|
|
2019-03-12 17:48:41 +01:00
|
|
|
if (s->chain_frozen) {
|
|
|
|
bdrv_unfreeze_backing_chain(s->commit_top_bs, s->base_bs);
|
|
|
|
}
|
|
|
|
|
2018-09-06 15:02:13 +02:00
|
|
|
/* Make sure commit_top_bs and top stay around until bdrv_replace_node() */
|
|
|
|
bdrv_ref(top_bs);
|
|
|
|
bdrv_ref(s->commit_top_bs);
|
|
|
|
|
|
|
|
if (s->base) {
|
|
|
|
blk_unref(s->base);
|
2014-10-21 13:03:59 +02:00
|
|
|
}
|
|
|
|
|
2018-09-06 15:02:13 +02:00
|
|
|
/* free the blockers on the intermediate nodes so that bdrv_replace_nodes
|
|
|
|
* can succeed */
|
|
|
|
block_job_remove_all_bdrv(&s->common);
|
|
|
|
|
|
|
|
/* If bdrv_drop_intermediate() failed (or was not invoked), remove the
|
|
|
|
* commit filter driver from the backing chain now. Do this as the final
|
|
|
|
* step so that the 'consistent read' permission can be granted.
|
|
|
|
*
|
|
|
|
* XXX Can (or should) we somehow keep 'consistent read' blocked even
|
|
|
|
* after the failed/cancelled commit job is gone? If we already wrote
|
|
|
|
* something to base, the intermediate images aren't valid any more. */
|
2019-06-12 17:47:37 +02:00
|
|
|
bdrv_replace_node(s->commit_top_bs, s->commit_top_bs->backing->bs,
|
2018-09-06 15:02:13 +02:00
|
|
|
&error_abort);
|
|
|
|
|
|
|
|
bdrv_unref(s->commit_top_bs);
|
|
|
|
bdrv_unref(top_bs);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void commit_clean(Job *job)
|
|
|
|
{
|
|
|
|
CommitBlockJob *s = container_of(job, CommitBlockJob, common.job);
|
|
|
|
|
2014-10-21 13:03:59 +02:00
|
|
|
/* restore base open flags here if appropriate (e.g., change the base back
|
|
|
|
* to r/o). These reopens do not need to be atomic, since we won't abort
|
|
|
|
* even on failure here */
|
2018-11-12 15:00:35 +01:00
|
|
|
if (s->base_read_only) {
|
|
|
|
bdrv_reopen_set_read_only(s->base_bs, true, NULL);
|
2014-10-21 13:03:59 +02:00
|
|
|
}
|
2018-09-06 15:02:13 +02:00
|
|
|
|
2014-10-21 13:03:59 +02:00
|
|
|
g_free(s->backing_file_str);
|
2016-04-14 13:09:53 +02:00
|
|
|
blk_unref(s->top);
|
2014-10-21 13:03:59 +02:00
|
|
|
}
|
|
|
|
|
2018-08-30 03:57:26 +02:00
|
|
|
static int coroutine_fn commit_run(Job *job, Error **errp)
|
2014-10-21 13:03:59 +02:00
|
|
|
{
|
2018-08-30 03:57:26 +02:00
|
|
|
CommitBlockJob *s = container_of(job, CommitBlockJob, common.job);
|
2017-07-07 14:44:45 +02:00
|
|
|
int64_t offset;
|
2012-09-27 19:29:13 +02:00
|
|
|
int ret = 0;
|
block: Make bdrv_is_allocated_above() byte-based
We are gradually moving away from sector-based interfaces, towards
byte-based. In the common case, allocation is unlikely to ever use
values that are not naturally sector-aligned, but it is possible
that byte-based values will let us be more precise about allocation
at the end of an unaligned file that can do byte-based access.
Changing the signature of the function to use int64_t *pnum ensures
that the compiler enforces that all callers are updated. For now,
the io.c layer still assert()s that all callers are sector-aligned,
but that can be relaxed when a later patch implements byte-based
block status. Therefore, for the most part this patch is just the
addition of scaling at the callers followed by inverse scaling at
bdrv_is_allocated(). But some code, particularly stream_run(),
gets a lot simpler because it no longer has to mess with sectors.
Leave comments where we can further simplify by switching to
byte-based iterations, once later patches eliminate the need for
sector-aligned operations.
For ease of review, bdrv_is_allocated() was tackled separately.
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2017-07-07 14:44:59 +02:00
|
|
|
int64_t n = 0; /* bytes */
|
2021-06-28 14:11:33 +02:00
|
|
|
QEMU_AUTO_VFREE void *buf = NULL;
|
2018-01-18 18:08:22 +01:00
|
|
|
int64_t len, base_len;
|
2012-09-27 19:29:13 +02:00
|
|
|
|
2023-01-13 21:42:04 +01:00
|
|
|
len = blk_co_getlength(s->top);
|
2018-01-18 18:08:22 +01:00
|
|
|
if (len < 0) {
|
2021-06-28 14:11:33 +02:00
|
|
|
return len;
|
2012-09-27 19:29:13 +02:00
|
|
|
}
|
2018-05-04 12:17:20 +02:00
|
|
|
job_progress_set_remaining(&s->common.job, len);
|
2012-09-27 19:29:13 +02:00
|
|
|
|
2023-01-13 21:42:04 +01:00
|
|
|
base_len = blk_co_getlength(s->base);
|
2012-09-27 19:29:13 +02:00
|
|
|
if (base_len < 0) {
|
2021-06-28 14:11:33 +02:00
|
|
|
return base_len;
|
2012-09-27 19:29:13 +02:00
|
|
|
}
|
|
|
|
|
2018-01-18 18:08:22 +01:00
|
|
|
if (base_len < len) {
|
2022-10-13 14:37:01 +02:00
|
|
|
ret = blk_co_truncate(s->base, len, false, PREALLOC_MODE_OFF, 0, NULL);
|
2012-09-27 19:29:13 +02:00
|
|
|
if (ret) {
|
2021-06-28 14:11:33 +02:00
|
|
|
return ret;
|
2012-09-27 19:29:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-14 13:09:53 +02:00
|
|
|
buf = blk_blockalign(s->top, COMMIT_BUFFER_SIZE);
|
2012-09-27 19:29:13 +02:00
|
|
|
|
2018-01-18 18:08:22 +01:00
|
|
|
for (offset = 0; offset < len; offset += n) {
|
2012-09-27 19:29:13 +02:00
|
|
|
bool copy;
|
2020-02-14 21:08:10 +01:00
|
|
|
bool error_in_source = true;
|
2012-09-27 19:29:13 +02:00
|
|
|
|
|
|
|
/* Note that even when no rate limit is applied we need to yield
|
2012-11-13 16:35:13 +01:00
|
|
|
* with no pending I/O here so that bdrv_drain_all() returns.
|
2012-09-27 19:29:13 +02:00
|
|
|
*/
|
2023-05-10 22:36:00 +02:00
|
|
|
block_job_ratelimit_sleep(&s->common);
|
2018-04-17 12:56:07 +02:00
|
|
|
if (job_is_cancelled(&s->common.job)) {
|
2012-09-27 19:29:13 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* Copy if allocated above the base */
|
2022-11-28 15:23:27 +01:00
|
|
|
ret = blk_co_is_allocated_above(s->top, s->base_overlay, true,
|
|
|
|
offset, COMMIT_BUFFER_SIZE, &n);
|
2020-10-27 06:05:53 +01:00
|
|
|
copy = (ret > 0);
|
block: Make bdrv_is_allocated_above() byte-based
We are gradually moving away from sector-based interfaces, towards
byte-based. In the common case, allocation is unlikely to ever use
values that are not naturally sector-aligned, but it is possible
that byte-based values will let us be more precise about allocation
at the end of an unaligned file that can do byte-based access.
Changing the signature of the function to use int64_t *pnum ensures
that the compiler enforces that all callers are updated. For now,
the io.c layer still assert()s that all callers are sector-aligned,
but that can be relaxed when a later patch implements byte-based
block status. Therefore, for the most part this patch is just the
addition of scaling at the callers followed by inverse scaling at
bdrv_is_allocated(). But some code, particularly stream_run(),
gets a lot simpler because it no longer has to mess with sectors.
Leave comments where we can further simplify by switching to
byte-based iterations, once later patches eliminate the need for
sector-aligned operations.
For ease of review, bdrv_is_allocated() was tackled separately.
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2017-07-07 14:44:59 +02:00
|
|
|
trace_commit_one_iteration(s, offset, n, ret);
|
2012-09-27 19:29:13 +02:00
|
|
|
if (copy) {
|
2020-02-14 21:08:09 +01:00
|
|
|
assert(n < SIZE_MAX);
|
|
|
|
|
|
|
|
ret = blk_co_pread(s->top, offset, n, buf, 0);
|
|
|
|
if (ret >= 0) {
|
|
|
|
ret = blk_co_pwrite(s->base, offset, n, buf, 0);
|
2020-02-14 21:08:10 +01:00
|
|
|
if (ret < 0) {
|
|
|
|
error_in_source = false;
|
|
|
|
}
|
2020-02-14 21:08:09 +01:00
|
|
|
}
|
2012-09-27 19:29:13 +02:00
|
|
|
}
|
|
|
|
if (ret < 0) {
|
2016-06-29 17:38:57 +02:00
|
|
|
BlockErrorAction action =
|
2020-02-14 21:08:10 +01:00
|
|
|
block_job_error_action(&s->common, s->on_error,
|
|
|
|
error_in_source, -ret);
|
2016-06-29 17:38:57 +02:00
|
|
|
if (action == BLOCK_ERROR_ACTION_REPORT) {
|
2021-06-28 14:11:33 +02:00
|
|
|
return ret;
|
2012-09-27 19:29:13 +02:00
|
|
|
} else {
|
|
|
|
n = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Publish progress */
|
2018-05-04 12:17:20 +02:00
|
|
|
job_progress_update(&s->common.job, n);
|
Improve block job rate limiting for small bandwidth values
ratelimit_calculate_delay() previously reset the accounting every time
slice, no matter how much data had been processed before. This had (at
least) two consequences:
1. The minimum speed is rather large, e.g. 5 MiB/s for commit and stream.
Not sure if there are real-world use cases where this would be a
problem. Mirroring and backup over a slow link (e.g. DSL) would
come to mind, though.
2. Tests for block job operations (e.g. cancel) were rather racy
All block jobs currently use a time slice of 100ms. That's a
reasonable value to get smooth output during regular
operation. However this also meant that the state of block jobs
changed every 100ms, no matter how low the configured limit was. On
busy hosts, qemu often transferred additional chunks until the test
case had a chance to cancel the job.
Fix the block job rate limit code to delay for more than one time
slice to address the above issues. To make it easier to handle
oversized chunks we switch the semantics from returning a delay
_before_ the current request to a delay _after_ the current
request. If necessary, this delay consists of multiple time slice
units.
Since the mirror job sends multiple chunks in one go even if the rate
limit was exceeded in between, we need to keep track of the start of
the current time slice so we can correctly re-compute the delay for
the updated amount of data.
The minimum bandwidth now is 1 data unit per time slice. The block
jobs are currently passing the amount of data transferred in sectors
and using 100ms time slices, so this translates to 5120
bytes/second. With chunk sizes usually being O(512KiB), tests have
plenty of time (O(100s)) to operate on block jobs. The chance of a
race condition now is fairly remote, except possibly on insanely
loaded systems.
Signed-off-by: Sascha Silbe <silbe@linux.vnet.ibm.com>
Message-id: 1467127721-9564-2-git-send-email-silbe@linux.vnet.ibm.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
2016-06-28 17:28:41 +02:00
|
|
|
|
2018-01-18 21:19:38 +01:00
|
|
|
if (copy) {
|
2023-05-10 22:36:00 +02:00
|
|
|
block_job_ratelimit_processed_bytes(&s->common, n);
|
Improve block job rate limiting for small bandwidth values
ratelimit_calculate_delay() previously reset the accounting every time
slice, no matter how much data had been processed before. This had (at
least) two consequences:
1. The minimum speed is rather large, e.g. 5 MiB/s for commit and stream.
Not sure if there are real-world use cases where this would be a
problem. Mirroring and backup over a slow link (e.g. DSL) would
come to mind, though.
2. Tests for block job operations (e.g. cancel) were rather racy
All block jobs currently use a time slice of 100ms. That's a
reasonable value to get smooth output during regular
operation. However this also meant that the state of block jobs
changed every 100ms, no matter how low the configured limit was. On
busy hosts, qemu often transferred additional chunks until the test
case had a chance to cancel the job.
Fix the block job rate limit code to delay for more than one time
slice to address the above issues. To make it easier to handle
oversized chunks we switch the semantics from returning a delay
_before_ the current request to a delay _after_ the current
request. If necessary, this delay consists of multiple time slice
units.
Since the mirror job sends multiple chunks in one go even if the rate
limit was exceeded in between, we need to keep track of the start of
the current time slice so we can correctly re-compute the delay for
the updated amount of data.
The minimum bandwidth now is 1 data unit per time slice. The block
jobs are currently passing the amount of data transferred in sectors
and using 100ms time slices, so this translates to 5120
bytes/second. With chunk sizes usually being O(512KiB), tests have
plenty of time (O(100s)) to operate on block jobs. The chance of a
race condition now is fairly remote, except possibly on insanely
loaded systems.
Signed-off-by: Sascha Silbe <silbe@linux.vnet.ibm.com>
Message-id: 1467127721-9564-2-git-send-email-silbe@linux.vnet.ibm.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
2016-06-28 17:28:41 +02:00
|
|
|
}
|
2012-09-27 19:29:13 +02:00
|
|
|
}
|
|
|
|
|
2021-06-28 14:11:33 +02:00
|
|
|
return 0;
|
2012-09-27 19:29:13 +02:00
|
|
|
}
|
|
|
|
|
2013-10-08 11:29:38 +02:00
|
|
|
static const BlockJobDriver commit_job_driver = {
|
2018-04-12 17:29:59 +02:00
|
|
|
.job_driver = {
|
|
|
|
.instance_size = sizeof(CommitBlockJob),
|
2018-04-12 17:57:08 +02:00
|
|
|
.job_type = JOB_TYPE_COMMIT,
|
2018-04-13 18:50:05 +02:00
|
|
|
.free = block_job_free,
|
2018-04-18 17:10:26 +02:00
|
|
|
.user_resume = block_job_user_resume,
|
2018-08-30 03:57:26 +02:00
|
|
|
.run = commit_run,
|
2018-09-06 15:02:13 +02:00
|
|
|
.prepare = commit_prepare,
|
|
|
|
.abort = commit_abort,
|
|
|
|
.clean = commit_clean
|
2018-04-12 17:29:59 +02:00
|
|
|
},
|
2012-09-27 19:29:13 +02:00
|
|
|
};
|
|
|
|
|
2023-02-03 16:21:50 +01:00
|
|
|
static int coroutine_fn GRAPH_RDLOCK
|
|
|
|
bdrv_commit_top_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
|
|
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
2017-01-16 16:22:34 +01:00
|
|
|
{
|
|
|
|
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
|
|
|
|
}
|
|
|
|
|
2019-02-01 20:29:28 +01:00
|
|
|
static void bdrv_commit_top_refresh_filename(BlockDriverState *bs)
|
2017-03-09 11:49:16 +01:00
|
|
|
{
|
|
|
|
pstrcpy(bs->exact_filename, sizeof(bs->exact_filename),
|
|
|
|
bs->backing->bs->filename);
|
|
|
|
}
|
2017-03-08 15:07:12 +01:00
|
|
|
|
2017-01-16 16:22:34 +01:00
|
|
|
static void bdrv_commit_top_child_perm(BlockDriverState *bs, BdrvChild *c,
|
2020-05-13 13:05:16 +02:00
|
|
|
BdrvChildRole role,
|
2017-09-14 12:47:11 +02:00
|
|
|
BlockReopenQueue *reopen_queue,
|
2017-01-16 16:22:34 +01:00
|
|
|
uint64_t perm, uint64_t shared,
|
|
|
|
uint64_t *nperm, uint64_t *nshared)
|
|
|
|
{
|
|
|
|
*nperm = 0;
|
|
|
|
*nshared = BLK_PERM_ALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Dummy node that provides consistent read to its users without requiring it
|
|
|
|
* from its backing file and that allows writes on the backing file chain. */
|
|
|
|
static BlockDriver bdrv_commit_top = {
|
2017-03-08 15:07:12 +01:00
|
|
|
.format_name = "commit_top",
|
|
|
|
.bdrv_co_preadv = bdrv_commit_top_preadv,
|
2017-03-09 11:49:16 +01:00
|
|
|
.bdrv_refresh_filename = bdrv_commit_top_refresh_filename,
|
2017-03-08 15:07:12 +01:00
|
|
|
.bdrv_child_perm = bdrv_commit_top_child_perm,
|
2020-05-13 13:05:11 +02:00
|
|
|
|
|
|
|
.is_filter = true,
|
2022-07-26 22:11:20 +02:00
|
|
|
.filtered_child_is_backing = true,
|
2017-01-16 16:22:34 +01:00
|
|
|
};
|
|
|
|
|
2016-07-05 16:29:00 +02:00
|
|
|
void commit_start(const char *job_id, BlockDriverState *bs,
|
2018-09-06 15:02:10 +02:00
|
|
|
BlockDriverState *base, BlockDriverState *top,
|
|
|
|
int creation_flags, int64_t speed,
|
2016-10-27 18:06:58 +02:00
|
|
|
BlockdevOnError on_error, const char *backing_file_str,
|
2017-02-20 18:10:05 +01:00
|
|
|
const char *filter_node_name, Error **errp)
|
2012-09-27 19:29:13 +02:00
|
|
|
{
|
|
|
|
CommitBlockJob *s;
|
2016-10-28 09:08:08 +02:00
|
|
|
BlockDriverState *iter;
|
2017-01-16 16:22:34 +01:00
|
|
|
BlockDriverState *commit_top_bs = NULL;
|
2019-06-12 17:47:37 +02:00
|
|
|
BlockDriverState *filtered_base;
|
|
|
|
int64_t base_size, top_size;
|
|
|
|
uint64_t base_perms, iter_shared_perms;
|
2017-01-13 19:02:32 +01:00
|
|
|
int ret;
|
2012-09-27 19:29:13 +02:00
|
|
|
|
2022-03-03 16:15:57 +01:00
|
|
|
GLOBAL_STATE_CODE();
|
|
|
|
|
2013-12-16 07:45:33 +01:00
|
|
|
assert(top != bs);
|
2019-06-12 17:47:37 +02:00
|
|
|
if (bdrv_skip_filters(top) == bdrv_skip_filters(base)) {
|
2012-09-27 19:29:13 +02:00
|
|
|
error_setg(errp, "Invalid files for merge: top and base are the same");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-06-12 17:47:37 +02:00
|
|
|
base_size = bdrv_getlength(base);
|
|
|
|
if (base_size < 0) {
|
|
|
|
error_setg_errno(errp, -base_size, "Could not inquire base image size");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
top_size = bdrv_getlength(top);
|
|
|
|
if (top_size < 0) {
|
|
|
|
error_setg_errno(errp, -top_size, "Could not inquire top image size");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
base_perms = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE;
|
|
|
|
if (base_size < top_size) {
|
|
|
|
base_perms |= BLK_PERM_RESIZE;
|
|
|
|
}
|
|
|
|
|
2018-03-10 09:27:27 +01:00
|
|
|
s = block_job_create(job_id, &commit_job_driver, NULL, bs, 0, BLK_PERM_ALL,
|
2018-09-06 15:02:10 +02:00
|
|
|
speed, creation_flags, NULL, NULL, errp);
|
2016-05-27 12:53:39 +02:00
|
|
|
if (!s) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-06-27 20:36:18 +02:00
|
|
|
/* convert base to r/w, if necessary */
|
2018-11-12 15:00:35 +01:00
|
|
|
s->base_read_only = bdrv_is_read_only(base);
|
|
|
|
if (s->base_read_only) {
|
|
|
|
if (bdrv_reopen_set_read_only(base, false, errp) != 0) {
|
2017-01-13 19:02:32 +01:00
|
|
|
goto fail;
|
2012-09-27 19:29:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-16 16:22:34 +01:00
|
|
|
/* Insert commit_top block node above top, so we can block consistent read
|
|
|
|
* on the backing chain below it */
|
2017-02-20 18:10:05 +01:00
|
|
|
commit_top_bs = bdrv_new_open_driver(&bdrv_commit_top, filter_node_name, 0,
|
|
|
|
errp);
|
2017-01-16 16:22:34 +01:00
|
|
|
if (commit_top_bs == NULL) {
|
|
|
|
goto fail;
|
|
|
|
}
|
2017-07-18 17:24:05 +02:00
|
|
|
if (!filter_node_name) {
|
|
|
|
commit_top_bs->implicit = true;
|
|
|
|
}
|
2019-07-03 19:28:02 +02:00
|
|
|
|
|
|
|
/* So that we can always drop this node */
|
|
|
|
commit_top_bs->never_freeze = true;
|
|
|
|
|
2017-04-06 19:07:14 +02:00
|
|
|
commit_top_bs->total_sectors = top->total_sectors;
|
2017-01-16 16:22:34 +01:00
|
|
|
|
2021-02-02 13:49:44 +01:00
|
|
|
ret = bdrv_append(commit_top_bs, top, errp);
|
2021-04-28 17:17:32 +02:00
|
|
|
bdrv_unref(commit_top_bs); /* referenced by new parents or failed */
|
2021-02-02 13:49:44 +01:00
|
|
|
if (ret < 0) {
|
2017-03-07 12:07:22 +01:00
|
|
|
commit_top_bs = NULL;
|
|
|
|
goto fail;
|
|
|
|
}
|
2017-01-16 16:22:34 +01:00
|
|
|
|
|
|
|
s->commit_top_bs = commit_top_bs;
|
2012-09-27 19:29:13 +02:00
|
|
|
|
2019-06-12 17:47:37 +02:00
|
|
|
/*
|
|
|
|
* Block all nodes between top and base, because they will
|
|
|
|
* disappear from the chain after this operation.
|
|
|
|
* Note that this assumes that the user is fine with removing all
|
|
|
|
* nodes (including R/W filters) between top and base. Assuring
|
|
|
|
* this is the responsibility of the interface (i.e. whoever calls
|
|
|
|
* commit_start()).
|
|
|
|
*/
|
|
|
|
s->base_overlay = bdrv_find_overlay(top, base);
|
|
|
|
assert(s->base_overlay);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The topmost node with
|
|
|
|
* bdrv_skip_filters(filtered_base) == bdrv_skip_filters(base)
|
|
|
|
*/
|
|
|
|
filtered_base = bdrv_cow_bs(s->base_overlay);
|
|
|
|
assert(bdrv_skip_filters(filtered_base) == bdrv_skip_filters(base));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX BLK_PERM_WRITE needs to be allowed so we don't block ourselves
|
|
|
|
* at s->base (if writes are blocked for a node, they are also blocked
|
|
|
|
* for its backing file). The other options would be a second filter
|
|
|
|
* driver above s->base.
|
|
|
|
*/
|
|
|
|
iter_shared_perms = BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE;
|
|
|
|
|
|
|
|
for (iter = top; iter != base; iter = bdrv_filter_or_cow_bs(iter)) {
|
|
|
|
if (iter == filtered_base) {
|
|
|
|
/*
|
|
|
|
* From here on, all nodes are filters on the base. This
|
|
|
|
* allows us to share BLK_PERM_CONSISTENT_READ.
|
|
|
|
*/
|
|
|
|
iter_shared_perms |= BLK_PERM_CONSISTENT_READ;
|
|
|
|
}
|
|
|
|
|
2017-01-16 16:22:34 +01:00
|
|
|
ret = block_job_add_bdrv(&s->common, "intermediate node", iter, 0,
|
2019-06-12 17:47:37 +02:00
|
|
|
iter_shared_perms, errp);
|
2017-01-16 16:22:34 +01:00
|
|
|
if (ret < 0) {
|
|
|
|
goto fail;
|
|
|
|
}
|
2016-10-28 09:08:08 +02:00
|
|
|
}
|
2017-01-16 16:22:34 +01:00
|
|
|
|
2019-03-12 17:48:41 +01:00
|
|
|
if (bdrv_freeze_backing_chain(commit_top_bs, base, errp) < 0) {
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
s->chain_frozen = true;
|
|
|
|
|
2017-01-16 16:22:34 +01:00
|
|
|
ret = block_job_add_bdrv(&s->common, "base", base, 0, BLK_PERM_ALL, errp);
|
|
|
|
if (ret < 0) {
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
2019-04-25 14:25:10 +02:00
|
|
|
s->base = blk_new(s->common.job.aio_context,
|
2019-06-12 17:47:37 +02:00
|
|
|
base_perms,
|
2017-01-16 16:22:34 +01:00
|
|
|
BLK_PERM_CONSISTENT_READ
|
|
|
|
| BLK_PERM_WRITE_UNCHANGED);
|
2017-01-13 19:02:32 +01:00
|
|
|
ret = blk_insert_bs(s->base, base, errp);
|
|
|
|
if (ret < 0) {
|
|
|
|
goto fail;
|
|
|
|
}
|
block-backend: Queue requests while drained
This fixes devices like IDE that can still start new requests from I/O
handlers in the CPU thread while the block backend is drained.
The basic assumption is that in a drain section, no new requests should
be allowed through a BlockBackend (blk_drained_begin/end don't exist,
we get drain sections only on the node level). However, there are two
special cases where requests should not be queued:
1. Block jobs: We already make sure that block jobs are paused in a
drain section, so they won't start new requests. However, if the
drain_begin is called on the job's BlockBackend first, it can happen
that we deadlock because the job stays busy until it reaches a pause
point - which it can't if its requests aren't processed any more.
The proper solution here would be to make all requests through the
job's filter node instead of using a BlockBackend. For now, just
disabling request queuing on the job BlockBackend is simpler.
2. In test cases where making requests through bdrv_* would be
cumbersome because we'd need a BdrvChild. As we already got the
functionality to disable request queuing from 1., use it in tests,
too, for convenience.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
2019-07-22 17:46:23 +02:00
|
|
|
blk_set_disable_request_queuing(s->base, true);
|
2018-09-06 15:02:13 +02:00
|
|
|
s->base_bs = base;
|
2016-04-14 13:09:53 +02:00
|
|
|
|
2017-01-16 16:22:34 +01:00
|
|
|
/* Required permissions are already taken with block_job_add_bdrv() */
|
2019-04-25 14:25:10 +02:00
|
|
|
s->top = blk_new(s->common.job.aio_context, 0, BLK_PERM_ALL);
|
2017-03-03 16:54:21 +01:00
|
|
|
ret = blk_insert_bs(s->top, top, errp);
|
2017-01-13 19:02:32 +01:00
|
|
|
if (ret < 0) {
|
|
|
|
goto fail;
|
|
|
|
}
|
block-backend: Queue requests while drained
This fixes devices like IDE that can still start new requests from I/O
handlers in the CPU thread while the block backend is drained.
The basic assumption is that in a drain section, no new requests should
be allowed through a BlockBackend (blk_drained_begin/end don't exist,
we get drain sections only on the node level). However, there are two
special cases where requests should not be queued:
1. Block jobs: We already make sure that block jobs are paused in a
drain section, so they won't start new requests. However, if the
drain_begin is called on the job's BlockBackend first, it can happen
that we deadlock because the job stays busy until it reaches a pause
point - which it can't if its requests aren't processed any more.
The proper solution here would be to make all requests through the
job's filter node instead of using a BlockBackend. For now, just
disabling request queuing on the job BlockBackend is simpler.
2. In test cases where making requests through bdrv_* would be
cumbersome because we'd need a BdrvChild. As we already got the
functionality to disable request queuing from 1., use it in tests,
too, for convenience.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
2019-07-22 17:46:23 +02:00
|
|
|
blk_set_disable_request_queuing(s->top, true);
|
2016-04-14 13:09:53 +02:00
|
|
|
|
block: extend block-commit to accept a string for the backing file
On some image chains, QEMU may not always be able to resolve the
filenames properly, when updating the backing file of an image
after a block commit.
For instance, certain relative pathnames may fail, or drives may
have been specified originally by file descriptor (e.g. /dev/fd/???),
or a relative protocol pathname may have been used.
In these instances, QEMU may lack the information to be able to make
the correct choice, but the user or management layer most likely does
have that knowledge.
With this extension to the block-commit api, the user is able to change
the backing file of the overlay image as part of the block-commit
operation.
This allows the change to be 'safe', in the sense that if the attempt
to write the overlay image metadata fails, then the block-commit
operation returns failure, without disrupting the guest.
If the commit top is the active layer, then specifying the backing
file string will be treated as an error (there is no overlay image
to modify in that case).
If a backing file string is not specified in the command, the backing
file string to use is determined in the same manner as it was
previously.
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-25 21:40:10 +02:00
|
|
|
s->backing_file_str = g_strdup(backing_file_str);
|
2012-09-27 19:29:13 +02:00
|
|
|
s->on_error = on_error;
|
|
|
|
|
2016-11-08 07:50:37 +01:00
|
|
|
trace_commit_start(bs, base, top, s);
|
2018-04-13 17:31:02 +02:00
|
|
|
job_start(&s->common.job);
|
2017-01-13 19:02:32 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
fail:
|
2019-03-12 17:48:41 +01:00
|
|
|
if (s->chain_frozen) {
|
|
|
|
bdrv_unfreeze_backing_chain(commit_top_bs, base);
|
|
|
|
}
|
2017-01-13 19:02:32 +01:00
|
|
|
if (s->base) {
|
|
|
|
blk_unref(s->base);
|
|
|
|
}
|
|
|
|
if (s->top) {
|
|
|
|
blk_unref(s->top);
|
|
|
|
}
|
2019-04-29 15:51:08 +02:00
|
|
|
if (s->base_read_only) {
|
|
|
|
bdrv_reopen_set_read_only(base, true, NULL);
|
|
|
|
}
|
2019-02-15 14:49:32 +01:00
|
|
|
job_early_fail(&s->common.job);
|
|
|
|
/* commit_top_bs has to be replaced after deleting the block job,
|
|
|
|
* otherwise this would fail because of lack of permissions. */
|
2017-01-16 16:22:34 +01:00
|
|
|
if (commit_top_bs) {
|
2017-06-27 20:36:18 +02:00
|
|
|
bdrv_replace_node(commit_top_bs, top, &error_abort);
|
2017-01-16 16:22:34 +01:00
|
|
|
}
|
2012-09-27 19:29:13 +02:00
|
|
|
}
|
2016-05-30 15:53:15 +02:00
|
|
|
|
|
|
|
|
block: Make bdrv_is_allocated() byte-based
We are gradually moving away from sector-based interfaces, towards
byte-based. In the common case, allocation is unlikely to ever use
values that are not naturally sector-aligned, but it is possible
that byte-based values will let us be more precise about allocation
at the end of an unaligned file that can do byte-based access.
Changing the signature of the function to use int64_t *pnum ensures
that the compiler enforces that all callers are updated. For now,
the io.c layer still assert()s that all callers are sector-aligned
on input and that *pnum is sector-aligned on return to the caller,
but that can be relaxed when a later patch implements byte-based
block status. Therefore, this code adds usages like
DIV_ROUND_UP(,BDRV_SECTOR_SIZE) to callers that still want aligned
values, where the call might reasonbly give non-aligned results
in the future; on the other hand, no rounding is needed for callers
that should just continue to work with byte alignment.
For the most part this patch is just the addition of scaling at the
callers followed by inverse scaling at bdrv_is_allocated(). But
some code, particularly bdrv_commit(), gets a lot simpler because it
no longer has to mess with sectors; also, it is now possible to pass
NULL if the caller does not care how much of the image is allocated
beyond the initial offset. Leave comments where we can further
simplify once a later patch eliminates the need for sector-aligned
requests through bdrv_is_allocated().
For ease of review, bdrv_is_allocated_above() will be tackled
separately.
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2017-07-07 14:44:57 +02:00
|
|
|
#define COMMIT_BUF_SIZE (2048 * BDRV_SECTOR_SIZE)
|
2016-05-30 15:53:15 +02:00
|
|
|
|
|
|
|
/* commit COW file into the raw image */
|
|
|
|
int bdrv_commit(BlockDriverState *bs)
|
|
|
|
{
|
2016-05-30 16:29:47 +02:00
|
|
|
BlockBackend *src, *backing;
|
2017-01-19 18:16:03 +01:00
|
|
|
BlockDriverState *backing_file_bs = NULL;
|
|
|
|
BlockDriverState *commit_top_bs = NULL;
|
2016-05-30 15:53:15 +02:00
|
|
|
BlockDriver *drv = bs->drv;
|
2019-04-25 14:25:10 +02:00
|
|
|
AioContext *ctx;
|
block: Make bdrv_is_allocated() byte-based
We are gradually moving away from sector-based interfaces, towards
byte-based. In the common case, allocation is unlikely to ever use
values that are not naturally sector-aligned, but it is possible
that byte-based values will let us be more precise about allocation
at the end of an unaligned file that can do byte-based access.
Changing the signature of the function to use int64_t *pnum ensures
that the compiler enforces that all callers are updated. For now,
the io.c layer still assert()s that all callers are sector-aligned
on input and that *pnum is sector-aligned on return to the caller,
but that can be relaxed when a later patch implements byte-based
block status. Therefore, this code adds usages like
DIV_ROUND_UP(,BDRV_SECTOR_SIZE) to callers that still want aligned
values, where the call might reasonbly give non-aligned results
in the future; on the other hand, no rounding is needed for callers
that should just continue to work with byte alignment.
For the most part this patch is just the addition of scaling at the
callers followed by inverse scaling at bdrv_is_allocated(). But
some code, particularly bdrv_commit(), gets a lot simpler because it
no longer has to mess with sectors; also, it is now possible to pass
NULL if the caller does not care how much of the image is allocated
beyond the initial offset. Leave comments where we can further
simplify once a later patch eliminates the need for sector-aligned
requests through bdrv_is_allocated().
For ease of review, bdrv_is_allocated_above() will be tackled
separately.
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2017-07-07 14:44:57 +02:00
|
|
|
int64_t offset, length, backing_length;
|
2018-11-12 15:00:36 +01:00
|
|
|
int ro;
|
block: Make bdrv_is_allocated() byte-based
We are gradually moving away from sector-based interfaces, towards
byte-based. In the common case, allocation is unlikely to ever use
values that are not naturally sector-aligned, but it is possible
that byte-based values will let us be more precise about allocation
at the end of an unaligned file that can do byte-based access.
Changing the signature of the function to use int64_t *pnum ensures
that the compiler enforces that all callers are updated. For now,
the io.c layer still assert()s that all callers are sector-aligned
on input and that *pnum is sector-aligned on return to the caller,
but that can be relaxed when a later patch implements byte-based
block status. Therefore, this code adds usages like
DIV_ROUND_UP(,BDRV_SECTOR_SIZE) to callers that still want aligned
values, where the call might reasonbly give non-aligned results
in the future; on the other hand, no rounding is needed for callers
that should just continue to work with byte alignment.
For the most part this patch is just the addition of scaling at the
callers followed by inverse scaling at bdrv_is_allocated(). But
some code, particularly bdrv_commit(), gets a lot simpler because it
no longer has to mess with sectors; also, it is now possible to pass
NULL if the caller does not care how much of the image is allocated
beyond the initial offset. Leave comments where we can further
simplify once a later patch eliminates the need for sector-aligned
requests through bdrv_is_allocated().
For ease of review, bdrv_is_allocated_above() will be tackled
separately.
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2017-07-07 14:44:57 +02:00
|
|
|
int64_t n;
|
2016-05-30 15:53:15 +02:00
|
|
|
int ret = 0;
|
2021-06-28 14:11:33 +02:00
|
|
|
QEMU_AUTO_VFREE uint8_t *buf = NULL;
|
2017-01-19 18:16:03 +01:00
|
|
|
Error *local_err = NULL;
|
2016-05-30 15:53:15 +02:00
|
|
|
|
2022-03-03 16:15:49 +01:00
|
|
|
GLOBAL_STATE_CODE();
|
2023-09-29 16:51:52 +02:00
|
|
|
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
2022-03-03 16:15:49 +01:00
|
|
|
|
2016-05-30 15:53:15 +02:00
|
|
|
if (!drv)
|
|
|
|
return -ENOMEDIUM;
|
|
|
|
|
2019-06-12 17:47:37 +02:00
|
|
|
backing_file_bs = bdrv_cow_bs(bs);
|
|
|
|
|
|
|
|
if (!backing_file_bs) {
|
2016-05-30 15:53:15 +02:00
|
|
|
return -ENOTSUP;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT_SOURCE, NULL) ||
|
2019-06-12 17:47:37 +02:00
|
|
|
bdrv_op_is_blocked(backing_file_bs, BLOCK_OP_TYPE_COMMIT_TARGET, NULL))
|
|
|
|
{
|
2016-05-30 15:53:15 +02:00
|
|
|
return -EBUSY;
|
|
|
|
}
|
|
|
|
|
2021-05-27 17:40:54 +02:00
|
|
|
ro = bdrv_is_read_only(backing_file_bs);
|
2016-05-30 15:53:15 +02:00
|
|
|
|
|
|
|
if (ro) {
|
2019-06-12 17:47:37 +02:00
|
|
|
if (bdrv_reopen_set_read_only(backing_file_bs, false, NULL)) {
|
2016-05-30 15:53:15 +02:00
|
|
|
return -EACCES;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-25 14:25:10 +02:00
|
|
|
ctx = bdrv_get_aio_context(bs);
|
2020-04-29 16:11:26 +02:00
|
|
|
/* WRITE_UNCHANGED is required for bdrv_make_empty() */
|
|
|
|
src = blk_new(ctx, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED,
|
|
|
|
BLK_PERM_ALL);
|
2019-04-25 14:25:10 +02:00
|
|
|
backing = blk_new(ctx, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
|
2017-01-13 19:02:32 +01:00
|
|
|
|
2017-01-19 18:16:03 +01:00
|
|
|
ret = blk_insert_bs(src, bs, &local_err);
|
2017-01-13 19:02:32 +01:00
|
|
|
if (ret < 0) {
|
2017-01-19 18:16:03 +01:00
|
|
|
error_report_err(local_err);
|
|
|
|
goto ro_cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Insert commit_top block node above backing, so we can write to it */
|
|
|
|
commit_top_bs = bdrv_new_open_driver(&bdrv_commit_top, NULL, BDRV_O_RDWR,
|
|
|
|
&local_err);
|
|
|
|
if (commit_top_bs == NULL) {
|
|
|
|
error_report_err(local_err);
|
2017-01-13 19:02:32 +01:00
|
|
|
goto ro_cleanup;
|
|
|
|
}
|
|
|
|
|
2017-02-17 20:42:32 +01:00
|
|
|
bdrv_set_backing_hd(commit_top_bs, backing_file_bs, &error_abort);
|
|
|
|
bdrv_set_backing_hd(bs, commit_top_bs, &error_abort);
|
2017-01-19 18:16:03 +01:00
|
|
|
|
|
|
|
ret = blk_insert_bs(backing, backing_file_bs, &local_err);
|
2017-01-13 19:02:32 +01:00
|
|
|
if (ret < 0) {
|
2017-01-19 18:16:03 +01:00
|
|
|
error_report_err(local_err);
|
2017-01-13 19:02:32 +01:00
|
|
|
goto ro_cleanup;
|
|
|
|
}
|
2016-05-30 16:29:47 +02:00
|
|
|
|
|
|
|
length = blk_getlength(src);
|
2016-05-30 15:53:15 +02:00
|
|
|
if (length < 0) {
|
|
|
|
ret = length;
|
|
|
|
goto ro_cleanup;
|
|
|
|
}
|
|
|
|
|
2016-05-30 16:29:47 +02:00
|
|
|
backing_length = blk_getlength(backing);
|
2016-05-30 15:53:15 +02:00
|
|
|
if (backing_length < 0) {
|
|
|
|
ret = backing_length;
|
|
|
|
goto ro_cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If our top snapshot is larger than the backing file image,
|
|
|
|
* grow the backing file image if possible. If not possible,
|
|
|
|
* we must return an error */
|
|
|
|
if (length > backing_length) {
|
2020-04-24 14:54:41 +02:00
|
|
|
ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF, 0,
|
2019-09-18 11:51:40 +02:00
|
|
|
&local_err);
|
2016-05-30 15:53:15 +02:00
|
|
|
if (ret < 0) {
|
2017-03-28 22:51:27 +02:00
|
|
|
error_report_err(local_err);
|
2016-05-30 15:53:15 +02:00
|
|
|
goto ro_cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-30 16:29:47 +02:00
|
|
|
/* blk_try_blockalign() for src will choose an alignment that works for
|
|
|
|
* backing as well, so no need to compare the alignment manually. */
|
block: Make bdrv_is_allocated() byte-based
We are gradually moving away from sector-based interfaces, towards
byte-based. In the common case, allocation is unlikely to ever use
values that are not naturally sector-aligned, but it is possible
that byte-based values will let us be more precise about allocation
at the end of an unaligned file that can do byte-based access.
Changing the signature of the function to use int64_t *pnum ensures
that the compiler enforces that all callers are updated. For now,
the io.c layer still assert()s that all callers are sector-aligned
on input and that *pnum is sector-aligned on return to the caller,
but that can be relaxed when a later patch implements byte-based
block status. Therefore, this code adds usages like
DIV_ROUND_UP(,BDRV_SECTOR_SIZE) to callers that still want aligned
values, where the call might reasonbly give non-aligned results
in the future; on the other hand, no rounding is needed for callers
that should just continue to work with byte alignment.
For the most part this patch is just the addition of scaling at the
callers followed by inverse scaling at bdrv_is_allocated(). But
some code, particularly bdrv_commit(), gets a lot simpler because it
no longer has to mess with sectors; also, it is now possible to pass
NULL if the caller does not care how much of the image is allocated
beyond the initial offset. Leave comments where we can further
simplify once a later patch eliminates the need for sector-aligned
requests through bdrv_is_allocated().
For ease of review, bdrv_is_allocated_above() will be tackled
separately.
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2017-07-07 14:44:57 +02:00
|
|
|
buf = blk_try_blockalign(src, COMMIT_BUF_SIZE);
|
2016-05-30 15:53:15 +02:00
|
|
|
if (buf == NULL) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto ro_cleanup;
|
|
|
|
}
|
|
|
|
|
block: Make bdrv_is_allocated() byte-based
We are gradually moving away from sector-based interfaces, towards
byte-based. In the common case, allocation is unlikely to ever use
values that are not naturally sector-aligned, but it is possible
that byte-based values will let us be more precise about allocation
at the end of an unaligned file that can do byte-based access.
Changing the signature of the function to use int64_t *pnum ensures
that the compiler enforces that all callers are updated. For now,
the io.c layer still assert()s that all callers are sector-aligned
on input and that *pnum is sector-aligned on return to the caller,
but that can be relaxed when a later patch implements byte-based
block status. Therefore, this code adds usages like
DIV_ROUND_UP(,BDRV_SECTOR_SIZE) to callers that still want aligned
values, where the call might reasonbly give non-aligned results
in the future; on the other hand, no rounding is needed for callers
that should just continue to work with byte alignment.
For the most part this patch is just the addition of scaling at the
callers followed by inverse scaling at bdrv_is_allocated(). But
some code, particularly bdrv_commit(), gets a lot simpler because it
no longer has to mess with sectors; also, it is now possible to pass
NULL if the caller does not care how much of the image is allocated
beyond the initial offset. Leave comments where we can further
simplify once a later patch eliminates the need for sector-aligned
requests through bdrv_is_allocated().
For ease of review, bdrv_is_allocated_above() will be tackled
separately.
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2017-07-07 14:44:57 +02:00
|
|
|
for (offset = 0; offset < length; offset += n) {
|
|
|
|
ret = bdrv_is_allocated(bs, offset, COMMIT_BUF_SIZE, &n);
|
2016-05-30 15:53:15 +02:00
|
|
|
if (ret < 0) {
|
|
|
|
goto ro_cleanup;
|
|
|
|
}
|
|
|
|
if (ret) {
|
block: Change blk_{pread,pwrite}() param order
Swap 'buf' and 'bytes' around for consistency with
blk_co_{pread,pwrite}(), and in preparation to implement these functions
using generated_co_wrapper.
Callers were updated using this Coccinelle script:
@@ expression blk, offset, buf, bytes, flags; @@
- blk_pread(blk, offset, buf, bytes, flags)
+ blk_pread(blk, offset, bytes, buf, flags)
@@ expression blk, offset, buf, bytes, flags; @@
- blk_pwrite(blk, offset, buf, bytes, flags)
+ blk_pwrite(blk, offset, bytes, buf, flags)
It had no effect on hw/block/nand.c, presumably due to the #if, so that
file was updated manually.
Overly-long lines were then fixed by hand.
Signed-off-by: Alberto Faria <afaria@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
Message-Id: <20220705161527.1054072-4-afaria@redhat.com>
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
2022-07-05 18:15:11 +02:00
|
|
|
ret = blk_pread(src, offset, n, buf, 0);
|
2016-05-30 15:53:15 +02:00
|
|
|
if (ret < 0) {
|
|
|
|
goto ro_cleanup;
|
|
|
|
}
|
|
|
|
|
block: Change blk_{pread,pwrite}() param order
Swap 'buf' and 'bytes' around for consistency with
blk_co_{pread,pwrite}(), and in preparation to implement these functions
using generated_co_wrapper.
Callers were updated using this Coccinelle script:
@@ expression blk, offset, buf, bytes, flags; @@
- blk_pread(blk, offset, buf, bytes, flags)
+ blk_pread(blk, offset, bytes, buf, flags)
@@ expression blk, offset, buf, bytes, flags; @@
- blk_pwrite(blk, offset, buf, bytes, flags)
+ blk_pwrite(blk, offset, bytes, buf, flags)
It had no effect on hw/block/nand.c, presumably due to the #if, so that
file was updated manually.
Overly-long lines were then fixed by hand.
Signed-off-by: Alberto Faria <afaria@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
Message-Id: <20220705161527.1054072-4-afaria@redhat.com>
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
2022-07-05 18:15:11 +02:00
|
|
|
ret = blk_pwrite(backing, offset, n, buf, 0);
|
2016-05-30 15:53:15 +02:00
|
|
|
if (ret < 0) {
|
|
|
|
goto ro_cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-29 16:11:26 +02:00
|
|
|
ret = blk_make_empty(src, NULL);
|
|
|
|
/* Ignore -ENOTSUP */
|
|
|
|
if (ret < 0 && ret != -ENOTSUP) {
|
|
|
|
goto ro_cleanup;
|
2016-05-30 15:53:15 +02:00
|
|
|
}
|
|
|
|
|
2020-04-29 16:11:26 +02:00
|
|
|
blk_flush(src);
|
|
|
|
|
2016-05-30 15:53:15 +02:00
|
|
|
/*
|
|
|
|
* Make sure all data we wrote to the backing device is actually
|
|
|
|
* stable on disk.
|
|
|
|
*/
|
2016-05-30 16:29:47 +02:00
|
|
|
blk_flush(backing);
|
2016-05-30 15:53:15 +02:00
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
ro_cleanup:
|
2016-05-30 16:29:47 +02:00
|
|
|
blk_unref(backing);
|
2019-06-12 17:47:37 +02:00
|
|
|
if (bdrv_cow_bs(bs) != backing_file_bs) {
|
2017-02-17 20:42:32 +01:00
|
|
|
bdrv_set_backing_hd(bs, backing_file_bs, &error_abort);
|
2017-01-19 18:16:03 +01:00
|
|
|
}
|
|
|
|
bdrv_unref(commit_top_bs);
|
|
|
|
blk_unref(src);
|
2016-05-30 16:29:47 +02:00
|
|
|
|
2016-05-30 15:53:15 +02:00
|
|
|
if (ro) {
|
|
|
|
/* ignoring error return here */
|
2019-06-12 17:47:37 +02:00
|
|
|
bdrv_reopen_set_read_only(backing_file_bs, true, NULL);
|
2016-05-30 15:53:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|