Skip to content

Commit bf6af17

Browse files
Coly Liaxboe
authored andcommitted
bcache: handle cache set verify_ondisk properly for bucket size > 8MB
In bch_btree_cache_alloc() when CONFIG_BCACHE_DEBUG is configured, allocate memory for c->verify_ondisk may fail if the bucket size > 8MB, which will require __get_free_pages() to allocate continuous pages with order > 11 (the default MAX_ORDER of Linux buddy allocator). Such over size allocation will fail, and cause 2 problems, - When CONFIG_BCACHE_DEBUG is configured, bch_btree_verify() does not work, because c->verify_ondisk is NULL and bch_btree_verify() returns immediately. - bch_btree_cache_alloc() will fail due to c->verify_ondisk allocation failed, then the whole cache device registration fails. And because of this failure, the first problem of bch_btree_verify() has no chance to be triggered. This patch fixes the above problem by two means, 1) If pages allocation of c->verify_ondisk fails, set it to NULL and returns bch_btree_cache_alloc() with -ENOMEM. 2) When calling __get_free_pages() to allocate c->verify_ondisk pages, use ilog2(meta_bucket_pages(&c->sb)) to make sure ilog2() will always generate a pages order <= MAX_ORDER (or CONFIG_FORCE_MAX_ZONEORDER). Then the buddy system won't directly reject the allocation request. Signed-off-by: Coly Li <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent c954ac8 commit bf6af17

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

drivers/md/bcache/btree.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ void bch_btree_cache_free(struct cache_set *c)
738738
if (c->verify_data)
739739
list_move(&c->verify_data->list, &c->btree_cache);
740740

741-
free_pages((unsigned long) c->verify_ondisk, ilog2(bucket_pages(c)));
741+
free_pages((unsigned long) c->verify_ondisk, ilog2(meta_bucket_pages(&c->sb)));
742742
#endif
743743

744744
list_splice(&c->btree_cache_freeable,
@@ -785,7 +785,15 @@ int bch_btree_cache_alloc(struct cache_set *c)
785785
mutex_init(&c->verify_lock);
786786

787787
c->verify_ondisk = (void *)
788-
__get_free_pages(GFP_KERNEL|__GFP_COMP, ilog2(bucket_pages(c)));
788+
__get_free_pages(GFP_KERNEL|__GFP_COMP, ilog2(meta_bucket_pages(&c->sb)));
789+
if (!c->verify_ondisk) {
790+
/*
791+
* Don't worry about the mca_rereserve buckets
792+
* allocated in previous for-loop, they will be
793+
* handled properly in bch_cache_set_unregister().
794+
*/
795+
return -ENOMEM;
796+
}
789797

790798
c->verify_data = mca_bucket_alloc(c, &ZERO_KEY, GFP_KERNEL);
791799

0 commit comments

Comments
 (0)