diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2017-03-19 15:56:34 -0800 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2017-03-19 17:31:47 -0800 |
commit | 5ec39af8eaba49aee7bafa44c661da39e2f40dc3 (patch) | |
tree | 1fb1a981602cbf22c7d2b2dba1168c715d7cecb5 /libbcache/keybuf.c | |
parent | bb1941de5378a7b8122d3575dcbc7d0aeb6326f0 (diff) |
Rename from bcache-tools to bcachefs-tools
Diffstat (limited to 'libbcache/keybuf.c')
-rw-r--r-- | libbcache/keybuf.c | 195 |
1 files changed, 0 insertions, 195 deletions
diff --git a/libbcache/keybuf.c b/libbcache/keybuf.c deleted file mode 100644 index 961fc79a..00000000 --- a/libbcache/keybuf.c +++ /dev/null @@ -1,195 +0,0 @@ - -#include "bcache.h" -#include "btree_gc.h" -#include "btree_iter.h" -#include "keybuf.h" - -#include <trace/events/bcache.h> - -/* - * For buffered iteration over the btree, with predicates and ratelimiting and - * whatnot - */ - -static inline int keybuf_cmp(struct keybuf_key *l, struct keybuf_key *r) -{ - /* Overlapping keys compare equal */ - if (bkey_cmp(l->key.k.p, bkey_start_pos(&r->key.k)) <= 0) - return -1; - if (bkey_cmp(bkey_start_pos(&l->key.k), r->key.k.p) >= 0) - return 1; - return 0; -} - -static inline int keybuf_nonoverlapping_cmp(struct keybuf_key *l, - struct keybuf_key *r) -{ - return clamp_t(s64, bkey_cmp(l->key.k.p, r->key.k.p), -1, 1); -} - -void bch_refill_keybuf(struct bch_fs *c, struct keybuf *buf, - struct bpos end, keybuf_pred_fn *pred) -{ - struct bpos start = buf->last_scanned; - struct btree_iter iter; - struct bkey_s_c k; - unsigned nr_found = 0; - - for_each_btree_key(&iter, c, BTREE_ID_EXTENTS, buf->last_scanned, k) { - if (bkey_cmp(k.k->p, end) >= 0) { - buf->last_scanned = k.k->p; - goto done; - } - - if (pred(buf, k)) { - struct keybuf_key *w; - - spin_lock(&buf->lock); - - w = array_alloc(&buf->freelist); - if (!w) { - spin_unlock(&buf->lock); - goto done; - } - - bkey_reassemble(&w->key, k); - atomic_set(&w->ref, -1); /* -1 means hasn't started */ - - if (RB_INSERT(&buf->keys, w, node, keybuf_cmp)) - array_free(&buf->freelist, w); - else - nr_found++; - - spin_unlock(&buf->lock); - } - - buf->last_scanned = k.k->p; - bch_btree_iter_cond_resched(&iter); - } - - /* If we end up here, it means: - * - the map_fn didn't fill up the keybuf - * - the map_fn didn't see the end key - * - there were no more keys to map over - * Therefore, we are at the end of the key space */ - buf->last_scanned = POS_MAX; -done: - bch_btree_iter_unlock(&iter); - - trace_bcache_keyscan(nr_found, - start.inode, start.offset, - buf->last_scanned.inode, - buf->last_scanned.offset); - - spin_lock(&buf->lock); - - if (!RB_EMPTY_ROOT(&buf->keys)) { - struct keybuf_key *w; - - w = RB_FIRST(&buf->keys, struct keybuf_key, node); - buf->start = bkey_start_pos(&w->key.k); - - w = RB_LAST(&buf->keys, struct keybuf_key, node); - buf->end = w->key.k.p; - } else { - buf->start = POS_MAX; - buf->end = POS_MAX; - } - - spin_unlock(&buf->lock); -} - -static void bch_keybuf_del(struct keybuf *buf, struct keybuf_key *w) -{ - rb_erase(&w->node, &buf->keys); - array_free(&buf->freelist, w); -} - -void bch_keybuf_put(struct keybuf *buf, struct keybuf_key *w) -{ - BUG_ON(atomic_read(&w->ref) <= 0); - - if (atomic_dec_and_test(&w->ref)) { - up(&buf->in_flight); - - spin_lock(&buf->lock); - bch_keybuf_del(buf, w); - spin_unlock(&buf->lock); - } -} - -void bch_keybuf_recalc_oldest_gens(struct bch_fs *c, struct keybuf *buf) -{ - struct keybuf_key *w, *n; - - spin_lock(&buf->lock); - rbtree_postorder_for_each_entry_safe(w, n, - &buf->keys, node) - bch_btree_key_recalc_oldest_gen(c, bkey_i_to_s_c(&w->key)); - spin_unlock(&buf->lock); -} - -bool bch_keybuf_check_overlapping(struct keybuf *buf, struct bpos start, - struct bpos end) -{ - bool ret = false; - struct keybuf_key *w, *next, s = { .key.k.p = start }; - - if (bkey_cmp(end, buf->start) <= 0 || - bkey_cmp(start, buf->end) >= 0) - return false; - - spin_lock(&buf->lock); - - for (w = RB_GREATER(&buf->keys, s, node, keybuf_nonoverlapping_cmp); - w && bkey_cmp(bkey_start_pos(&w->key.k), end) < 0; - w = next) { - next = RB_NEXT(w, node); - - if (atomic_read(&w->ref) == -1) - bch_keybuf_del(buf, w); - else - ret = true; - } - - spin_unlock(&buf->lock); - return ret; -} - -struct keybuf_key *bch_keybuf_next(struct keybuf *buf) -{ - struct keybuf_key *w; - - spin_lock(&buf->lock); - - w = RB_FIRST(&buf->keys, struct keybuf_key, node); - - while (w && atomic_read(&w->ref) != -1) - w = RB_NEXT(w, node); - - if (!w) { - spin_unlock(&buf->lock); - return NULL; - } - - atomic_set(&w->ref, 1); - spin_unlock(&buf->lock); - - down(&buf->in_flight); - - return w; -} - -void bch_keybuf_init(struct keybuf *buf) -{ - sema_init(&buf->in_flight, KEYBUF_REFILL_BATCH / 2); - - buf->last_scanned = POS_MAX; - buf->start = POS_MIN; - buf->end = POS_MIN; - - buf->keys = RB_ROOT; - - spin_lock_init(&buf->lock); - array_allocator_init(&buf->freelist); -} |