diff options
Diffstat (limited to 'drivers/md/bcache/btree.c')
-rw-r--r-- | drivers/md/bcache/btree.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index 5e2765aadce1..31bb53fcc67a 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c | |||
@@ -1561,6 +1561,28 @@ size_t bch_btree_gc_finish(struct cache_set *c) | |||
1561 | SET_GC_MARK(PTR_BUCKET(c, &c->uuid_bucket, i), | 1561 | SET_GC_MARK(PTR_BUCKET(c, &c->uuid_bucket, i), |
1562 | GC_MARK_METADATA); | 1562 | GC_MARK_METADATA); |
1563 | 1563 | ||
1564 | /* don't reclaim buckets to which writeback keys point */ | ||
1565 | rcu_read_lock(); | ||
1566 | for (i = 0; i < c->nr_uuids; i++) { | ||
1567 | struct bcache_device *d = c->devices[i]; | ||
1568 | struct cached_dev *dc; | ||
1569 | struct keybuf_key *w, *n; | ||
1570 | unsigned j; | ||
1571 | |||
1572 | if (!d || UUID_FLASH_ONLY(&c->uuids[i])) | ||
1573 | continue; | ||
1574 | dc = container_of(d, struct cached_dev, disk); | ||
1575 | |||
1576 | spin_lock(&dc->writeback_keys.lock); | ||
1577 | rbtree_postorder_for_each_entry_safe(w, n, | ||
1578 | &dc->writeback_keys.keys, node) | ||
1579 | for (j = 0; j < KEY_PTRS(&w->key); j++) | ||
1580 | SET_GC_MARK(PTR_BUCKET(c, &w->key, j), | ||
1581 | GC_MARK_DIRTY); | ||
1582 | spin_unlock(&dc->writeback_keys.lock); | ||
1583 | } | ||
1584 | rcu_read_unlock(); | ||
1585 | |||
1564 | for_each_cache(ca, c, i) { | 1586 | for_each_cache(ca, c, i) { |
1565 | uint64_t *i; | 1587 | uint64_t *i; |
1566 | 1588 | ||
@@ -1817,7 +1839,8 @@ static bool fix_overlapping_extents(struct btree *b, struct bkey *insert, | |||
1817 | if (KEY_START(k) > KEY_START(insert) + sectors_found) | 1839 | if (KEY_START(k) > KEY_START(insert) + sectors_found) |
1818 | goto check_failed; | 1840 | goto check_failed; |
1819 | 1841 | ||
1820 | if (KEY_PTRS(replace_key) != KEY_PTRS(k)) | 1842 | if (KEY_PTRS(k) != KEY_PTRS(replace_key) || |
1843 | KEY_DIRTY(k) != KEY_DIRTY(replace_key)) | ||
1821 | goto check_failed; | 1844 | goto check_failed; |
1822 | 1845 | ||
1823 | /* skip past gen */ | 1846 | /* skip past gen */ |
@@ -2217,7 +2240,7 @@ struct btree_insert_op { | |||
2217 | struct bkey *replace_key; | 2240 | struct bkey *replace_key; |
2218 | }; | 2241 | }; |
2219 | 2242 | ||
2220 | int btree_insert_fn(struct btree_op *b_op, struct btree *b) | 2243 | static int btree_insert_fn(struct btree_op *b_op, struct btree *b) |
2221 | { | 2244 | { |
2222 | struct btree_insert_op *op = container_of(b_op, | 2245 | struct btree_insert_op *op = container_of(b_op, |
2223 | struct btree_insert_op, op); | 2246 | struct btree_insert_op, op); |