diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2016-04-25 22:41:55 -0800 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2017-01-18 21:39:20 -0900 |
commit | 0a744dc46e969f531bc62abee28e670dd85a1eec (patch) | |
tree | bc8be278527f083cfab49a02aecb71efed508e61 | |
parent | a3b76d5b38af09034e07dbd036d034b850d959ec (diff) |
bcache: fix promotion locking bug
promote path uses @k for replace key, but it pointed into unlocked btree node
-rw-r--r-- | drivers/md/bcache/fs-io.c | 7 | ||||
-rw-r--r-- | drivers/md/bcache/io.c | 6 | ||||
-rw-r--r-- | drivers/md/bcache/request.c | 6 |
3 files changed, 13 insertions, 6 deletions
diff --git a/drivers/md/bcache/fs-io.c b/drivers/md/bcache/fs-io.c index add3db305fa9..fd1c751c2e57 100644 --- a/drivers/md/bcache/fs-io.c +++ b/drivers/md/bcache/fs-io.c @@ -642,17 +642,20 @@ static void bchfs_read(struct cache_set *c, struct bch_read_bio *rbio, u64 inode for_each_btree_key_with_holes(&iter, c, BTREE_ID_EXTENTS, POS(inode, bio->bi_iter.bi_sector), k) { + BKEY_PADDED(k) tmp; struct extent_pick_ptr pick; unsigned bytes, sectors; bool is_last; + bkey_reassemble(&tmp.k, k); + bch_btree_iter_unlock(&iter); + k = bkey_i_to_s_c(&tmp.k); + if (!bkey_extent_is_allocation(k.k) || bkey_extent_is_compressed(c, k)) bch_mark_pages_unalloc(bio); bch_extent_pick_ptr(c, k, &pick); - bch_btree_iter_unlock(&iter); - if (IS_ERR(pick.ca)) { bcache_io_error(c, bio, "no device to read from"); bio_endio(bio); diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c index 06da65f2fbb3..3f30cbcb0492 100644 --- a/drivers/md/bcache/io.c +++ b/drivers/md/bcache/io.c @@ -1885,18 +1885,20 @@ static void bch_read_iter(struct cache_set *c, struct bch_read_bio *rbio, for_each_btree_key_with_holes(&iter, c, BTREE_ID_EXTENTS, POS(inode, bvec_iter.bi_sector), k) { + BKEY_PADDED(k) tmp; struct extent_pick_ptr pick; unsigned bytes, sectors; bool is_last; - bch_extent_pick_ptr(c, k, &pick); - /* * Unlock the iterator while the btree node's lock is still in * cache, before doing the IO: */ + bkey_reassemble(&tmp.k, k); + k = bkey_i_to_s_c(&tmp.k); bch_btree_iter_unlock(&iter); + bch_extent_pick_ptr(c, k, &pick); if (IS_ERR(pick.ca)) { bcache_io_error(c, bio, "no device to read from"); bio_endio(bio); diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index 5ad20f2d87dc..97a2ba16fb1f 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c @@ -402,17 +402,19 @@ static void cached_dev_read(struct cached_dev *dc, struct search *s) for_each_btree_key_with_holes(&iter, s->iop.c, BTREE_ID_EXTENTS, POS(s->inode, bio->bi_iter.bi_sector), k) { + BKEY_PADDED(k) tmp; struct extent_pick_ptr pick; unsigned sectors, bytes; bool is_last; retry: - + bkey_reassemble(&tmp.k, k); + bch_btree_iter_unlock(&iter); + k = bkey_i_to_s_c(&tmp.k); bch_extent_pick_ptr(s->iop.c, k, &pick); if (IS_ERR(pick.ca)) { bcache_io_error(s->iop.c, bio, "no device to read from"); - bch_btree_iter_unlock(&iter); goto out; } |