[Devel] [PATCH RH7 1/2] ploop: Preallocate clusters before nullifying on grow
Kirill Tkhai
ktkhai at virtuozzo.com
Mon Oct 26 15:46:25 MSK 2020
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 <ktkhai at 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 99acad2d6994..316f62621c33 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 f67ce47e0562..dff12e2276bb 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 16a30076704a..bffd83b08764 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);
More information about the Devel
mailing list