The patch makes ploop use fallocate(0) to allocate new clus if this mode is enabled.
https://jira.sw.ru/browse/PSBM-106554 Signed-off-by: Kirill Tkhai <[email protected]> --- drivers/md/dm-ploop-map.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c index 30bb2c025653..dc68161d928e 100644 --- a/drivers/md/dm-ploop-map.c +++ b/drivers/md/dm-ploop-map.c @@ -537,6 +537,12 @@ static int punch_hole(struct file *file, loff_t pos, loff_t len) pos, len); } +static int zero_range(struct file *file, loff_t pos, loff_t len) +{ + return vfs_fallocate(file, FALLOC_FL_ZERO_RANGE|FALLOC_FL_KEEP_SIZE, + pos, len); +} + static void handle_discard_pio(struct ploop *ploop, struct pio *pio, u32 clu, u32 dst_clu) { @@ -924,19 +930,24 @@ static int find_dst_clu_bit(struct ploop *ploop, return 0; } -static int truncate_prealloc_safe(struct ploop_delta *delta, loff_t len, const char *func) +static int truncate_prealloc_safe(struct ploop *ploop, struct ploop_delta *delta, + loff_t len, const char *func) { struct file *file = delta->file; + loff_t old_len = delta->file_size; loff_t new_len = len; int ret; - if (new_len <= delta->file_size) + if (new_len <= old_len) return 0; new_len = ALIGN(new_len, PREALLOC_SIZE); - ret = vfs_truncate2(&file->f_path, new_len, file); + if (!ploop->falloc_new_clu) + ret = vfs_truncate2(&file->f_path, new_len, file); + else + ret = vfs_fallocate(file, 0, old_len, new_len - old_len); if (ret) { - pr_err("ploop: %s->truncate(): %d\n", func, ret); + pr_err("ploop: %s->prealloc: %d\n", func, ret); return ret; } @@ -969,22 +980,25 @@ static int allocate_cluster(struct ploop *ploop, u32 *dst_clu) 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 (!ploop->falloc_new_clu) + ret = punch_hole(file, pos, off - pos); + else + ret = zero_range(file, pos, off - pos); if (ret) { - pr_err("ploop: punch hole: %d\n", ret); + pr_err("ploop: punch/zero area: %d\n", ret); return ret; } } if (end > old_size) { - ret = truncate_prealloc_safe(top, end, __func__); + ret = truncate_prealloc_safe(ploop, 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. + * Flush punch_hole()/zero_range() modifications. + * TODO: track recentry unused blocks and do that + * in background. */ ret = vfs_fsync(file, 0); if (ret) _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
