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 <ktk...@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; _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel