The commit is pushed to "branch-rh7-3.10.0-1127.18.2.vz7.163.x-ovz" and will 
appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1127.18.2.vz7.163.42
------>
commit 163d72f3dde897256ab957c24f02e308146dbfc9
Author: Kirill Tkhai <ktk...@virtuozzo.com>
Date:   Thu Oct 29 23:15:13 2020 +0300

    ploop: Preallocate clusters before nullifying on grow
    
    In case of future BAT clusters are data clusters and
    there is a hole, nullifying code fails since there is
    no extent. Fix that by future BAT preallocation.
    
    https://jira.sw.ru/browse/PSBM-121772
    Signed-off-by: Kirill Tkhai <ktk...@virtuozzo.com>
---
 drivers/block/ploop/fmt_ploop1.c |  8 ++++++++
 drivers/block/ploop/io_direct.c  | 26 ++++++++++++++++++++++++++
 include/linux/ploop/ploop.h      |  2 ++
 3 files changed, 36 insertions(+)

diff --git a/drivers/block/ploop/fmt_ploop1.c b/drivers/block/ploop/fmt_ploop1.c
index 4fad1ba..26e7001 100644
--- a/drivers/block/ploop/fmt_ploop1.c
+++ b/drivers/block/ploop/fmt_ploop1.c
@@ -10,6 +10,7 @@
 #include <linux/version.h>
 #include <linux/fs.h>
 #include <linux/file.h>
+#include <uapi/linux/falloc.h>
 
 #include <linux/ploop/ploop.h>
 #include "ploop1_image.h"
@@ -775,6 +776,13 @@ ploop1_prepare_grow(struct ploop_delta * delta, u64 
*new_size, int *reloc)
                delta->io.plo->grow_start = n_present;
                delta->io.plo->grow_end = n_needed - n_alloced - 1;
 
+               if (delta->io.ops->prepare_reloc) {
+                       err = delta->io.ops->prepare_reloc(&delta->io,
+                                       delta->io.plo->grow_start, *reloc);
+                       if (err)
+                               return err;
+               }
+
                /* Does not use rellocated data clusters during grow. */
                if (delta->holes_bitmap) {
                        i = delta->io.plo->grow_start;
diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c
index f67ce47..dff12e2 100644
--- a/drivers/block/ploop/io_direct.c
+++ b/drivers/block/ploop/io_direct.c
@@ -1666,6 +1666,31 @@ static int dio_start_merge(struct ploop_io * io, struct 
ploop_snapdata *sd)
        return 0;
 }
 
+/*
+ * There may be a hole in a place, which will be new BAT clusters
+ * after grow (before grow these clusters are data). Nullifying code
+ * expects there is no a hole, so we preallocate them here.
+ */
+static int dio_prepare_reloc(struct ploop_io *io, unsigned int start_clu,
+                            unsigned int nr)
+{
+       struct file *file = io->files.file;
+       int log = io->plo->cluster_log;
+       loff_t start, len;
+       int err;
+
+       start = start_clu << (log + 9);
+       len = nr << (log + 9);
+
+       err = file->f_op->fallocate(file, 0, start, len);
+       if (err)
+               return err;
+       err = file->f_op->fallocate(file, FALLOC_FL_CONVERT_UNWRITTEN,
+                                   start, len);
+       return err;
+
+}
+
 static void dio_unplug(struct ploop_io * io)
 {      
        /* Need more thinking how to implement unplug */
@@ -1802,6 +1827,7 @@ static struct ploop_io_ops ploop_io_ops_direct =
        .complete_snapshot =    dio_complete_snapshot,
        .io_prepare_merge =     dio_prepare_merge,
        .start_merge    =       dio_start_merge,
+       .prepare_reloc  =       dio_prepare_reloc,
        .truncate       =       dio_truncate,
 
        .queue_settings =       dio_queue_settings,
diff --git a/include/linux/ploop/ploop.h b/include/linux/ploop/ploop.h
index 16a3007..bffd83b 100644
--- a/include/linux/ploop/ploop.h
+++ b/include/linux/ploop/ploop.h
@@ -198,6 +198,8 @@ struct ploop_io_ops
        int     (*complete_snapshot)(struct ploop_io *, struct ploop_snapdata 
*);
        int     (*io_prepare_merge)(struct ploop_io *, struct ploop_snapdata *);
        int     (*start_merge)(struct ploop_io *, struct ploop_snapdata *);
+       int     (*prepare_reloc)(struct ploop_io *, unsigned int, unsigned int);
+
        int     (*truncate)(struct ploop_io *, struct file *, __u32 alloc_head);
        void    (*queue_settings)(struct ploop_io *, struct request_queue *q);
 
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to