]> git.hungrycats.org Git - linux/commitdiff
btrfs: preserve btrfs.compression when setting inode flags
authorZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Sun, 17 Aug 2025 02:50:20 +0000 (22:50 -0400)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Wed, 16 Sep 2026 21:39:58 +0000 (17:39 -0400)
Any call to FS_IOC_SETFLAGS (e.g. via chattr), even when no flag bits
change, and even for flags unrelated to compression, overwrites the
btrfs.compression property with the mount default compression type.

Example:

# mount ... -o compress=zstd ...
$ touch zero
$ setfattr -n btrfs.compression -v zlib zero
$ getfattr -n btrfs.compression zero | grep =
btrfs.compression="zlib"
$ lsattr zero
--------c------------- zero
$ chattr +A zero
$ lsattr zero
-------Ac------------- zero
$ getfattr -n btrfs.compression zero | grep =
btrfs.compression="zstd"

Here, `+A` modifies only the atime flag, but the compression property was
silently replaced.  The same happens even if the ioctl writes back the
same flags value that was already set.

The problem is that btrfs_fileattr_set unconditionally regenerates the
compression string from fs_info->compress_type (or falls back to "zlib")
and overwrites any existing property.

Fix this by first checking for an existing per-inode compression property
and using it if present.  Only fall back to fs_info->compress_type or zlib
when no property has been set.  This ensures that inode-flag updates no
longer clobber user-configured compression settings.

Fixes: 63541927c8d1 ("Btrfs: add support for inode properties")
Signed-off-by: Zygo Blaxell <ce3g8jdj@umail.furryterror.org>
fs/btrfs/ioctl.c

index b702f625c753bc6d0ba54c4b4aa3c43f395b3eca..5039db10a47e8a67c0ce4a2183e7672b1607f35f 100644 (file)
@@ -365,7 +365,9 @@ int btrfs_fileattr_set(struct mnt_idmap *idmap,
                inode_flags |= BTRFS_INODE_COMPRESS;
                inode_flags &= ~BTRFS_INODE_NOCOMPRESS;
 
-               comp = btrfs_compress_type2str(fs_info->compress_type);
+               comp = btrfs_compress_type2str(inode->prop_compress);
+               if (!comp || comp[0] == 0)
+                       comp = btrfs_compress_type2str(fs_info->compress_type);
                if (!comp || comp[0] == 0)
                        comp = btrfs_compress_type2str(BTRFS_COMPRESS_ZLIB);
        } else {