From: Greg Kroah-Hartman Date: Mon, 9 May 2022 14:36:27 +0000 (+0200) Subject: 5.15-stable patches X-Git-Tag: v4.9.313~52 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=57398a61773d00db1c494ea277919a6d672a71fa;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: btrfs-always-log-symlinks-in-full-mode.patch btrfs-force-v2-space-cache-usage-for-subpage-mount.patch --- diff --git a/queue-5.15/btrfs-always-log-symlinks-in-full-mode.patch b/queue-5.15/btrfs-always-log-symlinks-in-full-mode.patch new file mode 100644 index 00000000000..6121065fb52 --- /dev/null +++ b/queue-5.15/btrfs-always-log-symlinks-in-full-mode.patch @@ -0,0 +1,89 @@ +From d0e64a981fd841cb0f28fcd6afcac55e6f1e6994 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Thu, 21 Apr 2022 10:56:39 +0100 +Subject: btrfs: always log symlinks in full mode + +From: Filipe Manana + +commit d0e64a981fd841cb0f28fcd6afcac55e6f1e6994 upstream. + +On Linux, empty symlinks are invalid, and attempting to create one with +the system call symlink(2) results in an -ENOENT error and this is +explicitly documented in the man page. + +If we rename a symlink that was created in the current transaction and its +parent directory was logged before, we actually end up logging the symlink +without logging its content, which is stored in an inline extent. That +means that after a power failure we can end up with an empty symlink, +having no content and an i_size of 0 bytes. + +It can be easily reproduced like this: + + $ mkfs.btrfs -f /dev/sdc + $ mount /dev/sdc /mnt + + $ mkdir /mnt/testdir + $ sync + + # Create a file inside the directory and fsync the directory. + $ touch /mnt/testdir/foo + $ xfs_io -c "fsync" /mnt/testdir + + # Create a symlink inside the directory and then rename the symlink. + $ ln -s /mnt/testdir/foo /mnt/testdir/bar + $ mv /mnt/testdir/bar /mnt/testdir/baz + + # Now fsync again the directory, this persist the log tree. + $ xfs_io -c "fsync" /mnt/testdir + + + + $ mount /dev/sdc /mnt + $ stat -c %s /mnt/testdir/baz + 0 + $ readlink /mnt/testdir/baz + $ + +Fix this by always logging symlinks in full mode (LOG_INODE_ALL), so that +their content is also logged. + +A test case for fstests will follow. + +CC: stable@vger.kernel.org # 4.9+ +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/tree-log.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -5484,6 +5484,18 @@ static int btrfs_log_inode(struct btrfs_ + } + + /* ++ * For symlinks, we must always log their content, which is stored in an ++ * inline extent, otherwise we could end up with an empty symlink after ++ * log replay, which is invalid on linux (symlink(2) returns -ENOENT if ++ * one attempts to create an empty symlink). ++ * We don't need to worry about flushing delalloc, because when we create ++ * the inline extent when the symlink is created (we never have delalloc ++ * for symlinks). ++ */ ++ if (S_ISLNK(inode->vfs_inode.i_mode)) ++ inode_only = LOG_INODE_ALL; ++ ++ /* + * This is for cases where logging a directory could result in losing a + * a file after replaying the log. For example, if we move a file from a + * directory A to a directory B, then fsync directory A, we have no way +@@ -5853,7 +5865,7 @@ process_leaf: + } + + ctx->log_new_dentries = false; +- if (type == BTRFS_FT_DIR || type == BTRFS_FT_SYMLINK) ++ if (type == BTRFS_FT_DIR) + log_mode = LOG_INODE_ALL; + ret = btrfs_log_inode(trans, root, BTRFS_I(di_inode), + log_mode, ctx); diff --git a/queue-5.15/btrfs-force-v2-space-cache-usage-for-subpage-mount.patch b/queue-5.15/btrfs-force-v2-space-cache-usage-for-subpage-mount.patch new file mode 100644 index 00000000000..6d9fdc8a931 --- /dev/null +++ b/queue-5.15/btrfs-force-v2-space-cache-usage-for-subpage-mount.patch @@ -0,0 +1,71 @@ +From 9f73f1aef98b2fa7252c0a89be64840271ce8ea0 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Fri, 1 Apr 2022 15:29:37 +0800 +Subject: btrfs: force v2 space cache usage for subpage mount + +From: Qu Wenruo + +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 +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 +Signed-off-by: Qu Wenruo +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/disk-io.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -3415,6 +3415,17 @@ int __cold open_ctree(struct super_block + } + + if (sectorsize != PAGE_SIZE) { ++ /* ++ * 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); diff --git a/queue-5.15/series b/queue-5.15/series index 47491a0a738..b0b8c62db92 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -77,3 +77,5 @@ bnxt_en-fix-possible-bnxt_open-failure-caused-by-wrong-rfs-flag.patch bnxt_en-fix-unnecessary-dropping-of-rx-packets.patch selftests-ocelot-tc_flower_chains-specify-conform-exceed-action-for-policer.patch smsc911x-allow-using-irq0.patch +btrfs-force-v2-space-cache-usage-for-subpage-mount.patch +btrfs-always-log-symlinks-in-full-mode.patch