The commit is pushed to "branch-rh8-4.18.0-240.1.1.vz8.5.x-ovz" and will appear 
at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-240.1.1.vz8.5.31
------>
commit 1d7315311bdc046fcf0d002dbd23a97097d33f9e
Author: Kirill Tkhai <[email protected]>
Date:   Mon May 24 12:57:21 2021 +0300

    ploop: Extend file size from kernel
    
    Do not wait for userspace truncates file at max length.
    We do not need this, since there is no loop anymore.
    
    https://jira.sw.ru/browse/PSBM-129278
    Signed-off-by: Kirill Tkhai <[email protected]>
    
    =====================
    Patchset description:
    
    ploop: Truncate top delta from kernel
    
    and refactoring at tail.
    
    https://jira.sw.ru/browse/PSBM-129278
    
    Signed-off-by: Kirill Tkhai <[email protected]>
---
 drivers/md/dm-ploop-map.c | 80 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 77 insertions(+), 3 deletions(-)

diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index 6504eb6fdfe3..6c0153218124 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -9,6 +9,8 @@
 #include <uapi/linux/falloc.h>
 #include "dm-ploop.h"
 
+#define PREALLOC_SIZE (128ULL * 1024 * 1024)
+
 /*
  * The idea of this driver is that the most part of time it does nothing:
  * ploop_map() just replaces bio->bi_iter.bi_sector with the cluster value
@@ -894,10 +896,76 @@ static int find_dst_cluster_bit(struct ploop *ploop,
        return 0;
 }
 
+static int truncate_prealloc_safe(struct ploop_delta *delta, loff_t len, const 
char *func)
+{
+       struct file *file = delta->file;
+       loff_t new_len = len;
+       int ret;
+
+       if (new_len <= delta->file_size)
+               return 0;
+       new_len = ALIGN(new_len, PREALLOC_SIZE);
+
+       ret = vfs_truncate(&file->f_path, new_len);
+       if (ret) {
+               pr_err("ploop: %s->truncate(): %d\n", func, ret);
+               return ret;
+       }
+
+       ret = vfs_fsync(file, 0);
+       if (ret) {
+               pr_err("ploop: %s->fsync(): %d\n", func, ret);
+               return ret;
+       }
+
+       delta->file_size = new_len;
+       delta->file_preallocated_area_start = len;
+       return 0;
+}
+
 static int allocate_cluster(struct ploop *ploop, unsigned int *dst_cluster)
 {
+       struct ploop_delta *top = top_delta(ploop);
+       u32 cluster_log = ploop->cluster_log;
+       u32 clu_size = to_bytes(1 << cluster_log);
+       loff_t off, pos, end, old_size;
+       struct file *file = top->file;
+       int ret;
+
        if (find_dst_cluster_bit(ploop, dst_cluster) < 0)
                return -EIO;
+
+       pos = to_bytes(*dst_cluster << cluster_log);
+       end = pos + clu_size;
+       old_size = top->file_size;
+
+       if (pos < top->file_preallocated_area_start) {
+               /* Clu at @pos may contain dirty data */
+               off = min_t(loff_t, old_size, end);
+               ret = punch_hole(file, pos, off - pos);
+               if (ret) {
+                       pr_err("ploop: punch hole: %d\n", ret);
+                       return ret;
+               }
+       }
+
+       if (end > old_size) {
+               ret = truncate_prealloc_safe(top, end, __func__);
+               if (ret)
+                       return ret;
+       } else if (pos < top->file_preallocated_area_start) {
+               /*
+                * Flush punch_hole() modifications.
+                * TODO: track recentry unused blocks
+                * and punch holes in background.
+                */
+               ret = vfs_fsync(file, 0);
+               if (ret)
+                       return ret;
+       }
+
+       if (end > top->file_preallocated_area_start)
+               top->file_preallocated_area_start = end;
        /*
         * Mark cluster as used. Find & clear bit is unlocked,
         * since currently this may be called only from deferred
@@ -915,6 +983,7 @@ static int ploop_alloc_cluster(struct ploop *ploop, struct 
ploop_index_wb *piwb,
                               unsigned int cluster, unsigned int *dst_cluster)
 {
        struct page *page = piwb->bat_page;
+       bool already_alloced = false;
        map_index_t *to;
        int ret = 0;
 
@@ -925,17 +994,22 @@ static int ploop_alloc_cluster(struct ploop *ploop, 
struct ploop_index_wb *piwb,
        if (to[cluster]) {
                /* Already mapped by one of previous bios */
                *dst_cluster = to[cluster];
-               goto unmap;
+               already_alloced = true;
        }
+       kunmap_atomic(to);
+
+       if (already_alloced)
+               goto out;
 
        if (allocate_cluster(ploop, dst_cluster) < 0) {
                ret = -EIO;
-               goto unmap;
+               goto out;
        }
 
+       to = kmap_atomic(page);
        to[cluster] = *dst_cluster;
-unmap:
        kunmap_atomic(to);
+out:
        return ret;
 }
 
_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to