From 452fe76ab7187a353746949b4a1fcd8cbebdba04 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 2 Jul 2024 10:36:55 +0200 Subject: [PATCH] 6.9-stable patches added patches: bcachefs-btree_gc-can-now-handle-unknown-btrees.patch bcachefs-fix-bch2_sb_downgrade_update.patch bcachefs-fix-sb-downgrade-validation.patch bcachefs-fix-sb_field_downgrade-validation.patch bcachefs-fix-setting-of-downgrade-recovery-passes-errors.patch --- ...ree_gc-can-now-handle-unknown-btrees.patch | 268 ++++++++++++++++++ ...cachefs-fix-bch2_sb_downgrade_update.patch | 28 ++ ...bcachefs-fix-sb-downgrade-validation.patch | 37 +++ ...fs-fix-sb_field_downgrade-validation.patch | 47 +++ ...-of-downgrade-recovery-passes-errors.patch | 44 +++ queue-6.9/series | 5 + 6 files changed, 429 insertions(+) create mode 100644 queue-6.9/bcachefs-btree_gc-can-now-handle-unknown-btrees.patch create mode 100644 queue-6.9/bcachefs-fix-bch2_sb_downgrade_update.patch create mode 100644 queue-6.9/bcachefs-fix-sb-downgrade-validation.patch create mode 100644 queue-6.9/bcachefs-fix-sb_field_downgrade-validation.patch create mode 100644 queue-6.9/bcachefs-fix-setting-of-downgrade-recovery-passes-errors.patch diff --git a/queue-6.9/bcachefs-btree_gc-can-now-handle-unknown-btrees.patch b/queue-6.9/bcachefs-btree_gc-can-now-handle-unknown-btrees.patch new file mode 100644 index 00000000000..f656bfbdee4 --- /dev/null +++ b/queue-6.9/bcachefs-btree_gc-can-now-handle-unknown-btrees.patch @@ -0,0 +1,268 @@ +From 3d86d0704d4d03f76e5098ddf16152ee53f000f8 Mon Sep 17 00:00:00 2001 +From: Kent Overstreet +Date: Mon, 27 May 2024 18:40:50 -0400 +Subject: bcachefs: btree_gc can now handle unknown btrees + +From: Kent Overstreet + +commit 088d0de81220a74d7d553febb81656927f10bb16 upstream. + +Compatibility fix - we no longer have a separate table for which order +gc walks btrees in, and special case the stripes btree directly. + +Signed-off-by: Kent Overstreet +Signed-off-by: Greg Kroah-Hartman +--- + fs/bcachefs/bcachefs.h | 44 --------------------------------------- + fs/bcachefs/btree_gc.c | 15 ++++++------- + fs/bcachefs/btree_gc.h | 48 +++++++++++++++++++------------------------ + fs/bcachefs/btree_gc_types.h | 29 +++++++++++++++++++++++++ + fs/bcachefs/ec.c | 2 - + 5 files changed, 60 insertions(+), 78 deletions(-) + create mode 100644 fs/bcachefs/btree_gc_types.h + +--- a/fs/bcachefs/bcachefs.h ++++ b/fs/bcachefs/bcachefs.h +@@ -455,6 +455,7 @@ enum bch_time_stats { + }; + + #include "alloc_types.h" ++#include "btree_gc_types.h" + #include "btree_types.h" + #include "btree_node_scan_types.h" + #include "btree_write_buffer_types.h" +@@ -485,49 +486,6 @@ enum bch_time_stats { + + struct btree; + +-enum gc_phase { +- GC_PHASE_NOT_RUNNING, +- GC_PHASE_START, +- GC_PHASE_SB, +- +- GC_PHASE_BTREE_stripes, +- GC_PHASE_BTREE_extents, +- GC_PHASE_BTREE_inodes, +- GC_PHASE_BTREE_dirents, +- GC_PHASE_BTREE_xattrs, +- GC_PHASE_BTREE_alloc, +- GC_PHASE_BTREE_quotas, +- GC_PHASE_BTREE_reflink, +- GC_PHASE_BTREE_subvolumes, +- GC_PHASE_BTREE_snapshots, +- GC_PHASE_BTREE_lru, +- GC_PHASE_BTREE_freespace, +- GC_PHASE_BTREE_need_discard, +- GC_PHASE_BTREE_backpointers, +- GC_PHASE_BTREE_bucket_gens, +- GC_PHASE_BTREE_snapshot_trees, +- GC_PHASE_BTREE_deleted_inodes, +- GC_PHASE_BTREE_logged_ops, +- GC_PHASE_BTREE_rebalance_work, +- GC_PHASE_BTREE_subvolume_children, +- +- GC_PHASE_PENDING_DELETE, +-}; +- +-struct gc_pos { +- enum gc_phase phase; +- struct bpos pos; +- unsigned level; +-}; +- +-struct reflink_gc { +- u64 offset; +- u32 size; +- u32 refcount; +-}; +- +-typedef GENRADIX(struct reflink_gc) reflink_gc_table; +- + struct io_count { + u64 sectors[2][BCH_DATA_NR]; + }; +--- a/fs/bcachefs/btree_gc.c ++++ b/fs/bcachefs/btree_gc.c +@@ -1080,8 +1080,7 @@ fsck_err: + + static inline int btree_id_gc_phase_cmp(enum btree_id l, enum btree_id r) + { +- return (int) btree_id_to_gc_phase(l) - +- (int) btree_id_to_gc_phase(r); ++ return cmp_int(gc_btree_order(l), gc_btree_order(r)); + } + + static int bch2_gc_btrees(struct bch_fs *c, bool initial, bool metadata_only) +@@ -1126,7 +1125,7 @@ static void mark_metadata_sectors(struct + min_t(u64, bucket_to_sector(ca, b + 1), end) - start; + + bch2_mark_metadata_bucket(c, ca, b, type, sectors, +- gc_phase(GC_PHASE_SB), flags); ++ gc_phase(GC_PHASE_sb), flags); + b++; + start += sectors; + } while (start < end); +@@ -1155,14 +1154,14 @@ static void bch2_mark_dev_superblock(str + b = ca->journal.buckets[i]; + bch2_mark_metadata_bucket(c, ca, b, BCH_DATA_journal, + ca->mi.bucket_size, +- gc_phase(GC_PHASE_SB), flags); ++ gc_phase(GC_PHASE_sb), flags); + } + } + + static void bch2_mark_superblocks(struct bch_fs *c) + { + mutex_lock(&c->sb_lock); +- gc_pos_set(c, gc_phase(GC_PHASE_SB)); ++ gc_pos_set(c, gc_phase(GC_PHASE_sb)); + + for_each_online_member(c, ca) + bch2_mark_dev_superblock(c, ca, BTREE_TRIGGER_GC); +@@ -1773,7 +1772,7 @@ int bch2_gc(struct bch_fs *c, bool initi + if (ret) + goto out; + again: +- gc_pos_set(c, gc_phase(GC_PHASE_START)); ++ gc_pos_set(c, gc_phase(GC_PHASE_start)); + + bch2_mark_superblocks(c); + +@@ -1800,7 +1799,7 @@ again: + */ + bch_info(c, "Second GC pass needed, restarting:"); + clear_bit(BCH_FS_need_another_gc, &c->flags); +- __gc_pos_set(c, gc_phase(GC_PHASE_NOT_RUNNING)); ++ __gc_pos_set(c, gc_phase(GC_PHASE_not_running)); + + bch2_gc_stripes_reset(c, metadata_only); + bch2_gc_alloc_reset(c, metadata_only); +@@ -1827,7 +1826,7 @@ out: + + percpu_down_write(&c->mark_lock); + /* Indicates that gc is no longer in progress: */ +- __gc_pos_set(c, gc_phase(GC_PHASE_NOT_RUNNING)); ++ __gc_pos_set(c, gc_phase(GC_PHASE_not_running)); + + bch2_gc_free(c); + percpu_up_write(&c->mark_lock); +--- a/fs/bcachefs/btree_gc.h ++++ b/fs/bcachefs/btree_gc.h +@@ -3,6 +3,7 @@ + #define _BCACHEFS_BTREE_GC_H + + #include "bkey.h" ++#include "btree_gc_types.h" + #include "btree_types.h" + + int bch2_check_topology(struct bch_fs *); +@@ -35,38 +36,17 @@ int bch2_gc_thread_start(struct bch_fs * + /* Position of (the start of) a gc phase: */ + static inline struct gc_pos gc_phase(enum gc_phase phase) + { +- return (struct gc_pos) { +- .phase = phase, +- .pos = POS_MIN, +- .level = 0, +- }; +-} +- +-static inline int gc_pos_cmp(struct gc_pos l, struct gc_pos r) +-{ +- return cmp_int(l.phase, r.phase) ?: +- bpos_cmp(l.pos, r.pos) ?: +- cmp_int(l.level, r.level); +-} +- +-static inline enum gc_phase btree_id_to_gc_phase(enum btree_id id) +-{ +- switch (id) { +-#define x(name, v, ...) case BTREE_ID_##name: return GC_PHASE_BTREE_##name; +- BCH_BTREE_IDS() +-#undef x +- default: +- BUG(); +- } ++ return (struct gc_pos) { .phase = phase, }; + } + +-static inline struct gc_pos gc_pos_btree(enum btree_id id, ++static inline struct gc_pos gc_pos_btree(enum btree_id btree, + struct bpos pos, unsigned level) + { + return (struct gc_pos) { +- .phase = btree_id_to_gc_phase(id), +- .pos = pos, ++ .phase = GC_PHASE_btree, ++ .btree = btree, + .level = level, ++ .pos = pos, + }; + } + +@@ -91,6 +71,22 @@ static inline struct gc_pos gc_pos_btree + return gc_pos_btree(id, SPOS_MAX, BTREE_MAX_DEPTH); + } + ++static inline int gc_btree_order(enum btree_id btree) ++{ ++ if (btree == BTREE_ID_stripes) ++ return -1; ++ return btree; ++} ++ ++static inline int gc_pos_cmp(struct gc_pos l, struct gc_pos r) ++{ ++ return cmp_int(l.phase, r.phase) ?: ++ cmp_int(gc_btree_order(l.btree), ++ gc_btree_order(r.btree)) ?: ++ -cmp_int(l.level, r.level) ?: ++ bpos_cmp(l.pos, r.pos); ++} ++ + static inline bool gc_visited(struct bch_fs *c, struct gc_pos pos) + { + unsigned seq; +--- /dev/null ++++ b/fs/bcachefs/btree_gc_types.h +@@ -0,0 +1,29 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef _BCACHEFS_BTREE_GC_TYPES_H ++#define _BCACHEFS_BTREE_GC_TYPES_H ++ ++#include ++ ++enum gc_phase { ++ GC_PHASE_not_running, ++ GC_PHASE_start, ++ GC_PHASE_sb, ++ GC_PHASE_btree, ++}; ++ ++struct gc_pos { ++ enum gc_phase phase:8; ++ enum btree_id btree:8; ++ u16 level; ++ struct bpos pos; ++}; ++ ++struct reflink_gc { ++ u64 offset; ++ u32 size; ++ u32 refcount; ++}; ++ ++typedef GENRADIX(struct reflink_gc) reflink_gc_table; ++ ++#endif /* _BCACHEFS_BTREE_GC_TYPES_H */ +--- a/fs/bcachefs/ec.c ++++ b/fs/bcachefs/ec.c +@@ -880,7 +880,7 @@ static int __ec_stripe_mem_alloc(struct + if (!genradix_ptr_alloc(&c->stripes, idx, gfp)) + return -BCH_ERR_ENOMEM_ec_stripe_mem_alloc; + +- if (c->gc_pos.phase != GC_PHASE_NOT_RUNNING && ++ if (c->gc_pos.phase != GC_PHASE_not_running && + !genradix_ptr_alloc(&c->gc_stripes, idx, gfp)) + return -BCH_ERR_ENOMEM_ec_stripe_mem_alloc; + diff --git a/queue-6.9/bcachefs-fix-bch2_sb_downgrade_update.patch b/queue-6.9/bcachefs-fix-bch2_sb_downgrade_update.patch new file mode 100644 index 00000000000..b884e94b724 --- /dev/null +++ b/queue-6.9/bcachefs-fix-bch2_sb_downgrade_update.patch @@ -0,0 +1,28 @@ +From a920ce7e2c563d8e7bc406306fcd9302d00ad618 Mon Sep 17 00:00:00 2001 +From: Kent Overstreet +Date: Mon, 17 Jun 2024 11:31:00 -0400 +Subject: bcachefs: Fix bch2_sb_downgrade_update() + +From: Kent Overstreet + +commit ddd118ab45e848b1956ef8c8ef84963a554b5b58 upstream. + +Missing enum conversion + +Signed-off-by: Kent Overstreet +Signed-off-by: Greg Kroah-Hartman +--- + fs/bcachefs/sb-downgrade.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/bcachefs/sb-downgrade.c ++++ b/fs/bcachefs/sb-downgrade.c +@@ -225,7 +225,7 @@ int bch2_sb_downgrade_update(struct bch_ + + dst = (void *) &darray_top(table); + dst->version = cpu_to_le16(src->version); +- dst->recovery_passes[0] = cpu_to_le64(src->recovery_passes); ++ dst->recovery_passes[0] = cpu_to_le64(bch2_recovery_passes_to_stable(src->recovery_passes)); + dst->recovery_passes[1] = 0; + dst->nr_errors = cpu_to_le16(src->nr_errors); + for (unsigned i = 0; i < src->nr_errors; i++) diff --git a/queue-6.9/bcachefs-fix-sb-downgrade-validation.patch b/queue-6.9/bcachefs-fix-sb-downgrade-validation.patch new file mode 100644 index 00000000000..ee9c88cc27a --- /dev/null +++ b/queue-6.9/bcachefs-fix-sb-downgrade-validation.patch @@ -0,0 +1,37 @@ +From 8e4dc66768a38acbadc3d84fb070d1220d0fbebd Mon Sep 17 00:00:00 2001 +From: Kent Overstreet +Date: Sat, 25 May 2024 12:38:53 -0400 +Subject: bcachefs: Fix sb-downgrade validation + +From: Kent Overstreet + +commit 9242a34b760648b722f4958749ad83ef7d0f7525 upstream. + +Superblock downgrade entries are only two byte aligned, but section +sizes are 8 byte aligned, which means we have to be careful about +overrun checks; an entry that crosses the end of the section is allowed +(and ignored) as long as it has zero errors. + +Signed-off-by: Kent Overstreet +Signed-off-by: Greg Kroah-Hartman +--- + fs/bcachefs/sb-downgrade.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/fs/bcachefs/sb-downgrade.c ++++ b/fs/bcachefs/sb-downgrade.c +@@ -146,6 +146,14 @@ static int bch2_sb_downgrade_validate(st + for (const struct bch_sb_field_downgrade_entry *i = e->entries; + (void *) i < vstruct_end(&e->field); + i = downgrade_entry_next_c(i)) { ++ /* ++ * Careful: sb_field_downgrade_entry is only 2 byte aligned, but ++ * section sizes are 8 byte aligned - an empty entry spanning ++ * the end of the section is allowed (and ignored): ++ */ ++ if ((void *) &i->errors[0] > vstruct_end(&e->field)) ++ break; ++ + if (BCH_VERSION_MAJOR(le16_to_cpu(i->version)) != + BCH_VERSION_MAJOR(le16_to_cpu(sb->version))) { + prt_printf(err, "downgrade entry with mismatched major version (%u != %u)", diff --git a/queue-6.9/bcachefs-fix-sb_field_downgrade-validation.patch b/queue-6.9/bcachefs-fix-sb_field_downgrade-validation.patch new file mode 100644 index 00000000000..3af45a88b47 --- /dev/null +++ b/queue-6.9/bcachefs-fix-sb_field_downgrade-validation.patch @@ -0,0 +1,47 @@ +From fc21785d6383b87a48601eab8c1df26a5572ca43 Mon Sep 17 00:00:00 2001 +From: Kent Overstreet +Date: Mon, 6 May 2024 09:16:33 -0400 +Subject: bcachefs: Fix sb_field_downgrade validation + +From: Kent Overstreet + +commit 692aa7a54b2b28d59f24b3bf8250837805484b99 upstream. + +- bch2_sb_downgrade_validate() wasn't checking for a downgrade entry + extending past the end of the superblock section + +- for_each_downgrade_entry() is used in to_text() and needs to work on + malformed input; it also was missing a check for a field extending + past the end of the section + +Reported-by: syzbot+e49ccab73449180bc9be@syzkaller.appspotmail.com +Fixes: 84f1638795da ("bcachefs: bch_sb_field_downgrade") +Signed-off-by: Kent Overstreet +Signed-off-by: Greg Kroah-Hartman +--- + fs/bcachefs/sb-downgrade.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/fs/bcachefs/sb-downgrade.c ++++ b/fs/bcachefs/sb-downgrade.c +@@ -134,7 +134,8 @@ downgrade_entry_next_c(const struct bch_ + #define for_each_downgrade_entry(_d, _i) \ + for (const struct bch_sb_field_downgrade_entry *_i = (_d)->entries; \ + (void *) _i < vstruct_end(&(_d)->field) && \ +- (void *) &_i->errors[0] < vstruct_end(&(_d)->field); \ ++ (void *) &_i->errors[0] <= vstruct_end(&(_d)->field) && \ ++ (void *) downgrade_entry_next_c(_i) <= vstruct_end(&(_d)->field); \ + _i = downgrade_entry_next_c(_i)) + + static int bch2_sb_downgrade_validate(struct bch_sb *sb, struct bch_sb_field *f, +@@ -142,7 +143,9 @@ static int bch2_sb_downgrade_validate(st + { + struct bch_sb_field_downgrade *e = field_to_type(f, downgrade); + +- for_each_downgrade_entry(e, i) { ++ for (const struct bch_sb_field_downgrade_entry *i = e->entries; ++ (void *) i < vstruct_end(&e->field); ++ i = downgrade_entry_next_c(i)) { + if (BCH_VERSION_MAJOR(le16_to_cpu(i->version)) != + BCH_VERSION_MAJOR(le16_to_cpu(sb->version))) { + prt_printf(err, "downgrade entry with mismatched major version (%u != %u)", diff --git a/queue-6.9/bcachefs-fix-setting-of-downgrade-recovery-passes-errors.patch b/queue-6.9/bcachefs-fix-setting-of-downgrade-recovery-passes-errors.patch new file mode 100644 index 00000000000..afd94567c68 --- /dev/null +++ b/queue-6.9/bcachefs-fix-setting-of-downgrade-recovery-passes-errors.patch @@ -0,0 +1,44 @@ +From c7a8965149de062f190bc81d1eaa8c9b36ea8df5 Mon Sep 17 00:00:00 2001 +From: Kent Overstreet +Date: Mon, 27 May 2024 16:30:19 -0400 +Subject: bcachefs: Fix setting of downgrade recovery passes/errors + +From: Kent Overstreet + +commit 247c056bde2ebc9fad2fc62332dc7cc99b58d720 upstream. + +bch2_check_version_downgrade() was setting c->sb.version, which +bch2_sb_set_downgrade() expects to be at the previous version; and it +shouldn't even have been set directly because c->sb.version is updated +by write_super(). + +Signed-off-by: Kent Overstreet +Signed-off-by: Greg Kroah-Hartman +--- + fs/bcachefs/super-io.c | 12 +++--------- + 1 file changed, 3 insertions(+), 9 deletions(-) + +--- a/fs/bcachefs/super-io.c ++++ b/fs/bcachefs/super-io.c +@@ -1123,18 +1123,12 @@ bool bch2_check_version_downgrade(struct + * c->sb will be checked before we write the superblock, so update it as + * well: + */ +- if (BCH_SB_VERSION_UPGRADE_COMPLETE(c->disk_sb.sb) > bcachefs_metadata_version_current) { ++ if (BCH_SB_VERSION_UPGRADE_COMPLETE(c->disk_sb.sb) > bcachefs_metadata_version_current) + SET_BCH_SB_VERSION_UPGRADE_COMPLETE(c->disk_sb.sb, bcachefs_metadata_version_current); +- c->sb.version_upgrade_complete = bcachefs_metadata_version_current; +- } +- if (c->sb.version > bcachefs_metadata_version_current) { ++ if (c->sb.version > bcachefs_metadata_version_current) + c->disk_sb.sb->version = cpu_to_le16(bcachefs_metadata_version_current); +- c->sb.version = bcachefs_metadata_version_current; +- } +- if (c->sb.version_min > bcachefs_metadata_version_current) { ++ if (c->sb.version_min > bcachefs_metadata_version_current) + c->disk_sb.sb->version_min = cpu_to_le16(bcachefs_metadata_version_current); +- c->sb.version_min = bcachefs_metadata_version_current; +- } + c->disk_sb.sb->compat[0] &= cpu_to_le64((1ULL << BCH_COMPAT_NR) - 1); + return ret; + } diff --git a/queue-6.9/series b/queue-6.9/series index c2673df873d..574e7524853 100644 --- a/queue-6.9/series +++ b/queue-6.9/series @@ -194,3 +194,8 @@ ata-libata-core-fix-double-free-on-error.patch ftruncate-pass-a-signed-offset.patch syscalls-fix-compat_sys_io_pgetevents_time64-usage.patch syscalls-fix-sys_fanotify_mark-prototype.patch +bcachefs-fix-sb_field_downgrade-validation.patch +bcachefs-fix-sb-downgrade-validation.patch +bcachefs-fix-bch2_sb_downgrade_update.patch +bcachefs-fix-setting-of-downgrade-recovery-passes-errors.patch +bcachefs-btree_gc-can-now-handle-unknown-btrees.patch -- 2.47.3