aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorKent Overstreet <kmo@daterainc.com>2013-07-24 19:46:42 -0400
committerKent Overstreet <kmo@daterainc.com>2013-11-11 00:56:34 -0500
commit3a3b6a4e075188342b58d4b6560f5540af64cac0 (patch)
tree5c64e4cdcb292d3b0a9e1d9f16e461ff5c4fdcbe /drivers/md
parent280481d06c8a683d9aaa26125476222e76b733c5 (diff)
bcache: Don't bother with bucket refcount for btree node allocations
The bucket refcount (dropped with bkey_put()) is only needed to prevent the newly allocated bucket from being garbage collected until we've added a pointer to it somewhere. But for btree node allocations, the fact that we have btree nodes locked is enough to guard against races with garbage collection. Eventually the per bucket refcount is going to be replaced with something specific to bch_alloc_sectors(). Signed-off-by: Kent Overstreet <kmo@daterainc.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/bcache/alloc.c4
-rw-r--r--drivers/md/bcache/btree.c28
-rw-r--r--drivers/md/bcache/btree.h2
-rw-r--r--drivers/md/bcache/super.c2
4 files changed, 9 insertions, 27 deletions
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c
index ed5920b20c61..2b46bf1d7e40 100644
--- a/drivers/md/bcache/alloc.c
+++ b/drivers/md/bcache/alloc.c
@@ -472,7 +472,7 @@ int __bch_bucket_alloc_set(struct cache_set *c, unsigned watermark,
472 return 0; 472 return 0;
473err: 473err:
474 bch_bucket_free(c, k); 474 bch_bucket_free(c, k);
475 __bkey_put(c, k); 475 bkey_put(c, k);
476 return -1; 476 return -1;
477} 477}
478 478
@@ -588,7 +588,7 @@ bool bch_alloc_sectors(struct cache_set *c, struct bkey *k, unsigned sectors,
588 * didn't use it, drop the refcount bch_bucket_alloc_set() took: 588 * didn't use it, drop the refcount bch_bucket_alloc_set() took:
589 */ 589 */
590 if (KEY_PTRS(&alloc.key)) 590 if (KEY_PTRS(&alloc.key))
591 __bkey_put(c, &alloc.key); 591 bkey_put(c, &alloc.key);
592 592
593 for (i = 0; i < KEY_PTRS(&b->key); i++) 593 for (i = 0; i < KEY_PTRS(&b->key); i++)
594 EBUG_ON(ptr_stale(c, &b->key, i)); 594 EBUG_ON(ptr_stale(c, &b->key, i));
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
index fa4d0b1f6d75..7dff73ba1b71 100644
--- a/drivers/md/bcache/btree.c
+++ b/drivers/md/bcache/btree.c
@@ -180,7 +180,7 @@ static inline bool should_split(struct btree *b)
180 180
181/* Btree key manipulation */ 181/* Btree key manipulation */
182 182
183void __bkey_put(struct cache_set *c, struct bkey *k) 183void bkey_put(struct cache_set *c, struct bkey *k)
184{ 184{
185 unsigned i; 185 unsigned i;
186 186
@@ -189,12 +189,6 @@ void __bkey_put(struct cache_set *c, struct bkey *k)
189 atomic_dec_bug(&PTR_BUCKET(c, k, i)->pin); 189 atomic_dec_bug(&PTR_BUCKET(c, k, i)->pin);
190} 190}
191 191
192static void bkey_put(struct cache_set *c, struct bkey *k, int level)
193{
194 if ((level && KEY_OFFSET(k)) || !level)
195 __bkey_put(c, k);
196}
197
198/* Btree IO */ 192/* Btree IO */
199 193
200static uint64_t btree_csum_set(struct btree *b, struct bset *i) 194static uint64_t btree_csum_set(struct btree *b, struct bset *i)
@@ -1068,6 +1062,7 @@ retry:
1068 if (__bch_bucket_alloc_set(c, WATERMARK_METADATA, &k.key, 1, true)) 1062 if (__bch_bucket_alloc_set(c, WATERMARK_METADATA, &k.key, 1, true))
1069 goto err; 1063 goto err;
1070 1064
1065 bkey_put(c, &k.key);
1071 SET_KEY_SIZE(&k.key, c->btree_pages * PAGE_SECTORS); 1066 SET_KEY_SIZE(&k.key, c->btree_pages * PAGE_SECTORS);
1072 1067
1073 b = mca_alloc(c, &k.key, level); 1068 b = mca_alloc(c, &k.key, level);
@@ -1077,7 +1072,6 @@ retry:
1077 if (!b) { 1072 if (!b) {
1078 cache_bug(c, 1073 cache_bug(c,
1079 "Tried to allocate bucket that was in btree cache"); 1074 "Tried to allocate bucket that was in btree cache");
1080 __bkey_put(c, &k.key);
1081 goto retry; 1075 goto retry;
1082 } 1076 }
1083 1077
@@ -1090,7 +1084,6 @@ retry:
1090 return b; 1084 return b;
1091err_free: 1085err_free:
1092 bch_bucket_free(c, &k.key); 1086 bch_bucket_free(c, &k.key);
1093 __bkey_put(c, &k.key);
1094err: 1087err:
1095 mutex_unlock(&c->bucket_lock); 1088 mutex_unlock(&c->bucket_lock);
1096 1089
@@ -1217,7 +1210,6 @@ static struct btree *btree_gc_alloc(struct btree *b, struct bkey *k)
1217 1210
1218 if (!IS_ERR_OR_NULL(n)) { 1211 if (!IS_ERR_OR_NULL(n)) {
1219 swap(b, n); 1212 swap(b, n);
1220 __bkey_put(b->c, &b->key);
1221 1213
1222 memcpy(k->ptr, b->key.ptr, 1214 memcpy(k->ptr, b->key.ptr,
1223 sizeof(uint64_t) * KEY_PTRS(&b->key)); 1215 sizeof(uint64_t) * KEY_PTRS(&b->key));
@@ -1932,19 +1924,12 @@ static bool bch_btree_insert_keys(struct btree *b, struct btree_op *op,
1932 break; 1924 break;
1933 1925
1934 if (bkey_cmp(k, &b->key) <= 0) { 1926 if (bkey_cmp(k, &b->key) <= 0) {
1935 bkey_put(b->c, k, b->level); 1927 if (!b->level)
1928 bkey_put(b->c, k);
1936 1929
1937 ret |= btree_insert_key(b, op, k, replace_key); 1930 ret |= btree_insert_key(b, op, k, replace_key);
1938 bch_keylist_pop_front(insert_keys); 1931 bch_keylist_pop_front(insert_keys);
1939 } else if (bkey_cmp(&START_KEY(k), &b->key) < 0) { 1932 } else if (bkey_cmp(&START_KEY(k), &b->key) < 0) {
1940#if 0
1941 if (replace_key) {
1942 bkey_put(b->c, k, b->level);
1943 bch_keylist_pop_front(insert_keys);
1944 op->insert_collision = true;
1945 break;
1946 }
1947#endif
1948 BKEY_PADDED(key) temp; 1933 BKEY_PADDED(key) temp;
1949 bkey_copy(&temp.key, insert_keys->keys); 1934 bkey_copy(&temp.key, insert_keys->keys);
1950 1935
@@ -2071,11 +2056,9 @@ static int btree_split(struct btree *b, struct btree_op *op,
2071 2056
2072 return 0; 2057 return 0;
2073err_free2: 2058err_free2:
2074 __bkey_put(n2->c, &n2->key);
2075 btree_node_free(n2); 2059 btree_node_free(n2);
2076 rw_unlock(true, n2); 2060 rw_unlock(true, n2);
2077err_free1: 2061err_free1:
2078 __bkey_put(n1->c, &n1->key);
2079 btree_node_free(n1); 2062 btree_node_free(n1);
2080 rw_unlock(true, n1); 2063 rw_unlock(true, n1);
2081err: 2064err:
@@ -2225,7 +2208,7 @@ int bch_btree_insert(struct cache_set *c, struct keylist *keys,
2225 pr_err("error %i", ret); 2208 pr_err("error %i", ret);
2226 2209
2227 while ((k = bch_keylist_pop(keys))) 2210 while ((k = bch_keylist_pop(keys)))
2228 bkey_put(c, k, 0); 2211 bkey_put(c, k);
2229 } else if (op.op.insert_collision) 2212 } else if (op.op.insert_collision)
2230 ret = -ESRCH; 2213 ret = -ESRCH;
2231 2214
@@ -2251,7 +2234,6 @@ void bch_btree_set_root(struct btree *b)
2251 mutex_unlock(&b->c->bucket_lock); 2234 mutex_unlock(&b->c->bucket_lock);
2252 2235
2253 b->c->root = b; 2236 b->c->root = b;
2254 __bkey_put(b->c, &b->key);
2255 2237
2256 bch_journal_meta(b->c, &cl); 2238 bch_journal_meta(b->c, &cl);
2257 closure_sync(&cl); 2239 closure_sync(&cl);
diff --git a/drivers/md/bcache/btree.h b/drivers/md/bcache/btree.h
index 27e90b189112..d4b705eeec24 100644
--- a/drivers/md/bcache/btree.h
+++ b/drivers/md/bcache/btree.h
@@ -216,7 +216,7 @@ static inline struct bkey *bch_btree_iter_init(struct btree *b,
216 return __bch_btree_iter_init(b, iter, search, b->sets); 216 return __bch_btree_iter_init(b, iter, search, b->sets);
217} 217}
218 218
219void __bkey_put(struct cache_set *c, struct bkey *k); 219void bkey_put(struct cache_set *c, struct bkey *k);
220 220
221/* Looping macros */ 221/* Looping macros */
222 222
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index c67d19a8913d..05f8ccb9f8ca 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -426,7 +426,7 @@ static int __uuid_write(struct cache_set *c)
426 closure_sync(&cl); 426 closure_sync(&cl);
427 427
428 bkey_copy(&c->uuid_bucket, &k.key); 428 bkey_copy(&c->uuid_bucket, &k.key);
429 __bkey_put(c, &k.key); 429 bkey_put(c, &k.key);
430 return 0; 430 return 0;
431} 431}
432 432