summaryrefslogtreecommitdiff
path: root/fs/ntfs3/run.c
diff options
context:
space:
mode:
authorKonstantin Komarov <almaz.alexandrovich@paragon-software.com>2022-06-21 12:46:25 +0300
committerKonstantin Komarov <almaz.alexandrovich@paragon-software.com>2022-06-28 18:51:06 +0300
commitaa30eccb24e5a66a2cf7f7b34a69c3651d12cc6a (patch)
treecaf0c144d130dbdb142999b195f7212caed7dc3b /fs/ntfs3/run.c
parentf759942b72a9ad309282b2fedcebcee3c4c58e24 (diff)
fs/ntfs3: Fallocate (FALLOC_FL_INSERT_RANGE) implementation
Add functions for inserting hole in file and inserting range in run. Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Diffstat (limited to 'fs/ntfs3/run.c')
-rw-r--r--fs/ntfs3/run.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
index a8fec651f973..7609d45a2d72 100644
--- a/fs/ntfs3/run.c
+++ b/fs/ntfs3/run.c
@@ -547,6 +547,49 @@ bool run_collapse_range(struct runs_tree *run, CLST vcn, CLST len)
return true;
}
+/* run_insert_range
+ *
+ * Helper for attr_insert_range(),
+ * which is helper for fallocate(insert_range).
+ */
+bool run_insert_range(struct runs_tree *run, CLST vcn, CLST len)
+{
+ size_t index;
+ struct ntfs_run *r, *e;
+
+ if (WARN_ON(!run_lookup(run, vcn, &index)))
+ return false; /* Should never be here. */
+
+ e = run->runs + run->count;
+ r = run->runs + index;
+
+ r = run->runs + index;
+ if (vcn > r->vcn)
+ r += 1;
+
+ for (; r < e; r++)
+ r->vcn += len;
+
+ r = run->runs + index;
+
+ if (vcn > r->vcn) {
+ /* split fragment. */
+ CLST len1 = vcn - r->vcn;
+ CLST len2 = r->len - len1;
+ CLST lcn2 = r->lcn == SPARSE_LCN ? SPARSE_LCN : (r->lcn + len1);
+
+ r->len = len1;
+
+ if (!run_add_entry(run, vcn + len, lcn2, len2, false))
+ return false;
+ }
+
+ if (!run_add_entry(run, vcn, SPARSE_LCN, len, false))
+ return false;
+
+ return true;
+}
+
/*
* run_get_entry - Return index-th mapped region.
*/