diff mbox series

btrfs: fix assertion failure when splitting ordered extent after transaction abort

Message ID efe1ae546864e0f22b4e29794115e3cedb602c30.1736782338.git.fdmanana@suse.com (mailing list archive)
State New
Headers show
Series btrfs: fix assertion failure when splitting ordered extent after transaction abort | expand

Commit Message

Filipe Manana Jan. 13, 2025, 3:32 p.m. UTC
From: Filipe Manana <fdmanana@suse.com>

If while we are doing a direct IO write a transaction abort happens, we
mark all existing ordered extents with the BTRFS_ORDERED_IOERR flag (done
at btrfs_destroy_ordered_extents()), and then after that if we enter
btrfs_split_ordered_extent() and the ordered extent has bytes left
(meaning we have a bio that doesn't cover the whole ordered extent, see
details at btrfs_extract_ordered_extent()), we will fail on the following
assertion at btrfs_split_ordered_extent():

   ASSERT(!(flags & ~BTRFS_ORDERED_TYPE_FLAGS));

because the BTRFS_ORDERED_IOERR flag is set and the definition of
BTRFS_ORDERED_TYPE_FLAGS is just the union of all flags that identify the
type of write (regular, nocow, prealloc, compressed, direct IO, encoded).

Fix this by returning an error from btrfs_extract_ordered_extent() if we
find the BTRFS_ORDERED_IOERR flag in the ordered extent. The error will
be the error that resulted in the transaction abort or -EIO if no
transaction abort happened.

This was recently reported by syzbot with the following trace:

   FAULT_INJECTION: forcing a failure.
   name failslab, interval 1, probability 0, space 0, times 1
   CPU: 0 UID: 0 PID: 5321 Comm: syz.0.0 Not tainted 6.13.0-rc5-syzkaller #0
   Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
   Call Trace:
    <TASK>
    __dump_stack lib/dump_stack.c:94 [inline]
    dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120
    fail_dump lib/fault-inject.c:53 [inline]
    should_fail_ex+0x3b0/0x4e0 lib/fault-inject.c:154
    should_failslab+0xac/0x100 mm/failslab.c:46
    slab_pre_alloc_hook mm/slub.c:4072 [inline]
    slab_alloc_node mm/slub.c:4148 [inline]
    __do_kmalloc_node mm/slub.c:4297 [inline]
    __kmalloc_noprof+0xdd/0x4c0 mm/slub.c:4310
    kmalloc_noprof include/linux/slab.h:905 [inline]
    kzalloc_noprof include/linux/slab.h:1037 [inline]
    btrfs_chunk_alloc_add_chunk_item+0x244/0x1100 fs/btrfs/volumes.c:5742
    reserve_chunk_space+0x1ca/0x2c0 fs/btrfs/block-group.c:4292
    check_system_chunk fs/btrfs/block-group.c:4319 [inline]
    do_chunk_alloc fs/btrfs/block-group.c:3891 [inline]
    btrfs_chunk_alloc+0x77b/0xf80 fs/btrfs/block-group.c:4187
    find_free_extent_update_loop fs/btrfs/extent-tree.c:4166 [inline]
    find_free_extent+0x42d1/0x5810 fs/btrfs/extent-tree.c:4579
    btrfs_reserve_extent+0x422/0x810 fs/btrfs/extent-tree.c:4672
    btrfs_new_extent_direct fs/btrfs/direct-io.c:186 [inline]
    btrfs_get_blocks_direct_write+0x706/0xfa0 fs/btrfs/direct-io.c:321
    btrfs_dio_iomap_begin+0xbb7/0x1180 fs/btrfs/direct-io.c:525
    iomap_iter+0x697/0xf60 fs/iomap/iter.c:90
    __iomap_dio_rw+0xeb9/0x25b0 fs/iomap/direct-io.c:702
    btrfs_dio_write fs/btrfs/direct-io.c:775 [inline]
    btrfs_direct_write+0x610/0xa30 fs/btrfs/direct-io.c:880
    btrfs_do_write_iter+0x2a0/0x760 fs/btrfs/file.c:1397
    do_iter_readv_writev+0x600/0x880
    vfs_writev+0x376/0xba0 fs/read_write.c:1050
    do_pwritev fs/read_write.c:1146 [inline]
    __do_sys_pwritev2 fs/read_write.c:1204 [inline]
    __se_sys_pwritev2+0x196/0x2b0 fs/read_write.c:1195
    do_syscall_x64 arch/x86/entry/common.c:52 [inline]
    do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
    entry_SYSCALL_64_after_hwframe+0x77/0x7f
   RIP: 0033:0x7f1281f85d29
   Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
   RSP: 002b:00007f12819fe038 EFLAGS: 00000246 ORIG_RAX: 0000000000000148
   RAX: ffffffffffffffda RBX: 00007f1282176080 RCX: 00007f1281f85d29
   RDX: 0000000000000001 RSI: 0000000020000240 RDI: 0000000000000005
   RBP: 00007f12819fe090 R08: 0000000000000000 R09: 0000000000000003
   R10: 0000000000007000 R11: 0000000000000246 R12: 0000000000000002
   R13: 0000000000000000 R14: 00007f1282176080 R15: 00007ffcb9e23328
    </TASK>
   BTRFS error (device loop0 state A): Transaction aborted (error -12)
   BTRFS: error (device loop0 state A) in btrfs_chunk_alloc_add_chunk_item:5745: errno=-12 Out of memory
   BTRFS info (device loop0 state EA): forced readonly
   assertion failed: !(flags & ~BTRFS_ORDERED_TYPE_FLAGS), in fs/btrfs/ordered-data.c:1234
   ------------[ cut here ]------------
   kernel BUG at fs/btrfs/ordered-data.c:1234!
   Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN NOPTI
   CPU: 0 UID: 0 PID: 5321 Comm: syz.0.0 Not tainted 6.13.0-rc5-syzkaller #0
   Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
   RIP: 0010:btrfs_split_ordered_extent+0xd8d/0xe20 fs/btrfs/ordered-data.c:1234
   Code: 43 fd 90 0f 0b e8 43 c4 db fd 48 c7 c7 20 0c 4c 8c 48 c7 c6 80 0f 4c 8c 48 c7 c2 e0 0b 4c 8c b9 d2 04 00 00 e8 04 57 43 fd 90 <0f> 0b e8 1c c4 db fd eb 5b e8 15 c4 db fd 48 c7 c7 20 0c 4c 8c 48
   RSP: 0018:ffffc9000d1df2b8 EFLAGS: 00010246
   RAX: 0000000000000057 RBX: 000000000006a000 RCX: 9ce21886c4195300
   RDX: 0000000000000000 RSI: 0000000080000000 RDI: 0000000000000000
   RBP: 0000000000000091 R08: ffffffff817f0a3c R09: 1ffff92001a3bdf4
   R10: dffffc0000000000 R11: fffff52001a3bdf5 R12: 1ffff1100a45f401
   R13: ffff8880522fa018 R14: dffffc0000000000 R15: 000000000006a000
   FS:  00007f12819fe6c0(0000) GS:ffff88801fc00000(0000) knlGS:0000000000000000
   CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
   CR2: 0000557750bd7da8 CR3: 00000000400ea000 CR4: 0000000000352ef0
   DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
   DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
   Call Trace:
    <TASK>
    btrfs_extract_ordered_extent fs/btrfs/direct-io.c:702 [inline]
    btrfs_dio_submit_io+0x4be/0x6d0 fs/btrfs/direct-io.c:737
    iomap_dio_submit_bio fs/iomap/direct-io.c:85 [inline]
    iomap_dio_bio_iter+0x1022/0x1740 fs/iomap/direct-io.c:447
    __iomap_dio_rw+0x13b7/0x25b0 fs/iomap/direct-io.c:703
    btrfs_dio_write fs/btrfs/direct-io.c:775 [inline]
    btrfs_direct_write+0x610/0xa30 fs/btrfs/direct-io.c:880
    btrfs_do_write_iter+0x2a0/0x760 fs/btrfs/file.c:1397
    do_iter_readv_writev+0x600/0x880
    vfs_writev+0x376/0xba0 fs/read_write.c:1050
    do_pwritev fs/read_write.c:1146 [inline]
    __do_sys_pwritev2 fs/read_write.c:1204 [inline]
    __se_sys_pwritev2+0x196/0x2b0 fs/read_write.c:1195
    do_syscall_x64 arch/x86/entry/common.c:52 [inline]
    do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
    entry_SYSCALL_64_after_hwframe+0x77/0x7f
   RIP: 0033:0x7f1281f85d29
   Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
   RSP: 002b:00007f12819fe038 EFLAGS: 00000246 ORIG_RAX: 0000000000000148
   RAX: ffffffffffffffda RBX: 00007f1282176080 RCX: 00007f1281f85d29
   RDX: 0000000000000001 RSI: 0000000020000240 RDI: 0000000000000005
   RBP: 00007f12819fe090 R08: 0000000000000000 R09: 0000000000000003
   R10: 0000000000007000 R11: 0000000000000246 R12: 0000000000000002
   R13: 0000000000000000 R14: 00007f1282176080 R15: 00007ffcb9e23328
    </TASK>
   Modules linked in:
   ---[ end trace 0000000000000000 ]---
   RIP: 0010:btrfs_split_ordered_extent+0xd8d/0xe20 fs/btrfs/ordered-data.c:1234
   Code: 43 fd 90 0f 0b e8 43 c4 db fd 48 c7 c7 20 0c 4c 8c 48 c7 c6 80 0f 4c 8c 48 c7 c2 e0 0b 4c 8c b9 d2 04 00 00 e8 04 57 43 fd 90 <0f> 0b e8 1c c4 db fd eb 5b e8 15 c4 db fd 48 c7 c7 20 0c 4c 8c 48
   RSP: 0018:ffffc9000d1df2b8 EFLAGS: 00010246
   RAX: 0000000000000057 RBX: 000000000006a000 RCX: 9ce21886c4195300
   RDX: 0000000000000000 RSI: 0000000080000000 RDI: 0000000000000000
   RBP: 0000000000000091 R08: ffffffff817f0a3c R09: 1ffff92001a3bdf4
   R10: dffffc0000000000 R11: fffff52001a3bdf5 R12: 1ffff1100a45f401
   R13: ffff8880522fa018 R14: dffffc0000000000 R15: 000000000006a000
   FS:  00007f12819fe6c0(0000) GS:ffff88801fc00000(0000) knlGS:0000000000000000
   CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
   CR2: 0000557750bd7da8 CR3: 00000000400ea000 CR4: 0000000000352ef0
   DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
   DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400

In this case the transaction abort was due to (an injected) memory
allocation failure when attempting to allocate a new chunk.

Reported-by: syzbot+f60d8337a5c8e8d92a77@syzkaller.appspotmail.com
Link: https://lore.kernel.org/linux-btrfs/6777f2dd.050a0220.178762.0045.GAE@google.com/
Fixes: 52b1fdca23ac ("btrfs: handle completed ordered extents in btrfs_split_ordered_extent")
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/ordered-data.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

Comments

Qu Wenruo Jan. 13, 2025, 9:12 p.m. UTC | #1
在 2025/1/14 02:02, fdmanana@kernel.org 写道:
> From: Filipe Manana <fdmanana@suse.com>
>
> If while we are doing a direct IO write a transaction abort happens, we
> mark all existing ordered extents with the BTRFS_ORDERED_IOERR flag (done
> at btrfs_destroy_ordered_extents()), and then after that if we enter
> btrfs_split_ordered_extent() and the ordered extent has bytes left
> (meaning we have a bio that doesn't cover the whole ordered extent, see
> details at btrfs_extract_ordered_extent()), we will fail on the following
> assertion at btrfs_split_ordered_extent():
>
>     ASSERT(!(flags & ~BTRFS_ORDERED_TYPE_FLAGS));
>
> because the BTRFS_ORDERED_IOERR flag is set and the definition of
> BTRFS_ORDERED_TYPE_FLAGS is just the union of all flags that identify the
> type of write (regular, nocow, prealloc, compressed, direct IO, encoded).
>
> Fix this by returning an error from btrfs_extract_ordered_extent() if we
> find the BTRFS_ORDERED_IOERR flag in the ordered extent. The error will
> be the error that resulted in the transaction abort or -EIO if no
> transaction abort happened.
>
> This was recently reported by syzbot with the following trace:
>
>     FAULT_INJECTION: forcing a failure.
>     name failslab, interval 1, probability 0, space 0, times 1
>     CPU: 0 UID: 0 PID: 5321 Comm: syz.0.0 Not tainted 6.13.0-rc5-syzkaller #0
>     Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
>     Call Trace:
>      <TASK>
>      __dump_stack lib/dump_stack.c:94 [inline]
>      dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120
>      fail_dump lib/fault-inject.c:53 [inline]
>      should_fail_ex+0x3b0/0x4e0 lib/fault-inject.c:154
>      should_failslab+0xac/0x100 mm/failslab.c:46
>      slab_pre_alloc_hook mm/slub.c:4072 [inline]
>      slab_alloc_node mm/slub.c:4148 [inline]
>      __do_kmalloc_node mm/slub.c:4297 [inline]
>      __kmalloc_noprof+0xdd/0x4c0 mm/slub.c:4310
>      kmalloc_noprof include/linux/slab.h:905 [inline]
>      kzalloc_noprof include/linux/slab.h:1037 [inline]
>      btrfs_chunk_alloc_add_chunk_item+0x244/0x1100 fs/btrfs/volumes.c:5742
>      reserve_chunk_space+0x1ca/0x2c0 fs/btrfs/block-group.c:4292
>      check_system_chunk fs/btrfs/block-group.c:4319 [inline]
>      do_chunk_alloc fs/btrfs/block-group.c:3891 [inline]
>      btrfs_chunk_alloc+0x77b/0xf80 fs/btrfs/block-group.c:4187
>      find_free_extent_update_loop fs/btrfs/extent-tree.c:4166 [inline]
>      find_free_extent+0x42d1/0x5810 fs/btrfs/extent-tree.c:4579
>      btrfs_reserve_extent+0x422/0x810 fs/btrfs/extent-tree.c:4672
>      btrfs_new_extent_direct fs/btrfs/direct-io.c:186 [inline]
>      btrfs_get_blocks_direct_write+0x706/0xfa0 fs/btrfs/direct-io.c:321
>      btrfs_dio_iomap_begin+0xbb7/0x1180 fs/btrfs/direct-io.c:525
>      iomap_iter+0x697/0xf60 fs/iomap/iter.c:90
>      __iomap_dio_rw+0xeb9/0x25b0 fs/iomap/direct-io.c:702
>      btrfs_dio_write fs/btrfs/direct-io.c:775 [inline]
>      btrfs_direct_write+0x610/0xa30 fs/btrfs/direct-io.c:880
>      btrfs_do_write_iter+0x2a0/0x760 fs/btrfs/file.c:1397
>      do_iter_readv_writev+0x600/0x880
>      vfs_writev+0x376/0xba0 fs/read_write.c:1050
>      do_pwritev fs/read_write.c:1146 [inline]
>      __do_sys_pwritev2 fs/read_write.c:1204 [inline]
>      __se_sys_pwritev2+0x196/0x2b0 fs/read_write.c:1195
>      do_syscall_x64 arch/x86/entry/common.c:52 [inline]
>      do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
>      entry_SYSCALL_64_after_hwframe+0x77/0x7f
>     RIP: 0033:0x7f1281f85d29
>     Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
>     RSP: 002b:00007f12819fe038 EFLAGS: 00000246 ORIG_RAX: 0000000000000148
>     RAX: ffffffffffffffda RBX: 00007f1282176080 RCX: 00007f1281f85d29
>     RDX: 0000000000000001 RSI: 0000000020000240 RDI: 0000000000000005
>     RBP: 00007f12819fe090 R08: 0000000000000000 R09: 0000000000000003
>     R10: 0000000000007000 R11: 0000000000000246 R12: 0000000000000002
>     R13: 0000000000000000 R14: 00007f1282176080 R15: 00007ffcb9e23328
>      </TASK>
>     BTRFS error (device loop0 state A): Transaction aborted (error -12)
>     BTRFS: error (device loop0 state A) in btrfs_chunk_alloc_add_chunk_item:5745: errno=-12 Out of memory
>     BTRFS info (device loop0 state EA): forced readonly
>     assertion failed: !(flags & ~BTRFS_ORDERED_TYPE_FLAGS), in fs/btrfs/ordered-data.c:1234
>     ------------[ cut here ]------------
>     kernel BUG at fs/btrfs/ordered-data.c:1234!
>     Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN NOPTI
>     CPU: 0 UID: 0 PID: 5321 Comm: syz.0.0 Not tainted 6.13.0-rc5-syzkaller #0
>     Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
>     RIP: 0010:btrfs_split_ordered_extent+0xd8d/0xe20 fs/btrfs/ordered-data.c:1234
>     Code: 43 fd 90 0f 0b e8 43 c4 db fd 48 c7 c7 20 0c 4c 8c 48 c7 c6 80 0f 4c 8c 48 c7 c2 e0 0b 4c 8c b9 d2 04 00 00 e8 04 57 43 fd 90 <0f> 0b e8 1c c4 db fd eb 5b e8 15 c4 db fd 48 c7 c7 20 0c 4c 8c 48
>     RSP: 0018:ffffc9000d1df2b8 EFLAGS: 00010246
>     RAX: 0000000000000057 RBX: 000000000006a000 RCX: 9ce21886c4195300
>     RDX: 0000000000000000 RSI: 0000000080000000 RDI: 0000000000000000
>     RBP: 0000000000000091 R08: ffffffff817f0a3c R09: 1ffff92001a3bdf4
>     R10: dffffc0000000000 R11: fffff52001a3bdf5 R12: 1ffff1100a45f401
>     R13: ffff8880522fa018 R14: dffffc0000000000 R15: 000000000006a000
>     FS:  00007f12819fe6c0(0000) GS:ffff88801fc00000(0000) knlGS:0000000000000000
>     CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>     CR2: 0000557750bd7da8 CR3: 00000000400ea000 CR4: 0000000000352ef0
>     DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
>     DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
>     Call Trace:
>      <TASK>
>      btrfs_extract_ordered_extent fs/btrfs/direct-io.c:702 [inline]
>      btrfs_dio_submit_io+0x4be/0x6d0 fs/btrfs/direct-io.c:737
>      iomap_dio_submit_bio fs/iomap/direct-io.c:85 [inline]
>      iomap_dio_bio_iter+0x1022/0x1740 fs/iomap/direct-io.c:447
>      __iomap_dio_rw+0x13b7/0x25b0 fs/iomap/direct-io.c:703
>      btrfs_dio_write fs/btrfs/direct-io.c:775 [inline]
>      btrfs_direct_write+0x610/0xa30 fs/btrfs/direct-io.c:880
>      btrfs_do_write_iter+0x2a0/0x760 fs/btrfs/file.c:1397
>      do_iter_readv_writev+0x600/0x880
>      vfs_writev+0x376/0xba0 fs/read_write.c:1050
>      do_pwritev fs/read_write.c:1146 [inline]
>      __do_sys_pwritev2 fs/read_write.c:1204 [inline]
>      __se_sys_pwritev2+0x196/0x2b0 fs/read_write.c:1195
>      do_syscall_x64 arch/x86/entry/common.c:52 [inline]
>      do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
>      entry_SYSCALL_64_after_hwframe+0x77/0x7f
>     RIP: 0033:0x7f1281f85d29
>     Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
>     RSP: 002b:00007f12819fe038 EFLAGS: 00000246 ORIG_RAX: 0000000000000148
>     RAX: ffffffffffffffda RBX: 00007f1282176080 RCX: 00007f1281f85d29
>     RDX: 0000000000000001 RSI: 0000000020000240 RDI: 0000000000000005
>     RBP: 00007f12819fe090 R08: 0000000000000000 R09: 0000000000000003
>     R10: 0000000000007000 R11: 0000000000000246 R12: 0000000000000002
>     R13: 0000000000000000 R14: 00007f1282176080 R15: 00007ffcb9e23328
>      </TASK>
>     Modules linked in:
>     ---[ end trace 0000000000000000 ]---
>     RIP: 0010:btrfs_split_ordered_extent+0xd8d/0xe20 fs/btrfs/ordered-data.c:1234
>     Code: 43 fd 90 0f 0b e8 43 c4 db fd 48 c7 c7 20 0c 4c 8c 48 c7 c6 80 0f 4c 8c 48 c7 c2 e0 0b 4c 8c b9 d2 04 00 00 e8 04 57 43 fd 90 <0f> 0b e8 1c c4 db fd eb 5b e8 15 c4 db fd 48 c7 c7 20 0c 4c 8c 48
>     RSP: 0018:ffffc9000d1df2b8 EFLAGS: 00010246
>     RAX: 0000000000000057 RBX: 000000000006a000 RCX: 9ce21886c4195300
>     RDX: 0000000000000000 RSI: 0000000080000000 RDI: 0000000000000000
>     RBP: 0000000000000091 R08: ffffffff817f0a3c R09: 1ffff92001a3bdf4
>     R10: dffffc0000000000 R11: fffff52001a3bdf5 R12: 1ffff1100a45f401
>     R13: ffff8880522fa018 R14: dffffc0000000000 R15: 000000000006a000
>     FS:  00007f12819fe6c0(0000) GS:ffff88801fc00000(0000) knlGS:0000000000000000
>     CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>     CR2: 0000557750bd7da8 CR3: 00000000400ea000 CR4: 0000000000352ef0
>     DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
>     DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
>
> In this case the transaction abort was due to (an injected) memory
> allocation failure when attempting to allocate a new chunk.
>
> Reported-by: syzbot+f60d8337a5c8e8d92a77@syzkaller.appspotmail.com
> Link: https://lore.kernel.org/linux-btrfs/6777f2dd.050a0220.178762.0045.GAE@google.com/
> Fixes: 52b1fdca23ac ("btrfs: handle completed ordered extents in btrfs_split_ordered_extent")
> Signed-off-by: Filipe Manana <fdmanana@suse.com>

Reviewed-by: Qu Wenruo <wqu@suse.com>

Thanks,
Qu

> ---
>   fs/btrfs/ordered-data.c | 12 ++++++++++++
>   1 file changed, 12 insertions(+)
>
> diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
> index 30eceaf829a7..3cf95a801086 100644
> --- a/fs/btrfs/ordered-data.c
> +++ b/fs/btrfs/ordered-data.c
> @@ -1229,6 +1229,18 @@ struct btrfs_ordered_extent *btrfs_split_ordered_extent(
>   	 */
>   	if (WARN_ON_ONCE(len >= ordered->num_bytes))
>   		return ERR_PTR(-EINVAL);
> +	/*
> +	 * If our ordered extent had an error there's no point in continuing.
> +	 * The error may have come from a transaction abort done either by this
> +	 * task or some other concurrent task, and the transaction abort path
> +	 * iterates over all existing ordered extents and sets the flag
> +	 * BTRFS_ORDERED_IOERR on them.
> +	 */
> +	if (unlikely(flags & BTRFS_ORDERED_IOERR)) {
> +		const int fs_error = BTRFS_FS_ERROR(fs_info);
> +
> +		return fs_error ? ERR_PTR(fs_error) : ERR_PTR(-EIO);
> +	}
>   	/* We cannot split partially completed ordered extents. */
>   	if (ordered->bytes_left) {
>   		ASSERT(!(flags & ~BTRFS_ORDERED_TYPE_FLAGS));
diff mbox series

Patch

diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 30eceaf829a7..3cf95a801086 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -1229,6 +1229,18 @@  struct btrfs_ordered_extent *btrfs_split_ordered_extent(
 	 */
 	if (WARN_ON_ONCE(len >= ordered->num_bytes))
 		return ERR_PTR(-EINVAL);
+	/*
+	 * If our ordered extent had an error there's no point in continuing.
+	 * The error may have come from a transaction abort done either by this
+	 * task or some other concurrent task, and the transaction abort path
+	 * iterates over all existing ordered extents and sets the flag
+	 * BTRFS_ORDERED_IOERR on them.
+	 */
+	if (unlikely(flags & BTRFS_ORDERED_IOERR)) {
+		const int fs_error = BTRFS_FS_ERROR(fs_info);
+
+		return fs_error ? ERR_PTR(fs_error) : ERR_PTR(-EIO);
+	}
 	/* We cannot split partially completed ordered extents. */
 	if (ordered->bytes_left) {
 		ASSERT(!(flags & ~BTRFS_ORDERED_TYPE_FLAGS));