On Wed, 2022-07-13 at 19:46 +0300, Konstantin Komarov wrote: > Added comments to code > Added new function run_clone to make a copy of run > Added done and undo labels for restoring after errors trivia: > diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c [] > index 7bcae3094712..24d545041787 100644llocate_ex(struct ntfs_sb_info *sbi, struct runs_tree *run, > } > > if (lcn != SPARSE_LCN) { > - mark_as_free_ex(sbi, lcn, clen, trim); > + if (sbi) { > + /* mark bitmap range [lcn + clen) as free and trim clusters. */ presumably the brackets or parentheses [ ) should match [] > @@ -2091,69 +2098,91 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size) [] > + > + /* Make a hole range (sparse) [vcn1 + zero). */ here too > diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c [] > @@ -1157,3 +1157,28 @@ int run_get_highest_vcn(CLST vcn, const u8 *run_buf, u64 *highest_vcn) > *highest_vcn = vcn64 - 1; > return 0; > } > + > +/* > + * run_clone > + * > + * Make a copy of run > + */ > +int run_clone(const struct runs_tree *run, struct runs_tree *new_run) > +{ > + size_t bytes = run->count * sizeof(struct ntfs_run); > + > + if (bytes > new_run->allocated) { > + struct ntfs_run *new_ptr = kvmalloc(bytes, GFP_KERNEL); kvmalloc_array ? > + > + if (!new_ptr) > + return -ENOMEM; > + > + kvfree(new_run->runs); > + new_run->runs = new_ptr; > + new_run->allocated = bytes; > + } > + > + memcpy(new_run->runs, run->runs, bytes); > + new_run->count = run->count; > + return 0; > +}