diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-10-06 04:12:42 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:10 -0400 |
commit | ef337c54c6d18d4c6ce0aef8f4f327d4cf42ae08 (patch) | |
tree | d27014f83c04d4b29a57b721b3451deea8b546ca /fs/bcachefs/alloc_foreground.h | |
parent | 7b3f84ea7d3f9bcbb7f0f1264a4c228a27a32703 (diff) | |
download | linux-ef337c54c6d18d4c6ce0aef8f4f327d4cf42ae08.tar.gz linux-ef337c54c6d18d4c6ce0aef8f4f327d4cf42ae08.tar.bz2 linux-ef337c54c6d18d4c6ce0aef8f4f327d4cf42ae08.zip |
bcachefs: Allocation code refactoring
bch2_alloc_sectors_start() was a nightmare to work with - it's got some
tricky stuff to do, since it wants to use the buckets the writepoint
already has, unless they're not in the target it wants to write to,
unless it can't allocate from any other devices in which case it will
use those buckets if it has to - et cetera.
This restructures the code to start with a new empty list of open
buckets we're going to use for the new allocation, pulling buckets from
the write point's list as we decide that we really are going to use
them - making the code somewhat more functional and drastically easier
to understand.
Also fixes a bug where we could end up waiting on c->freelist_wait
(because allocating from one device failed) but return success from
bch2_bucket_alloc(), because allocating from a different device
succeeded.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/alloc_foreground.h')
-rw-r--r-- | fs/bcachefs/alloc_foreground.h | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/fs/bcachefs/alloc_foreground.h b/fs/bcachefs/alloc_foreground.h index 1c738e4ba6c9..609685d08642 100644 --- a/fs/bcachefs/alloc_foreground.h +++ b/fs/bcachefs/alloc_foreground.h @@ -23,19 +23,23 @@ void bch2_wp_rescale(struct bch_fs *, struct bch_dev *, long bch2_bucket_alloc_new_fs(struct bch_dev *); -int bch2_bucket_alloc(struct bch_fs *, struct bch_dev *, enum alloc_reserve, bool, - struct closure *); +struct open_bucket *bch2_bucket_alloc(struct bch_fs *, struct bch_dev *, + enum alloc_reserve, bool, + struct closure *); -#define __writepoint_for_each_ptr(_wp, _ob, _i, _start) \ - for ((_i) = (_start); \ - (_i) < (_wp)->nr_ptrs && ((_ob) = (_wp)->ptrs[_i], true); \ - (_i)++) +static inline void ob_push(struct bch_fs *c, struct open_buckets *obs, + struct open_bucket *ob) +{ + BUG_ON(obs->nr >= ARRAY_SIZE(obs->v)); -#define writepoint_for_each_ptr_all(_wp, _ob, _i) \ - __writepoint_for_each_ptr(_wp, _ob, _i, 0) + obs->v[obs->nr++] = ob - c->open_buckets; +} -#define writepoint_for_each_ptr(_wp, _ob, _i) \ - __writepoint_for_each_ptr(_wp, _ob, _i, wp->first_ptr) +#define open_bucket_for_each(_c, _obs, _ob, _i) \ + for ((_i) = 0; \ + (_i) < (_obs)->nr && \ + ((_ob) = (_c)->open_buckets + (_obs)->v[_i], true); \ + (_i)++) void __bch2_open_bucket_put(struct bch_fs *, struct open_bucket *); @@ -45,26 +49,27 @@ static inline void bch2_open_bucket_put(struct bch_fs *c, struct open_bucket *ob __bch2_open_bucket_put(c, ob); } -static inline void bch2_open_bucket_put_refs(struct bch_fs *c, u8 *nr, u8 *refs) +static inline void bch2_open_buckets_put(struct bch_fs *c, + struct open_buckets *ptrs) { + struct open_bucket *ob; unsigned i; - for (i = 0; i < *nr; i++) - bch2_open_bucket_put(c, c->open_buckets + refs[i]); - - *nr = 0; + open_bucket_for_each(c, ptrs, ob, i) + bch2_open_bucket_put(c, ob); + ptrs->nr = 0; } static inline void bch2_open_bucket_get(struct bch_fs *c, struct write_point *wp, - u8 *nr, u8 *refs) + struct open_buckets *ptrs) { struct open_bucket *ob; unsigned i; - writepoint_for_each_ptr(wp, ob, i) { + open_bucket_for_each(c, &wp->ptrs, ob, i) { atomic_inc(&ob->pin); - refs[(*nr)++] = ob - c->open_buckets; + ob_push(c, ptrs, ob); } } @@ -84,9 +89,6 @@ void bch2_alloc_sectors_done(struct bch_fs *, struct write_point *); void bch2_writepoint_stop(struct bch_fs *, struct bch_dev *, struct write_point *); -void bch2_writepoint_drop_ptrs(struct bch_fs *, struct write_point *, - u16, bool); - static inline struct hlist_head *writepoint_hash(struct bch_fs *c, unsigned long write_point) { |