--- /dev/null
+From 0e852ab8974cd2b5946766b2d9baf82c78ace03d Mon Sep 17 00:00:00 2001
+From: Chung-Chiang Cheng <cccheng@synology.com>
+Date: Fri, 15 Apr 2022 16:04:06 +0800
+Subject: btrfs: do not allow compression on nodatacow files
+
+From: Chung-Chiang Cheng <cccheng@synology.com>
+
+commit 0e852ab8974cd2b5946766b2d9baf82c78ace03d upstream.
+
+Compression and nodatacow are mutually exclusive. A similar issue was
+fixed by commit f37c563bab429 ("btrfs: add missing check for nocow and
+compression inode flags"). Besides ioctl, there is another way to
+enable/disable/reset compression directly via xattr. The following
+steps will result in a invalid combination.
+
+ $ touch bar
+ $ chattr +C bar
+ $ lsattr bar
+ ---------------C-- bar
+ $ setfattr -n btrfs.compression -v zstd bar
+ $ lsattr bar
+ --------c------C-- bar
+
+To align with the logic in check_fsflags, nocompress will also be
+unacceptable after this patch, to prevent mix any compression-related
+options with nodatacow.
+
+ $ touch bar
+ $ chattr +C bar
+ $ lsattr bar
+ ---------------C-- bar
+ $ setfattr -n btrfs.compression -v zstd bar
+ setfattr: bar: Invalid argument
+ $ setfattr -n btrfs.compression -v no bar
+ setfattr: bar: Invalid argument
+
+When both compression and nodatacow are enabled, then
+btrfs_run_delalloc_range prefers nodatacow and no compression happens.
+
+Reported-by: Jayce Lin <jaycelin@synology.com>
+CC: stable@vger.kernel.org # 5.10.x: e6f9d6964802: btrfs: export a helper for compression hard check
+CC: stable@vger.kernel.org # 5.10.x
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Chung-Chiang Cheng <cccheng@synology.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/props.c | 16 +++++++++++-----
+ fs/btrfs/props.h | 3 ++-
+ fs/btrfs/xattr.c | 2 +-
+ 3 files changed, 14 insertions(+), 7 deletions(-)
+
+--- a/fs/btrfs/props.c
++++ b/fs/btrfs/props.c
+@@ -17,7 +17,8 @@ static DEFINE_HASHTABLE(prop_handlers_ht
+ struct prop_handler {
+ struct hlist_node node;
+ const char *xattr_name;
+- int (*validate)(const char *value, size_t len);
++ int (*validate)(const struct btrfs_inode *inode, const char *value,
++ size_t len);
+ int (*apply)(struct inode *inode, const char *value, size_t len);
+ const char *(*extract)(struct inode *inode);
+ int inheritable;
+@@ -55,7 +56,8 @@ find_prop_handler(const char *name,
+ return NULL;
+ }
+
+-int btrfs_validate_prop(const char *name, const char *value, size_t value_len)
++int btrfs_validate_prop(const struct btrfs_inode *inode, const char *name,
++ const char *value, size_t value_len)
+ {
+ const struct prop_handler *handler;
+
+@@ -69,7 +71,7 @@ int btrfs_validate_prop(const char *name
+ if (value_len == 0)
+ return 0;
+
+- return handler->validate(value, value_len);
++ return handler->validate(inode, value, value_len);
+ }
+
+ int btrfs_set_prop(struct btrfs_trans_handle *trans, struct inode *inode,
+@@ -252,8 +254,12 @@ int btrfs_load_inode_props(struct inode
+ return ret;
+ }
+
+-static int prop_compression_validate(const char *value, size_t len)
++static int prop_compression_validate(const struct btrfs_inode *inode,
++ const char *value, size_t len)
+ {
++ if (!btrfs_inode_can_compress(inode))
++ return -EINVAL;
++
+ if (!value)
+ return 0;
+
+@@ -364,7 +370,7 @@ static int inherit_props(struct btrfs_tr
+ * This is not strictly necessary as the property should be
+ * valid, but in case it isn't, don't propagate it further.
+ */
+- ret = h->validate(value, strlen(value));
++ ret = h->validate(BTRFS_I(inode), value, strlen(value));
+ if (ret)
+ continue;
+
+--- a/fs/btrfs/props.h
++++ b/fs/btrfs/props.h
+@@ -13,7 +13,8 @@ void __init btrfs_props_init(void);
+ int btrfs_set_prop(struct btrfs_trans_handle *trans, struct inode *inode,
+ const char *name, const char *value, size_t value_len,
+ int flags);
+-int btrfs_validate_prop(const char *name, const char *value, size_t value_len);
++int btrfs_validate_prop(const struct btrfs_inode *inode, const char *name,
++ const char *value, size_t value_len);
+
+ int btrfs_load_inode_props(struct inode *inode, struct btrfs_path *path);
+
+--- a/fs/btrfs/xattr.c
++++ b/fs/btrfs/xattr.c
+@@ -404,7 +404,7 @@ static int btrfs_xattr_handler_set_prop(
+ struct btrfs_root *root = BTRFS_I(inode)->root;
+
+ name = xattr_full_name(handler, name);
+- ret = btrfs_validate_prop(name, value, size);
++ ret = btrfs_validate_prop(BTRFS_I(inode), name, value, size);
+ if (ret)
+ return ret;
+
--- /dev/null
+From 193b4e83986d7ee6caa8ceefb5ee9f58240fbee0 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Thu, 21 Apr 2022 11:03:09 +0100
+Subject: btrfs: do not BUG_ON() on failure to update inode when setting xattr
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 193b4e83986d7ee6caa8ceefb5ee9f58240fbee0 upstream.
+
+We are doing a BUG_ON() if we fail to update an inode after setting (or
+clearing) a xattr, but there's really no reason to not instead simply
+abort the transaction and return the error to the caller. This should be
+a rare error because we have previously reserved enough metadata space to
+update the inode and the delayed inode should have already been setup, so
+an -ENOSPC or -ENOMEM, which are the possible errors, are very unlikely to
+happen.
+
+So replace the BUG_ON()s with a transaction abort.
+
+CC: stable@vger.kernel.org # 4.9+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: Anand Jain <anand.jain@oracle.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/xattr.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/xattr.c
++++ b/fs/btrfs/xattr.c
+@@ -262,7 +262,8 @@ int btrfs_setxattr_trans(struct inode *i
+ inode_inc_iversion(inode);
+ inode->i_ctime = current_time(inode);
+ ret = btrfs_update_inode(trans, root, BTRFS_I(inode));
+- BUG_ON(ret);
++ if (ret)
++ btrfs_abort_transaction(trans, ret);
+ out:
+ if (start_trans)
+ btrfs_end_transaction(trans);
+@@ -416,7 +417,8 @@ static int btrfs_xattr_handler_set_prop(
+ inode_inc_iversion(inode);
+ inode->i_ctime = current_time(inode);
+ ret = btrfs_update_inode(trans, root, BTRFS_I(inode));
+- BUG_ON(ret);
++ if (ret)
++ btrfs_abort_transaction(trans, ret);
+ }
+
+ btrfs_end_transaction(trans);
--- /dev/null
+From e6f9d69648029e48b8f97db09368d419b5e2614a Mon Sep 17 00:00:00 2001
+From: Chung-Chiang Cheng <cccheng@synology.com>
+Date: Fri, 15 Apr 2022 16:04:05 +0800
+Subject: btrfs: export a helper for compression hard check
+
+From: Chung-Chiang Cheng <cccheng@synology.com>
+
+commit e6f9d69648029e48b8f97db09368d419b5e2614a upstream.
+
+inode_can_compress will be used outside of inode.c to check the
+availability of setting compression flag by xattr. This patch moves
+this function as an internal helper and renames it to
+btrfs_inode_can_compress.
+
+Reviewed-by: Nikolay Borisov <nborisov@suse.com>
+Signed-off-by: Chung-Chiang Cheng <cccheng@synology.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/btrfs_inode.h | 11 +++++++++++
+ fs/btrfs/inode.c | 15 ++-------------
+ 2 files changed, 13 insertions(+), 13 deletions(-)
+
+--- a/fs/btrfs/btrfs_inode.h
++++ b/fs/btrfs/btrfs_inode.h
+@@ -346,6 +346,17 @@ static inline bool btrfs_inode_in_log(st
+ return ret;
+ }
+
++/*
++ * Check if the inode has flags compatible with compression
++ */
++static inline bool btrfs_inode_can_compress(const struct btrfs_inode *inode)
++{
++ if (inode->flags & BTRFS_INODE_NODATACOW ||
++ inode->flags & BTRFS_INODE_NODATASUM)
++ return false;
++ return true;
++}
++
+ struct btrfs_dio_private {
+ struct inode *inode;
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -486,17 +486,6 @@ static noinline int add_async_extent(str
+ }
+
+ /*
+- * Check if the inode has flags compatible with compression
+- */
+-static inline bool inode_can_compress(struct btrfs_inode *inode)
+-{
+- if (inode->flags & BTRFS_INODE_NODATACOW ||
+- inode->flags & BTRFS_INODE_NODATASUM)
+- return false;
+- return true;
+-}
+-
+-/*
+ * Check if the inode needs to be submitted to compression, based on mount
+ * options, defragmentation, properties or heuristics.
+ */
+@@ -505,7 +494,7 @@ static inline int inode_need_compress(st
+ {
+ struct btrfs_fs_info *fs_info = inode->root->fs_info;
+
+- if (!inode_can_compress(inode)) {
++ if (!btrfs_inode_can_compress(inode)) {
+ WARN(IS_ENABLED(CONFIG_BTRFS_DEBUG),
+ KERN_ERR "BTRFS: unexpected compression for ino %llu\n",
+ btrfs_ino(inode));
+@@ -2015,7 +2004,7 @@ int btrfs_run_delalloc_range(struct btrf
+ (zoned && btrfs_is_data_reloc_root(inode->root)));
+ ret = run_delalloc_nocow(inode, locked_page, start, end,
+ page_started, nr_written);
+- } else if (!inode_can_compress(inode) ||
++ } else if (!btrfs_inode_can_compress(inode) ||
+ !inode_need_compress(inode, start, end)) {
+ if (zoned)
+ ret = run_delalloc_zoned(inode, locked_page, start, end,
--- /dev/null
+From 9f73f1aef98b2fa7252c0a89be64840271ce8ea0 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Fri, 1 Apr 2022 15:29:37 +0800
+Subject: btrfs: force v2 space cache usage for subpage mount
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit 9f73f1aef98b2fa7252c0a89be64840271ce8ea0 upstream.
+
+[BUG]
+For a 4K sector sized btrfs with v1 cache enabled and only mounted on
+systems with 4K page size, if it's mounted on subpage (64K page size)
+systems, it can cause the following warning on v1 space cache:
+
+ BTRFS error (device dm-1): csum mismatch on free space cache
+ BTRFS warning (device dm-1): failed to load free space cache for block group 84082688, rebuilding it now
+
+Although not a big deal, as kernel can rebuild it without problem, such
+warning will bother end users, especially if they want to switch the
+same btrfs seamlessly between different page sized systems.
+
+[CAUSE]
+V1 free space cache is still using fixed PAGE_SIZE for various bitmap,
+like BITS_PER_BITMAP.
+
+Such hard-coded PAGE_SIZE usage will cause various mismatch, from v1
+cache size to checksum.
+
+Thus kernel will always reject v1 cache with a different PAGE_SIZE with
+csum mismatch.
+
+[FIX]
+Although we should fix v1 cache, it's already going to be marked
+deprecated soon.
+
+And we have v2 cache based on metadata (which is already fully subpage
+compatible), and it has almost everything superior than v1 cache.
+
+So just force subpage mount to use v2 cache on mount.
+
+Reported-by: Matt Corallo <blnxfsl@bluematt.me>
+CC: stable@vger.kernel.org # 5.15+
+Link: https://lore.kernel.org/linux-btrfs/61aa27d1-30fc-c1a9-f0f4-9df544395ec3@bluematt.me/
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/disk-io.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -3569,6 +3569,17 @@ int __cold open_ctree(struct super_block
+ if (sectorsize < PAGE_SIZE) {
+ struct btrfs_subpage_info *subpage_info;
+
++ /*
++ * V1 space cache has some hardcoded PAGE_SIZE usage, and is
++ * going to be deprecated.
++ *
++ * Force to use v2 cache for subpage case.
++ */
++ btrfs_clear_opt(fs_info->mount_opt, SPACE_CACHE);
++ btrfs_set_and_info(fs_info, FREE_SPACE_TREE,
++ "forcing free space tree for sector size %u with page size %lu",
++ sectorsize, PAGE_SIZE);
++
+ btrfs_warn(fs_info,
+ "read-write for sector size %u with page size %lu is experimental",
+ sectorsize, PAGE_SIZE);
--- /dev/null
+From 4b73c55fdebd8939f0f6000921075f7f6fa41397 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Thu, 21 Apr 2022 11:01:22 +0100
+Subject: btrfs: skip compression property for anything other than files and dirs
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 4b73c55fdebd8939f0f6000921075f7f6fa41397 upstream.
+
+The compression property only has effect on regular files and directories
+(so that it's propagated to files and subdirectories created inside a
+directory). For any other inode type (symlink, fifo, device, socket),
+it's pointless to set the compression property because it does nothing
+and ends up unnecessarily wasting leaf space due to the pointless xattr
+(75 or 76 bytes, depending on the compression value). Symlinks in
+particular are very common (for example, I have almost 10k symlinks under
+/etc, /usr and /var alone) and therefore it's worth to avoid wasting
+leaf space with the compression xattr.
+
+For example, the compression property can end up on a symlink or character
+device implicitly, through inheritance from a parent directory
+
+ $ mkdir /mnt/testdir
+ $ btrfs property set /mnt/testdir compression lzo
+
+ $ ln -s yadayada /mnt/testdir/lnk
+ $ mknod /mnt/testdir/dev c 0 0
+
+Or explicitly like this:
+
+ $ ln -s yadayda /mnt/lnk
+ $ setfattr -h -n btrfs.compression -v lzo /mnt/lnk
+
+So skip the compression property on inodes that are neither a regular
+file nor a directory.
+
+CC: stable@vger.kernel.org # 5.4+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/props.c | 43 +++++++++++++++++++++++++++++++++++++++++++
+ fs/btrfs/props.h | 1 +
+ fs/btrfs/xattr.c | 3 +++
+ 3 files changed, 47 insertions(+)
+
+--- a/fs/btrfs/props.c
++++ b/fs/btrfs/props.c
+@@ -21,6 +21,7 @@ struct prop_handler {
+ size_t len);
+ int (*apply)(struct inode *inode, const char *value, size_t len);
+ const char *(*extract)(struct inode *inode);
++ bool (*ignore)(const struct btrfs_inode *inode);
+ int inheritable;
+ };
+
+@@ -74,6 +75,28 @@ int btrfs_validate_prop(const struct btr
+ return handler->validate(inode, value, value_len);
+ }
+
++/*
++ * Check if a property should be ignored (not set) for an inode.
++ *
++ * @inode: The target inode.
++ * @name: The property's name.
++ *
++ * The caller must be sure the given property name is valid, for example by
++ * having previously called btrfs_validate_prop().
++ *
++ * Returns: true if the property should be ignored for the given inode
++ * false if the property must not be ignored for the given inode
++ */
++bool btrfs_ignore_prop(const struct btrfs_inode *inode, const char *name)
++{
++ const struct prop_handler *handler;
++
++ handler = find_prop_handler(name, NULL);
++ ASSERT(handler != NULL);
++
++ return handler->ignore(inode);
++}
++
+ int btrfs_set_prop(struct btrfs_trans_handle *trans, struct inode *inode,
+ const char *name, const char *value, size_t value_len,
+ int flags)
+@@ -316,6 +339,22 @@ static int prop_compression_apply(struct
+ return 0;
+ }
+
++static bool prop_compression_ignore(const struct btrfs_inode *inode)
++{
++ /*
++ * Compression only has effect for regular files, and for directories
++ * we set it just to propagate it to new files created inside them.
++ * Everything else (symlinks, devices, sockets, fifos) is pointless as
++ * it will do nothing, so don't waste metadata space on a compression
++ * xattr for anything that is neither a file nor a directory.
++ */
++ if (!S_ISREG(inode->vfs_inode.i_mode) &&
++ !S_ISDIR(inode->vfs_inode.i_mode))
++ return true;
++
++ return false;
++}
++
+ static const char *prop_compression_extract(struct inode *inode)
+ {
+ switch (BTRFS_I(inode)->prop_compress) {
+@@ -336,6 +375,7 @@ static struct prop_handler prop_handlers
+ .validate = prop_compression_validate,
+ .apply = prop_compression_apply,
+ .extract = prop_compression_extract,
++ .ignore = prop_compression_ignore,
+ .inheritable = 1
+ },
+ };
+@@ -362,6 +402,9 @@ static int inherit_props(struct btrfs_tr
+ if (!h->inheritable)
+ continue;
+
++ if (h->ignore(BTRFS_I(inode)))
++ continue;
++
+ value = h->extract(parent);
+ if (!value)
+ continue;
+--- a/fs/btrfs/props.h
++++ b/fs/btrfs/props.h
+@@ -15,6 +15,7 @@ int btrfs_set_prop(struct btrfs_trans_ha
+ int flags);
+ int btrfs_validate_prop(const struct btrfs_inode *inode, const char *name,
+ const char *value, size_t value_len);
++bool btrfs_ignore_prop(const struct btrfs_inode *inode, const char *name);
+
+ int btrfs_load_inode_props(struct inode *inode, struct btrfs_path *path);
+
+--- a/fs/btrfs/xattr.c
++++ b/fs/btrfs/xattr.c
+@@ -408,6 +408,9 @@ static int btrfs_xattr_handler_set_prop(
+ if (ret)
+ return ret;
+
++ if (btrfs_ignore_prop(BTRFS_I(inode), name))
++ return 0;
++
+ trans = btrfs_start_transaction(root, 2);
+ if (IS_ERR(trans))
+ return PTR_ERR(trans);
--- /dev/null
+From 3e1ad196385c65c1454aceab1226d9a4baca27d5 Mon Sep 17 00:00:00 2001
+From: David Sterba <dsterba@suse.com>
+Date: Tue, 3 May 2022 17:35:25 +0200
+Subject: btrfs: sysfs: export the balance paused state of exclusive operation
+
+From: David Sterba <dsterba@suse.com>
+
+commit 3e1ad196385c65c1454aceab1226d9a4baca27d5 upstream.
+
+The new state allowing device addition with paused balance is not
+exported to user space so it can't recognize it and actually start the
+operation.
+
+Fixes: efc0e69c2fea ("btrfs: introduce exclusive operation BALANCE_PAUSED state")
+CC: stable@vger.kernel.org # 5.17
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/sysfs.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/fs/btrfs/sysfs.c
++++ b/fs/btrfs/sysfs.c
+@@ -919,6 +919,9 @@ static ssize_t btrfs_exclusive_operation
+ case BTRFS_EXCLOP_BALANCE:
+ str = "balance\n";
+ break;
++ case BTRFS_EXCLOP_BALANCE_PAUSED:
++ str = "balance paused\n";
++ break;
+ case BTRFS_EXCLOP_DEV_ADD:
+ str = "device add\n";
+ break;
firewire-remove-check-of-list-iterator-against-head-past-the-loop-body.patch
firewire-core-extend-card-lock-in-fw_core_handle_bus_reset.patch
net-stmmac-disable-split-header-sph-for-intel-platforms.patch
+btrfs-sysfs-export-the-balance-paused-state-of-exclusive-operation.patch
+btrfs-force-v2-space-cache-usage-for-subpage-mount.patch
+btrfs-do-not-bug_on-on-failure-to-update-inode-when-setting-xattr.patch
+btrfs-export-a-helper-for-compression-hard-check.patch
+btrfs-do-not-allow-compression-on-nodatacow-files.patch
+btrfs-skip-compression-property-for-anything-other-than-files-and-dirs.patch