summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2015-05-04 19:02:58 -0700
committerKent Overstreet <kent.overstreet@gmail.com>2016-10-07 12:34:09 -0800
commit4a0356faae061e57178182729d5392b28a17778c (patch)
tree3eebdc643fd1ef5e1296099ad1c3167d4711c38f
parent26d9f337c55d0ee02bb49b28fccf8abe4b31f934 (diff)
bcache: bch_btree_key_recalc_oldest_gen() now takes rcu_read_lock()
-rw-r--r--drivers/md/bcache/gc.c63
-rw-r--r--drivers/md/bcache/gc.h7
-rw-r--r--drivers/md/bcache/keybuf.c5
-rw-r--r--drivers/md/bcache/keylist.c7
-rw-r--r--drivers/md/bcache/move.c5
5 files changed, 41 insertions, 46 deletions
diff --git a/drivers/md/bcache/gc.c b/drivers/md/bcache/gc.c
index 44b8b3cf4a66..b6a02b7c0922 100644
--- a/drivers/md/bcache/gc.c
+++ b/drivers/md/bcache/gc.c
@@ -23,35 +23,43 @@
#include <linux/delay.h>
#include <trace/events/bcache.h>
-u8 bch_btree_key_recalc_oldest_gen(struct cache_set *c,
- struct bkey_s_c_extent e)
+u8 bch_btree_key_recalc_oldest_gen(struct cache_set *c, struct bkey_s_c k)
{
+ struct bkey_s_c_extent e;
const struct bch_extent_ptr *ptr;
struct cache *ca;
u8 max_stale = 0;
- extent_for_each_ptr(e, ptr)
- if (PTR_DEV(ptr) < MAX_CACHES_PER_SET)
- __set_bit(PTR_DEV(ptr), c->cache_slots_used);
+ switch (k.k->type) {
+ case BCH_EXTENT:
+ e = bkey_s_c_to_extent(k);
+
+ rcu_read_lock();
+
+ extent_for_each_ptr(e, ptr)
+ if (PTR_DEV(ptr) < MAX_CACHES_PER_SET)
+ __set_bit(PTR_DEV(ptr), c->cache_slots_used);
- extent_for_each_online_device(c, e, ptr, ca) {
- struct bucket *g = PTR_BUCKET(ca, ptr);
+ extent_for_each_online_device(c, e, ptr, ca) {
+ struct bucket *g = PTR_BUCKET(ca, ptr);
- if (__gen_after(g->oldest_gen, PTR_GEN(ptr)))
- g->oldest_gen = PTR_GEN(ptr);
+ if (__gen_after(g->oldest_gen, PTR_GEN(ptr)))
+ g->oldest_gen = PTR_GEN(ptr);
- max_stale = max(max_stale, ptr_stale(ca, ptr));
+ max_stale = max(max_stale, ptr_stale(ca, ptr));
+ }
+
+ rcu_read_unlock();
}
return max_stale;
}
-u8 __bch_btree_mark_key(struct cache_set *c, int level, struct bkey_s_c k)
+void __bch_btree_mark_key(struct cache_set *c, int level, struct bkey_s_c k)
{
- struct bkey_s_c_extent e;
const struct bch_extent_ptr *ptr;
+ struct bkey_s_c_extent e;
struct cache *ca;
- u8 max_stale;
switch (k.k->type) {
case BCH_EXTENT:
@@ -59,8 +67,6 @@ u8 __bch_btree_mark_key(struct cache_set *c, int level, struct bkey_s_c k)
rcu_read_lock();
- max_stale = bch_btree_key_recalc_oldest_gen(c, e);
-
if (level) {
extent_for_each_online_device(c, e, ptr, ca)
bch_mark_metadata_bucket(ca,
@@ -71,17 +77,13 @@ u8 __bch_btree_mark_key(struct cache_set *c, int level, struct bkey_s_c k)
}
rcu_read_unlock();
-
- return max_stale;
- default:
- return 0;
}
}
-static u8 btree_mark_key(struct cache_set *c, struct btree *b,
+static void btree_mark_key(struct cache_set *c, struct btree *b,
struct bkey_s_c k)
{
- return __bch_btree_mark_key(c, b->level, k);
+ __bch_btree_mark_key(c, b->level, k);
}
/* Only the extent btree has leafs whose keys point to data */
@@ -107,26 +109,29 @@ bool btree_gc_mark_node(struct cache_set *c, struct btree *b,
if (btree_node_has_ptrs(b)) {
struct btree_node_iter iter;
- struct bkey_packed *k;
+ struct bkey_packed *k_p;
struct bkey_tup tup;
+ struct bkey_s_c k;
unsigned keys = 0, good_keys = 0, u64s;
u8 stale = 0;
- for_each_btree_node_key(&b->keys, k, &iter) {
- bkey_disassemble(&tup, f, k);
+ for_each_btree_node_key(&b->keys, k_p, &iter) {
+ bkey_disassemble(&tup, f, k_p);
+ k = bkey_tup_to_s_c(&tup);
+
+ bkey_debugcheck(c, b, k);
- bkey_debugcheck(c, b, bkey_tup_to_s_c(&tup));
+ btree_mark_key(c, b, k);
stale = max(stale,
- btree_mark_key(c, b,
- bkey_tup_to_s_c(&tup)));
+ bch_btree_key_recalc_oldest_gen(c, k));
keys++;
- u64s = bch_extent_nr_ptrs_after_normalize(c, b, k);
+ u64s = bch_extent_nr_ptrs_after_normalize(c, b, k_p);
if (stat && u64s) {
good_keys++;
- stat->key_bytes += k->u64s;
+ stat->key_bytes += k_p->u64s;
stat->nkeys++;
stat->data += tup.k.size;
}
diff --git a/drivers/md/bcache/gc.h b/drivers/md/bcache/gc.h
index 90953c90a116..1b6556e47240 100644
--- a/drivers/md/bcache/gc.h
+++ b/drivers/md/bcache/gc.h
@@ -9,11 +9,10 @@ static inline void set_gc_sectors(struct cache_set *c)
void bch_gc(struct cache_set *);
int bch_gc_thread_start(struct cache_set *);
int bch_initial_gc(struct cache_set *, struct list_head *);
-u8 bch_btree_key_recalc_oldest_gen(struct cache_set *, struct bkey_s_c_extent);
-u8 __bch_btree_mark_key(struct cache_set *, int, struct bkey_s_c);
+u8 bch_btree_key_recalc_oldest_gen(struct cache_set *, struct bkey_s_c);
+void __bch_btree_mark_key(struct cache_set *, int, struct bkey_s_c);
-bool btree_gc_mark_node(struct cache_set *, struct btree *,
- struct gc_stat *);
+bool btree_gc_mark_node(struct cache_set *, struct btree *, struct gc_stat *);
/**
* __gc_will_visit_node - for checking GC marks while holding a btree read lock
diff --git a/drivers/md/bcache/keybuf.c b/drivers/md/bcache/keybuf.c
index 0a2a24d0d59a..fc09a962094d 100644
--- a/drivers/md/bcache/keybuf.c
+++ b/drivers/md/bcache/keybuf.c
@@ -123,12 +123,9 @@ void bch_keybuf_recalc_oldest_gens(struct cache_set *c, struct keybuf *buf)
struct keybuf_key *w, *n;
spin_lock(&buf->lock);
- rcu_read_lock();
rbtree_postorder_for_each_entry_safe(w, n,
&buf->keys, node)
- bch_btree_key_recalc_oldest_gen(c,
- bkey_i_to_s_c_extent(&w->key));
- rcu_read_unlock();
+ bch_btree_key_recalc_oldest_gen(c, bkey_i_to_s_c(&w->key));
spin_unlock(&buf->lock);
}
diff --git a/drivers/md/bcache/keylist.c b/drivers/md/bcache/keylist.c
index 361608f24cfb..f6f7eabf9b0f 100644
--- a/drivers/md/bcache/keylist.c
+++ b/drivers/md/bcache/keylist.c
@@ -204,11 +204,8 @@ void bch_keylist_recalc_oldest_gens(struct cache_set *c,
mutex_lock(&kl->lock);
- keylist_for_each(k, &kl->list) {
- rcu_read_lock();
- bch_btree_key_recalc_oldest_gen(c, bkey_i_to_s_c_extent(k));
- rcu_read_unlock();
- }
+ keylist_for_each(k, &kl->list)
+ bch_btree_key_recalc_oldest_gen(c, bkey_i_to_s_c(k));
mutex_unlock(&kl->lock);
}
diff --git a/drivers/md/bcache/move.c b/drivers/md/bcache/move.c
index ad12e15fc1de..18d4204c97eb 100644
--- a/drivers/md/bcache/move.c
+++ b/drivers/md/bcache/move.c
@@ -412,10 +412,7 @@ static void pending_recalc_oldest_gens(struct cache_set *c, struct list_head *l)
* don't need to be marked because they are pointing
* to open buckets until the write completes
*/
- rcu_read_lock();
- bch_btree_key_recalc_oldest_gen(c,
- bkey_i_to_s_c_extent(&io->key));
- rcu_read_unlock();
+ bch_btree_key_recalc_oldest_gen(c, bkey_i_to_s_c(&io->key));
}
}