[Devel] [PATCH RH8 4/4] ploop: Check next delta in stack not bigger then previous
Kirill Tkhai
ktkhai at virtuozzo.com
Wed May 5 13:11:27 MSK 2021
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