]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 2 Jul 2024 08:36:55 +0000 (10:36 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 2 Jul 2024 08:36:55 +0000 (10:36 +0200)
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

queue-6.9/bcachefs-btree_gc-can-now-handle-unknown-btrees.patch [new file with mode: 0644]
queue-6.9/bcachefs-fix-bch2_sb_downgrade_update.patch [new file with mode: 0644]
queue-6.9/bcachefs-fix-sb-downgrade-validation.patch [new file with mode: 0644]
queue-6.9/bcachefs-fix-sb_field_downgrade-validation.patch [new file with mode: 0644]
queue-6.9/bcachefs-fix-setting-of-downgrade-recovery-passes-errors.patch [new file with mode: 0644]
queue-6.9/series

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 (file)
index 0000000..f656bfb
--- /dev/null
@@ -0,0 +1,268 @@
+From 3d86d0704d4d03f76e5098ddf16152ee53f000f8 Mon Sep 17 00:00:00 2001
+From: Kent Overstreet <kent.overstreet@linux.dev>
+Date: Mon, 27 May 2024 18:40:50 -0400
+Subject: bcachefs: btree_gc can now handle unknown btrees
+
+From: Kent Overstreet <kent.overstreet@linux.dev>
+
+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 <kent.overstreet@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <linux/generic-radix-tree.h>
++
++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 (file)
index 0000000..b884e94
--- /dev/null
@@ -0,0 +1,28 @@
+From a920ce7e2c563d8e7bc406306fcd9302d00ad618 Mon Sep 17 00:00:00 2001
+From: Kent Overstreet <kent.overstreet@linux.dev>
+Date: Mon, 17 Jun 2024 11:31:00 -0400
+Subject: bcachefs: Fix bch2_sb_downgrade_update()
+
+From: Kent Overstreet <kent.overstreet@linux.dev>
+
+commit ddd118ab45e848b1956ef8c8ef84963a554b5b58 upstream.
+
+Missing enum conversion
+
+Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..ee9c88c
--- /dev/null
@@ -0,0 +1,37 @@
+From 8e4dc66768a38acbadc3d84fb070d1220d0fbebd Mon Sep 17 00:00:00 2001
+From: Kent Overstreet <kent.overstreet@linux.dev>
+Date: Sat, 25 May 2024 12:38:53 -0400
+Subject: bcachefs: Fix sb-downgrade validation
+
+From: Kent Overstreet <kent.overstreet@linux.dev>
+
+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 <kent.overstreet@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..3af45a8
--- /dev/null
@@ -0,0 +1,47 @@
+From fc21785d6383b87a48601eab8c1df26a5572ca43 Mon Sep 17 00:00:00 2001
+From: Kent Overstreet <kent.overstreet@linux.dev>
+Date: Mon, 6 May 2024 09:16:33 -0400
+Subject: bcachefs: Fix sb_field_downgrade validation
+
+From: Kent Overstreet <kent.overstreet@linux.dev>
+
+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 <kent.overstreet@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..afd9456
--- /dev/null
@@ -0,0 +1,44 @@
+From c7a8965149de062f190bc81d1eaa8c9b36ea8df5 Mon Sep 17 00:00:00 2001
+From: Kent Overstreet <kent.overstreet@linux.dev>
+Date: Mon, 27 May 2024 16:30:19 -0400
+Subject: bcachefs: Fix setting of downgrade recovery passes/errors
+
+From: Kent Overstreet <kent.overstreet@linux.dev>
+
+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 <kent.overstreet@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
+ }
index c2673df873d948664e5d1e63ab2bdaefc76a1b67..574e75248532ec9f6139772640e5e07e600e8f0e 100644 (file)
@@ -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