This makes images size to update after delta metadata re-read
and also fixes algorithm of bat_entries[] assignment.

https://jira.sw.ru/browse/PSBM-132561
Signed-off-by: Kirill Tkhai <[email protected]>
---
 drivers/md/dm-ploop-cmd.c |   47 ++++++++++++++++++++++++++++++++++-----------
 1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/drivers/md/dm-ploop-cmd.c b/drivers/md/dm-ploop-cmd.c
index b9be80492eae..8e696ac2fcf4 100644
--- a/drivers/md/dm-ploop-cmd.c
+++ b/drivers/md/dm-ploop-cmd.c
@@ -709,28 +709,33 @@ static void notify_delta_merged(struct ploop *ploop, u8 
level,
                        if (clu == size_in_clus - 1)
                                stop = true;
 
-                       if (md_page_cluster_is_in_top_delta(ploop, md, i) ||
-                           d_bat_entries[i] == BAT_ENTRY_NONE ||
-                           md->bat_levels[i] < level)
-                               continue;
-
                        /* deltas above @level become renumbered */
-                       if (md->bat_levels[i] > level) {
+                       if (bat_entries[i] != BAT_ENTRY_NONE &&
+                           md->bat_levels[i] > level) {
                                md->bat_levels[i]--;
                                continue;
                        }
 
+                       if (bat_entries[i] != BAT_ENTRY_NONE &&
+                            md->bat_levels[i] < level)
+                               continue;
+
+                       if (d_bat_entries[i] == BAT_ENTRY_NONE) {
+                               WARN_ON_ONCE(bat_entries[i] != BAT_ENTRY_NONE);
+                               continue;
+                       }
+
                        /*
                         * clusters from deltas of @level become pointing to
                         * 1)next delta (which became renumbered) or
                         * 2)prev delta (if !@forward).
                         */
                        bat_entries[i] = d_bat_entries[i];
-                       WARN_ON(bat_entries[i] == BAT_ENTRY_NONE);
                        if (!forward)
-                               md->bat_levels[i]--;
+                               md->bat_levels[i] = level - 1;
+                       else
+                               md->bat_levels[i] = level;
                }
-
                kunmap_atomic(bat_entries);
                kunmap_atomic(d_bat_entries);
                if (stop)
@@ -742,7 +747,8 @@ static void notify_delta_merged(struct ploop *ploop, u8 
level,
        /* Renumber deltas above @level */
        for (i = level + 1; i < ploop->nr_deltas; i++)
                ploop->deltas[i - 1] = ploop->deltas[i];
-       ploop->deltas[--ploop->nr_deltas].file = NULL;
+       memset(&ploop->deltas[--ploop->nr_deltas], 0,
+              sizeof(struct ploop_delta));
        write_unlock_irq(&ploop->bat_rwlock);
        fput(file);
 }
@@ -780,24 +786,41 @@ static int process_update_delta_index(struct ploop 
*ploop, u8 level,
 static int ploop_delta_clusters_merged(struct ploop *ploop, u8 level,
                                       bool forward)
 {
+       struct ploop_delta *deltas = ploop->deltas;
        struct rb_root md_root = RB_ROOT;
        struct file *file;
+       loff_t file_size;
        u32 size_in_clus;
+       u8 changed_level;
        int ret;
 
        /* Reread BAT of deltas[@level + 1] (or [@level - 1]) */
-       file = ploop->deltas[level + forward ? 1 : -1].file;
+       changed_level = level + (forward ? 1 : -1);
+       file = deltas[changed_level].file;
+
+       ret = ploop_check_delta_length(ploop, file, &file_size);
+       if (ret)
+               goto out;
 
        ret = ploop_read_delta_metadata(ploop, file, &md_root, &size_in_clus);
        if (ret)
                goto out;
 
+       ret = -EFBIG;
+       if (changed_level != top_level(ploop) &&
+           size_in_clus > deltas[changed_level + 1].size_in_clus)
+               goto out;
+
        ret = ploop_suspend_submitting_pios(ploop);
        if (ret)
                goto out;
 
        notify_delta_merged(ploop, level, &md_root, forward, size_in_clus);
 
+       deltas[changed_level].file_size = file_size;
+       deltas[changed_level].file_preallocated_area_start = file_size;
+       deltas[changed_level].size_in_clus = size_in_clus;
+
        ploop_resume_submitting_pios(ploop);
        ret = 0;
 out:
@@ -813,6 +836,8 @@ static int ploop_notify_merged(struct ploop *ploop, u8 
level, bool forward)
                return -ENOENT;
        if (level == 0 && !forward)
                return -EINVAL;
+       if (level == 0 && ploop->deltas[0].is_raw)
+               return -ENOTSUPP;
        if (level == top_level(ploop) - 1 && forward)
                return -EINVAL;
        if (ploop->nr_deltas < 3)


_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to