summaryrefslogtreecommitdiffstats
path: root/drivers/md/bcache
diff options
context:
space:
mode:
authorColy Li <colyli@suse.de>2019-06-28 19:59:35 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-07-26 09:10:39 +0200
commit51e5050bf9ccea95bbe8918a811b471bfd311603 (patch)
treee9a170f40a0e17bd22c36bc8fdcec2ef5f120ad5 /drivers/md/bcache
parentc067bf154c846fc9eb6f1e1205031bf9615475c4 (diff)
downloadlinux-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.c9
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);