linux/fs/btrfs
Qu Wenruo 3228b2eceb btrfs: reject new transactions if the fs is fully read-only
[ Upstream commit 1972f44c18 ]

[BUG]
There is a bug report where a heavily fuzzed fs is mounted with all
rescue mount options, which leads to the following warnings during
unmount:

  BTRFS: Transaction aborted (error -22)
  Modules linked in:
  CPU: 0 UID: 0 PID: 9758 Comm: repro.out Not tainted
  6.19.0-rc5-00002-gb71e635feefc #7 PREEMPT(full)
  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
  RIP: 0010:find_free_extent_update_loop fs/btrfs/extent-tree.c:4208 [inline]
  RIP: 0010:find_free_extent+0x52f0/0x5d20 fs/btrfs/extent-tree.c:4611
  Call Trace:
   <TASK>
   btrfs_reserve_extent+0x2cd/0x790 fs/btrfs/extent-tree.c:4705
   btrfs_alloc_tree_block+0x1e1/0x10e0 fs/btrfs/extent-tree.c:5157
   btrfs_force_cow_block+0x578/0x2410 fs/btrfs/ctree.c:517
   btrfs_cow_block+0x3c4/0xa80 fs/btrfs/ctree.c:708
   btrfs_search_slot+0xcad/0x2b50 fs/btrfs/ctree.c:2130
   btrfs_truncate_inode_items+0x45d/0x2350 fs/btrfs/inode-item.c:499
   btrfs_evict_inode+0x923/0xe70 fs/btrfs/inode.c:5628
   evict+0x5f4/0xae0 fs/inode.c:837
   __dentry_kill+0x209/0x660 fs/dcache.c:670
   finish_dput+0xc9/0x480 fs/dcache.c:879
   shrink_dcache_for_umount+0xa0/0x170 fs/dcache.c:1661
   generic_shutdown_super+0x67/0x2c0 fs/super.c:621
   kill_anon_super+0x3b/0x70 fs/super.c:1289
   btrfs_kill_super+0x41/0x50 fs/btrfs/super.c:2127
   deactivate_locked_super+0xbc/0x130 fs/super.c:474
   cleanup_mnt+0x425/0x4c0 fs/namespace.c:1318
   task_work_run+0x1d4/0x260 kernel/task_work.c:233
   exit_task_work include/linux/task_work.h:40 [inline]
   do_exit+0x694/0x22f0 kernel/exit.c:971
   do_group_exit+0x21c/0x2d0 kernel/exit.c:1112
   __do_sys_exit_group kernel/exit.c:1123 [inline]
   __se_sys_exit_group kernel/exit.c:1121 [inline]
   __x64_sys_exit_group+0x3f/0x40 kernel/exit.c:1121
   x64_sys_call+0x2210/0x2210 arch/x86/include/generated/asm/syscalls_64.h:232
   do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
   do_syscall_64+0xe8/0xf80 arch/x86/entry/syscall_64.c:94
   entry_SYSCALL_64_after_hwframe+0x77/0x7f
  RIP: 0033:0x44f639
  Code: Unable to access opcode bytes at 0x44f60f.
  RSP: 002b:00007ffc15c4e088 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
  RAX: ffffffffffffffda RBX: 00000000004c32f0 RCX: 000000000044f639
  RDX: 000000000000003c RSI: 00000000000000e7 RDI: 0000000000000001
  RBP: 0000000000000001 R08: ffffffffffffffc0 R09: 0000000000000000
  R10: 0000000000000000 R11: 0000000000000246 R12: 00000000004c32f0
  R13: 0000000000000001 R14: 0000000000000000 R15: 0000000000000001
   </TASK>

Since rescue mount options will mark the full fs read-only, there should
be no new transaction triggered.

But during unmount we will evict all inodes, which can trigger a new
transaction, and triggers warnings on a heavily corrupted fs.

[CAUSE]
Btrfs allows new transaction even on a read-only fs, this is to allow
log replay happen even on read-only mounts, just like what ext4/xfs do.

However with rescue mount options, the fs is fully read-only and cannot
be remounted read-write, thus in that case we should also reject any new
transactions.

[FIX]
If we find the fs has rescue mount options, we should treat the fs as
error, so that no new transaction can be started.

Reported-by: Jiaming Zhang <r772577952@gmail.com>
Link: https://lore.kernel.org/linux-btrfs/CANypQFYw8Nt8stgbhoycFojOoUmt+BoZ-z8WJOZVxcogDdwm=Q@mail.gmail.com/
Reviewed-by: Boris Burkov <boris@bur.io>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2026-02-11 13:41:53 +01:00
..
tests btrfs: fix typos in comments and strings 2025-09-23 08:49:16 +02:00
accessors.c btrfs: fix typos in comments and strings 2025-09-23 08:49:16 +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: add unlikely annotations to branches leading to EIO 2025-09-23 08:49:26 +02:00
backref.h btrfs: fix typos in comments and strings 2025-09-23 08:49:16 +02:00
bio.c btrfs: add unlikely annotations to branches leading to EIO 2025-09-23 08:49:26 +02:00
bio.h btrfs: try to search for data csums in commit root 2025-09-22 10:54:31 +02:00
block-group.c btrfs: fix racy bitfield write in btrfs_clear_space_info_full() 2025-12-18 14:03:16 +01:00
block-group.h btrfs: fix typos in comments and strings 2025-09-23 08:49:16 +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 for-6.18-tag 2025-09-30 08:14:49 -07:00
compression.c btrfs: prepare compression folio alloc/free for bs > ps cases 2025-09-23 08:49:24 +02:00
compression.h btrfs: prepare compression folio alloc/free for bs > ps cases 2025-09-23 08:49:24 +02:00
ctree.c btrfs: fix leaf leak in an error path in btrfs_del_items() 2025-12-18 14:03:16 +01: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: add unlikely annotations to branches leading to EIO 2025-09-23 08:49:26 +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: fix use-after-free warning in btrfs_get_or_create_delayed_node() 2026-01-17 16:35:18 +01:00
delayed-inode.h btrfs: fix delayed_node ref_tracker use after free 2025-10-22 09:40:04 +02:00
delayed-ref.c btrfs: fix double free of qgroup record after failure to add delayed ref head 2025-12-18 14:03:16 +01:00
delayed-ref.h btrfs: move ref-verify under CONFIG_BTRFS_DEBUG 2025-09-22 10:54:32 +02:00
dev-replace.c btrfs: add unlikely annotations to branches leading to EIO 2025-09-23 08:49:26 +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: enable experimental bs > ps support 2025-09-23 08:49:25 +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 btrfs: reject new transactions if the fs is fully read-only 2026-02-11 13:41:53 +01:00
disk-io.h btrfs: convert several int parameters to bool 2025-09-22 10:54:32 +02:00
export.c btrfs: avoid potential out-of-bounds in btrfs_encode_fh() 2025-09-26 08:48:30 +02:00
export.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
extent-io-tree.c btrfs: fix typos in comments and strings 2025-09-23 08:49:16 +02:00
extent-io-tree.h btrfs: convert several int parameters to bool 2025-09-22 10:54:32 +02:00
extent-tree.c btrfs: add unlikely annotations to branches leading to transaction abort 2025-09-23 08:49:26 +02:00
extent-tree.h btrfs: convert several int parameters to bool 2025-09-22 10:54:32 +02:00
extent_io.c btrfs: do not strictly require dirty metadata threshold for metadata writepages 2026-02-06 16:57:40 +01:00
extent_io.h btrfs: do not strictly require dirty metadata threshold for metadata writepages 2026-02-06 16:57:40 +01:00
extent_map.c for-6.18-tag 2025-09-30 08:14:49 -07:00
extent_map.h btrfs: rename remaining exported extent map functions 2025-05-15 14:30:45 +02:00
fiemap.c btrfs: fix typos in comments and strings 2025-09-23 08:49:16 +02:00
fiemap.h btrfs: move fiemap code into its own file 2024-07-11 15:33:20 +02:00
file-item.c btrfs: add unlikely annotations to branches leading to transaction abort 2025-09-23 08:49:26 +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 btrfs: fix changeset leak on mmap write after failure to reserve metadata 2026-01-02 12:56:37 +01:00
file.h btrfs: update include and forward declarations in headers 2025-03-18 20:35:43 +01:00
free-space-cache.c btrfs: add unlikely annotations to branches leading to transaction abort 2025-09-23 08:49:26 +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: do not assert we found block group item when creating free space tree 2025-10-13 22:33:22 +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: enable experimental bs > ps support 2025-09-23 08:49:25 +02:00
fs.h btrfs: reject new transactions if the fs is fully read-only 2026-02-11 13:41:53 +01:00
inode-item.c btrfs: add unlikely annotations to branches leading to transaction abort 2025-09-23 08:49:26 +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 reservation leak in some error paths when inserting inline extent 2026-02-11 13:41:48 +01:00
ioctl.c btrfs: don't rewrite ret from inode_permission 2026-01-02 12:57:08 +01:00
ioctl.h tree-wide: s/struct fileattr/struct file_kattr/g 2025-07-04 16:14:39 +02:00
Kconfig btrfs: implement ref_tracker for delayed_nodes 2025-09-22 10:54:32 +02:00
locking.c btrfs: fix typos in comments and strings 2025-09-23 08:49:16 +02:00
locking.h btrfs: fix typos in comments and strings 2025-09-23 08:49:16 +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: add unlikely annotations to branches leading to EUCLEAN 2025-09-23 08:49:26 +02:00
Makefile btrfs: move ref-verify under CONFIG_BTRFS_DEBUG 2025-09-22 10:54:32 +02:00
messages.c btrfs: dump detailed info and specific messages on log replay failures 2025-09-23 08:49:21 +02:00
messages.h btrfs: remove duplicate inclusion of linux/types.h 2025-09-22 10:54:31 +02:00
misc.h btrfs: introduce btrfs_bio_for_each_block_all() helper 2025-09-23 08:49:17 +02:00
ordered-data.c btrfs: truncate ordered extent when skipping writeback past i_size 2026-01-17 16:35:30 +01: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: print-tree: print key types as human readable strings 2025-09-23 08:49:23 +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: qgroup: update all parent qgroups when doing quick inherit 2026-01-17 16:35:18 +01:00
qgroup.h btrfs: update include and forward declarations in headers 2025-03-18 20:35:43 +01:00
raid-stripe-tree.c btrfs: add unlikely annotations to branches leading to transaction abort 2025-09-23 08:49:26 +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: add unlikely annotations to branches leading to EIO 2025-09-23 08:49:26 +02:00
raid56.h btrfs: prepare scrub to support bs > ps cases 2025-09-23 08:49:25 +02:00
ref-verify.c btrfs: ref-verify: fix IS_ERR() vs NULL check in btrfs_build_ref_tree() 2025-10-22 09:40:07 +02:00
ref-verify.h btrfs: move ref-verify under CONFIG_BTRFS_DEBUG 2025-09-22 10:54:32 +02:00
reflink.c btrfs: add unlikely annotations to branches leading to transaction abort 2025-09-23 08:49:26 +02:00
reflink.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
relocation.c btrfs: fix clearing of BTRFS_FS_RELOC_RUNNING if relocation already running 2025-10-13 22:29:03 +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: add unlikely annotations to branches leading to transaction abort 2025-09-23 08:49:26 +02: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: scrub: always update btrfs_scrub_progress::last_physical 2026-01-02 12:56:41 +01:00
scrub.h btrfs: convert several int parameters to bool 2025-09-22 10:54:32 +02:00
send.c btrfs: send: check for inline extents in range_is_hole_in_parent() 2026-01-23 11:21:15 +01:00
send.h btrfs: pass btrfs_root pointers to send ioctl parameters 2025-03-18 20:35:49 +01:00
space-info.c btrfs: fix memory leaks in create_space_info() error paths 2026-01-23 11:21:17 +01:00
space-info.h btrfs: fix racy bitfield write in btrfs_clear_space_info_full() 2025-12-18 14:03:16 +01:00
subpage.c btrfs: fix typos in comments and strings 2025-09-23 08:49:16 +02:00
subpage.h btrfs: fix typos in comments and strings 2025-09-23 08:49:16 +02:00
super.c btrfs: only enforce free space tree if v1 cache is required for bs < ps cases 2026-01-17 16:35:25 +01:00
super.h btrfs: change BTRFS_MOUNT_* flags to 64bit type 2024-07-19 17:20:23 +02:00
sysfs.c btrfs: simplify support block size check 2025-09-22 10:54:31 +02:00
sysfs.h btrfs: update include and forward declarations in headers 2025-03-18 20:35:43 +01:00
transaction.c btrfs: fix deadlock in wait_current_trans() due to ignored transaction type 2026-01-23 11:21:36 +01: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 bounds check in check_inode_extref() 2025-10-13 22:35:51 +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 Wmaybe-uninitialized warning in replay_one_buffer() 2026-02-11 13:41:53 +01: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 for-6.18-tag 2025-09-30 08:14:49 -07:00
verity.h btrfs: add forward declarations and headers, part 1 2024-03-04 16:24:49 +01:00
volumes.c btrfs: sync read disk super and set block size 2026-02-11 13:41:53 +01:00
volumes.h btrfs: fix typos in comments and strings 2025-09-23 08:49:16 +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: zlib: fix the folio leak on S390 hardware acceleration 2026-02-06 16:57:29 +01:00
zoned.c for-6.18-rc5-tag 2025-11-11 10:13:17 -08:00
zoned.h btrfs: zoned: return error from btrfs_zone_finish_endio() 2025-09-22 10:54:30 +02:00
zstd.c btrfs: add unlikely annotations to branches leading to EIO 2025-09-23 08:49:26 +02:00