summaryrefslogtreecommitdiff
path: root/fs/ntfs3/attrib.c
diff options
context:
space:
mode:
authorKonstantin Komarov <almaz.alexandrovich@paragon-software.com>2022-06-30 18:31:26 +0300
committerKonstantin Komarov <almaz.alexandrovich@paragon-software.com>2022-08-03 18:25:05 +0300
commit560f7736b94622c077344e2c541c43c63b4e90e4 (patch)
tree53384f06cb4b712b9cc14b85890f24a82b443e87 /fs/ntfs3/attrib.c
parent42f86b1226a42bfc79a7125af435432ad4680a32 (diff)
fs/ntfs3: Fix very fragmented case in attr_punch_hole
In some cases we need to ni_find_attr attr_b Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Diffstat (limited to 'fs/ntfs3/attrib.c')
-rw-r--r--fs/ntfs3/attrib.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c
index ad713f620155..3d64335fa4c7 100644
--- a/fs/ntfs3/attrib.c
+++ b/fs/ntfs3/attrib.c
@@ -2054,6 +2054,7 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
if (err)
goto out;
/* Layout of records maybe changed. */
+ attr_b = NULL;
}
}
/* Free all allocated memory. */
@@ -2073,6 +2074,14 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
}
total_size -= (u64)dealloc << sbi->cluster_bits;
+ if (!attr_b) {
+ attr_b = ni_find_attr(ni, NULL, NULL, ATTR_DATA, NULL, 0, NULL,
+ &mi_b);
+ if (!attr_b) {
+ err = -EINVAL;
+ goto out;
+ }
+ }
attr_b->nres.total_size = cpu_to_le64(total_size);
mi_b->dirty = true;
@@ -2083,8 +2092,10 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
out:
up_write(&ni->file.run_lock);
- if (err)
+ if (err) {
+ ntfs_set_state(sbi, NTFS_DIRTY_ERROR);
make_bad_inode(&ni->vfs_inode);
+ }
return err;
}