[Devel] [PATCH RH8] ploop: Do not forget to update cached md0 page copy

Kirill Tkhai ktkhai at virtuozzo.com
Wed May 5 19:41:02 MSK 2021


We mustn't have obsolete data in cached pages.
In this BUG this resulted in that next update
of page 0 metadata overwrites header on disk
with old value.

https://jira.sw.ru/browse/PSBM-129136

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 drivers/md/dm-ploop-cmd.c |   27 +++++++++++++++++++--------
 drivers/md/dm-ploop.h     |    1 +
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/md/dm-ploop-cmd.c b/drivers/md/dm-ploop-cmd.c
index 0b8ef1382717..f259ff5d7652 100644
--- a/drivers/md/dm-ploop-cmd.c
+++ b/drivers/md/dm-ploop-cmd.c
@@ -313,6 +313,8 @@ static int ploop_grow_update_header(struct ploop *ploop,
 {
 	unsigned int size, first_block_off, cluster_log = ploop->cluster_log;
 	struct ploop_pvd_header *hdr;
+	u32 nr_be, offset;
+	u64 sectors;
 	int ret;
 
 	/* hdr is in the same page as bat_entries[0] index */
@@ -327,13 +329,21 @@ static int ploop_grow_update_header(struct ploop *ploop,
 
 	hdr = kmap_atomic(piwb->bat_page);
 	/* TODO: head and cylinders */
-	hdr->m_Size = cpu_to_le32(cmd->resize.nr_bat_entries);
-	hdr->m_SizeInSectors_v2 = cpu_to_le64(cmd->resize.new_size);
-	hdr->m_FirstBlockOffset = cpu_to_le32(first_block_off);
+	nr_be = hdr->m_Size = cpu_to_le32(cmd->resize.nr_bat_entries);
+	sectors = hdr->m_SizeInSectors_v2 = cpu_to_le64(cmd->resize.new_size);
+	offset = hdr->m_FirstBlockOffset = cpu_to_le32(first_block_off);
 	kunmap_atomic(hdr);
 
 	ploop_submit_index_wb_sync(ploop, piwb);
 	ret = blk_status_to_errno(piwb->bi_status);
+	if (!ret) {
+		/* Now update our cached page */
+		hdr = kmap_atomic(cmd->resize.md0->page);
+		hdr->m_Size = nr_be;
+		hdr->m_SizeInSectors_v2 = sectors;
+		hdr->m_FirstBlockOffset = offset;
+		kunmap_atomic(hdr);
+	}
 
 	ploop_reset_bat_update(piwb);
 	return ret;
@@ -463,7 +473,7 @@ static int ploop_resize(struct ploop *ploop, u64 new_size)
 	unsigned int hb_nr, size, cluster_log = ploop->cluster_log;
 	struct ploop_cmd cmd = { .resize.md_pages_root = RB_ROOT };
 	struct ploop_pvd_header *hdr;
-	struct md_page *md;
+	struct md_page *md0;
 	int ret = -ENOMEM;
 	u64 old_size;
 
@@ -472,12 +482,12 @@ static int ploop_resize(struct ploop *ploop, u64 new_size)
 	if (ploop_is_ro(ploop))
 		return -EROFS;
 
-	md = md_page_find(ploop, 0);
-	if (WARN_ON(!md))
+	md0 = md_page_find(ploop, 0);
+	if (WARN_ON(!md0))
 		return -EIO;
-	hdr = kmap(md->page);
+	hdr = kmap(md0->page);
 	old_size = le64_to_cpu(hdr->m_SizeInSectors_v2);
-	kunmap(md->page);
+	kunmap(md0->page);
 
 	if (old_size == new_size)
 		return 0;
@@ -528,6 +538,7 @@ static int ploop_resize(struct ploop *ploop, u64 new_size)
 	cmd.resize.nr_bat_entries = nr_bat_entries;
 	cmd.resize.hb_nr = hb_nr;
 	cmd.resize.new_size = new_size;
+	cmd.resize.md0 = md0;
 	cmd.retval = 0;
 	cmd.type = PLOOP_CMD_RESIZE;
 	cmd.ploop = ploop;
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index e2af133c45a2..466f1506741e 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -57,6 +57,7 @@ struct ploop_cmd {
 			u64 new_size;
 			/* Preallocated data */
 			struct rb_root md_pages_root;
+			struct md_page *md0;
 			void *holes_bitmap;
 #define PLOOP_GROW_STAGE_INITIAL	0
 			unsigned int stage;




More information about the Devel mailing list