From 9305ee44e25b5ca8cdba4dbfe98d395039b45344 Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Sat, 16 Aug 2025 22:50:20 -0400 Subject: [PATCH] btrfs: preserve btrfs.compression when setting inode flags 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 --- fs/btrfs/ioctl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index b702f625c753b..5039db10a47e8 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -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 { -- 2.53.0