aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorSlava Pestov <sp@daterainc.com>2014-07-12 03:22:53 -0400
committerKent Overstreet <kmo@daterainc.com>2014-08-04 18:23:04 -0400
commit2452cc89063a2a6890368f185c4b6d7d8802179e (patch)
tree842af976b4c614cb1cf6b27c60bb7bbaac1f8cb1 /drivers/md
parentc9a78332b42cbdcdd386a95192a716b67d1711a4 (diff)
bcache: try to set b->parent properly
bcache_flash_dev.ktest would reliably crash with 8k and 16k bucket size before; now it passes. Change-Id: Ib542232235e39298c3a7548fe52b645cabb823d1
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/bcache/btree.c37
-rw-r--r--drivers/md/bcache/btree.h4
-rw-r--r--drivers/md/bcache/super.c4
3 files changed, 25 insertions, 20 deletions
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
index 776583f7247d..00cde40db572 100644
--- a/drivers/md/bcache/btree.c
+++ b/drivers/md/bcache/btree.c
@@ -117,9 +117,9 @@
117({ \ 117({ \
118 int _r, l = (b)->level - 1; \ 118 int _r, l = (b)->level - 1; \
119 bool _w = l <= (op)->lock; \ 119 bool _w = l <= (op)->lock; \
120 struct btree *_child = bch_btree_node_get((b)->c, op, key, l, _w);\ 120 struct btree *_child = bch_btree_node_get((b)->c, op, key, l, \
121 _w, b); \
121 if (!IS_ERR(_child)) { \ 122 if (!IS_ERR(_child)) { \
122 _child->parent = (b); \
123 _r = bch_btree_ ## fn(_child, op, ##__VA_ARGS__); \ 123 _r = bch_btree_ ## fn(_child, op, ##__VA_ARGS__); \
124 rw_unlock(_w, _child); \ 124 rw_unlock(_w, _child); \
125 } else \ 125 } else \
@@ -142,7 +142,6 @@
142 rw_lock(_w, _b, _b->level); \ 142 rw_lock(_w, _b, _b->level); \
143 if (_b == (c)->root && \ 143 if (_b == (c)->root && \
144 _w == insert_lock(op, _b)) { \ 144 _w == insert_lock(op, _b)) { \
145 _b->parent = NULL; \
146 _r = bch_btree_ ## fn(_b, op, ##__VA_ARGS__); \ 145 _r = bch_btree_ ## fn(_b, op, ##__VA_ARGS__); \
147 } \ 146 } \
148 rw_unlock(_w, _b); \ 147 rw_unlock(_w, _b); \
@@ -967,7 +966,8 @@ err:
967 * level and op->lock. 966 * level and op->lock.
968 */ 967 */
969struct btree *bch_btree_node_get(struct cache_set *c, struct btree_op *op, 968struct btree *bch_btree_node_get(struct cache_set *c, struct btree_op *op,
970 struct bkey *k, int level, bool write) 969 struct bkey *k, int level, bool write,
970 struct btree *parent)
971{ 971{
972 int i = 0; 972 int i = 0;
973 struct btree *b; 973 struct btree *b;
@@ -1002,6 +1002,7 @@ retry:
1002 BUG_ON(b->level != level); 1002 BUG_ON(b->level != level);
1003 } 1003 }
1004 1004
1005 b->parent = parent;
1005 b->accessed = 1; 1006 b->accessed = 1;
1006 1007
1007 for (; i <= b->keys.nsets && b->keys.set[i].size; i++) { 1008 for (; i <= b->keys.nsets && b->keys.set[i].size; i++) {
@@ -1022,15 +1023,16 @@ retry:
1022 return b; 1023 return b;
1023} 1024}
1024 1025
1025static void btree_node_prefetch(struct cache_set *c, struct bkey *k, int level) 1026static void btree_node_prefetch(struct btree *parent, struct bkey *k)
1026{ 1027{
1027 struct btree *b; 1028 struct btree *b;
1028 1029
1029 mutex_lock(&c->bucket_lock); 1030 mutex_lock(&parent->c->bucket_lock);
1030 b = mca_alloc(c, NULL, k, level); 1031 b = mca_alloc(parent->c, NULL, k, parent->level - 1);
1031 mutex_unlock(&c->bucket_lock); 1032 mutex_unlock(&parent->c->bucket_lock);
1032 1033
1033 if (!IS_ERR_OR_NULL(b)) { 1034 if (!IS_ERR_OR_NULL(b)) {
1035 b->parent = parent;
1034 bch_btree_node_read(b); 1036 bch_btree_node_read(b);
1035 rw_unlock(true, b); 1037 rw_unlock(true, b);
1036 } 1038 }
@@ -1061,7 +1063,8 @@ static void btree_node_free(struct btree *b)
1061} 1063}
1062 1064
1063struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op, 1065struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op,
1064 int level, bool wait) 1066 int level, bool wait,
1067 struct btree *parent)
1065{ 1068{
1066 BKEY_PADDED(key) k; 1069 BKEY_PADDED(key) k;
1067 struct btree *b = ERR_PTR(-EAGAIN); 1070 struct btree *b = ERR_PTR(-EAGAIN);
@@ -1085,6 +1088,7 @@ retry:
1085 } 1088 }
1086 1089
1087 b->accessed = 1; 1090 b->accessed = 1;
1091 b->parent = parent;
1088 bch_bset_init_next(&b->keys, b->keys.set->data, bset_magic(&b->c->sb)); 1092 bch_bset_init_next(&b->keys, b->keys.set->data, bset_magic(&b->c->sb));
1089 1093
1090 mutex_unlock(&c->bucket_lock); 1094 mutex_unlock(&c->bucket_lock);
@@ -1101,15 +1105,16 @@ err:
1101} 1105}
1102 1106
1103static struct btree *bch_btree_node_alloc(struct cache_set *c, 1107static struct btree *bch_btree_node_alloc(struct cache_set *c,
1104 struct btree_op *op, int level) 1108 struct btree_op *op, int level,
1109 struct btree *parent)
1105{ 1110{
1106 return __bch_btree_node_alloc(c, op, level, op != NULL); 1111 return __bch_btree_node_alloc(c, op, level, op != NULL, parent);
1107} 1112}
1108 1113
1109static struct btree *btree_node_alloc_replacement(struct btree *b, 1114static struct btree *btree_node_alloc_replacement(struct btree *b,
1110 struct btree_op *op) 1115 struct btree_op *op)
1111{ 1116{
1112 struct btree *n = bch_btree_node_alloc(b->c, op, b->level); 1117 struct btree *n = bch_btree_node_alloc(b->c, op, b->level, b->parent);
1113 if (!IS_ERR_OR_NULL(n)) { 1118 if (!IS_ERR_OR_NULL(n)) {
1114 mutex_lock(&n->write_lock); 1119 mutex_lock(&n->write_lock);
1115 bch_btree_sort_into(&b->keys, &n->keys, &b->c->sort); 1120 bch_btree_sort_into(&b->keys, &n->keys, &b->c->sort);
@@ -1523,7 +1528,7 @@ static int btree_gc_recurse(struct btree *b, struct btree_op *op,
1523 k = bch_btree_iter_next_filter(&iter, &b->keys, bch_ptr_bad); 1528 k = bch_btree_iter_next_filter(&iter, &b->keys, bch_ptr_bad);
1524 if (k) { 1529 if (k) {
1525 r->b = bch_btree_node_get(b->c, op, k, b->level - 1, 1530 r->b = bch_btree_node_get(b->c, op, k, b->level - 1,
1526 true); 1531 true, b);
1527 if (IS_ERR(r->b)) { 1532 if (IS_ERR(r->b)) {
1528 ret = PTR_ERR(r->b); 1533 ret = PTR_ERR(r->b);
1529 break; 1534 break;
@@ -1818,7 +1823,7 @@ static int bch_btree_check_recurse(struct btree *b, struct btree_op *op)
1818 k = bch_btree_iter_next_filter(&iter, &b->keys, 1823 k = bch_btree_iter_next_filter(&iter, &b->keys,
1819 bch_ptr_bad); 1824 bch_ptr_bad);
1820 if (k) 1825 if (k)
1821 btree_node_prefetch(b->c, k, b->level - 1); 1826 btree_node_prefetch(b, k);
1822 1827
1823 if (p) 1828 if (p)
1824 ret = btree(check_recurse, p, b, op); 1829 ret = btree(check_recurse, p, b, op);
@@ -1983,12 +1988,12 @@ static int btree_split(struct btree *b, struct btree_op *op,
1983 1988
1984 trace_bcache_btree_node_split(b, btree_bset_first(n1)->keys); 1989 trace_bcache_btree_node_split(b, btree_bset_first(n1)->keys);
1985 1990
1986 n2 = bch_btree_node_alloc(b->c, op, b->level); 1991 n2 = bch_btree_node_alloc(b->c, op, b->level, b->parent);
1987 if (IS_ERR(n2)) 1992 if (IS_ERR(n2))
1988 goto err_free1; 1993 goto err_free1;
1989 1994
1990 if (!b->parent) { 1995 if (!b->parent) {
1991 n3 = bch_btree_node_alloc(b->c, op, b->level + 1); 1996 n3 = bch_btree_node_alloc(b->c, op, b->level + 1, NULL);
1992 if (IS_ERR(n3)) 1997 if (IS_ERR(n3))
1993 goto err_free2; 1998 goto err_free2;
1994 } 1999 }
diff --git a/drivers/md/bcache/btree.h b/drivers/md/bcache/btree.h
index 00441821f5ad..5c391fa01bed 100644
--- a/drivers/md/bcache/btree.h
+++ b/drivers/md/bcache/btree.h
@@ -243,9 +243,9 @@ void bch_btree_node_write(struct btree *, struct closure *);
243 243
244void bch_btree_set_root(struct btree *); 244void bch_btree_set_root(struct btree *);
245struct btree *__bch_btree_node_alloc(struct cache_set *, struct btree_op *, 245struct btree *__bch_btree_node_alloc(struct cache_set *, struct btree_op *,
246 int, bool); 246 int, bool, struct btree *);
247struct btree *bch_btree_node_get(struct cache_set *, struct btree_op *, 247struct btree *bch_btree_node_get(struct cache_set *, struct btree_op *,
248 struct bkey *, int, bool); 248 struct bkey *, int, bool, struct btree *);
249 249
250int bch_btree_insert_check_key(struct btree *, struct btree_op *, 250int bch_btree_insert_check_key(struct btree *, struct btree_op *,
251 struct bkey *); 251 struct bkey *);
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 12ad381bdbab..b6114d672413 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1601,7 +1601,7 @@ static void run_cache_set(struct cache_set *c)
1601 goto err; 1601 goto err;
1602 1602
1603 err = "error reading btree root"; 1603 err = "error reading btree root";
1604 c->root = bch_btree_node_get(c, NULL, k, j->btree_level, true); 1604 c->root = bch_btree_node_get(c, NULL, k, j->btree_level, true, NULL);
1605 if (IS_ERR_OR_NULL(c->root)) 1605 if (IS_ERR_OR_NULL(c->root))
1606 goto err; 1606 goto err;
1607 1607
@@ -1676,7 +1676,7 @@ static void run_cache_set(struct cache_set *c)
1676 goto err; 1676 goto err;
1677 1677
1678 err = "cannot allocate new btree root"; 1678 err = "cannot allocate new btree root";
1679 c->root = __bch_btree_node_alloc(c, NULL, 0, true); 1679 c->root = __bch_btree_node_alloc(c, NULL, 0, true, NULL);
1680 if (IS_ERR_OR_NULL(c->root)) 1680 if (IS_ERR_OR_NULL(c->root))
1681 goto err; 1681 goto err;
1682 1682