fs/ntfs3: remove ability to change compression on mounted volume
authorKonstantin Komarov <almaz.alexandrovich@paragon-software.com>
Mon, 19 May 2025 09:07:07 +0000 (11:07 +0200)
committerKonstantin Komarov <almaz.alexandrovich@paragon-software.com>
Mon, 19 May 2025 09:17:33 +0000 (11:17 +0200)
Remove all the code related to changing compression on the fly because
it's not safe and not maintainable.

Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
fs/ntfs3/attrib.c
fs/ntfs3/file.c
fs/ntfs3/frecord.c
fs/ntfs3/namei.c
fs/ntfs3/ntfs_fs.h

index e946f75..eced901 100644 (file)
@@ -2605,75 +2605,3 @@ int attr_force_nonresident(struct ntfs_inode *ni)
 
        return err;
 }
-
-/*
- * Change the compression of data attribute
- */
-int attr_set_compress(struct ntfs_inode *ni, bool compr)
-{
-       struct ATTRIB *attr;
-       struct mft_inode *mi;
-
-       attr = ni_find_attr(ni, NULL, NULL, ATTR_DATA, NULL, 0, NULL, &mi);
-       if (!attr)
-               return -ENOENT;
-
-       if (is_attr_compressed(attr) == !!compr) {
-               /* Already required compressed state. */
-               return 0;
-       }
-
-       if (attr->non_res) {
-               u16 run_off;
-               u32 run_size;
-               char *run;
-
-               if (attr->nres.data_size) {
-                       /*
-                        * There are rare cases when it possible to change
-                        * compress state without big changes.
-                        * TODO: Process these cases.
-                        */
-                       return -EOPNOTSUPP;
-               }
-
-               run_off = le16_to_cpu(attr->nres.run_off);
-               run_size = le32_to_cpu(attr->size) - run_off;
-               run = Add2Ptr(attr, run_off);
-
-               if (!compr) {
-                       /* remove field 'attr->nres.total_size'. */
-                       memmove(run - 8, run, run_size);
-                       run_off -= 8;
-               }
-
-               if (!mi_resize_attr(mi, attr, compr ? +8 : -8)) {
-                       /*
-                        * Ignore rare case when there are no 8 bytes in record with attr.
-                        * TODO: split attribute.
-                        */
-                       return -EOPNOTSUPP;
-               }
-
-               if (compr) {
-                       /* Make a gap for 'attr->nres.total_size'. */
-                       memmove(run + 8, run, run_size);
-                       run_off += 8;
-                       attr->nres.total_size = attr->nres.alloc_size;
-               }
-               attr->nres.run_off = cpu_to_le16(run_off);
-       }
-
-       /* Update attribute flags. */
-       if (compr) {
-               attr->flags &= ~ATTR_FLAG_SPARSED;
-               attr->flags |= ATTR_FLAG_COMPRESSED;
-               attr->nres.c_unit = NTFS_LZNT_CUNIT;
-       } else {
-               attr->flags &= ~ATTR_FLAG_COMPRESSED;
-               attr->nres.c_unit = 0;
-       }
-       mi->dirty = true;
-
-       return 0;
-}
index 9b6a3f8..34ed242 100644 (file)
@@ -49,90 +49,6 @@ static int ntfs_ioctl_fitrim(struct ntfs_sb_info *sbi, unsigned long arg)
        return 0;
 }
 
-/*
- * ntfs_fileattr_get - inode_operations::fileattr_get
- */
-int ntfs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
-{
-       struct inode *inode = d_inode(dentry);
-       struct ntfs_inode *ni = ntfs_i(inode);
-       u32 flags = 0;
-
-       if (inode->i_flags & S_IMMUTABLE)
-               flags |= FS_IMMUTABLE_FL;
-
-       if (inode->i_flags & S_APPEND)
-               flags |= FS_APPEND_FL;
-
-       if (is_compressed(ni))
-               flags |= FS_COMPR_FL;
-
-       if (is_encrypted(ni))
-               flags |= FS_ENCRYPT_FL;
-
-       fileattr_fill_flags(fa, flags);
-
-       return 0;
-}
-
-/*
- * ntfs_fileattr_set - inode_operations::fileattr_set
- */
-int ntfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry,
-                     struct fileattr *fa)
-{
-       struct inode *inode = d_inode(dentry);
-       struct ntfs_inode *ni = ntfs_i(inode);
-       u32 flags = fa->flags;
-       unsigned int new_fl = 0;
-
-       if (fileattr_has_fsx(fa))
-               return -EOPNOTSUPP;
-
-       if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_COMPR_FL))
-               return -EOPNOTSUPP;
-
-       if (flags & FS_IMMUTABLE_FL)
-               new_fl |= S_IMMUTABLE;
-
-       if (flags & FS_APPEND_FL)
-               new_fl |= S_APPEND;
-
-       /* Allowed to change compression for empty files and for directories only. */
-       if (!is_dedup(ni) && !is_encrypted(ni) &&
-           (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
-               int err = 0;
-               struct address_space *mapping = inode->i_mapping;
-
-               /* write out all data and wait. */
-               filemap_invalidate_lock(mapping);
-               err = filemap_write_and_wait(mapping);
-
-               if (err >= 0) {
-                       /* Change compress state. */
-                       bool compr = flags & FS_COMPR_FL;
-                       err = ni_set_compress(inode, compr);
-
-                       /* For files change a_ops too. */
-                       if (!err)
-                               mapping->a_ops = compr ? &ntfs_aops_cmpr :
-                                                        &ntfs_aops;
-               }
-
-               filemap_invalidate_unlock(mapping);
-
-               if (err)
-                       return err;
-       }
-
-       inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND);
-
-       inode_set_ctime_current(inode);
-       mark_inode_dirty(inode);
-
-       return 0;
-}
-
 /*
  * ntfs_ioctl - file_operations::unlocked_ioctl
  */
@@ -430,7 +346,6 @@ static int ntfs_extend(struct inode *inode, loff_t pos, size_t count,
        }
 
        if (extend_init && !is_compressed(ni)) {
-               WARN_ON(ni->i_valid >= pos);
                err = ntfs_extend_initialized_size(file, ni, ni->i_valid, pos);
                if (err)
                        goto out;
@@ -1409,8 +1324,6 @@ const struct inode_operations ntfs_file_inode_operations = {
        .get_acl        = ntfs_get_acl,
        .set_acl        = ntfs_set_acl,
        .fiemap         = ntfs_fiemap,
-       .fileattr_get   = ntfs_fileattr_get,
-       .fileattr_set   = ntfs_fileattr_set,
 };
 
 const struct file_operations ntfs_file_operations = {
index b7a8320..756e130 100644 (file)
@@ -3327,77 +3327,3 @@ out:
 
        return 0;
 }
-
-/*
- * ni_set_compress
- *
- * Helper for 'ntfs_fileattr_set'.
- * Changes compression for empty files and directories only.
- */
-int ni_set_compress(struct inode *inode, bool compr)
-{
-       int err;
-       struct ntfs_inode *ni = ntfs_i(inode);
-       struct ATTR_STD_INFO *std;
-       const char *bad_inode;
-
-       if (is_compressed(ni) == !!compr)
-               return 0;
-
-       if (is_sparsed(ni)) {
-               /* sparse and compress not compatible. */
-               return -EOPNOTSUPP;
-       }
-
-       if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) {
-               /*Skip other inodes. (symlink,fifo,...) */
-               return -EOPNOTSUPP;
-       }
-
-       bad_inode = NULL;
-
-       ni_lock(ni);
-
-       std = ni_std(ni);
-       if (!std) {
-               bad_inode = "no std";
-               goto out;
-       }
-
-       if (S_ISREG(inode->i_mode)) {
-               err = attr_set_compress(ni, compr);
-               if (err) {
-                       if (err == -ENOENT) {
-                               /* Fix on the fly? */
-                               /* Each file must contain data attribute. */
-                               bad_inode = "no data attribute";
-                       }
-                       goto out;
-               }
-       }
-
-       ni->std_fa = std->fa;
-       if (compr) {
-               std->fa &= ~FILE_ATTRIBUTE_SPARSE_FILE;
-               std->fa |= FILE_ATTRIBUTE_COMPRESSED;
-       } else {
-               std->fa &= ~FILE_ATTRIBUTE_COMPRESSED;
-       }
-
-       if (ni->std_fa != std->fa) {
-               ni->std_fa = std->fa;
-               ni->mi.dirty = true;
-       }
-       /* update duplicate information and directory entries in ni_write_inode.*/
-       ni->ni_flags |= NI_FLAG_UPDATE_PARENT;
-       err = 0;
-
-out:
-       ni_unlock(ni);
-       if (bad_inode) {
-               ntfs_bad_inode(inode, bad_inode);
-               err = -EINVAL;
-       }
-
-       return err;
-}
index 652735a..b807744 100644 (file)
@@ -507,8 +507,6 @@ const struct inode_operations ntfs_dir_inode_operations = {
        .getattr        = ntfs_getattr,
        .listxattr      = ntfs_listxattr,
        .fiemap         = ntfs_fiemap,
-       .fileattr_get   = ntfs_fileattr_get,
-       .fileattr_set   = ntfs_fileattr_set,
 };
 
 const struct inode_operations ntfs_special_inode_operations = {
index d628977..36b8052 100644 (file)
@@ -454,7 +454,6 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes);
 int attr_insert_range(struct ntfs_inode *ni, u64 vbo, u64 bytes);
 int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size);
 int attr_force_nonresident(struct ntfs_inode *ni);
-int attr_set_compress(struct ntfs_inode *ni, bool compr);
 
 /* Functions from attrlist.c */
 void al_destroy(struct ntfs_inode *ni);
@@ -497,9 +496,6 @@ extern const struct file_operations ntfs_dir_operations;
 extern const struct file_operations ntfs_legacy_dir_operations;
 
 /* Globals from file.c */
-int ntfs_fileattr_get(struct dentry *dentry, struct fileattr *fa);
-int ntfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry,
-                     struct fileattr *fa);
 int ntfs_getattr(struct mnt_idmap *idmap, const struct path *path,
                 struct kstat *stat, u32 request_mask, u32 flags);
 int ntfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
@@ -585,7 +581,6 @@ int ni_rename(struct ntfs_inode *dir_ni, struct ntfs_inode *new_dir_ni,
              bool *is_bad);
 
 bool ni_is_dirty(struct inode *inode);
-int ni_set_compress(struct inode *inode, bool compr);
 
 /* Globals from fslog.c */
 bool check_index_header(const struct INDEX_HDR *hdr, size_t bytes);