summary refs log tree commit diff stats
path: root/block/commit.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-02-18 14:23:43 +0000
committerPeter Maydell <peter.maydell@linaro.org>2020-02-18 14:23:43 +0000
commit672f9d0df10a68a5c5f2b32cbc8284abf9f5ee18 (patch)
tree2288bb7887cf822679bf7d538ba4c085fa8d798a /block/commit.c
parent6c599282f8ab382fe59f03a6cae755b89561a7b3 (diff)
parentc45a88f4429d7a8f384b75f3fd3fed5138a6edca (diff)
downloadfocaccia-qemu-672f9d0df10a68a5c5f2b32cbc8284abf9f5ee18.tar.gz
focaccia-qemu-672f9d0df10a68a5c5f2b32cbc8284abf9f5ee18.zip
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches:

- Fix check_to_replace_node()
- commit: Expose on-error option in QMP
- qcow2: Fix qcow2_alloc_cluster_abort() for external data file
- mirror: Fix deadlock
- vvfat: Fix segfault while closing read-write node
- Code cleanups

# gpg: Signature made Tue 18 Feb 2020 14:04:43 GMT
# gpg:                using RSA key 7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream: (36 commits)
  iotests: Check that @replaces can replace filters
  iotests: Add tests for invalid Quorum @replaces
  iotests: Use self.image_len in TestRepairQuorum
  iotests: Resolve TODOs in 041
  iotests/041: Drop superfluous shutdowns
  iotests: Add VM.assert_block_path()
  iotests: Use complete_and_wait() in 155
  quorum: Stop marking it as a filter
  mirror: Double-check immediately before replacing
  block: Remove bdrv_recurse_is_first_non_filter()
  block: Use bdrv_recurse_can_replace()
  quorum: Implement .bdrv_recurse_can_replace()
  blkverify: Implement .bdrv_recurse_can_replace()
  block: Add bdrv_recurse_can_replace()
  quorum: Fix child permissions
  iotests: Let 041 use -blockdev for quorum children
  block: Drop bdrv_is_first_non_filter()
  blockdev: Allow resizing everywhere
  blockdev: Allow external snapshots everywhere
  block/io_uring: Remove superfluous semicolon
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'block/commit.c')
-rw-r--r--block/commit.c37
1 files changed, 12 insertions, 25 deletions
diff --git a/block/commit.c b/block/commit.c
index 23c90b3b91..8e672799af 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -43,27 +43,6 @@ typedef struct CommitBlockJob {
     char *backing_file_str;
 } CommitBlockJob;
 
-static int coroutine_fn commit_populate(BlockBackend *bs, BlockBackend *base,
-                                        int64_t offset, uint64_t bytes,
-                                        void *buf)
-{
-    int ret = 0;
-
-    assert(bytes < SIZE_MAX);
-
-    ret = blk_co_pread(bs, offset, bytes, buf, 0);
-    if (ret < 0) {
-        return ret;
-    }
-
-    ret = blk_co_pwrite(base, offset, bytes, buf, 0);
-    if (ret < 0) {
-        return ret;
-    }
-
-    return 0;
-}
-
 static int commit_prepare(Job *job)
 {
     CommitBlockJob *s = container_of(job, CommitBlockJob, common.job);
@@ -140,7 +119,6 @@ static int coroutine_fn commit_run(Job *job, Error **errp)
     int ret = 0;
     int64_t n = 0; /* bytes */
     void *buf = NULL;
-    int bytes_written = 0;
     int64_t len, base_len;
 
     ret = len = blk_getlength(s->top);
@@ -165,6 +143,7 @@ static int coroutine_fn commit_run(Job *job, Error **errp)
 
     for (offset = 0; offset < len; offset += n) {
         bool copy;
+        bool error_in_source = true;
 
         /* Note that even when no rate limit is applied we need to yield
          * with no pending I/O here so that bdrv_drain_all() returns.
@@ -179,12 +158,20 @@ static int coroutine_fn commit_run(Job *job, Error **errp)
         copy = (ret == 1);
         trace_commit_one_iteration(s, offset, n, ret);
         if (copy) {
-            ret = commit_populate(s->top, s->base, offset, n, buf);
-            bytes_written += n;
+            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);
+                if (ret < 0) {
+                    error_in_source = false;
+                }
+            }
         }
         if (ret < 0) {
             BlockErrorAction action =
-                block_job_error_action(&s->common, false, s->on_error, -ret);
+                block_job_error_action(&s->common, s->on_error,
+                                       error_in_source, -ret);
             if (action == BLOCK_ERROR_ACTION_REPORT) {
                 goto out;
             } else {