diff options
| author | Namjae Jeon <linkinjeon@kernel.org> | 2026-07-13 16:49:57 +0900 |
|---|---|---|
| committer | Namjae Jeon <linkinjeon@kernel.org> | 2026-07-21 18:48:24 +0900 |
| commit | 4e646ecd44759e552b0b9ccd995f3f608daab414 (patch) | |
| tree | f1cbe99f34ef5aed50e592b93d452a7ab6cff7db | |
| parent | 8bed376124ab4505b70083a2b91f2c7ef6d51e24 (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.c | 10 |
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); |
