From: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
To: andrey.zhadchenko@virtuozzo.com
Cc: devel@openvz.org
Subject: [Devel] [PATCH hci-8.1 1/3] drivers/md/dm-qcow2: treat images of a read-only table as read-only
Date: Fri, 23 Oct 2026 15:20:06 +0200 [thread overview]
Message-ID: <20261023132008.2304901-2-alexander.ivanov@virtuozzo.com> (raw)
In-Reply-To: <20261023132008.2304901-1-alexander.ivanov@virtuozzo.com>
Whether an image may be modified is decided by the mode of its file
only. Userspace may pass an O_RDWR top image to a read-only table, and
then dm-qcow2 truncates the unaligned image tail on every .ctr and
.preresume and considers the image writable on the I/O and discard
paths.
merge_backward is also allowed on a read-only table if the lower image
is opened for write. qcow2_set_image_file_features() checks the table
mode and skips the lower image, so the merge writes to it without the
dirty bit and without clearing the bitmaps autoclear bit. Enabled
persistent bitmaps of the lower image are left marked consistent
although the image data changed.
Consider an image writable only if both its file and the table are
writable, and use this check for the header update, the tail truncate
and the short read near EOF as well. merge_backward on a read-only
table now fails with -EACCES.
https://virtuozzo.atlassian.net/browse/VSTOR-138887
Feature: dm-qcow2: block device over QCOW2 files driver
Signed-off-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
---
drivers/md/dm-qcow2-map.c | 4 +---
drivers/md/dm-qcow2-target.c | 6 ++----
drivers/md/dm-qcow2.h | 3 ++-
3 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/drivers/md/dm-qcow2-map.c b/drivers/md/dm-qcow2-map.c
index 78ee7cf5e881..54b3a345f927 100644
--- a/drivers/md/dm-qcow2-map.c
+++ b/drivers/md/dm-qcow2-map.c
@@ -1470,7 +1470,6 @@ static void md_page_read_complete(struct qio *qio)
struct md_page *md = qio->ext->md;
struct qcow2 *qcow2 = qio->qcow2;
int ret = qio->ret;
- mode_t mode;
BUG_ON(qvec->bvec[0].bv_page != md->page);
@@ -1478,8 +1477,7 @@ static void md_page_read_complete(struct qio *qio)
/* Read near EOF? See qcow2_attach_file() */
loff_t pos = (md->id << PAGE_SHIFT) + ret;
- mode = qcow2->file->f_mode;
- if (pos == qcow2->file_size && !(mode & FMODE_WRITE)) {
+ if (pos == qcow2->file_size && !qcow2_file_is_writable(qcow2)) {
qcow2_zero_fill_page_from(md->page, ret);
ret = PAGE_SIZE;
}
diff --git a/drivers/md/dm-qcow2-target.c b/drivers/md/dm-qcow2-target.c
index be09615eb8e2..2d1e5d4e1b3a 100644
--- a/drivers/md/dm-qcow2-target.c
+++ b/drivers/md/dm-qcow2-target.c
@@ -623,13 +623,11 @@ int qcow2_set_image_file_features(struct qcow2 *qcow2, bool dirty)
u64 dirty_mask = cpu_to_be64(INCOMPATIBLE_FEATURES_DIRTY_BIT);
struct QCowHeader *raw_hdr;
struct md_page *md;
- bool is_ro;
if (qcow2->hdr.version == 2)
return 0;
- is_ro = !(dm_table_get_mode(qcow2->tgt->ti->table) & FMODE_WRITE);
- if (is_ro)
+ if (!qcow2_file_is_writable(qcow2))
return 0;
md = qcow2_md_page_find(qcow2, 0);
@@ -840,7 +838,7 @@ static int qcow2_parse_header(struct dm_target *ti, struct qcow2 *qcow2,
int ret;
qcow2->file_size = i_size_read(file_inode(file));
- if ((file->f_mode & FMODE_WRITE) && (qcow2->file_size & ~PAGE_MASK)) {
+ if (qcow2_file_is_writable(qcow2) && (qcow2->file_size & ~PAGE_MASK)) {
new_size = PAGE_ALIGN(qcow2->file_size);
ret = qcow2_truncate_safe(file, new_size);
if (ret) {
diff --git a/drivers/md/dm-qcow2.h b/drivers/md/dm-qcow2.h
index d9b8c38e093f..8f10c5812a1b 100644
--- a/drivers/md/dm-qcow2.h
+++ b/drivers/md/dm-qcow2.h
@@ -462,7 +462,8 @@ static inline bool qcow2_wants_check(struct qcow2_target *tgt)
static inline bool qcow2_file_is_writable(struct qcow2 *qcow2)
{
- return qcow2->file->f_mode & FMODE_WRITE;
+ return (qcow2->file->f_mode & FMODE_WRITE) &&
+ (dm_table_get_mode(qcow2->tgt->ti->table) & BLK_OPEN_WRITE);
}
static inline void remap_to_clu(struct qcow2 *qcow2, struct qio *qio, loff_t clu_pos)
--
2.53.0
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel
next prev parent reply other threads:[~2026-10-23 13:21 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-23 13:20 [Devel] [PATCH hci-8.1 0/3] dm-qcow2: keep images of a read-only table unmodified Alexander Ivanov
2026-10-23 13:20 ` Alexander Ivanov [this message]
2026-10-23 13:24 ` [Devel] [PATCH hci-8.1 1/3] drivers/md/dm-qcow2: treat images of a read-only table as read-only no-reply
2026-10-29 11:36 ` Konstantin Khorenko
2026-10-23 13:20 ` [Devel] [PATCH hci-8.1 2/3] drivers/md/dm-qcow2: fail writes to a read-only table Alexander Ivanov
2026-10-23 13:23 ` no-reply
2026-10-28 10:35 ` Andrey Zhadchenko
2026-10-23 13:20 ` [Devel] [PATCH hci-8.1 3/3] drivers/md/dm-qcow2: do not revalidate inconsistent persistent bitmaps Alexander Ivanov
2026-10-23 13:25 ` no-reply
2026-10-23 13:58 ` Alexander Ivanov
2026-10-29 11:39 ` Konstantin Khorenko
2026-10-28 10:47 ` [Devel] [PATCH hci-8.1 0/3] dm-qcow2: keep images of a read-only table unmodified Andrey Zhadchenko
2026-10-29 11:42 ` Konstantin Khorenko
2026-10-29 14:48 ` Alexander Ivanov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261023132008.2304901-2-alexander.ivanov@virtuozzo.com \
--to=alexander.ivanov@virtuozzo.com \
--cc=andrey.zhadchenko@virtuozzo.com \
--cc=devel@openvz.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.