diff --git a/block.c b/block.c
index ca7e7a0b45..4e27c49a75 100644
--- a/block.c
+++ b/block.c
@@ -2028,18 +2028,12 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
 
     update_flags_from_options(&reopen_state->flags, opts);
 
-    /* If a guest device is attached, it owns WCE */
-    if (reopen_state->bs->blk && blk_get_attached_dev(reopen_state->bs->blk)) {
-        bool old_wce = bdrv_enable_write_cache(reopen_state->bs);
-        bool new_wce = (reopen_state->flags & BDRV_O_CACHE_WB);
-        if (old_wce != new_wce) {
-            error_setg(errp, "Cannot change cache.writeback: Device attached");
-            ret = -EINVAL;
-            goto error;
-        }
-    }
-    if (!reopen_state->bs->blk && !(reopen_state->flags & BDRV_O_CACHE_WB)) {
-        error_setg(errp, "Cannot disable cache.writeback: No BlockBackend");
+    /* WCE is a BlockBackend level option, can't change it */
+    bool old_wce = bdrv_enable_write_cache(reopen_state->bs);
+    bool new_wce = (reopen_state->flags & BDRV_O_CACHE_WB);
+
+    if (old_wce != new_wce) {
+        error_setg(errp, "Cannot change cache.writeback");
         ret = -EINVAL;
         goto error;
     }
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 139f7ebcbb..932e367a17 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -2106,6 +2106,7 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
     QDict *opts;
     int c;
     int flags = bs->open_flags;
+    bool writethrough = !blk_enable_write_cache(blk);
 
     BlockReopenQueue *brq;
     Error *local_err = NULL;
@@ -2113,7 +2114,7 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
     while ((c = getopt(argc, argv, "c:o:r")) != -1) {
         switch (c) {
         case 'c':
-            if (bdrv_parse_cache_flags(optarg, &flags) < 0) {
+            if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) {
                 error_report("Invalid cache option: %s", optarg);
                 return 0;
             }
@@ -2138,14 +2139,25 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
         return qemuio_command_usage(&reopen_cmd);
     }
 
+    if (writethrough != blk_enable_write_cache(blk) &&
+        blk_get_attached_dev(blk))
+    {
+        error_report("Cannot change cache.writeback: Device attached");
+        qemu_opts_reset(&reopen_opts);
+        return 0;
+    }
+
     qopts = qemu_opts_find(&reopen_opts, NULL);
     opts = qopts ? qemu_opts_to_qdict(qopts, NULL) : NULL;
     qemu_opts_reset(&reopen_opts);
 
+    flags |= blk_enable_write_cache(blk) ? BDRV_O_CACHE_WB : 0;
     brq = bdrv_reopen_queue(NULL, bs, opts, flags);
     bdrv_reopen_multiple(brq, &local_err);
     if (local_err) {
         error_report_err(local_err);
+    } else {
+        blk_set_enable_write_cache(blk, !writethrough);
     }
 
     return 0;
diff --git a/tests/qemu-iotests/142 b/tests/qemu-iotests/142
index 8bbbfde3a1..a035747904 100755
--- a/tests/qemu-iotests/142
+++ b/tests/qemu-iotests/142
@@ -216,7 +216,7 @@ echo
 # BDS initialised with the json: pseudo-protocol, but still have it inherit
 # options from its parent node.
 
-hmp_cmds="qemu-io none0 \"reopen -o cache.writeback=off,cache.direct=on,cache.no-flush=on\"
+hmp_cmds="qemu-io none0 \"reopen -o cache.direct=on,cache.no-flush=on\"
 info block none0
 info block image
 info block blkdebug
diff --git a/tests/qemu-iotests/142.out b/tests/qemu-iotests/142.out
index c9224909b5..3d5ef5fe8d 100644
--- a/tests/qemu-iotests/142.out
+++ b/tests/qemu-iotests/142.out
@@ -414,7 +414,7 @@ cache.no-flush=on on backing-file
 
 --- Change cache mode in parent, child has explicit option in JSON ---
 
-    Cache mode:       writethrough, direct, ignore flushes
+    Cache mode:       writeback, direct, ignore flushes
     Cache mode:       writeback, direct, ignore flushes
     Cache mode:       writeback, direct, ignore flushes
     Cache mode:       writeback, ignore flushes