summaryrefslogtreecommitdiff
path: root/fs/btrfs
AgeCommit message (Collapse)Author
12 hoursMerge branch 'vfs.all' of ↵Mark Brown
https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
12 hoursMerge branch 'for-next' of https://git.kernel.org/pub/scm/fs/fsverity/linux.gitMark Brown
26 hoursMerge branch 'vfs-7.4.idmap' into vfs.allChristian Brauner
3 daysbtrfs: stop reading free space inodes from the commit rootTal Zussman
Free space inode data was only read when loading the v1 cache, which is gone, so btrfs_get_extent() and btrfs_lookup_bio_sums() no longer need to search the commit root for them. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Tal Zussman <tz2294@columbia.edu> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: stop special-casing free space inodes in the delalloc accountingTal Zussman
Free space inodes never have delalloc or outstanding extents any more, so they don't need to be kept off the root's delalloc inode list or out of the outstanding extents tracepoint. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Tal Zussman <tz2294@columbia.edu> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: remove the free space inode special cases from the COW pathsTal Zussman
Free space inodes are never written anymore, so drop the special cases for them in cow_file_range(), fallback_to_cow(), can_nocow_file_extent() and btrfs_finish_one_ordered(). Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Tal Zussman <tz2294@columbia.edu> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: remove the free space inode ordered extent special casesTal Zussman
Free space inodes never have ordered extents anymore. Drop the lockdep exceptions for them and btrfs_join_transaction_spacecache(), which was only used to finish their ordered extents during a commit. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Tal Zussman <tz2294@columbia.edu> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: remove BTRFS_RESERVE_FLUSH_FREE_SPACE_INODETal Zussman
Free space inodes no longer reserve data or delalloc space, as nothing writes to them. Remove the flush mode and the special cases that selected it. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Tal Zussman <tz2294@columbia.edu> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: remove the free space cache trimming rangesTal Zussman
cache_writeout_mutex and trimming_ranges let the v1 cache writer see ranges that were unlinked from the free space tree while being discarded. Nothing consumes the list anymore, and the tree itself is protected by tree_lock, so remove them. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Tal Zussman <tz2294@columbia.edu> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: replace btrfs_set_free_space_cache_v1_active() with a cleanup helperTal Zussman
The only caller passes active = false. Turn it into btrfs_cleanup_free_space_cache_v1() and fold the block group loop into it. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Tal Zussman <tz2294@columbia.edu> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: remove the SPACE_CACHE mount option flagTal Zussman
Nothing sets BTRFS_MOUNT_SPACE_CACHE anymore, so every test of it is false. Remove the flag, the checks rejecting the v1 cache on zoned filesystems and for sector sizes other than the page size, and the deprecation warning. Show a read-only filesystem that still has an old cache as nospace_cache, since that's what's in effect. space_cache and space_cache=v1 keep falling back to no space cache with a warning. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Tal Zussman <tz2294@columbia.edu> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: remove btrfs_disk_cache_stateTal Zussman
With neither the writer nor the loader left, nothing acts on disk_cache_state. Remove it, the need_clear handling when reading block groups, and the enum. While at it, drop the unused cache_generation field from struct btrfs_block_group. lookup_free_space_inode() converted old style space inodes by clearing disk_cache_state so the cache would be rewritten with the new inode flags. Without that it only sets flags on the in-memory inode, which every remaining caller truncates or deletes right after, so drop the conversion too. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Tal Zussman <tz2294@columbia.edu> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: remove the v1 space cache load pathTal Zussman
Nothing writes a v1 space cache any more, and since commit 545e560a5b0f ("btrfs: disable v1 space cache") the mount option can't be enabled to read one either. Remove load_free_space_cache(), its io_ctl helpers and struct btrfs_io_ctl. Drop the gfp constraint on the inode mapping as well, it only covered the cache's page cache allocations. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Tal Zussman <tz2294@columbia.edu> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: drop the transaction handle from the prealloc helpersTal Zussman
The v1 space cache created its inode during the transaction commit, and btrfs_prealloc_file_range_trans() existed so that preallocation could reuse the open handle. It was the only caller passing a transaction, so __btrfs_prealloc_file_range() and insert_prealloc_file_extent() now always start their own. Fold the wrapper into btrfs_prealloc_file_range() and drop the parameter. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Tal Zussman <tz2294@columbia.edu> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: rename cache_write_mutex to dirty_bgs_update_mutexTal Zussman
The v1 space cache writeout is gone, but the mutex is still needed. It keeps btrfs_remove_block_group() from deleting a block group item while btrfs_start_dirty_block_groups() is updating it outside the commit critical section. Rename it to reflect what it protects, and update the comments around the dirty block group writeout that still refer to the space cache. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Tal Zussman <tz2294@columbia.edu> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: remove the v1 space cache write pathTal Zussman
Nothing writes out a v1 space cache any more. Remove the writers and their io_ctl helpers, along with create_free_space_inode() and btrfs_prealloc_file_range_trans(), whose only user was the cache inode creation. The io_list and io_ctl block group fields were only used by the writers, so remove them too. btrfs_truncate_free_space_cache() only needed the block group to wait for and clear in-flight cache IO, so drop that parameter. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Tal Zussman <tz2294@columbia.edu> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: remove the free space cache endio workqueueTal Zussman
Free space inodes are no longer written to, so nothing queues ordered extent completion on endio_freespace_worker. Remove it and always use endio_write_workers in btrfs_queue_ordered_fn(). Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Tal Zussman <tz2294@columbia.edu> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: remove the v1 space cache writeout from the transaction commitTal Zussman
Nothing sets SPACE_CACHE anymore, so the dirty block group writers never have a cache to write out or wait for. Remove cache_save_setup(), btrfs_setup_space_cache(), the io_list handling, the io_bgs list and BTRFS_TRANS_CACHE_ENOSPC, and the abort-time cleanup of in-flight cache IO. The -ENOENT retry in btrfs_write_dirty_block_groups() handled a free space endio worker creating a block group during the commit critical section, so drop it too. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Tal Zussman <tz2294@columbia.edu> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: stop enabling the v1 space cache from the on-disk stateTal Zussman
Since commit 545e560a5b0f ("btrfs: disable v1 space cache") the mount options can no longer request the v1 space cache, but a filesystem with an active v1 cache and no free space tree still enables it from cache_generation, and remount does the same. Drop both, so SPACE_CACHE can never be set. btrfs_start_pre_rw_mount() then sees the on-disk cache as active but unwanted and cleans it up, as -o nospace_cache does today. That covers the read-only to read-write remount as well, so drop the toggle in btrfs_remount_cleanup(), which would otherwise start a transaction on remounts of a read-only filesystem with an old cache. The cleanup is now unconditional, and the first read-write mount fails if it fails, as it did with -o nospace_cache. This also lets an old filesystem mount without options when the page size is larger than the sector size, which btrfs_check_features() rejected once SPACE_CACHE was set from the superblock. Assisted-by: Claude:claude-fable-5-1 Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Tal Zussman <tz2294@columbia.edu> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: === misc-next on b-for-next ===David Sterba
Any commits after this one are for testing and evaluation only. Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: fix use-after-free on quota enable allocation failureYalagada Pavan Kumar
[BUG] There is a syzbot report that a use-after-free bug is triggered after a failed btrfs_quota_enable(): loop0: detected capacity change from 32768 to 0 ================================================================== BUG: KASAN: slab-use-after-free in __list_add_valid_or_report+0x4e/0x130 lib/list_debug.c:29 Read of size 8 at addr ffff888040e0a528 by task syz.0.0/5324 CPU: 0 UID: 0 PID: 5324 Comm: syz.0.0 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120 print_address_description+0x55/0x1e0 mm/kasan/report.c:378 print_report+0x58/0x70 mm/kasan/report.c:482 kasan_report+0x117/0x150 mm/kasan/report.c:595 __list_add_valid_or_report+0x4e/0x130 lib/list_debug.c:29 __list_add_valid include/linux/list.h:104 [inline] __list_add include/linux/list.h:169 [inline] list_add include/linux/list.h:192 [inline] list_move include/linux/list.h:345 [inline] add_root_to_dirty_list+0x38b/0x470 fs/btrfs/ctree.c:232 btrfs_force_cow_block+0xf09/0x1bf0 fs/btrfs/ctree.c:553 btrfs_cow_block+0x3f1/0xaf0 fs/btrfs/ctree.c:696 btrfs_search_slot+0xd70/0x2d20 fs/btrfs/ctree.c:-1 btrfs_search_prev_slot fs/btrfs/free-space-tree.c:134 [inline] remove_free_space_extent fs/btrfs/free-space-tree.c:732 [inline] __btrfs_remove_from_free_space_tree fs/btrfs/free-space-tree.c:837 [inline] btrfs_remove_from_free_space_tree+0x4d6/0xda0 fs/btrfs/free-space-tree.c:866 alloc_reserved_extent+0x4a/0x2b0 fs/btrfs/extent-tree.c:4976 alloc_reserved_tree_block fs/btrfs/extent-tree.c:5155 [inline] run_delayed_tree_ref fs/btrfs/extent-tree.c:1815 [inline] run_one_delayed_ref fs/btrfs/extent-tree.c:1851 [inline] btrfs_run_delayed_refs_for_head fs/btrfs/extent-tree.c:2058 [inline] __btrfs_run_delayed_refs+0x18b5/0x43b0 fs/btrfs/extent-tree.c:2134 btrfs_run_delayed_refs+0xdc/0x2a0 fs/btrfs/extent-tree.c:2246 btrfs_commit_transaction+0x28a/0x3170 fs/btrfs/transaction.c:2267 sync_filesystem+0x1d2/0x240 fs/sync.c:66 btrfs_reconfigure+0x2dc/0x2100 fs/btrfs/super.c:1511 reconfigure_super+0x232/0x8f0 fs/super.c:1128 do_remount fs/namespace.c:3410 [inline] path_mount+0xd4e/0x1050 fs/namespace.c:4160 do_mount fs/namespace.c:4181 [inline] __do_sys_mount fs/namespace.c:4397 [inline] __se_sys_mount+0x31d/0x420 fs/namespace.c:4374 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline] do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f9c8dd9f3ca </TASK> Allocated by task 5323: kasan_save_stack mm/kasan/common.c:57 [inline] kasan_save_track+0x3e/0x80 mm/kasan/common.c:78 poison_kmalloc_redzone mm/kasan/common.c:409 [inline] __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:426 kasan_kmalloc include/linux/kasan.h:263 [inline] __kmalloc_cache_noprof+0x321/0x600 mm/slub.c:5563 _kmalloc_noprof include/linux/slab.h:991 [inline] _kzalloc_noprof include/linux/slab.h:1312 [inline] btrfs_alloc_root+0x75/0x840 fs/btrfs/disk-io.c:638 btrfs_create_tree+0xa8/0x5c0 fs/btrfs/disk-io.c:832 btrfs_quota_enable+0x3d6/0x1e20 fs/btrfs/qgroup.c:1074 btrfs_ioctl_quota_ctl+0x186/0x1f0 fs/btrfs/ioctl.c:3581 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:597 [inline] __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline] do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 5323: kasan_save_stack mm/kasan/common.c:57 [inline] kasan_save_track+0x3e/0x80 mm/kasan/common.c:78 kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:584 poison_slab_object mm/kasan/common.c:264 [inline] __kasan_slab_free+0x5c/0x80 mm/kasan/common.c:296 kasan_slab_free include/linux/kasan.h:235 [inline] slab_free_hook mm/slub.c:2748 [inline] slab_free mm/slub.c:6508 [inline] kfree+0x1c5/0x650 mm/slub.c:6801 btrfs_quota_enable+0x1208/0x1e20 fs/btrfs/qgroup.c:1292 btrfs_ioctl_quota_ctl+0x186/0x1f0 fs/btrfs/ioctl.c:3581 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:597 [inline] __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline] do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84 entry_SYSCALL_64_after_hwframe+0x77/0x7f [CAUSE] During btrfs_quota_enable(), a temporary quota_root is created, then qgroup items are created for each subvolume and inserted into that root. If there are enough subvolumes, the level of quota_root will be bumped, and add_root_to_dirty_list() will be called, adding quota_root->dirty_list into fs_info->dirty_cowonly_roots. But if a problem is hit during btrfs_quota_enable() later, that quota_root will be released through btrfs_put_root(), causing the whole quota_root structure to be released, while leaving fs_info->dirty_cowonly_roots still pointing to the released quota_root->dirty_list. Later access through fs_info->dirty_cowonly_roots will trigger a use-after-free bug. [FIX] We can just call list_del_init(&root->dirty_list) when btrfs_quota_enable() failed. Also to follow the existing error handling behavior, abort the transaction when the memory preallocation failed. Reported-by: syzbot+947286c775f432b073a8@syzkaller.appspotmail.com Link: https://lore.kernel.org/linux-btrfs/6ac5a5e1.9ad129c8.3ce5b3.0010.GAE@google.com/ Closes: https://syzkaller.appspot.com/bug?extid=947286c775f432b073a8 Signed-off-by: Yalagada Pavan Kumar <pavankumaryalagada@gmail.com> Reviewed-by: Boris Burkov <boris@bur.io> Reviewed-by: Qu Wenruo <wqu@suse.com> [ Change the commit message to include a proper analysis. ] Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: prevent use-after-free in btrfs_transaction::switch_commitsQu Wenruo
If a transaction is aborted during committing, btrfs_transaction::switch_commits can be non-empty, but the btrfs_transaction structure can be freed at the last btrfs_put_transaction() inside cleanup_transaction(). The btrfs_root::dirty_list entry still linked into switch_commits will point to already released memory, causing use-after-free. Address this problem by manually deleting all entries inside btrfs_transaction::switch_commits. And since we're here, also release the dirty_log_pages and qgroup swapped blocks for that root, which are only released during a successful switch_commit_roots() call. Reviewed-by: Boris Burkov <boris@bur.io> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: return -ENOTTY for unknown ioctls on the control deviceHengyu Liang
Commit 5ab2b180884c ("btrfs: factor out validation of btrfs_ioctl_vol_args::name") made btrfs_control_ioctl() store the result of btrfs_check_ioctl_vol_args_path() in ret before it looks at the command. However, ret is initialized to -ENOTTY and the switch has no default case, so this initial value was what an unknown command returned. As of now, every unknown ioctl on /dev/btrfs-control returns 0. A tool that tries a control ioctl which the running kernel does not have is told that the ioctl succeeded. The issue can be reproduced with a simple C program, run as root: #include <fcntl.h> #include <stdio.h> #include <sys/ioctl.h> int main(void) { static char buf[4096]; int fd = open("/dev/btrfs-control", O_RDWR); if (ioctl(fd, TCGETS, buf) < 0) perror("ioctl"); else printf("ioctl succeeded\n"); return 0; } Before commit 5ab2b180884c ("btrfs: factor out validation of btrfs_ioctl_vol_args::name"), the result is: ioctl: Inappropriate ioctl for device After that commit, the result is: ioctl succeeded This patch will add a default case that returns -ENOTTY. Fixes: 5ab2b180884c ("btrfs: factor out validation of btrfs_ioctl_vol_args::name") CC: stable@vger.kernel.org Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Hengyu Liang <hengyul@cs.unc.edu> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: defrag: fix check to see if next extent can be defragged tooFilipe Manana
We want to check if the next extent is at maximum capacity but we are passing the current extent map to get_extent_max_capacity() and not the next extent map. For example if the current extent is compressed (its maximum capacity is 128K) and the next extent is uncompressed (its maximum capacity is 128M), then we can bail out and not defrag the next extent too - when for example the next extent as a size of 128K, is uncompressed, and the extent threshold is >= 256K. Fixes: 979b25c300db ("btrfs: defrag: don't defrag extents which are already at max capacity") Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: defrag: fix key comparison with max defrag key in btrfs_defrag_leaves()Filipe Manana
The comparison can not be done in isolation for each key component (type and offset) after the objectid component. For example if the defrag_max key is (300 2 0) and the defrag_progress key is (301 1 0), the existing comparison makes us jump to the 'done' label with 'ret' set to -EAGAIN because 2 > 1, resulting in continuing to defrag despite having passed the objectid of 300. Fix this by doing the comparison correctly with btrfs_comp_cpu_keys(). Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: use READ_ONCE() to read the chunk size from the data space_infoFilipe Manana
The chunk size of a space_info is always updated with WRITE_ONCE() (see btrfs_update_space_info_chunk_size()), so when reading it in calc_effective_data_chunk_size() we should use READ_ONCE() to prevent load tearing. We are already using READ_ONCE() in every other function that accesses the chunk size of a space_info. Reviewed-by: Daniel Vacek <neelx@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: qgroup: make btrfs_record_squota_delta() return voidFilipe Manana
The function never returns any error, so simplify it and its callers by making it return void. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: fix lost error return value in btrfs_alloc_logged_file_extent()Filipe Manana
If we fail to allocate a reserved file extent we then call btrfs_record_squota_delta() and assign its return value to 'ret', discarding the error from the failed allocation attempt and allowing log replay to proceed as if no errors happened, resulting in some replayed file extent item to point to an unallocated extent. At the moment btrfs_record_squota_delta() always returns 0 (success). Fixes: cecbb533b5fc ("btrfs: record simple quota deltas in delayed refs") Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: qgroup: fix off-by-one max level check in ↵Filipe Manana
qgroup_trace_new_subtree_blocks() We have maximum of 8 (BTRFS_MAX_LEVEL) levels in a btree, going from 0 to 7, so the upper bound checks should be: >= BTRFS_MAX_LEVEL and not: >= BTRFS_MAX_LEVEL - 1 In practice this will hardly ever be a problem since having a btree with 8 levels would imply a massively huge fs. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: abort transaction on qgroup failures in create_pending_snapshot()Filipe Manana
If we get an error when calling one of the qgroup functions, we jump to the 'fail' label without aborting the transaction. This is not a bug as up the call chain (transaction commit path), we will end up aborting the transaction. However having the explicit transaction abort in create_pending_snapshot() allows us to get a stack trace and log message that tells us exactly where we failed, useful for troubleshooting, and also adds consistency since in that function we abort the transaction in every other error path. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: qgroup: merge error labels in btrfs_quota_enable()Filipe Manana
There is no need to have 3 different labels to which we goto on error. Simplify this and have a single one, named 'out', where we always free the path and put the root, as btrfs_free_path() and btrfs_put_root() accept NULL arguments and do nothing in that case. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: qgroup: fix leak of qgroups in rb tree after failure to enable quotasFilipe Manana
When enabling quotas we add struct btrfs_qroup items to the rbtree fs_info->qgroup_tree, however if there's an error during the quota enable operation after adding those items, we exit without removing the items from the rbtree and freeing them. Fix this by calling btrfs_free_qgroup_config() on error, which also deletes all sysfs entries (it calls btrfs_sysfs_del_qgroups()). Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: qgroup: abort transaction on failure to add qgroup relationFilipe Manana
When adding a qgroup relation, if we fail to add the relation item from "dst" to "src", we attempt to delete the relation item from "src" to "dst" that we added just before, however we ignore the deletion result and if we failed to delete we leave an inconsistency in the quota root. So check the result of the deletion and if it fails, abort the transaction to avoid persisting an inconsistent state. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: qgroup: fix swapped blocks existence check when tracing after COWFilipe Manana
In btrfs_qgroup_trace_subtree_after_cow(), after we erase the swapped block, iterate over all possible tree levels to check if we sill have other swapped blocks. However the check is wrong, it considers that there are other swapped blocks if any rbtree for any level is empty, instead of not empty. As a consequence we set blocks->swapped to true basically every time since we always find an empty rbtree at least at level 7, since in practice it's nearly impossible to find such a huge btree. This makes every future call to btrfs_qgroup_trace_subtree_after_cow() do an unnecessary rbtree search instead of returning immediately. Fix this by updating the condition to set swapped to true if we find an rbtree that is not empty. Fixes: f616f5cd9da7 ("btrfs: qgroup: Use delayed subtree rescan for balance") Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: introduce more accurate usebackuproot optionsQu Wenruo
Previously we had no way to tell btrfs to use which backup slot, but always use the newest backup, and retry until all backup roots are exhausted. This doesn't give any control to the end user, even if the end user wants to use a specific backup slot. To address this problem, allow more fine-control on usebackuproot rescue option by introducing the following 4 rescue mount options: - rescue=usebackuproot_0 - rescue=usebackuproot_1 - rescue=usebackuproot_2 - rescue=usebackuproot_3 The number 0 means the newest slot, which should be the same as the one recorded in the super block and no need to load any backup root. 1/2/3 means the second/third/fourth(oldest) backup slot to use. The existing "rescue=usebackuproot" is just an alias of "rescue=usebackuproot_1". This will allow users to choose which backup root to use, thus can have a better control than blindly choose any slot that can pass the very basic root node checks. Reviewed-by: Boris Burkov <boris@bur.io> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: always use the second newest slot for rescue=usebackuprootQu Wenruo
[RESCUE FAILURE] There is a bug report that "rescue=usebackuproot" failed to properly mount the fs, but if using btrfs-mod-sb to use the second newest slot, then the fs can even pass the full "btrfs check" and be mounted RW. [CAUSE] During init_tree_roots(), "rescue=usebackuproot" only makes a difference if the tree and chunk roots failed to be load. The loading only requires the root node/leaf to be properly loaded: - tree root - extent tree - block group tree - device tree - data reloc tree - quota tree (optional) - uuid tree - raid stripe tree (for RST feature) And it doesn't really check any child tree blocks, thus for a lot of cases, "rescue=usebackuproot" won't make a difference. [ENHANCEMENT] Instead of trying every slot and settling down on the first passing backup slot, always use the second newest slot. The newest slot should always match the root info in the super block, and if it worked the end user should not even need to bother to use backup root. Older backup slots normally have a very low chance to work. Link: https://github.com/kdave/btrfs-progs/issues/1162#issuecomment-5475477108 Reviewed-by: Boris Burkov <boris@bur.io> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: raid56: do not verify the content if there is no data checksumQu Wenruo
[BUG] There is a bug report that fio can fail to sync the data on a degraded RAID56 mount: # mkfs.btrfs -m raid1 -d raid5 -f $dev1 $dev2 $dev3 # mount $dev1 $mnt # btrfs balance start -d $mnt # umount $mnt # btrfs dev scan -u $dev2 # wipefs -fa $dev2 # mount -o degraded $dev1 $mnt # fio --name=degraded-write --directory=$mnt --rw=randwrite --fdatasync=4 \ --bs=4k --size=512M --randrepeat=1 The run will fail at fsync: fio: io_u error on file /mnt/btrfs/degraded-write.0.0: Input/output error: datasync offset=142254080, buflen=0 fio: pid=2064, err=5/file:io_u.c:2008, func=io_u error, error=Input/output error [CAUSE] With extra debug output, it shows the problem pretty well: rbio=2876243968 faila=0 sectornr=0 rbio=2876243968 error=0-15 csum=2 bio=15 The first line shows the rbio's full stripe logical, and stripe/sector number when verify_one_sector() failed. The second line shows more detail about the rbio, the sector range [0, 16) is corrupted, which indicates the first data stripe is corrupted, matching the missing device. The important part is that the csum bitmap shows the data csum is only for sector number 2, meanwhile the failed verification is at sector number 0. This means we did the checksum verification even if no corresponding checksum is populated. [FIX] There is already a similar check at verify_bio_data_sectors(), but unfortunately there is no such check at verify_one_sector(). Add the missing check to skip the csum verification if there is no corresponding data checksum. Reported-by: Bartosz Fenski <bartosz@fenski.pl> Link: https://lore.kernel.org/linux-btrfs/a72409af-45ef-45df-9970-2e38bcb22ea6@fenski.pl/ Fixes: 7a3150723061 ("btrfs: raid56: do data csum verification during RMW cycle") CC: stable@vger.kernel.org Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: qgroup: do not leak -ENOENT from btrfs_remove_qgroup()Qu Wenruo
If btrfs_remove_qgroup() is called on a qgroup that only exists in the rb-tree, then del_qgroup_item() will return -ENOENT, and we tolerate that -ENOENT. However if the to-be-deleted qgroup has no parent qgroups, the @ret will not be updated, and will leak to user space. It will make the ioctl() caller incorrectly assume the operation failed. Fix it by resetting @ret to 0 after a successful or tolerated del_qgroup_item() call, so the -ENOENT from del_qgroup_item() won't be leaked. Assisted-by: LLM (exposing this pre-existing problem) Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: qgroup: use qgroup_mark_inconsistent() in quick_update_accounting()Qu Wenruo
When quick_update_accounting() fails to handle a qgroup which is not fully exclusive (its exclusive number doesn't match the reference one), we have to mark the qgroup inconsistent. Unlike other locations we didn't use qgroup_mark_inconsistent(), thus when such problem happens no extra error message is shown. Use the helper in quick_update_accounting(), which does not only show the reason of marking qgroup inconsistent, but also cancels any running rescan and skips dirty accounting, avoiding wasting CPU time on already inconsistent qgroup numbers. Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: qgroup: do not treat "ret > 0" as error when deleting a qgroupQu Wenruo
[BUG] There is a bug report that when removing a child qgroup, if removing the qgroup requires a rescan, it will delete the on-disk relation and qgroup items but not the in-memory qgroup rb entry. This makes all later qgroup rescan to fail. [CAUSE] The call chain looks like the following: btrfs_remove_qgroup() |- __del_qgroup_relation() | |- quick_update_accounting() | Which returns 1, showing this operation will require | a qgroup rescan |- if (ret) goto out; Which skips the del_qgroup_rb() call, leaving the in-memory qgroup rb entry still intact. Then later qgroup rescan/update will always fail and mark qgroup inconsistent: btrfs_run_qgroups() |- update_qgroup_info_item() | |- btrfs_search_slot() | Which returns -ENOENT, as the qgroup info item is already | deleted. |- qgroup_mark_inconsistent() |- return -ENOENT; [FIX] Do not treat "ret > 0" as an error. Reported-by: c.f.a@posteo.de Link: https://lore.kernel.org/linux-btrfs/14846642-85d3-4afb-ad99-1b74b22f5f90@posteo.de/ Fixes: 9c8b35b1ba21 ("btrfs: quota: Automatically update related qgroups or mark INCONSISTENT flags when assigning/deleting a qgroup relations.") Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: remove unnecessary forward struct declarations in volumes.hFilipe Manana
There is no need to forward declare the structures as their definitions are brought in by the include of the linux/blkdev.h and fs.h files. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: remove pointless qgroup assignment in block_rsv_release_bytes()Filipe Manana
If num_bytes == (u64)-1, there's no point to set qgroup_to_release to block_rsv->qgroup_rsv_size as later on we will overwrite that value without ever reading the variable before that. So simplify things and remove that assignment. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: remove fs_info argument from btrfs_block_rsv_refill()Filipe Manana
The fs_info argument is not used, so remove it. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: remove fs_info argument from btrfs_block_rsv_add()Filipe Manana
The fs_info argument is not used, so remove it. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: fix off-by-one end offset check in report_setget_bounds()Filipe Manana
The addressable range with an extent buffer goes from byte 0 to byte eb->len - 1, so if a byte address matches eb->len, it's already beyond the addressable range and we should log that it's bad start address and not end address. Fixes: 234fdd2815ce ("btrfs: remove redundant check in up check_setget_bounds") Reviewed-by: Qu Wenruo <wqu@suse.com> Reviewed-by: Daniel Vacek <neelx@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: avoid overhead when logging messages if fs state is cleanFilipe Manana
If the fs state does not have any errors and is not in some special state (like emergency shutdown or mounted with rescue options), then in btrfs_state_to_string() we end up doing a memcpy() into the buffer and then later just undo that work by setting the buffer's first element to the NUL terminator, since fs_info->fs_error is 0 and there is no bit set in fs_info->fs_state. Improve on this by returning early if there's no error in the fs and the fs state is clean, which is the expected scenario for a healthy fs that is not mounted with special options like the rescue options. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: remove unnecessary pointer increment in btrfs_state_to_string()Filipe Manana
There's no point in incrementing the local pointer after we set the NUL terminator, as we don't use the pointer anymore after that. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: add missing code for no delayed iput fs state in log messagesFilipe Manana
Add a letter code for the BTRFS_FS_STATE_NO_DELAYED_IPUT fs state, which is currently missing and it's useful to have. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: fix duplicated code in fs state string in logged messagesFilipe Manana
We are using the code 'E' when the fs is in an error state (transaction aborted) and when it's in the emergency shutdown state, which is confusing and not intentional. Fix this by using an unused code such as 'H' for the emergency shutdown state and add a comment over the fs_state_chars array to warn to not use 'E' as its use is not defined in the array but instead in the function btrfs_state_to_string(), since the fs state error is not defined as a bit but as an error code in fs_info->fs_error. Fixes: 9b2839451dfc ("btrfs: introduce a new shutdown state") Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
3 daysbtrfs: fix incomplete iteration over fs state when logging messagesFilipe Manana
In btrfs_state_to_string() we iterate over all the bits set in fs_info->fs_state using for_each_set_bit(), which requires its third argument to match the number of bits, but we pass it the number of bytes of the type used by fs_info->fs_state, an unsigned long, which is 8 on 64 bits platforms and 4 on 32 bits platforms. This means we are not iterating over bits in the ranges [8, 63] or [4, 31]. Fix this by passing BTRFS_FS_STATE_COUNT instead of sizeof(fs_state). Note that we could pass BITS_PER_TYPE(fs_state), but since BTRFS_FS_STATE_COUNT is 11 and we have no bits beyond that, it would cause pointless iterations over fs_state. This also makes pointless the checks for the bit being inside the limit of BTRFS_FS_STATE_COUNT inside the loop. Fixes: c067da878156 ("btrfs: add filesystems state details to error messages") Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>