Darrick J. Wong
2013-Sep-20 03:37 UTC
[PATCH] btrfs: Fix crash due to not allocating integrity data for a bioset
When btrfs creates a bioset, we must also allocate the integrity data pool. Otherwise btrfs will crash when it tries to submit a bio to a checksumming disk: BUG: unable to handle kernel NULL pointer dereference at 0000000000000018 IP: [<ffffffff8111e28a>] mempool_alloc+0x4a/0x150 PGD 2305e4067 PUD 23063d067 PMD 0 Oops: 0000 [#1] PREEMPT SMP Modules linked in: btrfs scsi_debug xfs ext4 jbd2 ext3 jbd mbcache sch_fq_codel eeprom lpc_ich mfd_core nfsd exportfs auth_rpcgss af_packet raid6_pq xor zlib_deflate libcrc32c [last unloaded: scsi_debug] CPU: 1 PID: 4486 Comm: mount Not tainted 3.12.0-rc1-mcsum #2 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 task: ffff8802451c9720 ti: ffff880230698000 task.ti: ffff880230698000 RIP: 0010:[<ffffffff8111e28a>] [<ffffffff8111e28a>] mempool_alloc+0x4a/0x150 RSP: 0018:ffff880230699688 EFLAGS: 00010286 RAX: 0000000000000001 RBX: 0000000000000000 RCX: 00000000005f8445 RDX: 0000000000000001 RSI: 0000000000000010 RDI: 0000000000000000 RBP: ffff8802306996f8 R08: 0000000000011200 R09: 0000000000000008 R10: 0000000000000020 R11: ffff88009d6e8000 R12: 0000000000011210 R13: 0000000000000030 R14: ffff8802306996b8 R15: ffff8802451c9720 FS: 00007f25b8a16800(0000) GS:ffff88024fc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000018 CR3: 0000000230576000 CR4: 00000000000007e0 Stack: ffff8802451c9720 0000000000000002 ffffffff81a97100 0000000000281250 ffffffff81a96480 ffff88024fc99150 ffff880228d18200 0000000000000000 0000000000000000 0000000000000040 ffff880230e8c2e8 ffff8802459dc900 Call Trace: [<ffffffff811b2208>] bio_integrity_alloc+0x48/0x1b0 [<ffffffff811b26fc>] bio_integrity_prep+0xac/0x360 [<ffffffff8111e298>] ? mempool_alloc+0x58/0x150 [<ffffffffa03e8041>] ? alloc_extent_state+0x31/0x110 [btrfs] [<ffffffff81241579>] blk_queue_bio+0x1c9/0x460 [<ffffffff8123e58a>] generic_make_request+0xca/0x100 [<ffffffff8123e639>] submit_bio+0x79/0x160 [<ffffffffa03f865e>] btrfs_map_bio+0x48e/0x5b0 [btrfs] [<ffffffffa03c821a>] btree_submit_bio_hook+0xda/0x110 [btrfs] [<ffffffffa03e7eba>] submit_one_bio+0x6a/0xa0 [btrfs] [<ffffffffa03ef450>] read_extent_buffer_pages+0x250/0x310 [btrfs] [<ffffffff8125eef6>] ? __radix_tree_preload+0x66/0xf0 [<ffffffff8125f1c5>] ? radix_tree_insert+0x95/0x260 [<ffffffffa03c66f6>] btree_read_extent_buffer_pages.constprop.128+0xb6/0x120 [btrfs] [<ffffffffa03c8c1a>] read_tree_block+0x3a/0x60 [btrfs] [<ffffffffa03caefd>] open_ctree+0x139d/0x2030 [btrfs] [<ffffffffa03a282a>] btrfs_mount+0x53a/0x7d0 [btrfs] [<ffffffff8113ab0b>] ? pcpu_alloc+0x8eb/0x9f0 [<ffffffff81167305>] ? __kmalloc_track_caller+0x35/0x1e0 [<ffffffff81176ba0>] mount_fs+0x20/0xd0 [<ffffffff81191096>] vfs_kern_mount+0x76/0x120 [<ffffffff81193320>] do_mount+0x200/0xa40 [<ffffffff81135cdb>] ? strndup_user+0x5b/0x80 [<ffffffff81193bf0>] SyS_mount+0x90/0xe0 [<ffffffff8156d31d>] system_call_fastpath+0x1a/0x1f Code: 4c 8d 75 a8 4c 89 6d e8 45 89 e0 4c 8d 6f 30 48 89 5d d8 41 83 e0 af 48 89 fb 49 83 c6 18 4c 89 7d f8 65 4c 8b 3c 25 c0 b8 00 00 <48> 8b 73 18 44 89 c7 44 89 45 98 ff 53 20 48 85 c0 48 89 c2 74 RIP [<ffffffff8111e28a>] mempool_alloc+0x4a/0x150 RSP <ffff880230699688> CR2: 0000000000000018 ---[ end trace 7a96042017ed21e2 ]--- Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/btrfs/extent_io.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 09582b8..ae131c0 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -145,8 +145,16 @@ int __init extent_io_init(void) offsetof(struct btrfs_io_bio, bio)); if (!btrfs_bioset) goto free_buffer_cache; + + if (bioset_integrity_create(btrfs_bioset, BIO_POOL_SIZE)) + goto free_bioset; + return 0; +free_bioset: + bioset_free(btrfs_bioset); + btrfs_bioset = NULL; + free_buffer_cache: kmem_cache_destroy(extent_buffer_cache); extent_buffer_cache = NULL; @@ -170,8 +178,10 @@ void extent_io_exit(void) kmem_cache_destroy(extent_state_cache); if (extent_buffer_cache) kmem_cache_destroy(extent_buffer_cache); - if (btrfs_bioset) + if (btrfs_bioset) { + bioset_integrity_free(btrfs_bioset); bioset_free(btrfs_bioset); + } } void extent_io_tree_init(struct extent_io_tree *tree, -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Josef Bacik
2013-Sep-26 18:12 UTC
Re: [PATCH] btrfs: Fix crash due to not allocating integrity data for a bioset
On Thu, Sep 19, 2013 at 08:37:07PM -0700, Darrick J. Wong wrote:> When btrfs creates a bioset, we must also allocate the integrity data pool. > Otherwise btrfs will crash when it tries to submit a bio to a checksumming > disk: > > BUG: unable to handle kernel NULL pointer dereference at 0000000000000018 > IP: [<ffffffff8111e28a>] mempool_alloc+0x4a/0x150 > PGD 2305e4067 PUD 23063d067 PMD 0 > Oops: 0000 [#1] PREEMPT SMP > Modules linked in: btrfs scsi_debug xfs ext4 jbd2 ext3 jbd mbcache > sch_fq_codel eeprom lpc_ich mfd_core nfsd exportfs auth_rpcgss af_packet > raid6_pq xor zlib_deflate libcrc32c [last unloaded: scsi_debug] > CPU: 1 PID: 4486 Comm: mount Not tainted 3.12.0-rc1-mcsum #2 > Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 > task: ffff8802451c9720 ti: ffff880230698000 task.ti: ffff880230698000 > RIP: 0010:[<ffffffff8111e28a>] [<ffffffff8111e28a>] mempool_alloc+0x4a/0x150 > RSP: 0018:ffff880230699688 EFLAGS: 00010286 > RAX: 0000000000000001 RBX: 0000000000000000 RCX: 00000000005f8445 > RDX: 0000000000000001 RSI: 0000000000000010 RDI: 0000000000000000 > RBP: ffff8802306996f8 R08: 0000000000011200 R09: 0000000000000008 > R10: 0000000000000020 R11: ffff88009d6e8000 R12: 0000000000011210 > R13: 0000000000000030 R14: ffff8802306996b8 R15: ffff8802451c9720 > FS: 00007f25b8a16800(0000) GS:ffff88024fc80000(0000) knlGS:0000000000000000 > CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b > CR2: 0000000000000018 CR3: 0000000230576000 CR4: 00000000000007e0 > Stack: > ffff8802451c9720 0000000000000002 ffffffff81a97100 0000000000281250 > ffffffff81a96480 ffff88024fc99150 ffff880228d18200 0000000000000000 > 0000000000000000 0000000000000040 ffff880230e8c2e8 ffff8802459dc900 > Call Trace: > [<ffffffff811b2208>] bio_integrity_alloc+0x48/0x1b0 > [<ffffffff811b26fc>] bio_integrity_prep+0xac/0x360 > [<ffffffff8111e298>] ? mempool_alloc+0x58/0x150 > [<ffffffffa03e8041>] ? alloc_extent_state+0x31/0x110 [btrfs] > [<ffffffff81241579>] blk_queue_bio+0x1c9/0x460 > [<ffffffff8123e58a>] generic_make_request+0xca/0x100 > [<ffffffff8123e639>] submit_bio+0x79/0x160 > [<ffffffffa03f865e>] btrfs_map_bio+0x48e/0x5b0 [btrfs] > [<ffffffffa03c821a>] btree_submit_bio_hook+0xda/0x110 [btrfs] > [<ffffffffa03e7eba>] submit_one_bio+0x6a/0xa0 [btrfs] > [<ffffffffa03ef450>] read_extent_buffer_pages+0x250/0x310 [btrfs] > [<ffffffff8125eef6>] ? __radix_tree_preload+0x66/0xf0 > [<ffffffff8125f1c5>] ? radix_tree_insert+0x95/0x260 > [<ffffffffa03c66f6>] btree_read_extent_buffer_pages.constprop.128+0xb6/0x120 > [btrfs] > [<ffffffffa03c8c1a>] read_tree_block+0x3a/0x60 [btrfs] > [<ffffffffa03caefd>] open_ctree+0x139d/0x2030 [btrfs] > [<ffffffffa03a282a>] btrfs_mount+0x53a/0x7d0 [btrfs] > [<ffffffff8113ab0b>] ? pcpu_alloc+0x8eb/0x9f0 > [<ffffffff81167305>] ? __kmalloc_track_caller+0x35/0x1e0 > [<ffffffff81176ba0>] mount_fs+0x20/0xd0 > [<ffffffff81191096>] vfs_kern_mount+0x76/0x120 > [<ffffffff81193320>] do_mount+0x200/0xa40 > [<ffffffff81135cdb>] ? strndup_user+0x5b/0x80 > [<ffffffff81193bf0>] SyS_mount+0x90/0xe0 > [<ffffffff8156d31d>] system_call_fastpath+0x1a/0x1f > Code: 4c 8d 75 a8 4c 89 6d e8 45 89 e0 4c 8d 6f 30 48 89 5d d8 41 83 e0 af 48 > 89 fb 49 83 c6 18 4c 89 7d f8 65 4c 8b 3c 25 c0 b8 00 00 <48> 8b 73 18 44 89 c7 > 44 89 45 98 ff 53 20 48 85 c0 48 89 c2 74 > RIP [<ffffffff8111e28a>] mempool_alloc+0x4a/0x150 > RSP <ffff880230699688> > CR2: 0000000000000018 > ---[ end trace 7a96042017ed21e2 ]--- > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > fs/btrfs/extent_io.c | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c > index 09582b8..ae131c0 100644 > --- a/fs/btrfs/extent_io.c > +++ b/fs/btrfs/extent_io.c > @@ -145,8 +145,16 @@ int __init extent_io_init(void) > offsetof(struct btrfs_io_bio, bio)); > if (!btrfs_bioset) > goto free_buffer_cache; > + > + if (bioset_integrity_create(btrfs_bioset, BIO_POOL_SIZE)) > + goto free_bioset; > + > return 0; > > +free_bioset: > + bioset_free(btrfs_bioset); > + btrfs_bioset = NULL; > + > free_buffer_cache: > kmem_cache_destroy(extent_buffer_cache); > extent_buffer_cache = NULL; > @@ -170,8 +178,10 @@ void extent_io_exit(void) > kmem_cache_destroy(extent_state_cache); > if (extent_buffer_cache) > kmem_cache_destroy(extent_buffer_cache); > - if (btrfs_bioset) > + if (btrfs_bioset) { > + bioset_integrity_free(btrfs_bioset);This is wrong, bioset_free calls bioset_integrity_free(), I''m fixing it up locally. Thanks, Josef -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html