Update inode->i_mapping->a_ops when the compression state changes to ensure correct address space operations. Clear ATTR_FLAG_SPARSED/FILE_ATTRIBUTE_SPARSE_FILE when enabling compression to prevent flag conflicts. Fixes: 6b39bfaeec44 ("fs/ntfs3: Add support for the compression attribute") Reported-by: Kun Hu <huk23@xxxxxxxxxxxxxx>, Jiaji Qin <jjtan24@xxxxxxxxxxxxxx> Signed-off-by: Konstantin Komarov <almaz.alexandrovich@xxxxxxxxxxxxxxxxxxxx> --- fs/ntfs3/attrib.c | 1 + fs/ntfs3/file.c | 2 ++ fs/ntfs3/frecord.c | 6 ++++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c index af94e3737470..d2410ab6c7bf 100644 --- a/fs/ntfs3/attrib.c +++ b/fs/ntfs3/attrib.c @@ -2666,6 +2666,7 @@ int attr_set_compress(struct ntfs_inode *ni, bool compr) /* Update data attribute flags. */ if (compr) { + attr->flags &= ATTR_FLAG_SPARSED; attr->flags |= ATTR_FLAG_COMPRESSED; attr->nres.c_unit = NTFS_LZNT_CUNIT; } else { diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c index 3f96a11804c9..e8f452f47cd5 100644 --- a/fs/ntfs3/file.c +++ b/fs/ntfs3/file.c @@ -105,6 +105,8 @@ int ntfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry, int err = ni_set_compress(inode, flags & FS_COMPR_FL); if (err) return err; + inode->i_mapping->a_ops = + (flags & FS_COMPR_FL) ? &ntfs_aops_cmpr : &ntfs_aops; } inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND); diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c index 5df6a0b5add9..81271196c557 100644 --- a/fs/ntfs3/frecord.c +++ b/fs/ntfs3/frecord.c @@ -3434,10 +3434,12 @@ int ni_set_compress(struct inode *inode, bool compr) } ni->std_fa = std->fa; - if (compr) + if (compr) { + std->fa &= ~FILE_ATTRIBUTE_SPARSE_FILE; std->fa |= FILE_ATTRIBUTE_COMPRESSED; - else + } else { std->fa &= ~FILE_ATTRIBUTE_COMPRESSED; + } if (ni->std_fa != std->fa) { ni->std_fa = std->fa; -- 2.34.1