diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-05-07 22:05:05 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-01-18 12:05:14 -0500 |
commit | 7b7c8ff48eb0e9942bf6f58bd4941241ea76cc23 (patch) | |
tree | 5b62bdf9692617042d0c9db7359821dc74f4b298 | |
parent | c3fe35500f7161f67bad9c5eb0ddd027a99e7ec7 (diff) |
bcachefs: Fix bch2_dev_in_target
wasn't updated for nested disk groups
-rw-r--r-- | fs/bcachefs/alloc.c | 15 | ||||
-rw-r--r-- | fs/bcachefs/disk_groups.c | 30 | ||||
-rw-r--r-- | fs/bcachefs/disk_groups.h | 28 | ||||
-rw-r--r-- | fs/bcachefs/extents.c | 12 | ||||
-rw-r--r-- | fs/bcachefs/rebalance.c | 4 |
5 files changed, 44 insertions, 45 deletions
diff --git a/fs/bcachefs/alloc.c b/fs/bcachefs/alloc.c index b0bcdf2e0cfc..54cfac1fc9e2 100644 --- a/fs/bcachefs/alloc.c +++ b/fs/bcachefs/alloc.c @@ -1398,12 +1398,10 @@ static void writepoint_drop_ptrs(struct bch_fs *c, { int i; - for (i = wp->first_ptr - 1; i >= 0; --i) { - struct bch_dev *ca = bch_dev_bkey_exists(c, wp->ptrs[i]->ptr.dev); - - if (dev_in_target(ca, target) == in_target) + for (i = wp->first_ptr - 1; i >= 0; --i) + if (bch2_dev_in_target(c, wp->ptrs[i]->ptr.dev, + target) == in_target) writepoint_drop_ptr(c, wp, i); - } } static void verify_not_stale(struct bch_fs *c, const struct write_point *wp) @@ -1564,7 +1562,7 @@ struct write_point *bch2_alloc_sectors_start(struct bch_fs *c, /* does writepoint have ptrs we don't want to use? */ if (target) writepoint_for_each_ptr(wp, ob, i) - if (!dev_idx_in_target(c, ob->ptr.dev, target)) { + if (!bch2_dev_in_target(c, ob->ptr.dev, target)) { swap(wp->ptrs[i], wp->ptrs[wp->first_ptr]); wp->first_ptr++; } @@ -1599,7 +1597,8 @@ alloc_done: * one in the target we want: */ if (cache_idx >= 0) { - if (!dev_in_target(ca, target)) { + if (!bch2_dev_in_target(c, wp->ptrs[i]->ptr.dev, + target)) { writepoint_drop_ptr(c, wp, i); } else { writepoint_drop_ptr(c, wp, cache_idx); @@ -1630,7 +1629,7 @@ alloc_done: if (ca->mi.durability && ca->mi.durability <= nr_ptrs_effective - nr_replicas && - !dev_idx_in_target(c, ob->ptr.dev, target)) { + !bch2_dev_in_target(c, ob->ptr.dev, target)) { swap(wp->ptrs[i], wp->ptrs[wp->first_ptr]); wp->first_ptr++; nr_ptrs_effective -= ca->mi.durability; diff --git a/fs/bcachefs/disk_groups.c b/fs/bcachefs/disk_groups.c index 24e8a45970c1..0687e8d224cd 100644 --- a/fs/bcachefs/disk_groups.c +++ b/fs/bcachefs/disk_groups.c @@ -196,6 +196,36 @@ const struct bch_devs_mask *bch2_target_to_mask(struct bch_fs *c, unsigned targe } } +bool bch2_dev_in_target(struct bch_fs *c, unsigned dev, unsigned target) +{ + struct target t = target_decode(target); + + switch (t.type) { + case TARGET_NULL: + return false; + case TARGET_DEV: + return dev == t.dev; + case TARGET_GROUP: { + struct bch_disk_groups_cpu *g; + const struct bch_devs_mask *m; + bool ret; + + rcu_read_lock(); + g = rcu_dereference(c->disk_groups); + m = t.group < g->nr && !g->entries[t.group].deleted + ? &g->entries[t.group].devs + : NULL; + + ret = m ? test_bit(dev, m->d) : false; + rcu_read_unlock(); + + return ret; + } + default: + BUG(); + } +} + static int __bch2_disk_group_find(struct bch_sb_field_disk_groups *groups, unsigned parent, const char *name, unsigned namelen) diff --git a/fs/bcachefs/disk_groups.h b/fs/bcachefs/disk_groups.h index 3f006a4ffa6e..d202eb3a9de6 100644 --- a/fs/bcachefs/disk_groups.h +++ b/fs/bcachefs/disk_groups.h @@ -54,34 +54,8 @@ static inline struct target target_decode(unsigned target) return (struct target) { .type = TARGET_NULL }; } -static inline bool dev_in_target(struct bch_dev *ca, unsigned target) -{ - struct target t = target_decode(target); - - switch (t.type) { - case TARGET_NULL: - return false; - case TARGET_DEV: - return ca->dev_idx == t.dev; - case TARGET_GROUP: - return ca->mi.group && ca->mi.group - 1 == t.group; - default: - BUG(); - } -} - -static inline bool dev_idx_in_target(struct bch_fs *c, unsigned dev, unsigned target) -{ - bool ret; - - rcu_read_lock(); - ret = dev_in_target(rcu_dereference(c->devs[dev]), target); - rcu_read_unlock(); - - return ret; -} - const struct bch_devs_mask *bch2_target_to_mask(struct bch_fs *, unsigned); +bool bch2_dev_in_target(struct bch_fs *, unsigned, unsigned); int bch2_disk_path_find(struct bch_sb_handle *, const char *); int bch2_disk_path_find_or_create(struct bch_sb_handle *, const char *); diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c index b00e89037e37..b414fd43f772 100644 --- a/fs/bcachefs/extents.c +++ b/fs/bcachefs/extents.c @@ -160,13 +160,11 @@ bch2_extent_has_target(struct bch_fs *c, struct bkey_s_c_extent e, unsigned targ { const struct bch_extent_ptr *ptr; - extent_for_each_ptr(e, ptr) { - struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev); - - if (dev_in_target(ca, target) && - (!ptr->cached || !ptr_stale(ca, ptr))) + extent_for_each_ptr(e, ptr) + if (bch2_dev_in_target(c, ptr->dev, target) && + (!ptr->cached || + !ptr_stale(bch_dev_bkey_exists(c, ptr->dev), ptr))) return ptr; - } return NULL; } @@ -2025,7 +2023,7 @@ void bch2_extent_mark_replicas_cached(struct bch_fs *c, int n = bch2_extent_ptr_durability(c, ptr); if (n && n <= extra && - !dev_in_target(c->devs[ptr->dev], target)) { + !bch2_dev_in_target(c, ptr->dev, target)) { ptr->cached = true; extra -= n; } diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c index 7dd376fa500f..7be9113ca6bd 100644 --- a/fs/bcachefs/rebalance.c +++ b/fs/bcachefs/rebalance.c @@ -22,10 +22,8 @@ static inline bool rebalance_ptr_pred(struct bch_fs *c, struct bch_extent_crc_unpacked crc, struct bch_io_opts *io_opts) { - struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev); - if (io_opts->background_target && - !dev_in_target(ca, io_opts->background_target) && + !bch2_dev_in_target(c, ptr->dev, io_opts->background_target) && !ptr->cached) return true; |