summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamjae Jeon <linkinjeon@kernel.org>2026-07-13 16:49:57 +0900
committerNamjae Jeon <linkinjeon@kernel.org>2026-07-21 18:48:24 +0900
commit4e646ecd44759e552b0b9ccd995f3f608daab414 (patch)
treef1cbe99f34ef5aed50e592b93d452a7ab6cff7db
parent8bed376124ab4505b70083a2b91f2c7ef6d51e24 (diff)
ntfs: drop stale page-cache when shrinking a non-resident attr
ntfs_non_resident_attr_shrink() shrinks attribute sizes but fails to trim the page cache. This leaves orphaned dirty folios beyond the new end of the attribute, leading to writeback failures (-ENOENT), data loss, and $EA chain corruption. Fix this by truncating the page cache to the new size immediately after updating the sizes, preventing writeback from flushing out-of-range folios. Fixes: 495e90fa3348 ("ntfs: update attrib operations") Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
-rw-r--r--fs/ntfs/attrib.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 239b7bcbaedf..58f32aac5f61 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -4293,6 +4293,16 @@ static int ntfs_non_resident_attr_shrink(struct ntfs_inode *ni, const s64 newsiz
ni->initialized_size = newsize;
ctx->attr->data.non_resident.initialized_size = cpu_to_le64(newsize);
}
+
+ /*
+ * Drop any page-cache folios that now lie beyond the shrunk
+ * attribute. The clusters backing them have just been freed and the
+ * runlist truncated, so leaving stale dirty folios around makes a
+ * later writeback map a vcn past the new allocation, which fails with
+ * -ENOENT and loses the write.
+ */
+ truncate_inode_pages(VFS_I(ni)->i_mapping, newsize);
+
/* Update data size in the index. */
if (ni->type == AT_DATA && ni->name == AT_UNNAMED)
NInoSetFileNameDirty(ni);