aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/check-integrity.c
diff options
context:
space:
mode:
authorShilong Wang <wangshilong1991@gmail.com>2014-10-10 17:35:59 -0400
committerChris Mason <clm@fb.com>2014-11-20 20:14:28 -0500
commit6b3a4d60dbf7a60b91d810498e8c212f26718efd (patch)
tree9e436defeaefdf64b17493677804486e787460ca /fs/btrfs/check-integrity.c
parente6eb43142a72ba356f9fcd0f0fe2169c3642b460 (diff)
Btrfs: fix allocationg memory failure for btrfsic_state structure
size of @btrfsic_state needs more than 2M, it is very likely to fail allocating memory using kzalloc(). see following mesage: [91428.902148] Call Trace: [<ffffffff816f6e0f>] dump_stack+0x4d/0x66 [<ffffffff811b1c7f>] warn_alloc_failed+0xff/0x170 [<ffffffff811b66e1>] __alloc_pages_nodemask+0x951/0xc30 [<ffffffff811fd9da>] alloc_pages_current+0x11a/0x1f0 [<ffffffff811b1e0b>] ? alloc_kmem_pages+0x3b/0xf0 [<ffffffff811b1e0b>] alloc_kmem_pages+0x3b/0xf0 [<ffffffff811d1018>] kmalloc_order+0x18/0x50 [<ffffffff811d1074>] kmalloc_order_trace+0x24/0x140 [<ffffffffa06c097b>] btrfsic_mount+0x8b/0xae0 [btrfs] [<ffffffff810af555>] ? check_preempt_curr+0x85/0xa0 [<ffffffff810b2de3>] ? try_to_wake_up+0x103/0x430 [<ffffffffa063d200>] open_ctree+0x1bd0/0x2130 [btrfs] [<ffffffffa060fdde>] btrfs_mount+0x62e/0x8b0 [btrfs] [<ffffffff811fd9da>] ? alloc_pages_current+0x11a/0x1f0 [<ffffffff811b0a5e>] ? __get_free_pages+0xe/0x50 [<ffffffff81230429>] mount_fs+0x39/0x1b0 [<ffffffff812509fb>] vfs_kern_mount+0x6b/0x150 [<ffffffff812537fb>] do_mount+0x27b/0xc30 [<ffffffff811b0a5e>] ? __get_free_pages+0xe/0x50 [<ffffffff812544f6>] SyS_mount+0x96/0xf0 [<ffffffff81701970>] system_call_fastpath+0x16/0x1b Since we are allocating memory for hash table array, so it will be good if we could allocate continuous pages here. Fix this problem by firstly trying kzalloc(), if we fail, use vzalloc() instead. Signed-off-by: Wang Shilong <wangshilong1991@gmail.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/check-integrity.c')
-rw-r--r--fs/btrfs/check-integrity.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c
index cb7f3fe9c9f6..66e820f7b440 100644
--- a/fs/btrfs/check-integrity.c
+++ b/fs/btrfs/check-integrity.c
@@ -3130,10 +3130,13 @@ int btrfsic_mount(struct btrfs_root *root,
3130 root->sectorsize, PAGE_CACHE_SIZE); 3130 root->sectorsize, PAGE_CACHE_SIZE);
3131 return -1; 3131 return -1;
3132 } 3132 }
3133 state = kzalloc(sizeof(*state), GFP_NOFS); 3133 state = kzalloc(sizeof(*state), GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
3134 if (NULL == state) { 3134 if (!state) {
3135 printk(KERN_INFO "btrfs check-integrity: kmalloc() failed!\n"); 3135 state = vzalloc(sizeof(*state));
3136 return -1; 3136 if (!state) {
3137 printk(KERN_INFO "btrfs check-integrity: vzalloc() failed!\n");
3138 return -1;
3139 }
3137 } 3140 }
3138 3141
3139 if (!btrfsic_is_initialized) { 3142 if (!btrfsic_is_initialized) {
@@ -3277,5 +3280,8 @@ void btrfsic_unmount(struct btrfs_root *root,
3277 3280
3278 mutex_unlock(&btrfsic_mutex); 3281 mutex_unlock(&btrfsic_mutex);
3279 3282
3280 kfree(state); 3283 if (is_vmalloc_addr(state))
3284 vfree(state);
3285 else
3286 kfree(state);
3281} 3287}