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>
Este cometimento está contido em:

cometido por
Chris Mason

ascendente
e6eb43142a
cometimento
6b3a4d60db
@@ -3130,10 +3130,13 @@ int btrfsic_mount(struct btrfs_root *root,
|
||||
root->sectorsize, PAGE_CACHE_SIZE);
|
||||
return -1;
|
||||
}
|
||||
state = kzalloc(sizeof(*state), GFP_NOFS);
|
||||
if (NULL == state) {
|
||||
printk(KERN_INFO "btrfs check-integrity: kmalloc() failed!\n");
|
||||
return -1;
|
||||
state = kzalloc(sizeof(*state), GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
|
||||
if (!state) {
|
||||
state = vzalloc(sizeof(*state));
|
||||
if (!state) {
|
||||
printk(KERN_INFO "btrfs check-integrity: vzalloc() failed!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!btrfsic_is_initialized) {
|
||||
@@ -3277,5 +3280,8 @@ void btrfsic_unmount(struct btrfs_root *root,
|
||||
|
||||
mutex_unlock(&btrfsic_mutex);
|
||||
|
||||
kfree(state);
|
||||
if (is_vmalloc_addr(state))
|
||||
vfree(state);
|
||||
else
|
||||
kfree(state);
|
||||
}
|
||||
|
Criar uma nova questão referindo esta
Bloquear um utilizador