diff options
author | Coly Li <colyli@suse.de> | 2019-06-28 19:59:35 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-07-26 09:10:39 +0200 |
commit | 51e5050bf9ccea95bbe8918a811b471bfd311603 (patch) | |
tree | e9a170f40a0e17bd22c36bc8fdcec2ef5f120ad5 /drivers/md/bcache | |
parent | c067bf154c846fc9eb6f1e1205031bf9615475c4 (diff) | |
download | linux-stable-51e5050bf9ccea95bbe8918a811b471bfd311603.tar.gz linux-stable-51e5050bf9ccea95bbe8918a811b471bfd311603.tar.bz2 linux-stable-51e5050bf9ccea95bbe8918a811b471bfd311603.zip |
bcache: check CACHE_SET_IO_DISABLE in allocator code
[ Upstream commit e775339e1ae1205b47d94881db124c11385e597c ]
If CACHE_SET_IO_DISABLE of a cache set flag is set by too many I/O
errors, currently allocator routines can still continue allocate
space which may introduce inconsistent metadata state.
This patch checkes CACHE_SET_IO_DISABLE bit in following allocator
routines,
- bch_bucket_alloc()
- __bch_bucket_alloc_set()
Once CACHE_SET_IO_DISABLE is set on cache set, the allocator routines
may reject allocation request earlier to avoid potential inconsistent
metadata.
Signed-off-by: Coly Li <colyli@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/md/bcache')
-rw-r--r-- | drivers/md/bcache/alloc.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c index f8986effcb50..6f776823b9ba 100644 --- a/drivers/md/bcache/alloc.c +++ b/drivers/md/bcache/alloc.c @@ -393,6 +393,11 @@ long bch_bucket_alloc(struct cache *ca, unsigned int reserve, bool wait) struct bucket *b; long r; + + /* No allocation if CACHE_SET_IO_DISABLE bit is set */ + if (unlikely(test_bit(CACHE_SET_IO_DISABLE, &ca->set->flags))) + return -1; + /* fastpath */ if (fifo_pop(&ca->free[RESERVE_NONE], r) || fifo_pop(&ca->free[reserve], r)) @@ -484,6 +489,10 @@ int __bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve, { int i; + /* No allocation if CACHE_SET_IO_DISABLE bit is set */ + if (unlikely(test_bit(CACHE_SET_IO_DISABLE, &c->flags))) + return -1; + lockdep_assert_held(&c->bucket_lock); BUG_ON(!n || n > c->caches_loaded || n > MAX_CACHES_PER_SET); |