summaryrefslogtreecommitdiffstats
path: root/fs/bcachefs/extents.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-12-16 14:18:33 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:50 -0400
commitded54580bdf18ba3a2b38e7910c54b1c53f007c6 (patch)
tree32ccba1206735a8aa61d558f7e62fbe779033d29 /fs/bcachefs/extents.c
parent1d8305c11a289a13591d4c51726803cd37d8f646 (diff)
downloadlinux-ded54580bdf18ba3a2b38e7910c54b1c53f007c6.tar.gz
linux-ded54580bdf18ba3a2b38e7910c54b1c53f007c6.tar.bz2
linux-ded54580bdf18ba3a2b38e7910c54b1c53f007c6.zip
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> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/extents.c')
-rw-r--r--fs/bcachefs/extents.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
index f9838c1f36db..7cdfd09d797e 100644
--- a/fs/bcachefs/extents.c
+++ b/fs/bcachefs/extents.c
@@ -1045,11 +1045,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;
@@ -1100,6 +1102,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;
}