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