]> git.hungrycats.org Git - linux/commit
btrfs: props: add per-inode compression level support
authorZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Fri, 7 Aug 2026 01:43:39 +0000 (21:43 -0400)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Wed, 16 Sep 2026 21:39:58 +0000 (17:39 -0400)
commit0b207d2b9a8a51b4a67ff5f451e1e46fb59bf1a2
treec30c7420f12972188d875249e4db90ec29b34a13
parent17ffaf03473925ff79b62345373b883d2f67b860
btrfs: props: add per-inode compression level support

Setting a per-file compression level is an often requested feature, and
the btrfs.compression property has silently accepted level suffixes
("zstd:9") since compression types were added to it:  the property
validator only matches the algorithm name prefix, the verbatim string is
stored in the xattr and returned by getxattr, and everything after the
algorithm name is ignored when the value is parsed into the in-memory
compression type.

All of the pieces needed to honor the level already exist:  the level is
a per-call argument down the whole compression path, per-inode levels
are already implemented for the defrag ioctl (defrag_compress_level),
and btrfs_compress_str2level() already parses and clamps ":level"
suffixes for the mount options.  Wire the property path up to them:

 * Cache the parsed level in a new btrfs_inode::prop_compress_level,
   with 0 meaning no level was specified, in which case the level from
   the mount options is used as before.  The field is signed to allow
   negative (realtime) zstd levels.

 * Parse an optional ":level" suffix in prop_compression_apply().
   Values stored by old kernels were never validated, so an unparseable
   suffix falls back to the default level rather than making the inode's
   properties fail to load.  Levels for lzo parse and clamp to nothing,
   matching commit 6db1df415d73 ("btrfs: accept and ignore compression
   level for lzo").

 * Use the level in compress_file_range() when compression is selected
   by the property.  The defrag ioctl retains precedence.

 * Regenerate the canonical "type:level" string with a new helper,
   btrfs_prop_compression_extract(), so that directory inheritance
   propagates the level to new inodes, and so that FS_IOC_SETFLAGS,
   which rewrites the property when setting FS_COMPR_FL, preserves the
   level instead of truncating the value to the bare algorithm name.
   The prop_handler extract hook itself is unchanged: it still returns
   a static string, and the inheritance loop regenerates the leveled
   value only for the compression property.

There is no disk format change:  the level lives in the already-existing
xattr value string.  Note that levels stored by old kernels (which were
accepted but ignored) become effective after this change.

Signed-off-by: Zygo Blaxell <ce3g8jdj@umail.furryterror.org>
Assisted-by: Claude:claude-fable-5
fs/btrfs/btrfs_inode.h
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/props.c
fs/btrfs/props.h