[Devel] [PATCH RHEL8 COMMIT] ploop: Check next delta in stack not bigger then previous

Konstantin Khorenko khorenko at virtuozzo.com
Thu May 6 00:30:46 MSK 2021


The commit is pushed to "branch-rh8-4.18.0-240.1.1.vz8.5.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-240.1.1.vz8.5.26
------>
commit 03c6a6aeb35de6a3862e0e435b4e0986f53255ba
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date:   Thu May 6 00:30:46 2021 +0300

    ploop: Check next delta in stack not bigger then previous
    
    Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
    
    =====================
    Patchset description:
    
    ploop: Preparation to kill-loop from dm-ploop (series 2)
    
    Currently, ploop requires underlining loop for top delta. This is overkill,
    since we may submit bios directly to fs, without using it.
    
    Initially there was a possibility, we may use device-mapper format snapshots
    instead of ploop-based. But we don't do that, so we have to use loop for top
    delta and directly submit bios to the rest of deltas. So, these two ways to do
    the same actions are wrong.
    
    This is preparations #2 for further series.
    Let's this goes to testing earlier.
    
    Kirill Tkhai (4):
          ploop: Move ploop_add_delta() to another file
          ploop: Pass level directly in ploop_add_delta()
          ploop: Add deltas in normal order
          ploop: Check next delta in stack not bigger then previous
    
    https://jira.sw.ru/browse/PSBM-123654
    
    Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 drivers/md/dm-ploop-bat.c | 30 +++++++++++++++++++++---------
 drivers/md/dm-ploop.h     |  1 +
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/drivers/md/dm-ploop-bat.c b/drivers/md/dm-ploop-bat.c
index 45f651ce5549..c17f874fc25d 100644
--- a/drivers/md/dm-ploop-bat.c
+++ b/drivers/md/dm-ploop-bat.c
@@ -420,7 +420,7 @@ static void apply_delta_mappings(struct ploop *ploop, struct ploop_delta *deltas
 				 u32 level, void *hdr, u64 size_in_clus)
 {
 	map_index_t *bat_entries, *delta_bat_entries;
-	unsigned int i, end, dst_cluster;
+	unsigned int i, end, dst_cluster, clu;
 	struct rb_node *node;
 	struct md_page *md;
 	bool is_raw;
@@ -434,13 +434,16 @@ static void apply_delta_mappings(struct ploop *ploop, struct ploop_delta *deltas
 		init_bat_entries_iter(ploop, md->id, &i, &end);
 		bat_entries = kmap_atomic(md->page);
 		for (; i <= end; i++) {
+			clu = page_clu_idx_to_bat_clu(md->id, i);
+			if (clu >= size_in_clus)
+				goto unlock;
 			if (bat_entries[i] != BAT_ENTRY_NONE)
 				continue;
 
 			if (!is_raw)
 				dst_cluster = delta_bat_entries[i];
 			else {
-				dst_cluster = page_clu_idx_to_bat_clu(md->id, i);
+				dst_cluster = clu;
 				if (dst_cluster >= size_in_clus)
 					dst_cluster = BAT_ENTRY_NONE;
 			}
@@ -453,11 +456,12 @@ static void apply_delta_mappings(struct ploop *ploop, struct ploop_delta *deltas
 		kunmap_atomic(bat_entries);
 		delta_bat_entries += PAGE_SIZE / sizeof(map_index_t);
 	}
+unlock:
 	write_unlock_irq(&ploop->bat_rwlock);
 }
 
 static int ploop_check_delta_length(struct ploop *ploop, struct file *file,
-				    u64 *size_in_clus)
+				    u32 *size_in_clus)
 {
 	loff_t loff = i_size_read(file->f_mapping->host);
 	unsigned int cluster_log = ploop->cluster_log;
@@ -475,9 +479,9 @@ static int ploop_check_delta_length(struct ploop *ploop, struct file *file,
 int ploop_add_delta(struct ploop *ploop, u32 level, int fd, bool is_raw)
 {
 	struct ploop_delta *deltas = ploop->deltas;
+	struct ploop_pvd_header *hdr = NULL;
 	struct file *file;
-	u64 size_in_clus;
-	void *hdr = NULL;
+	u32 size_in_clus;
 	int ret;
 
 	file = fget(fd);
@@ -491,14 +495,22 @@ int ploop_add_delta(struct ploop *ploop, u32 level, int fd, bool is_raw)
 	if (ret)
 		goto out;
 
-	if (!is_raw)
-		ret = ploop_read_delta_metadata(ploop, file, &hdr);
-	if (ret)
+	if (!is_raw) {
+		ret = ploop_read_delta_metadata(ploop, file, (void *)&hdr);
+		if (ret)
+			goto out;
+		size_in_clus = le32_to_cpu(hdr->m_Size);
+	}
+
+	ret = -EBADSLT;
+	if (level != ploop->nr_deltas - 1 &&
+	    size_in_clus > deltas[level + 1].size_in_clus)
 		goto out;
 
-	apply_delta_mappings(ploop, deltas, level, hdr, size_in_clus);
+	apply_delta_mappings(ploop, deltas, level, (void *)hdr, size_in_clus);
 
 	deltas[level].file = file;
+	deltas[level].size_in_clus = size_in_clus;
 	deltas[level].is_raw = is_raw;
 	ret = 0;
 out:
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index 1eeac9ca064d..e21a0ab83378 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -34,6 +34,7 @@ struct ploop_pvd_header {
 
 struct ploop_delta {
 	struct file *file;
+	u32 size_in_clus;
 	bool is_raw;
 };
 


More information about the Devel mailing list