From: Sam Ho <samho@synology.com>
To: clm@fb.com, dsterba@suse.com
Cc: linux-btrfs@vger.kernel.org, Sam Ho <samho@synology.com>
Subject: [PATCH] btrfs: preserve the compression property when other inode flags change
Date: Fri, 14 Aug 2026 05:14:06 +0000 [thread overview]
Message-ID: <20260814051406.1244006-1-samho@synology.com> (raw)
Setting the compression property on an inode also sets BTRFS_INODE_COMPRESS
on it, and btrfs_inode_flags_to_fsflags() reports that back as FS_COMPR_FL
to FS_IOC_GETFLAGS. chattr(1), like any other FS_IOC_SETFLAGS caller, reads
the current flags, flips only the bit the user asked for and writes the
whole set back, so a request as unrelated as "chattr +i" reaches
btrfs_fileattr_set() with FS_COMPR_FL set.
btrfs_fileattr_set() takes that as a request to enable compression and
overwrites the compression property with the algorithm from the mount
options, falling back to zlib when the filesystem was not mounted with
-o compress. The algorithm the user selected is silently replaced:
# btrfs property set /mnt/foo compression zstd
# btrfs property get /mnt/foo compression
compression=zstd
# chattr +i /mnt/foo
# btrfs property get /mnt/foo compression
compression=zlib
Every chattr operation triggers this, not just +i, and directories are
affected as well, so files created afterwards inherit the wrong algorithm
too. On a filesystem mounted with -o compress=lzo the property is replaced
with lzo instead. Recovering needs a chattr -i first, because the immutable
flag rejects the setxattr that "btrfs property set" issues.
Only pick the default algorithm when compression is actually being enabled
by this call, that is when FS_COMPR_FL was not set before, and otherwise
keep the algorithm recorded in the property. Inodes that have the compress
flag set but no property still get the default, so they behave as before.
Signed-off-by: Sam Ho <samho@synology.com>
---
fs/btrfs/ioctl.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index baa645e98812..2e54694f06f7 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -384,9 +384,25 @@ 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);
- if (!comp || comp[0] == 0)
- comp = btrfs_compress_type2str(BTRFS_COMPRESS_ZLIB);
+ /*
+ * If compression was already enabled, keep the algorithm that
+ * is recorded in the compression property. Otherwise changing
+ * an unrelated attribute would reset it to the mount default,
+ * since FS_IOC_SETFLAGS callers pass back the whole flag set
+ * they got from FS_IOC_GETFLAGS.
+ *
+ * Fall back to the default when compression is being enabled
+ * by this call, or when the inode has the compress flag set
+ * but no property, which is possible on filesystems touched by
+ * kernels that did not keep the two in sync.
+ */
+ if (old_fsflags & FS_COMPR_FL)
+ 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 {
inode_flags &= ~(BTRFS_INODE_COMPRESS | BTRFS_INODE_NOCOMPRESS);
}
--
2.34.1
Disclaimer: The contents of this e-mail message and any attachments are confidential and are intended solely for addressee. The information may also be legally privileged. This transmission is sent in trust, for the sole purpose of delivery to the intended recipient. If you have received this transmission in error, any use, reproduction or dissemination of this transmission is strictly prohibited. If you are not the intended recipient, please immediately notify the sender by reply e-mail or phone and delete this message and its attachments, if any.
next reply other threads:[~2026-08-14 5:21 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-14 5:14 Sam Ho [this message]
2026-08-14 8:58 ` [PATCH] btrfs: preserve the compression property when other inode flags change Qu Wenruo
2026-08-14 13:01 ` [PATCH v2] " Sam Ho
2026-08-14 22:08 ` Qu Wenruo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260814051406.1244006-1-samho@synology.com \
--to=samho@synology.com \
--cc=clm@fb.com \
--cc=dsterba@suse.com \
--cc=linux-btrfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox