aboutsummaryrefslogtreecommitdiffstats
diff options
-rw-r--r--queue-5.15/arm64-restrict-pagetable-teardown-to-avoid-false-warning.patch46
-rw-r--r--queue-5.15/btrfs-don-t-drop-extent_map-for-free-space-inode-on-write-error.patch97
-rw-r--r--queue-5.15/series2
3 files changed, 145 insertions, 0 deletions
diff --git a/queue-5.15/arm64-restrict-pagetable-teardown-to-avoid-false-warning.patch b/queue-5.15/arm64-restrict-pagetable-teardown-to-avoid-false-warning.patch
new file mode 100644
index 0000000000..2ea4fe9d32
--- /dev/null
+++ b/queue-5.15/arm64-restrict-pagetable-teardown-to-avoid-false-warning.patch
@@ -0,0 +1,46 @@
+From 650768c512faba8070bf4cfbb28c95eb5cd203f3 Mon Sep 17 00:00:00 2001
+From: Dev Jain <dev.jain@arm.com>
+Date: Tue, 27 May 2025 13:56:33 +0530
+Subject: arm64: Restrict pagetable teardown to avoid false warning
+
+From: Dev Jain <dev.jain@arm.com>
+
+commit 650768c512faba8070bf4cfbb28c95eb5cd203f3 upstream.
+
+Commit 9c006972c3fe ("arm64: mmu: drop pXd_present() checks from
+pXd_free_pYd_table()") removes the pxd_present() checks because the
+caller checks pxd_present(). But, in case of vmap_try_huge_pud(), the
+caller only checks pud_present(); pud_free_pmd_page() recurses on each
+pmd through pmd_free_pte_page(), wherein the pmd may be none. Thus it is
+possible to hit a warning in the latter, since pmd_none => !pmd_table().
+Thus, add a pmd_present() check in pud_free_pmd_page().
+
+This problem was found by code inspection.
+
+Fixes: 9c006972c3fe ("arm64: mmu: drop pXd_present() checks from pXd_free_pYd_table()")
+Cc: stable@vger.kernel.org
+Reported-by: Ryan Roberts <ryan.roberts@arm.com>
+Acked-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Dev Jain <dev.jain@arm.com>
+Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
+Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
+Link: https://lore.kernel.org/r/20250527082633.61073-1-dev.jain@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/mm/mmu.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/mm/mmu.c
++++ b/arch/arm64/mm/mmu.c
+@@ -1466,7 +1466,8 @@ int pud_free_pmd_page(pud_t *pudp, unsig
+ next = addr;
+ end = addr + PUD_SIZE;
+ do {
+- pmd_free_pte_page(pmdp, next);
++ if (pmd_present(READ_ONCE(*pmdp)))
++ pmd_free_pte_page(pmdp, next);
+ } while (pmdp++, next += PMD_SIZE, next != end);
+
+ pud_clear(pudp);
diff --git a/queue-5.15/btrfs-don-t-drop-extent_map-for-free-space-inode-on-write-error.patch b/queue-5.15/btrfs-don-t-drop-extent_map-for-free-space-inode-on-write-error.patch
new file mode 100644
index 0000000000..c4d8d00352
--- /dev/null
+++ b/queue-5.15/btrfs-don-t-drop-extent_map-for-free-space-inode-on-write-error.patch
@@ -0,0 +1,97 @@
+From 5571e41ec6e56e35f34ae9f5b3a335ef510e0ade Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Wed, 31 Jan 2024 14:27:25 -0500
+Subject: btrfs: don't drop extent_map for free space inode on write error
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit 5571e41ec6e56e35f34ae9f5b3a335ef510e0ade upstream.
+
+While running the CI for an unrelated change I hit the following panic
+with generic/648 on btrfs_holes_spacecache.
+
+assertion failed: block_start != EXTENT_MAP_HOLE, in fs/btrfs/extent_io.c:1385
+------------[ cut here ]------------
+kernel BUG at fs/btrfs/extent_io.c:1385!
+invalid opcode: 0000 [#1] PREEMPT SMP NOPTI
+CPU: 1 PID: 2695096 Comm: fsstress Kdump: loaded Tainted: G W 6.8.0-rc2+ #1
+RIP: 0010:__extent_writepage_io.constprop.0+0x4c1/0x5c0
+Call Trace:
+ <TASK>
+ extent_write_cache_pages+0x2ac/0x8f0
+ extent_writepages+0x87/0x110
+ do_writepages+0xd5/0x1f0
+ filemap_fdatawrite_wbc+0x63/0x90
+ __filemap_fdatawrite_range+0x5c/0x80
+ btrfs_fdatawrite_range+0x1f/0x50
+ btrfs_write_out_cache+0x507/0x560
+ btrfs_write_dirty_block_groups+0x32a/0x420
+ commit_cowonly_roots+0x21b/0x290
+ btrfs_commit_transaction+0x813/0x1360
+ btrfs_sync_file+0x51a/0x640
+ __x64_sys_fdatasync+0x52/0x90
+ do_syscall_64+0x9c/0x190
+ entry_SYSCALL_64_after_hwframe+0x6e/0x76
+
+This happens because we fail to write out the free space cache in one
+instance, come back around and attempt to write it again. However on
+the second pass through we go to call btrfs_get_extent() on the inode to
+get the extent mapping. Because this is a new block group, and with the
+free space inode we always search the commit root to avoid deadlocking
+with the tree, we find nothing and return a EXTENT_MAP_HOLE for the
+requested range.
+
+This happens because the first time we try to write the space cache out
+we hit an error, and on an error we drop the extent mapping. This is
+normal for normal files, but the free space cache inode is special. We
+always expect the extent map to be correct. Thus the second time
+through we end up with a bogus extent map.
+
+Since we're deprecating this feature, the most straightforward way to
+fix this is to simply skip dropping the extent map range for this failed
+range.
+
+I shortened the test by using error injection to stress the area to make
+it easier to reproduce. With this patch in place we no longer panic
+with my error injection test.
+
+CC: stable@vger.kernel.org # 4.14+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+[ Larry: backport to 5.15.y. Minor conflict resolved due to missing commit 4c0c8cfc8433
+ btrfs: move btrfs_drop_extent_cache() to extent_map.c ]
+Signed-off-by: Larry Bassel <larry.bassel@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/inode.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -3197,8 +3197,23 @@ out:
+ unwritten_start += logical_len;
+ clear_extent_uptodate(io_tree, unwritten_start, end, NULL);
+
+- /* Drop the cache for the part of the extent we didn't write. */
+- btrfs_drop_extent_cache(inode, unwritten_start, end, 0);
++ /*
++ * Drop extent maps for the part of the extent we didn't write.
++ *
++ * We have an exception here for the free_space_inode, this is
++ * because when we do btrfs_get_extent() on the free space inode
++ * we will search the commit root. If this is a new block group
++ * we won't find anything, and we will trip over the assert in
++ * writepage where we do ASSERT(em->block_start !=
++ * EXTENT_MAP_HOLE).
++ *
++ * Theoretically we could also skip this for any NOCOW extent as
++ * we don't mess with the extent map tree in the NOCOW case, but
++ * for now simply skip this if we are the free space inode.
++ */
++ if (!btrfs_is_free_space_inode(inode))
++ btrfs_drop_extent_cache(inode, unwritten_start,
++ end, 0);
+
+ /*
+ * If the ordered extent had an IOERR or something else went
diff --git a/queue-5.15/series b/queue-5.15/series
index d769a474c9..55370c2cdd 100644
--- a/queue-5.15/series
+++ b/queue-5.15/series
@@ -92,3 +92,5 @@ media-uvcvideo-rollback-non-processed-entities-on-error.patch
s390-entry-fix-last-breaking-event-handling-in-case-of-stack-corruption.patch
s390-add-std-gnu11-to-decompressor-and-purgatory-cflags.patch
revert-ipv6-save-dontfrag-in-cork.patch
+arm64-restrict-pagetable-teardown-to-avoid-false-warning.patch
+btrfs-don-t-drop-extent_map-for-free-space-inode-on-write-error.patch