diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2020-12-16 14:18:33 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2020-12-16 15:29:51 -0500 |
commit | 10e0294af802bf23016633f8b9d0dec38ec0d8ad (patch) | |
tree | be8aa58f982cee5c354d34a97fb99c29112a19cd | |
parent | 4d925ccec837a72eb3b0ff3543cab2885c0d5e2a (diff) |
bcachefs: Check for duplicate device ptrs in bch2_bkey_ptrs_invalid()
This is something we clearly should be checking for, but weren't -
oops.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r-- | fs/bcachefs/extents.c | 8 | ||||
-rw-r--r-- | fs/bcachefs/replicas.c | 5 | ||||
-rw-r--r-- | fs/bcachefs/util.h | 5 |
3 files changed, 13 insertions, 5 deletions
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c index 7fae6a4ba26f..828ccf07da61 100644 --- a/fs/bcachefs/extents.c +++ b/fs/bcachefs/extents.c @@ -1046,11 +1046,13 @@ static const char *extent_ptr_invalid(const struct bch_fs *c, const char *bch2_bkey_ptrs_invalid(const struct bch_fs *c, struct bkey_s_c k) { struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k); + struct bch_devs_list devs; const union bch_extent_entry *entry; struct bch_extent_crc_unpacked crc; unsigned size_ondisk = k.k->size; const char *reason; unsigned nonce = UINT_MAX; + unsigned i; if (k.k->type == KEY_TYPE_btree_ptr) size_ondisk = c->opts.btree_node_size; @@ -1101,6 +1103,12 @@ const char *bch2_bkey_ptrs_invalid(const struct bch_fs *c, struct bkey_s_c k) } } + devs = bch2_bkey_devs(k); + bubble_sort(devs.devs, devs.nr, u8_cmp); + for (i = 0; i + 1 < devs.nr; i++) + if (devs.devs[i] == devs.devs[i + 1]) + return "multiple ptrs to same device"; + return NULL; } diff --git a/fs/bcachefs/replicas.c b/fs/bcachefs/replicas.c index 00a197b65e0b..d37d173f3ba6 100644 --- a/fs/bcachefs/replicas.c +++ b/fs/bcachefs/replicas.c @@ -11,11 +11,6 @@ static int bch2_cpu_replicas_to_sb_replicas(struct bch_fs *, /* Replicas tracking - in memory: */ -static inline int u8_cmp(u8 l, u8 r) -{ - return cmp_int(l, r); -} - static void verify_replicas_entry(struct bch_replicas_entry *e) { #ifdef CONFIG_BCACHEFS_DEBUG diff --git a/fs/bcachefs/util.h b/fs/bcachefs/util.h index 6e5335440b4b..c69b05deec41 100644 --- a/fs/bcachefs/util.h +++ b/fs/bcachefs/util.h @@ -747,4 +747,9 @@ u64 *bch2_acc_percpu_u64s(u64 __percpu *, unsigned); #define cmp_int(l, r) ((l > r) - (l < r)) +static inline int u8_cmp(u8 l, u8 r) +{ + return cmp_int(l, r); +} + #endif /* _BCACHEFS_UTIL_H */ |