linux/fs/btrfs
Naohiro Aota c02d35d89b btrfs: zoned: skip splitting and logical rewriting on pre-alloc write
When doing a relocation, there is a chance that at the time of
btrfs_reloc_clone_csums(), there is no checksum for the corresponding
region.

In this case, btrfs_finish_ordered_zoned()'s sum points to an invalid item
and so ordered_extent's logical is set to some invalid value. Then,
btrfs_lookup_block_group() in btrfs_zone_finish_endio() failed to find a
block group and will hit an assert or a null pointer dereference as
following.

This can be reprodcued by running btrfs/028 several times (e.g, 4 to 16
times) with a null_blk setup. The device's zone size and capacity is set to
32 MB and the storage size is set to 5 GB on my setup.

    KASAN: null-ptr-deref in range [0x0000000000000088-0x000000000000008f]
    CPU: 6 PID: 3105720 Comm: kworker/u16:13 Tainted: G        W          6.5.0-rc6-kts+ #1
    Hardware name: Supermicro Super Server/X10SRL-F, BIOS 2.0 12/17/2015
    Workqueue: btrfs-endio-write btrfs_work_helper [btrfs]
    RIP: 0010:btrfs_zone_finish_endio.part.0+0x34/0x160 [btrfs]
    Code: 41 54 49 89 fc 55 48 89 f5 53 e8 57 7d fc ff 48 8d b8 88 00 00 00 48 89 c3 48 b8 00 00 00 00 00
    > 3c 02 00 0f 85 02 01 00 00 f6 83 88 00 00 00 01 0f 84 a8 00 00
    RSP: 0018:ffff88833cf87b08 EFLAGS: 00010206
    RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000
    RDX: 0000000000000011 RSI: 0000000000000004 RDI: 0000000000000088
    RBP: 0000000000000002 R08: 0000000000000001 R09: ffffed102877b827
    R10: ffff888143bdc13b R11: ffff888125b1cbc0 R12: ffff888143bdc000
    R13: 0000000000007000 R14: ffff888125b1cba8 R15: 0000000000000000
    FS:  0000000000000000(0000) GS:ffff88881e500000(0000) knlGS:0000000000000000
    CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 00007f3ed85223d5 CR3: 00000001519b4005 CR4: 00000000001706e0
    Call Trace:
     <TASK>
     ? die_addr+0x3c/0xa0
     ? exc_general_protection+0x148/0x220
     ? asm_exc_general_protection+0x22/0x30
     ? btrfs_zone_finish_endio.part.0+0x34/0x160 [btrfs]
     ? btrfs_zone_finish_endio.part.0+0x19/0x160 [btrfs]
     btrfs_finish_one_ordered+0x7b8/0x1de0 [btrfs]
     ? rcu_is_watching+0x11/0xb0
     ? lock_release+0x47a/0x620
     ? btrfs_finish_ordered_zoned+0x59b/0x800 [btrfs]
     ? __pfx_btrfs_finish_one_ordered+0x10/0x10 [btrfs]
     ? btrfs_finish_ordered_zoned+0x358/0x800 [btrfs]
     ? __smp_call_single_queue+0x124/0x350
     ? rcu_is_watching+0x11/0xb0
     btrfs_work_helper+0x19f/0xc60 [btrfs]
     ? __pfx_try_to_wake_up+0x10/0x10
     ? _raw_spin_unlock_irq+0x24/0x50
     ? rcu_is_watching+0x11/0xb0
     process_one_work+0x8c1/0x1430
     ? __pfx_lock_acquire+0x10/0x10
     ? __pfx_process_one_work+0x10/0x10
     ? __pfx_do_raw_spin_lock+0x10/0x10
     ? _raw_spin_lock_irq+0x52/0x60
     worker_thread+0x100/0x12c0
     ? __kthread_parkme+0xc1/0x1f0
     ? __pfx_worker_thread+0x10/0x10
     kthread+0x2ea/0x3c0
     ? __pfx_kthread+0x10/0x10
     ret_from_fork+0x30/0x70
     ? __pfx_kthread+0x10/0x10
     ret_from_fork_asm+0x1b/0x30
     </TASK>

On the zoned mode, writing to pre-allocated region means data relocation
write. Such write always uses WRITE command so there is no need of splitting
and rewriting logical address. Thus, we can just skip the function for the
case.

Fixes: cbfce4c7fb ("btrfs: optimize the logical to physical mapping for zoned writes")
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2023-08-22 14:19:59 +02:00
..
tests btrfs: tests: test invalid splitting when skipping pinned drop extent_map 2023-08-21 14:54:49 +02:00
accessors.c btrfs: add eb to btrfs_node_key_ptr_offset 2022-12-05 18:00:58 +01:00
accessors.h btrfs: use helper sizeof_field in struct accessors 2023-08-21 14:52:13 +02:00
acl.c fs: port acl to mnt_idmap 2023-01-19 09:24:28 +01:00
acl.h fs: port ->set_acl() to pass mnt_idmap 2023-01-19 09:24:27 +01:00
async-thread.c btrfs: use alloc_ordered_workqueue() to create ordered workqueues 2023-06-19 13:59:30 +02:00
async-thread.h btrfs: use alloc_ordered_workqueue() to create ordered workqueues 2023-06-19 13:59:30 +02:00
backref.c btrfs: remove v0 extent handling 2023-08-21 14:54:48 +02:00
backref.h btrfs: fix backref walking not returning all inode refs 2023-05-09 22:09:11 +02:00
bio.c btrfs: add an ordered_extent pointer to struct btrfs_bio 2023-06-19 13:59:36 +02:00
bio.h btrfs: add an ordered_extent pointer to struct btrfs_bio 2023-06-19 13:59:36 +02:00
block-group.c btrfs: zoned: don't activate non-DATA BG on allocation 2023-08-21 14:52:19 +02:00
block-group.h btrfs: rename add_new_free_space() to btrfs_add_new_free_space() 2023-08-21 14:52:12 +02:00
block-rsv.c btrfs: account block group tree when calculating global reserve size 2023-07-20 19:22:54 +02:00
block-rsv.h btrfs: move btrfs_check_trunc_cache_free_space into block-rsv.c 2023-06-19 13:59:24 +02:00
btrfs_inode.h btrfs: reduce the number of arguments to btrfs_run_delalloc_range 2023-08-21 14:52:14 +02:00
check-integrity.c btrfs: rename __btrfs_map_block to btrfs_map_block 2023-06-19 13:59:34 +02:00
check-integrity.h
compression.c btrfs: make btrfs_compressed_bioset static 2023-06-19 17:01:44 +02:00
compression.h btrfs: pass an ordered_extent to btrfs_submit_compressed_write 2023-06-19 13:59:36 +02:00
ctree.c btrfs: replace BUG_ON() at split_item() with proper error handling 2023-06-19 13:59:39 +02:00
ctree.h btrfs: fix infinite directory reads 2023-08-14 16:17:37 +02:00
defrag.c btrfs: drop gfp from parameter extent state helpers 2023-06-19 13:59:30 +02:00
defrag.h btrfs: move defrag related prototypes to their own header 2022-12-05 18:00:46 +01:00
delalloc-space.c btrfs: count extents before taking inode's spinlock when reserving metadata 2023-04-17 18:01:19 +02:00
delalloc-space.h btrfs: move delalloc space related prototypes to delalloc-space.h 2022-12-05 18:00:44 +01:00
delayed-inode.c btrfs: remove pointless empty list check when reading delayed dir indexes 2023-08-21 14:54:48 +02:00
delayed-inode.h btrfs: fix infinite directory reads 2023-08-14 16:17:37 +02:00
delayed-ref.c btrfs: use a single switch statement when initializing delayed ref head 2023-06-19 13:59:32 +02:00
delayed-ref.h btrfs: use bool type for delayed ref head fields that are used as booleans 2023-06-19 13:59:32 +02:00
dev-replace.c btrfs: make find_first_extent_bit() return a boolean 2023-08-21 14:52:12 +02:00
dev-replace.h btrfs: move dev-replace prototypes into dev-replace.h 2022-12-05 18:00:47 +01:00
dir-item.c btrfs: move dir-item prototypes into dir-item.h 2022-12-05 18:00:46 +01:00
dir-item.h btrfs: move dir-item prototypes into dir-item.h 2022-12-05 18:00:46 +01:00
discard.c btrfs: unexport btrfs_run_discard_work and make it static 2023-06-19 13:59:25 +02:00
discard.h btrfs: unexport btrfs_run_discard_work and make it static 2023-06-19 13:59:25 +02:00
disk-io.c btrfs: drop redundant check to use fs_devices::metadata_uuid 2023-08-21 14:54:48 +02:00
disk-io.h btrfs: make btrfs_cleanup_fs_roots() static 2023-08-21 14:52:18 +02:00
export.c btrfs: move super_block specific helpers into super.h 2022-12-05 18:00:47 +01:00
export.h btrfs: simplify generation check in btrfs_get_dentry 2022-12-05 18:00:41 +01:00
extent_io.c btrfs: zoned: defer advancing meta write pointer 2023-08-21 14:52:19 +02:00
extent_io.h btrfs: zoned: introduce block group context to btrfs_eb_write_context 2023-08-21 14:52:19 +02:00
extent_map.c btrfs: fix incorrect splitting in btrfs_drop_extent_map_range 2023-08-18 14:38:10 +02:00
extent_map.h btrfs: pass the new logical address to split_extent_map 2023-06-19 13:59:33 +02:00
extent-io-tree.c btrfs: make find_first_extent_bit() return a boolean 2023-08-21 14:52:12 +02:00
extent-io-tree.h btrfs: make find_first_extent_bit() return a boolean 2023-08-21 14:52:12 +02:00
extent-tree.c btrfs: remove v0 extent handling 2023-08-21 14:54:48 +02:00
extent-tree.h btrfs: wait on uncached block groups on every allocation loop 2023-08-21 14:54:47 +02:00
file-item.c btrfs: scrub: avoid unnecessary csum tree search preparing stripes 2023-08-21 14:54:48 +02:00
file-item.h btrfs: scrub: avoid unnecessary csum tree search preparing stripes 2023-08-21 14:54:48 +02:00
file.c btrfs: use LIST_HEAD() to initialize the list_head 2023-08-21 14:54:46 +02:00
file.h btrfs: use cached state when looking for delalloc ranges with fiemap 2022-12-05 18:00:56 +01:00
free-space-cache.c btrfs: zoned: no longer count fresh BG region as zone unusable 2023-08-21 14:52:19 +02:00
free-space-cache.h btrfs: move btrfs_check_trunc_cache_free_space into block-rsv.c 2023-06-19 13:59:24 +02:00
free-space-tree.c btrfs: rename add_new_free_space() to btrfs_add_new_free_space() 2023-08-21 14:52:12 +02:00
free-space-tree.h btrfs: make clear_cache mount option to rebuild FST without disabling it 2023-05-10 14:51:27 +02:00
fs.c btrfs: sysfs: update fs features directory asynchronously 2023-02-13 17:50:35 +01:00
fs.h btrfs: zoned: activate metadata block group on write time 2023-08-21 14:52:19 +02:00
inode-item.c btrfs: remove obsolete delayed ref throttling logic when truncating items 2023-04-17 18:01:19 +02:00
inode-item.h btrfs: move split_flags/combine_flags helpers to inode-item.h 2023-06-19 13:59:25 +02:00
inode.c btrfs: copy dir permission and time when creating a stub subvolume 2023-08-21 14:54:48 +02:00
ioctl.c for-6.5/block-2023-06-23 2023-06-26 12:47:20 -07:00
ioctl.h fs: port ->fileattr_set() to pass mnt_idmap 2023-01-19 09:24:27 +01:00
Kconfig btrfs: deprecate integrity checker feature 2023-08-21 14:52:13 +02:00
locking.c btrfs: add block-group tree to lockdep classes 2023-06-19 13:59:35 +02:00
locking.h btrfs: locking: use atomic for DREW lock writers 2023-04-17 18:01:17 +02:00
lru_cache.c btrfs: send: cache utimes operations for directories if possible 2023-02-15 19:38:50 +01:00
lru_cache.h btrfs: remove btrfs_lru_cache_is_full() inline function 2023-04-17 18:01:18 +02:00
lzo.c btrfs: disable allocation warnings for compression workspaces 2023-06-19 13:59:34 +02:00
Makefile btrfs: send: genericize the backref cache to allow it to be reused 2023-02-13 17:50:35 +01:00
messages.c btrfs: remove v0 extent handling 2023-08-21 14:54:48 +02:00
messages.h btrfs: remove v0 extent handling 2023-08-21 14:54:48 +02:00
misc.h btrfs: export bitmap_test_range_all_{set,zero} 2023-06-19 13:59:22 +02:00
ordered-data.c btrfs: use LIST_HEAD() to initialize the list_head 2023-08-21 14:54:46 +02:00
ordered-data.h btrfs: add a btrfs_finish_ordered_extent helper 2023-06-19 13:59:37 +02:00
orphan.c btrfs: move orphan prototypes into orphan.h 2022-12-05 18:00:47 +01:00
orphan.h btrfs: move orphan prototypes into orphan.h 2022-12-05 18:00:47 +01:00
print-tree.c btrfs: remove v0 extent handling 2023-08-21 14:54:48 +02:00
print-tree.h btrfs: print-tree: pass const extent buffer pointer 2023-06-19 13:59:22 +02:00
props.c btrfs: move super_block specific helpers into super.h 2022-12-05 18:00:47 +01:00
props.h btrfs: make module init/exit match their sequence 2022-12-05 18:00:40 +01:00
qgroup.c btrfs: avoid start and commit empty transaction when flushing qgroups 2023-08-21 14:52:18 +02:00
qgroup.h btrfs: sink gfp_t parameter to btrfs_qgroup_trace_extent 2022-12-05 18:00:43 +01:00
raid56.c btrfs: scrub: avoid unnecessary csum tree search preparing stripes 2023-08-21 14:54:48 +02:00
raid56.h btrfs: raid56: remove unused BTRFS_RBIO_REBUILD_MISSING 2023-08-21 14:52:12 +02:00
rcu-string.h btrfs: replace strncpy() with strscpy() 2022-12-05 18:00:59 +01:00
ref-verify.c btrfs: move accessor helpers into accessors.h 2022-12-05 18:00:42 +01:00
ref-verify.h
reflink.c btrfs: pass btrfs_inode to btrfs_inode_unlock 2022-12-05 18:00:53 +01:00
reflink.h
relocation.c btrfs: remove v0 extent handling 2023-08-21 14:54:48 +02:00
relocation.h btrfs: pass an ordered_extent to btrfs_reloc_clone_csums 2023-06-19 13:59:36 +02:00
root-tree.c btrfs: move orphan prototypes into orphan.h 2022-12-05 18:00:47 +01:00
root-tree.h btrfs: move root tree prototypes to their own header 2022-12-05 18:00:44 +01:00
scrub.c btrfs: scrub: move write back of repaired sectors to scrub_stripe_read_repair_worker() 2023-08-21 14:54:49 +02:00
scrub.h btrfs: scrub: remove scrub_bio structure 2023-04-17 18:01:24 +02:00
send.c btrfs: use LIST_HEAD() to initialize the list_head 2023-08-21 14:54:46 +02:00
send.h btrfs: send add define for v2 buffer size 2022-12-05 18:00:41 +01:00
space-info.c btrfs: zoned: re-enable metadata over-commit for zoned mode 2023-08-21 14:52:19 +02:00
space-info.h btrfs: update documentation for BTRFS_RESERVE_FLUSH_EVICT flush method 2023-04-17 18:01:18 +02:00
subpage.c btrfs: stop setting PageError in the data I/O path 2023-06-19 13:59:35 +02:00
subpage.h btrfs: stop setting PageError in the data I/O path 2023-06-19 13:59:35 +02:00
super.c btrfs: deprecate integrity checker feature 2023-08-21 14:52:13 +02:00
super.h btrfs: move super_block specific helpers into super.h 2022-12-05 18:00:47 +01:00
sysfs.c btrfs: sysfs: show if ACL support has been compiled in 2023-08-21 14:52:12 +02:00
sysfs.h btrfs: sysfs: update fs features directory asynchronously 2023-02-13 17:50:35 +01:00
transaction.c btrfs: update comment for btrfs_join_transaction_nostart() 2023-08-21 14:52:17 +02:00
transaction.h btrfs: don't hold an extra reference for redirtied buffers 2023-06-19 13:59:26 +02:00
tree-checker.c for-6.5-rc5-tag 2023-08-12 13:28:55 -07:00
tree-checker.h btrfs: move btrfs_verify_level_key into tree-checker.c 2023-06-19 13:59:25 +02:00
tree-log.c btrfs: use LIST_HEAD() to initialize the list_head 2023-08-21 14:54:46 +02:00
tree-log.h btrfs: change for_rename argument of btrfs_record_unlink_dir() to bool 2023-06-19 13:59:26 +02:00
tree-mod-log.c btrfs: avoid tree mod log ENOMEM failures when we don't need to log 2023-06-19 13:59:38 +02:00
tree-mod-log.h btrfs: fix SPDX comment in tree-mod-log.h 2022-12-05 18:00:48 +01:00
ulist.c btrfs: constify ulist parameter of ulist_next() 2022-12-05 18:00:50 +01:00
ulist.h btrfs: constify ulist parameter of ulist_next() 2022-12-05 18:00:50 +01:00
uuid-tree.c btrfs: move uuid tree prototypes to uuid-tree.h 2022-12-05 18:00:46 +01:00
uuid-tree.h btrfs: move uuid tree prototypes to uuid-tree.h 2022-12-05 18:00:46 +01:00
verity.c fsverity: pass pos and size to ->write_merkle_tree_block 2023-01-01 15:46:48 -08:00
verity.h btrfs: move verity prototypes into verity.h 2022-12-05 18:00:47 +01:00
volumes.c btrfs: simplify memcpy either of metadata_uuid or fsid 2023-08-21 14:54:48 +02:00
volumes.h btrfs: add a helper to read the superblock metadata_uuid 2023-08-21 14:54:48 +02:00
xattr.c fs: drop unused posix acl handlers 2023-03-06 09:57:12 +01:00
xattr.h
zlib.c btrfs: disable allocation warnings for compression workspaces 2023-06-19 13:59:34 +02:00
zoned.c btrfs: zoned: skip splitting and logical rewriting on pre-alloc write 2023-08-22 14:19:59 +02:00
zoned.h btrfs: zoned: reserve zones for an active metadata/system block group 2023-08-21 14:52:19 +02:00
zstd.c btrfs: disable allocation warnings for compression workspaces 2023-06-19 13:59:34 +02:00