summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2025-04-30 15:40:38 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2025-04-30 15:40:38 -0400
commite7acf15b702df37aa3571cc28a8f2dd39b80b20d (patch)
tree4d72f794497d490c98afc32fdb22a8676a2d2bcc
parent2f1171b09647142da831c47675b419da3fdf4707 (diff)
pop assert when freeing page after bcachefs shutdownbcachefs-put-folio-assert
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/fs-io-buffered.c1
-rw-r--r--fs/bcachefs/fs.c5
-rw-r--r--include/linux/page-flags.h3
-rw-r--r--include/trace/events/mmflags.h3
-rw-r--r--mm/swap.c8
5 files changed, 19 insertions, 1 deletions
diff --git a/fs/bcachefs/fs-io-buffered.c b/fs/bcachefs/fs-io-buffered.c
index e3a75dcca60c..669f84dbe953 100644
--- a/fs/bcachefs/fs-io-buffered.c
+++ b/fs/bcachefs/fs-io-buffered.c
@@ -140,6 +140,7 @@ static int readpage_bio_extend(struct btree_trans *trans,
break;
}
+ folio_set_bcachefs_warn(folio);
folio_put(folio);
}
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
index f1472e9135cc..b6ba6f6c7005 100644
--- a/fs/bcachefs/fs.c
+++ b/fs/bcachefs/fs.c
@@ -45,6 +45,8 @@
#include <linux/string.h>
#include <linux/xattr.h>
+extern int bcachefs_shutdown;
+
static struct kmem_cache *bch2_inode_cache;
static void bch2_vfs_inode_init(struct btree_trans *, subvol_inum,
@@ -2380,6 +2382,7 @@ static void bch2_put_super(struct super_block *sb)
{
struct bch_fs *c = sb->s_fs_info;
+ bcachefs_shutdown = 1;
__bch2_fs_stop(c);
}
@@ -2610,6 +2613,8 @@ err:
* userspace as that causes util-linux to retry the mount RO - which is
* confusing:
*/
+
+ bcachefs_shutdown = 0;
if (bch2_err_matches(ret, EROFS) && ret != -EROFS)
ret = -EIO;
return bch2_err_class(ret);
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index e6a21b62dcce..f21463fd43ed 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -111,6 +111,7 @@ enum pageflags {
PG_swapbacked, /* Page is backed by RAM/swap */
PG_unevictable, /* Page is "unevictable" */
PG_dropbehind, /* drop pages on IO completion */
+ PG_bcachefs_warn,
#ifdef CONFIG_MMU
PG_mlocked, /* Page is vma mlocked */
#endif
@@ -667,6 +668,8 @@ FOLIO_TEST_CLEAR_FLAG_FALSE(young)
FOLIO_FLAG_FALSE(idle)
#endif
+FOLIO_FLAG(bcachefs_warn, FOLIO_HEAD_PAGE)
+
/*
* PageReported() is used to track reported free pages within the Buddy
* allocator. We can use the non-atomic version of the test and set
diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h
index 15aae955a10b..aa41fba7ef4a 100644
--- a/include/trace/events/mmflags.h
+++ b/include/trace/events/mmflags.h
@@ -159,7 +159,8 @@ TRACE_DEFINE_ENUM(___GFP_LAST_BIT);
DEF_PAGEFLAG_NAME(reclaim), \
DEF_PAGEFLAG_NAME(swapbacked), \
DEF_PAGEFLAG_NAME(unevictable), \
- DEF_PAGEFLAG_NAME(dropbehind) \
+ DEF_PAGEFLAG_NAME(dropbehind), \
+ DEF_PAGEFLAG_NAME(bcachefs_warn) \
IF_HAVE_PG_MLOCK(mlocked) \
IF_HAVE_PG_HWPOISON(hwpoison) \
IF_HAVE_PG_IDLE(idle) \
diff --git a/mm/swap.c b/mm/swap.c
index 77b2d5997873..56d23d61c9cb 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -45,6 +45,7 @@
/* How many pages do we try to swap or page in/out together? As a power of 2 */
int page_cluster;
+int bcachefs_shutdown;
static const int page_cluster_max = 31;
struct cpu_fbatches {
@@ -106,6 +107,13 @@ void __folio_put(struct folio *folio)
return;
}
+ if (folio_test_bcachefs_warn(folio) && bcachefs_shutdown) {
+ BUG();
+ dump_stack();
+ }
+
+ folio_clear_bcachefs_warn(folio);
+
page_cache_release(folio);
folio_unqueue_deferred_split(folio);
mem_cgroup_uncharge(folio);