diff options
author | Konstantin Komarov <almaz.alexandrovich@paragon-software.com> | 2022-06-21 12:46:25 +0300 |
---|---|---|
committer | Konstantin Komarov <almaz.alexandrovich@paragon-software.com> | 2022-06-28 18:51:06 +0300 |
commit | aa30eccb24e5a66a2cf7f7b34a69c3651d12cc6a (patch) | |
tree | caf0c144d130dbdb142999b195f7212caed7dc3b /fs/ntfs3/run.c | |
parent | f759942b72a9ad309282b2fedcebcee3c4c58e24 (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.c | 43 |
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. */ |