linux/fs/btrfs
Qu Wenruo 3ea252a5c4 btrfs: fix symbolic link reading when bs > ps
[ Upstream commit 67378b7546 ]

[BUG DURING BS > PS TEST]
When running the following script on a btrfs whose block size is larger
than page size, e.g. 8K block size and 4K page size, it will trigger a
kernel BUG:

  # mkfs.btrfs -s 8k $dev
  # mount $dev $mnt
  # mkdir $mnt/dir
  # ln -s dir $mnt/link
  # ls $mnt/link

The call trace looks like this:

  BTRFS warning (device dm-2): support for block size 8192 with page size 4096 is experimental, some features may be missing
  BTRFS info (device dm-2): checking UUID tree
  BTRFS info (device dm-2): enabling ssd optimizations
  BTRFS info (device dm-2): enabling free space tree
  ------------[ cut here ]------------
  kernel BUG at /home/adam/linux/include/linux/highmem.h:275!
  Oops: invalid opcode: 0000 [#1] SMP
  CPU: 8 UID: 0 PID: 667 Comm: ls Tainted: G           OE       6.17.0-rc4-custom+ #283 PREEMPT(full)
  Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS unknown 02/02/2022
  RIP: 0010:zero_user_segments.constprop.0+0xdc/0xe0 [btrfs]
  Call Trace:
   <TASK>
   btrfs_get_extent.cold+0x85/0x101 [btrfs 7453c70c03e631c8d8bfdd4264fa62d3e238da6f]
   btrfs_do_readpage+0x244/0x750 [btrfs 7453c70c03e631c8d8bfdd4264fa62d3e238da6f]
   btrfs_read_folio+0x9c/0x100 [btrfs 7453c70c03e631c8d8bfdd4264fa62d3e238da6f]
   filemap_read_folio+0x37/0xe0
   do_read_cache_folio+0x94/0x3e0
   __page_get_link.isra.0+0x20/0x90
   page_get_link+0x16/0x40
   step_into+0x69b/0x830
   path_lookupat+0xa7/0x170
   filename_lookup+0xf7/0x200
   ? set_ptes.isra.0+0x36/0x70
   vfs_statx+0x7a/0x160
   do_statx+0x63/0xa0
   __x64_sys_statx+0x90/0xe0
   do_syscall_64+0x82/0xae0
   entry_SYSCALL_64_after_hwframe+0x4b/0x53
   </TASK>

Please note bs > ps support is still under development and the
enablement patch is not even in btrfs development branch.

[CAUSE]
Btrfs reuses its data folio read path to handle symbolic links, as the
symbolic link target is stored as an inline data extent.

But for newly created inodes, btrfs only set the minimal order if the
target inode is a regular file.

Thus for above newly created symbolic link, it doesn't properly respect
the minimal folio order, and triggered the above crash.

[FIX]
Call btrfs_set_inode_mapping_order() unconditionally inside
btrfs_create_new_inode().

For symbolic links this will fix the crash as now the folio will meet
the minimal order.

For regular files this brings no change.

For directory/bdev/char and all the other types of inodes, they won't
go through the data read path, thus no effect either.

Fixes: cc38d178ff ("btrfs: enable large data folio support under CONFIG_BTRFS_EXPERIMENTAL")
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2025-10-15 12:03:18 +02:00
..
tests btrfs: remove btrfs_clear_extent_bits() 2025-07-22 00:09:22 +02:00
accessors.c btrfs: accessors: rename variable for folio offset 2025-07-22 00:09:21 +02:00
accessors.h btrfs: accessors: delete token versions of set/get helpers 2025-07-22 00:05:00 +02:00
acl.c btrfs: remove unused included headers 2024-03-04 16:24:46 +01:00
acl.h btrfs: update include and forward declarations in headers 2025-03-18 20:35:43 +01:00
async-thread.c btrfs: use list_first_entry() everywhere 2025-05-15 14:30:47 +02:00
async-thread.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
backref.c btrfs: set search_commit_root to false in iterate_inodes_from_logical() 2025-07-22 00:09:20 +02:00
backref.h btrfs: set search_commit_root to false in iterate_inodes_from_logical() 2025-07-22 00:09:20 +02:00
bio.c btrfs: switch RCU helper versions to btrfs_debug() 2025-07-21 23:56:38 +02:00
bio.h btrfs: pass a physical address to btrfs_repair_io_failure() 2025-05-15 14:30:46 +02:00
block-group.c btrfs: annotate block group access with data_race() when sorting for reclaim 2025-09-15 05:25:43 +02:00
block-group.h btrfs: cache if we are using free space bitmaps for a block group 2025-07-21 23:58:03 +02:00
block-rsv.c btrfs: add block reserve for treelog 2025-05-15 14:30:53 +02:00
block-rsv.h btrfs: add block reserve for treelog 2025-05-15 14:30:53 +02:00
btrfs_inode.h btrfs: fix race between setting last_dir_index_offset and inode logging 2025-08-22 00:58:47 +02:00
compression.c btrfs: reject invalid compression level 2025-09-18 13:18:49 +02:00
compression.h btrfs: reject invalid compression level 2025-09-18 13:18:49 +02:00
ctree.c btrfs: don't use token set/get accessors for btrfs_item members 2025-07-22 00:04:59 +02:00
ctree.h btrfs: split btrfs_is_fstree() into multiple if statements for readability 2025-07-21 23:58:04 +02:00
defrag.c btrfs: defrag: add flag to force no-compression 2025-07-22 01:13:03 +02:00
defrag.h btrfs: pass struct btrfs_inode to btrfs_defrag_file() 2025-03-18 20:35:43 +01:00
delalloc-space.c btrfs: add block reserve for treelog 2025-05-15 14:30:53 +02:00
delalloc-space.h btrfs: pass struct btrfs_inode to btrfs_free_reserved_data_space_noquota() 2025-05-15 14:30:52 +02:00
delayed-inode.c btrfs: initialize inode::file_extent_tree after i_mode has been set 2025-09-15 05:25:40 +02:00
delayed-inode.h btrfs: make btrfs_readdir_delayed_dir_index() return a bool instead 2025-07-21 23:53:30 +02:00
delayed-ref.c btrfs: add btrfs prefix to is_fstree() and make it return bool 2025-07-21 23:58:04 +02:00
delayed-ref.h btrfs: constify more pointer parameters 2025-07-21 23:53:26 +02:00
dev-replace.c btrfs: use fs_holder_ops for all opened devices 2025-07-22 00:06:20 +02:00
dev-replace.h btrfs: trivial conversion to return bool instead of int 2025-05-15 14:30:49 +02:00
dir-item.c btrfs: rename inode number parameter passed to btrfs_check_dir_item_collision() 2025-07-22 00:05:00 +02:00
dir-item.h btrfs: rename inode number parameter passed to btrfs_check_dir_item_collision() 2025-07-22 00:05:00 +02:00
direct-io.c btrfs: remove superfluous return value check at btrfs_dio_iomap_begin() 2025-05-15 14:30:57 +02:00
direct-io.h btrfs: update include and forward declarations in headers 2025-03-18 20:35:43 +01:00
discard.c btrfs: use verbose assert at peek_discard_list() 2025-05-15 14:30:55 +02:00
discard.h btrfs: update include and forward declarations in headers 2025-03-18 20:35:43 +01:00
disk-io.c CRC updates for 6.17 2025-07-28 17:43:29 -07:00
disk-io.h btrfs: get rid of btrfs_read_dev_super() 2025-05-15 14:30:50 +02:00
export.c btrfs: make btrfs_iget() return a btrfs inode instead 2025-03-18 20:35:50 +01:00
export.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
extent-io-tree.c btrfs: use our message helpers instead of pr_err/pr_warn/pr_info 2025-07-21 23:58:04 +02:00
extent-io-tree.h btrfs: remove btrfs_clear_extent_bits() 2025-07-22 00:09:22 +02:00
extent-tree.c btrfs: fix ssd_spread overallocation 2025-07-22 01:12:52 +02:00
extent-tree.h btrfs: constify more pointer parameters 2025-07-21 23:53:26 +02:00
extent_io.c btrfs: return any hit error from extent_writepage_io() 2025-10-15 12:03:18 +02:00
extent_io.h btrfs: make extent_buffer_test_bit() return a boolean instead 2025-07-21 23:58:02 +02:00
extent_map.c btrfs: add btrfs prefix to is_fstree() and make it return bool 2025-07-21 23:58:04 +02:00
extent_map.h btrfs: rename remaining exported extent map functions 2025-05-15 14:30:45 +02:00
fiemap.c btrfs: use refcount_t type for the extent buffer reference counter 2025-07-21 23:53:30 +02:00
fiemap.h btrfs: move fiemap code into its own file 2024-07-11 15:33:20 +02:00
file-item.c btrfs: use btrfs_is_data_reloc_root() where not done yet 2025-07-21 23:53:31 +02:00
file-item.h btrfs: change return type of btrfs_alloc_dummy_sum() to int 2025-05-15 14:30:49 +02:00
file.c vfs-6.17-rc1.mmap_prepare 2025-07-28 13:43:25 -07:00
file.h btrfs: update include and forward declarations in headers 2025-03-18 20:35:43 +01:00
free-space-cache.c btrfs: use pgoff_t for page index variables 2025-07-21 23:58:05 +02:00
free-space-cache.h btrfs: add cancellation points to trim loops 2024-10-07 23:21:56 +02:00
free-space-tree.c btrfs: cache if we are using free space bitmaps for a block group 2025-07-21 23:58:03 +02:00
free-space-tree.h btrfs: add btrfs prefix to free space tree exported functions 2025-07-21 23:58:02 +02:00
fs.c btrfs: update include and forward declarations in headers 2025-03-18 20:35:43 +01:00
fs.h btrfs: index buffer_tree using node size 2025-07-22 00:09:20 +02:00
inode-item.c btrfs: remove unused parameters from btrfs_lookup_inode_extref() 2025-07-21 23:58:03 +02:00
inode-item.h btrfs: remove unused parameters from btrfs_lookup_inode_extref() 2025-07-21 23:58:03 +02:00
inode.c btrfs: fix symbolic link reading when bs > ps 2025-10-15 12:03:18 +02:00
ioctl.c for-6.17/io_uring-20250728 2025-07-28 16:30:12 -07:00
ioctl.h tree-wide: s/struct fileattr/struct file_kattr/g 2025-07-04 16:14:39 +02:00
Kconfig btrfs: enable large data folio support under CONFIG_BTRFS_EXPERIMENTAL 2025-07-21 23:53:30 +02:00
locking.c btrfs: trivial conversion to return bool instead of int 2025-05-15 14:30:49 +02:00
locking.h btrfs: trivial conversion to return bool instead of int 2025-05-15 14:30:49 +02:00
lru_cache.c btrfs: fix typos found by codespell 2023-12-15 23:00:04 +01:00
lru_cache.h btrfs: cleanup recursive include of the same header 2024-07-11 15:33:22 +02:00
lzo.c btrfs: prepare compression paths for large data folios 2025-05-15 14:30:45 +02:00
Makefile btrfs: selftests: add delayed ref self test cases 2025-01-13 14:53:13 +01:00
messages.c btrfs: disable rate limiting when debug enabled 2024-10-01 19:29:41 +02:00
messages.h btrfs: merge btrfs_printk_ratelimited() and its only caller 2025-07-21 23:56:39 +02:00
misc.h btrfs: add helper folio_end() 2025-07-21 23:58:01 +02:00
ordered-data.c btrfs: use folio_end() where appropriate 2025-07-21 23:58:01 +02:00
ordered-data.h btrfs: introduce a read path dedicated extent lock helper 2025-03-18 20:35:48 +01:00
orphan.c btrfs: BTRFS_PATH_AUTO_FREE in orphan.c 2024-09-10 16:51:22 +02:00
orphan.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
print-tree.c btrfs: use our message helpers instead of pr_err/pr_warn/pr_info 2025-07-21 23:58:04 +02:00
print-tree.h btrfs: update include and forward declarations in headers 2025-03-18 20:35:43 +01:00
props.c btrfs: props: switch prop_handler::extract to struct btrfs_inode 2025-03-18 20:35:44 +01:00
props.h btrfs: pass struct btrfs_inode to btrfs_inode_inherit_props() 2025-03-18 20:35:44 +01:00
qgroup.c btrfs: fix squota compressed stats leak 2025-09-02 20:45:15 +02:00
qgroup.h btrfs: update include and forward declarations in headers 2025-03-18 20:35:43 +01:00
raid-stripe-tree.c btrfs: unfold transaction abort at btrfs_insert_one_raid_extent() 2025-07-21 23:53:24 +02:00
raid-stripe-tree.h btrfs: update include and forward declarations in headers 2025-03-18 20:35:43 +01:00
raid56.c btrfs: raid56: use list_last_entry() at cache_rbio() 2025-05-15 14:30:54 +02:00
raid56.h btrfs: add forward declarations and headers, part 2 2024-03-04 16:24:49 +01:00
ref-verify.c btrfs: ref-verify: handle damaged extent root tree 2025-09-18 05:47:34 +02:00
ref-verify.h btrfs: constify more pointer parameters 2025-07-21 23:53:26 +02:00
reflink.c btrfs: remove btrfs_clear_extent_bits() 2025-07-22 00:09:22 +02:00
reflink.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
relocation.c btrfs: do not allow relocation of partially dropped subvolumes 2025-08-07 17:07:15 +02:00
relocation.h btrfs: don't print relocation messages from auto reclaim 2025-07-22 00:09:22 +02:00
root-tree.c btrfs: root-tree: remove unnecessary calls to btrfs_mark_buffer_dirty() 2025-01-13 14:53:20 +01:00
root-tree.h btrfs: qgroup: fix qgroup prealloc rsv leak in subvolume operations 2024-04-02 19:18:23 +02:00
scrub.c btrfs: switch RCU helper versions to btrfs_warn() 2025-07-21 23:56:38 +02:00
scrub.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
send.c btrfs: send: use fallocate for hole punching with send stream v2 2025-07-22 01:23:14 +02:00
send.h btrfs: pass btrfs_root pointers to send ioctl parameters 2025-03-18 20:35:49 +01:00
space-info.c btrfs: change dump_block_groups() in btrfs_dump_space_info() from int to bool 2025-07-21 23:58:05 +02:00
space-info.h btrfs: change dump_block_groups() in btrfs_dump_space_info() from int to bool 2025-07-21 23:58:05 +02:00
subpage.c btrfs: subpage: keep TOWRITE tag until folio is cleaned 2025-08-13 14:08:45 +02:00
subpage.h btrfs: enable large data folio support under CONFIG_BTRFS_EXPERIMENTAL 2025-07-21 23:53:30 +02:00
super.c for-6.17-rc6-tag 2025-09-20 21:41:26 -07:00
super.h btrfs: change BTRFS_MOUNT_* flags to 64bit type 2024-07-19 17:20:23 +02:00
sysfs.c btrfs: use our message helpers instead of pr_err/pr_warn/pr_info 2025-07-21 23:58:04 +02:00
sysfs.h btrfs: update include and forward declarations in headers 2025-03-18 20:35:43 +01:00
transaction.c btrfs: qgroup: fix qgroup create ioctl returning success after quotas disabled 2025-07-22 00:07:30 +02:00
transaction.h btrfs: move abort_should_print_stack() to transaction.h 2025-01-13 14:53:17 +01:00
tree-checker.c btrfs: tree-checker: fix the incorrect inode ref size check 2025-09-18 05:47:25 +02:00
tree-checker.h btrfs: validate system chunk array at btrfs_validate_super() 2025-01-13 14:53:18 +01:00
tree-log.c btrfs: fix invalid extref key setup when replaying dentry 2025-09-15 05:25:31 +02:00
tree-log.h btrfs: avoid transaction commit on any fsync after subvolume creation 2024-07-11 15:33:24 +02:00
tree-mod-log.c btrfs: reduce size of struct tree_mod_elem 2025-07-22 00:09:20 +02:00
tree-mod-log.h btrfs: drop unused parameter path from btrfs_tree_mod_log_rewind() 2024-11-11 14:34:15 +01:00
ulist.c btrfs: use rb_find_add() in ulist_rbtree_insert() 2025-07-21 23:53:25 +02:00
ulist.h btrfs: preallocate ulist memory for qgroup rsv 2024-07-11 15:33:26 +02:00
uuid-tree.c btrfs: uuid-tree: remove unnecessary call to btrfs_mark_buffer_dirty() 2025-01-13 14:53:20 +01:00
uuid-tree.h btrfs: move uuid tree related code to uuid-tree.[ch] 2024-09-10 16:51:12 +02:00
verity.c btrfs: pass struct btrfs_inode to btrfs_sync_inode_flags_to_i_flags() 2025-03-18 20:35:49 +01:00
verity.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
volumes.c btrfs: don't allow adding block device of less than 1 MB 2025-09-05 19:52:10 +02:00
volumes.h btrfs: don't print relocation messages from auto reclaim 2025-07-22 00:09:22 +02:00
xattr.c btrfs: replace strcpy() with strscpy() 2025-07-22 00:05:00 +02:00
xattr.h btrfs: update include and forward declarations in headers 2025-03-18 20:35:43 +01:00
zlib.c btrfs: prepare compression paths for large data folios 2025-05-15 14:30:45 +02:00
zoned.c btrfs: zoned: don't fail mount needlessly due to too many active zones 2025-09-23 11:22:21 +02:00
zoned.h btrfs: zoned: reserve data_reloc block group on mount 2025-07-21 23:56:31 +02:00
zstd.c btrfs: use our message helpers instead of pr_err/pr_warn/pr_info 2025-07-21 23:58:04 +02:00