linux-stable/fs/btrfs
Johannes Thumshirn 082b3d4e78 btrfs: zoned: allocate dummy checksums for zoned NODATASUM writes
[ Upstream commit cebae292e0 ]

Shin'ichiro reported that when he's running fstests' test-case
btrfs/167 on emulated zoned devices, he's seeing the following NULL
pointer dereference in 'btrfs_zone_finish_endio()':

  Oops: general protection fault, probably for non-canonical address 0xdffffc0000000011: 0000 [#1] PREEMPT SMP KASAN NOPTI
  KASAN: null-ptr-deref in range [0x0000000000000088-0x000000000000008f]
  CPU: 4 PID: 2332440 Comm: kworker/u80:15 Tainted: G        W          6.10.0-rc2-kts+ #4
  Hardware name: Supermicro Super Server/X11SPi-TF, BIOS 3.3 02/21/2020
  Workqueue: btrfs-endio-write btrfs_work_helper [btrfs]
  RIP: 0010:btrfs_zone_finish_endio.part.0+0x34/0x160 [btrfs]

  RSP: 0018:ffff88867f107a90 EFLAGS: 00010206
  RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff893e5534
  RDX: 0000000000000011 RSI: 0000000000000004 RDI: 0000000000000088
  RBP: 0000000000000002 R08: 0000000000000001 R09: ffffed1081696028
  R10: ffff88840b4b0143 R11: ffff88834dfff600 R12: ffff88840b4b0000
  R13: 0000000000020000 R14: 0000000000000000 R15: ffff888530ad5210
  FS:  0000000000000000(0000) GS:ffff888e3f800000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 00007f87223fff38 CR3: 00000007a7c6a002 CR4: 00000000007706f0
  DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
  DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
  PKRU: 55555554
  Call Trace:
   <TASK>
   ? __die_body.cold+0x19/0x27
   ? die_addr+0x46/0x70
   ? exc_general_protection+0x14f/0x250
   ? asm_exc_general_protection+0x26/0x30
   ? do_raw_read_unlock+0x44/0x70
   ? btrfs_zone_finish_endio.part.0+0x34/0x160 [btrfs]
   btrfs_finish_one_ordered+0x5d9/0x19a0 [btrfs]
   ? __pfx_lock_release+0x10/0x10
   ? do_raw_write_lock+0x90/0x260
   ? __pfx_do_raw_write_lock+0x10/0x10
   ? __pfx_btrfs_finish_one_ordered+0x10/0x10 [btrfs]
   ? _raw_write_unlock+0x23/0x40
   ? btrfs_finish_ordered_zoned+0x5a9/0x850 [btrfs]
   ? lock_acquire+0x435/0x500
   btrfs_work_helper+0x1b1/0xa70 [btrfs]
   ? __schedule+0x10a8/0x60b0
   ? __pfx___might_resched+0x10/0x10
   process_one_work+0x862/0x1410
   ? __pfx_lock_acquire+0x10/0x10
   ? __pfx_process_one_work+0x10/0x10
   ? assign_work+0x16c/0x240
   worker_thread+0x5e6/0x1010
   ? __pfx_worker_thread+0x10/0x10
   kthread+0x2c3/0x3a0
   ? trace_irq_enable.constprop.0+0xce/0x110
   ? __pfx_kthread+0x10/0x10
   ret_from_fork+0x31/0x70
   ? __pfx_kthread+0x10/0x10
   ret_from_fork_asm+0x1a/0x30
   </TASK>

Enabling CONFIG_BTRFS_ASSERT revealed the following assertion to
trigger:

  assertion failed: !list_empty(&ordered->list), in fs/btrfs/zoned.c:1815

This indicates, that we're missing the checksums list on the
ordered_extent. As btrfs/167 is doing a NOCOW write this is to be
expected.

Further analysis with drgn confirmed the assumption:

  >>> inode = prog.crashed_thread().stack_trace()[11]['ordered'].inode
  >>> btrfs_inode = drgn.container_of(inode, "struct btrfs_inode", \
         				"vfs_inode")
  >>> print(btrfs_inode.flags)
  (u32)1

As zoned emulation mode simulates conventional zones on regular devices,
we cannot use zone-append for writing. But we're only attaching dummy
checksums if we're doing a zone-append write.

So for NOCOW zoned data writes on conventional zones, also attach a
dummy checksum.

Reported-by: Shinichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Fixes: cbfce4c7fb ("btrfs: optimize the logical to physical mapping for zoned writes")
CC: Naohiro Aota <Naohiro.Aota@wdc.com> # 6.6+
Tested-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Reviewed-by: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2024-06-27 13:49:06 +02:00
..
tests btrfs: fix wrong block_start calculation for btrfs_drop_extent_map_range() 2024-05-02 16:32:44 +02:00
accessors.c
accessors.h btrfs: use helper sizeof_field in struct accessors 2023-08-21 14:52:13 +02:00
acl.c
acl.h
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: fix information leak in btrfs_ioctl_logical_to_ino() 2024-05-02 16:32:44 +02:00
backref.h btrfs: fix unwritten extent buffer after snapshotting a new subvolume 2023-10-23 17:17:30 +02:00
bio.c btrfs: zoned: allocate dummy checksums for zoned NODATASUM writes 2024-06-27 13:49:06 +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 skip block groups with 100% zone unusable 2024-04-03 15:28:54 +02:00
block-group.h btrfs: add and use helper to check if block group is used 2024-02-23 09:24:47 +01:00
block-rsv.c btrfs: fix data race at btrfs_use_block_rsv() when accessing block reserve 2024-03-26 18:19:13 -04:00
block-rsv.h btrfs: fix data race at btrfs_use_block_rsv() when accessing block reserve 2024-03-26 18:19:13 -04: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: abort transaction on generation mismatch when marking eb as dirty 2023-11-28 17:19:35 +00:00
ctree.h btrfs: abort transaction on generation mismatch when marking eb as dirty 2023-11-28 17:19:35 +00:00
defrag.c btrfs: defrag: avoid unnecessary defrag caused by incorrect extent size 2024-03-01 13:34:58 +01:00
defrag.h
delalloc-space.c btrfs: don't reserve space for checksums when writing to nocow files 2024-02-23 09:24:48 +01:00
delalloc-space.h
delayed-inode.c btrfs: record delayed inode root in transaction 2024-04-17 11:19:33 +02:00
delayed-inode.h btrfs: add __counted_by for struct btrfs_delayed_item and use struct_size() 2023-10-11 11:37:19 +02:00
delayed-ref.c btrfs: prevent transaction block reserve underflow when starting transaction 2023-09-20 20:42:18 +02:00
delayed-ref.h btrfs: prevent transaction block reserve underflow when starting transaction 2023-09-20 20:42:18 +02:00
dev-replace.c btrfs: dev-replace: properly validate device names 2024-03-06 14:48:40 +00:00
dev-replace.h
dir-item.c btrfs: abort transaction on generation mismatch when marking eb as dirty 2023-11-28 17:19:35 +00:00
dir-item.h
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: fix leak of qgroup extent records after transaction abort 2024-06-16 13:47:48 +02:00
disk-io.h btrfs: fix double free of anonymous device after snapshot creation failure 2024-03-06 14:48:40 +00:00
export.c btrfs: export: handle invalid inode or root reference in btrfs_get_parent() 2024-04-13 13:07:32 +02:00
export.h
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: zoned: optimize hint byte for zoned allocator 2024-01-31 16:19:10 -08:00
extent-tree.h btrfs: wait on uncached block groups on every allocation loop 2023-08-21 14:54:47 +02:00
extent_io.c btrfs: do not wait for short bulk allocation 2024-05-17 12:02:39 +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 wrong block_start calculation for btrfs_drop_extent_map_range() 2024-05-02 16:32:44 +02:00
extent_map.h btrfs: pass the new logical address to split_extent_map 2023-06-19 13:59:33 +02:00
file-item.c btrfs: abort transaction on generation mismatch when marking eb as dirty 2023-11-28 17:19:35 +00:00
file-item.h btrfs: scrub: avoid unnecessary csum tree search preparing stripes 2023-08-21 14:54:48 +02:00
file.c btrfs: fix qgroup_free_reserved_data int overflow 2023-12-20 17:02:03 +01:00
file.h
free-space-cache.c btrfs: abort transaction on generation mismatch when marking eb as dirty 2023-11-28 17:19:35 +00: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: abort transaction on generation mismatch when marking eb as dirty 2023-11-28 17:19:35 +00: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
fs.h btrfs: zoned: activate metadata block group on write time 2023-08-21 14:52:19 +02:00
inode-item.c btrfs: abort transaction on generation mismatch when marking eb as dirty 2023-11-28 17:19:35 +00: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: make btrfs_clear_delalloc_extent() free delalloc reserve 2024-05-17 12:02:14 +02:00
ioctl.c btrfs: qgroup: fix qgroup prealloc rsv leak in subvolume operations 2024-04-17 11:19:33 +02:00
ioctl.h
Kconfig MAINTAINERS: remove links to obsolete btrfs.wiki.kernel.org 2023-09-08 14:21:27 +02:00
locking.c btrfs: add block-group tree to lockdep classes 2023-06-19 13:59:35 +02:00
locking.h btrfs: do not block starts waiting on previous transaction commit 2023-09-08 14:10:49 +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
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 minmax: add in_range() macro 2023-08-24 16:20:18 -07:00
ordered-data.c btrfs: set correct ram_bytes when splitting ordered extent 2024-05-17 12:02:30 +02:00
ordered-data.h btrfs: add a btrfs_finish_ordered_extent helper 2023-06-19 13:59:37 +02:00
orphan.c
orphan.h
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
props.h
qgroup.c btrfs: qgroup: correctly model root qgroup rsv in convert 2024-04-17 11:19:33 +02:00
qgroup.h btrfs: qgroup: iterate qgroups without memory allocation for qgroup_reserve() 2024-01-01 12:42:24 +00: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
ref-verify.c btrfs: ref-verify: free ref cache before clearing mount opt 2024-01-31 16:19:06 -08:00
ref-verify.h
reflink.c btrfs: convert to ctime accessor functions 2023-07-13 10:28:04 +02:00
reflink.h
relocation.c btrfs: abort transaction on generation mismatch when marking eb as dirty 2023-11-28 17:19:35 +00: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: qgroup: fix qgroup prealloc rsv leak in subvolume operations 2024-04-17 11:19:33 +02:00
root-tree.h btrfs: qgroup: fix qgroup prealloc rsv leak in subvolume operations 2024-04-17 11:19:33 +02:00
scrub.c btrfs: scrub: run relocation repair when/only needed 2024-05-02 16:32:44 +02:00
scrub.h btrfs: scrub: remove scrub_bio structure 2023-04-17 18:01:24 +02:00
send.c btrfs: fix kvcalloc() arguments order in btrfs_ioctl_send() 2024-05-17 12:02:27 +02:00
send.h
space-info.c btrfs: fix data races when accessing the reserved amount of block reserves 2024-03-26 18:19:13 -04: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: add dmesg output for first mount and last unmount of a filesystem 2023-12-08 08:52:20 +01:00
super.h
sysfs.c btrfs: sysfs: validate scrub_speed_max value 2024-01-31 16:18:49 -08:00
sysfs.h
transaction.c btrfs: always clear PERTRANS metadata during commit 2024-05-17 12:02:14 +02:00
transaction.h btrfs: free qgroup pertrans reserve on transaction abort 2024-01-01 12:42:24 +00:00
tree-checker.c btrfs: tree-checker: fix inline ref size in error messages 2024-01-31 16:19:06 -08: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: fix crash on racing fsync and size-extending write into prealloc 2024-06-16 13:47:48 +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
ulist.c
ulist.h
uuid-tree.c btrfs: abort transaction on generation mismatch when marking eb as dirty 2023-11-28 17:19:35 +00:00
uuid-tree.h
verity.c btrfs: convert btrfs_read_merkle_tree_page() to use a folio 2023-09-13 18:40:54 +02:00
verity.h
volumes.c btrfs: add missing mutex_unlock in btrfs_relocate_sys_chunks() 2024-05-17 12:02:30 +02:00
volumes.h btrfs: add a helper to read the superblock metadata_uuid 2023-08-21 14:54:48 +02:00
xattr.c btrfs: abort transaction on generation mismatch when marking eb as dirty 2023-11-28 17:19:35 +00:00
xattr.h
zlib.c btrfs: disable allocation warnings for compression workspaces 2023-06-19 13:59:34 +02:00
zoned.c btrfs: zoned: fix use-after-free due to race with dev replace 2024-06-21 14:38:44 +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