summaryrefslogtreecommitdiff
path: root/fs/btrfs
AgeCommit message (Collapse)Author
2024-11-11btrfs: make the extent map shrinker run asynchronously as a work queue jobFilipe Manana
Currently the extent map shrinker is run synchronously for kswapd tasks that end up calling the fs shrinker (fs/super.c:super_cache_scan()). This has some disadvantages and for some heavy workloads with memory pressure it can cause some delays and stalls that make a machine unresponsive for some periods. This happens because: 1) We can have several kswapd tasks on machines with multiple NUMA zones, and running the extent map shrinker concurrently can cause high contention on some spin locks, namely the spin locks that protect the radix tree that tracks roots, the per root xarray that tracks open inodes and the list of delayed iputs. This not only delays the shrinker but also causes high CPU consumption and makes the task running the shrinker monopolize a core, resulting in the symptoms of an unresponsive system. This was noted in previous commits such as commit ae1e766f623f ("btrfs: only run the extent map shrinker from kswapd tasks"); 2) The extent map shrinker's iteration over inodes can often be slow, even after changing the data structure that tracks open inodes for a root from a red black tree (up to kernel 6.10) to an xarray (kernel 6.10+). The transition to the xarray while it made things a bit faster, it's still somewhat slow - for example in a test scenario with 10000 inodes that have no extent maps loaded, the extent map shrinker took between 5ms to 8ms, using a release, non-debug kernel. Iterating over the extent maps of an inode can also be slow if have an inode with many thousands of extent maps, since we use a red black tree to track and search extent maps. So having the extent map shrinker run synchronously adds extra delay for other things a kswapd task does. So make the extent map shrinker run asynchronously as a job for the system unbounded workqueue, just like what we do for data and metadata space reclaim jobs. Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: add and use helper to remove extent map from its inode's treeFilipe Manana
Move the common code to remove an extent map from its inode's tree into a helper function and use it, reducing duplicated code. Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: reduce lock contention when eb cache miss for btree searchRobbie Ko
When crawling btree, if an eb cache miss occurs, we change to use the eb read lock and release all previous locks (including the parent lock) to reduce lock contention. If an eb cache miss occurs in a leaf and needs to execute IO, before this change we released locks only from level 2 and up and we read a leaf's content from disk while holding a lock on its parent (level 1), causing the unnecessary lock contention on the parent, after this change we release locks from level 1 and up, but we lock level 0, and read leaf's content from disk. Because we have prepared the check parameters and the read lock of eb we hold, we can ensure that no race will occur during the check and cause unexpected errors. Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Robbie Ko <robbieko@synology.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter level from alloc_heuristic_ws()David Sterba
The compression heuristic pass does not need a level, so we can drop the parameter. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter fs_info from btrfs_match_dir_item_name()David Sterba
Cascaded removal of fs_info that is not needed in several functions. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter transaction from alloc_log_tree()David Sterba
The function got split in commit 6ab6ebb76042d3 ("btrfs: split alloc_log_tree()") and since then transaction parameter has been unused. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter data from btrfs_fill_super()David Sterba
The only caller passes NULL, we can drop the parameter. This is since the new mount option parser done in 3bb17a25bcb09a ("btrfs: add get_tree callback for new mount API"). Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter options from open_ctree()David Sterba
Since the new mount option parser in commit ad21f15b0f79 ("btrfs: switch to the new mount API") we don't pass the options like that anymore. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter fs_info from folio_range_has_eb()David Sterba
The parameter was added in 8ff8466d29efc2 ("btrfs: support subpage for extent buffer page release") for page but hasn't been used since, so we can drop it. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter mask from try_release_extent_state()David Sterba
The mask parameter used for allocations got unified to GFP_NOFS and removed from relevant functions in 1d1268004430 ("btrfs: drop gfp from parameter extent state helpers"). Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter refs from visit_node_for_delete()David Sterba
The parameter duplicates what can be effectively obtained from wc->refs[level - 1] and this is what's actually used inside. Added in commit 2b73c7e761c4 ("btrfs: unify logic to decide if we need to walk down into a node during snapshot delete"). Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter iov_iter from btrfs_write_check()David Sterba
The parameter 'from' has never been used since commit b8d8e1fd570a ("btrfs: introduce btrfs_write_check()"), this is for buffered write. Direct io write needs it so it was probably an interface thing, but we can drop it. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter file_offset from ↵David Sterba
btrfs_encoded_read_regular_fill_pages() The file_offset parameter used to be passed to encoded read struct but was removed in commit b665affe93d8 ("btrfs: remove unused members from struct btrfs_encoded_read_private"). Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter offset from __cow_file_range_inline()David Sterba
We don't need offset for inline extents, they always start from 0. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter inode from read_inline_extent()David Sterba
We don't need the inode pointer to read inline extent, it's all accessible from the path pointer. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter argp from btrfs_ioctl_quota_rescan_wait()David Sterba
We don't need the user passed parameter, rescan is a filesystem operation so fs_info is sufficient. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: lzo: drop unused paramter level from lzo_alloc_workspace()David Sterba
The LZO compression has only one level, we don't need to pass the parameter. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused transaction parameter from btrfs_qgroup_add_swapped_blocks()David Sterba
The caller replace_path() runs under transaction but we don't need it in btrfs_qgroup_add_swapped_blocks(). Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: qgroup: drop unused parameter fs_info from __del_qgroup_rb()David Sterba
We don't need fs_info here, everything is reachable from qgroup. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter map from scrub_simple_mirror()David Sterba
The parameter map used to be passed to scrub_extent() until e02ee89baa66c4 ("btrfs: scrub: switch scrub_simple_mirror() to scrub_stripe infrastructure"), where the scrub implementation was completely reworked. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: scrub: drop unused parameter sctx from scrub_submit_extent_sector_read()David Sterba
The parameter is unused and we can reach sctx from scrub stripe if needed. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: send: drop unused parameter index from iterate_inode_ref_t callbacksDavid Sterba
None of the ref iteration callbacks needs the index parameter (this is for the directory item iteration), so we can drop it. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: send: drop unused parameter num from iterate_inode_ref_t callbacksDavid Sterba
None of the ref iteration callbacks needs the num parameter (this is for the directory item iteration), so we can drop it. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter fs_info from do_reclaim_sweep()David Sterba
The parameter is unused and we can get it from space info if needed. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter fs_info from wait_reserve_ticket()David Sterba
The parameter is not used, we can also reach it from the space info if needed in the future. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter ctx from batch_delete_dir_index_items()David Sterba
The ctx parameter is not used, we can drop it. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: drop unused parameter path from btrfs_tree_mod_log_rewind()David Sterba
The path parameter was used for our own locking, that got converted to rwsem eventually. Last usage in ac5887c8e013d6 ("btrfs: locking: remove all the blocking helpers"). Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: zstd: assert the timer pointer in callbackDavid Sterba
Make sure we got the right timer struct for the zstd workspace reclaim work. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: remove btrfs_set_range_writeback()Qu Wenruo
The function btrfs_set_range_writeback() was originally a callback for metadata and data, to mark a range with writeback flag. Then it was converted into a common function call for both metadata and data. From the very beginning, the function had been only called on a full page, later converted to handle range inside a page. But it never needed to handle multiple pages, and since commit 8189197425e7 ("btrfs: refactor __extent_writepage_io() to do sector-by-sector submission") the function was only called on a sector-by-sector basis. This makes the function unnecessary, and can be converted to a simple btrfs_folio_set_writeback() call instead. Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: qgroup: run delayed iputs after ordered extent completionFilipe Manana
When trying to flush qgroups in order to release space we run delayed iputs in order to release space from recently deleted files (their link counted reached zero), and then we start delalloc and wait for any existing ordered extents to complete. However there's a time window here where we end up not doing the final iput on a deleted file which could release necessary space: 1) An unlink operation starts; 2) During the unlink, or right before it completes, delalloc is flushed and an ordered extent is created; 3) When the ordered extent is created, the inode's ref count is incremented (with igrab() at alloc_ordered_extent()); 4) When the unlink finishes it doesn't drop the last reference on the inode and so it doesn't trigger inode eviction to delete all of the inode's items in its root and drop all references on its data extents; 5) Another task enters try_flush_qgroup() to try to release space, it runs all delayed iputs, but there's no delayed iput yet for that deleted file because the ordered extent hasn't completed yet; 6) Then at try_flush_qgroup() we wait for the ordered extent to complete and that results in adding a delayed iput at btrfs_put_ordered_extent() when called from btrfs_finish_one_ordered(); 7) Adding the delayed iput results in waking the cleaner kthread if it's not running already. However it may take some time for it to be scheduled, or it may be running but busy running auto defrag, dropping deleted snapshots or doing other work, so by the time we return from try_flush_qgroup() the space for deleted file isn't released. Improve on this by running delayed iputs only after flushing delalloc and waiting for ordered extent completion. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: scrub: skip initial RST lookup errorsJohannes Thumshirn
Performing the initial extent sector read on a RAID stripe-tree backed filesystem with pre-allocated extents will cause the RAID stripe-tree lookup code to return ENODATA, as pre-allocated extents do not have any on-disk bytes and thus no RAID stripe-tree entries. But the current scrub read code marks these extents as errors, because the lookup fails. If btrfs_map_block() returns -ENODATA, it means that the call to btrfs_get_raid_extent_offset() returned -ENODATA, because there is no entry for the corresponding range in the RAID stripe-tree. But as this range is in the extent tree it means we've hit a pre-allocated extent. In this case, don't mark the sector in the stripe's error bitmaps as faulty and carry on to the next. Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: return ENODATA in case RST lookup failsJohannes Thumshirn
In case a lookup in the RAID stripe-tree fails, return ENODATA instead of ENOENT to better distinguish stripe-tree lookups from other code paths where we return ENOENT. Suggested-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: Josef Bacik <josef@toxicpanda.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>
2024-11-11btrfs: handle empty list of NOCOW ordered extents with checksum listJohannes Thumshirn
Currently we BUG_ON() in btrfs_finish_one_ordered() if we are finishing an ordered extent that is flagged as NOCOW, but it's checksum list is not empty. This is clearly a logic error which we can recover from by aborting the transaction. For developer builds which enable CONFIG_BTRFS_ASSERT, also ASSERT() that the list is empty. Suggested-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: Qu Wenruo <wqu@suse.com> Reviewed-by: Filipe Manana <fdmanana@suse.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>
2024-11-11btrfs: simplify the page uptodate preparation for prepare_pages()Qu Wenruo
Currently inside prepare_pages(), we handle the leading and tailing page differently, and skip the middle pages (if any). This is to avoid reading pages which are fully covered by the dirty range. Refactor the code by moving all checks (alignment check, range check, force read check) into prepare_uptodate_page(). So that prepare_pages() only needs to iterate all the pages unconditionally. And since we're here, also update prepare_uptodate_page() to use folio API other than the old page API. Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: remove the dirty_page local variableQu Wenruo
Inside btrfs_buffered_write(), we have a local variable @dirty_pages, recording the number of pages we dirtied in the current iteration. However we do not really need that variable, since it can be calculated from @pos and @copied. In fact there is already a problem inside the short copy path, where we use @dirty_pages to calculate the range we need to release. But that usage assumes sectorsize == PAGE_SIZE, which is no longer true. Instead of keeping @dirty_pages and cause incorrect usage, just calculate the number of dirtied pages inside btrfs_dirty_pages(). Reviewed-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: remove unused btrfs_try_tree_write_lock()Dr. David Alan Gilbert
btrfs_try_tree_write_lock() has been unused since commit 50b21d7a066f ("btrfs: submit a writeback bio per extent_buffer"). Remove it as we don't need it anymore. Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Dr. David Alan Gilbert <linux@treblig.org> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: remove unused btrfs_is_parity_mirror()Dr. David Alan Gilbert
btrfs_is_parity_mirror() has been unused since commit 4886ff7b50f6 ("btrfs: introduce a new helper to submit write bio for repair"). Remove it as the code was refactored and we don't need the helper anymore. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Dr. David Alan Gilbert <linux@treblig.org> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: remove unused btrfs_free_squota_rsv()Dr. David Alan Gilbert
btrfs_free_squota_rsv() was added in commit e85a0adacf17 ("btrfs: ensure releasing squota reserve on head refs") but has remained unused since then. Remove it as we don't seem to need it and was probably a leftover. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Dr. David Alan Gilbert <linux@treblig.org> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: tests: add selftests for raid-stripe-treeJohannes Thumshirn
Add first stash of very basic self tests for the RAID stripe-tree. More test cases will follow exercising the tree. Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: correct typos in multiple comments across various filesShen Lichuan
Fix some confusing spelling errors that were currently identified, the details are as follows: block-group.c: 2800: uncompressible ==> incompressible extent-tree.c: 3131: EXTEMT ==> EXTENT extent_io.c: 3124: utlizing ==> utilizing extent_map.c: 1323: ealier ==> earlier extent_map.c: 1325: possiblity ==> possibility fiemap.c: 189: emmitted ==> emitted fiemap.c: 197: emmitted ==> emitted fiemap.c: 203: emmitted ==> emitted transaction.h: 36: trasaction ==> transaction volumes.c: 5312: filesysmte ==> filesystem zoned.c: 1977: trasnsaction ==> transaction Signed-off-by: Shen Lichuan <shenlichuan@vivo.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: remove unused page_to_inode and page_to_fs_info macrosYouling Tang
This macro is no longer used after the "btrfs: Cleaned up folio->page conversion" series patch [1] was applied, so remove it. [1]: https://patchwork.kernel.org/project/linux-btrfs/cover/20240828182908.3735344-1-lizetao1@huawei.com/ Reviewed-by: Neal Gompa <neal@gompa.dev> Signed-off-by: Youling Tang <tangyouling@kylinos.cn> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: remove redundant stop_loop variable in scrub_stripe()Riyan Dhiman
The variable stop_loop was originally introduced in commit 625f1c8dc66d7 ("Btrfs: improve the loop of scrub_stripe"). It was initialized to 0 in commit 3b080b2564287 ("Btrfs: scrub raid56 stripes in the right way"). However, in a later commit 18d30ab961497 ("btrfs: scrub: use scrub_simple_mirror() to handle RAID56 data stripe scrub"), the code that modified stop_loop was removed, making the variable redundant. Currently, stop_loop is only initialized with 0 and is never used or modified within the scrub_stripe() function. As a result, this patch removes the stop_loop variable to clean up the code and eliminate unnecessary redundancy. This change has no impact on functionality, as stop_loop was never utilized in any meaningful way in the final version of the code. Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Riyan Dhiman <riyandhiman14@gmail.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: remove pointless initialization at btrfs_qgroup_trace_extent()Filipe Manana
The qgroup record was allocated with kzalloc(), so it's pointless to set its old_roots member to NULL. Remove the 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>
2024-11-11btrfs: always use delayed_refs local variable at btrfs_qgroup_trace_extent()Filipe Manana
Instead of dereferencing the delayed refs from the transaction multiple times, store it early in the local variable and then always use the variable. 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>
2024-11-11btrfs: remove unnecessary delayed refs locking at btrfs_qgroup_trace_extent()Filipe Manana
There's no need to hold the delayed refs spinlock when calling btrfs_qgroup_trace_extent_nolock() from btrfs_qgroup_trace_extent(), since it doesn't change anything in delayed refs and it only changes the xarray used to track qgroup extent records, which is protected by the xarray's lock. Holding the lock is only adding unnecessary lock contention with other tasks that actually need to take the lock to add/remove/change delayed references. So remove the locking. 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>
2024-11-11btrfs: store fs_info in a local variable at btrfs_qgroup_trace_extent_post()Filipe Manana
Instead of extracting fs_info from the transaction multiples times, store it in a local variable and use 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>
2024-11-11btrfs: qgroups: remove bytenr field from struct btrfs_qgroup_extent_recordFilipe Manana
Now that we track qgroup extent records in a xarray we don't need to have a "bytenr" field in struct btrfs_qgroup_extent_record, since we can get it from the index of the record in the xarray. So remove the field and grab the bytenr from either the index key or any other place where it's available (delayed refs). This reduces the size of struct btrfs_qgroup_extent_record from 40 bytes down to 32 bytes, meaning that we now can store 128 instances of this structure instead of 102 per 4K page. 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>
2024-11-11btrfs: remove code duplication in ordered extent finishingJohannes Thumshirn
Remove the duplicated transaction joining, block reserve setting and raid extent inserting in btrfs_finish_ordered_extent(). While at it, also abort the transaction in case inserting a RAID stripe-tree entry fails. Suggested-by: Naohiro Aota <naohiro.aota@wdc.com> Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: canonicalize the device path before adding itQu Wenruo
[PROBLEM] Currently btrfs accepts any file path for its device, resulting some weird situation: # ./mount_by_fd /dev/test/scratch1 /mnt/btrfs/ The program has the following source code: #include <fcntl.h> #include <stdio.h> #include <sys/mount.h> int main(int argc, char *argv[]) { int fd = open(argv[1], O_RDWR); char path[256]; snprintf(path, sizeof(path), "/proc/self/fd/%d", fd); return mount(path, argv[2], "btrfs", 0, NULL); } Then we can have the following weird device path: BTRFS: device fsid 2378be81-fe12-46d2-a9e8-68cf08dd98d5 devid 1 transid 7 /proc/self/fd/3 (253:2) scanned by mount_by_fd (18440) Normally it's not a big deal, and later udev can trigger a device path rename. But if udev didn't trigger, the device path "/proc/self/fd/3" will show up in mtab. [CAUSE] For filename "/proc/self/fd/3", it means the opened file descriptor 3. In above case, it's exactly the device we want to open, aka points to "/dev/test/scratch1" which is another symlink pointing to "/dev/dm-2". Inside kernel we solve the mount source using LOOKUP_FOLLOW, which follows the symbolic link and grab the proper block device. But inside btrfs we also save the filename into btrfs_device::name, and utilize that member to report our mount source, which leads to the above situation. [FIX] Instead of unconditionally trust the path, check if the original file (not following the symbolic link) is inside "/dev/", if not, then manually lookup the path to its final destination, and use that as our device path. This allows us to still use symbolic links, like "/dev/mapper/test-scratch" from LVM2, which is required for fstests runs with LVM2 setup. And for really weird names, like the above case, we solve it to "/dev/dm-2" instead. Reviewed-by: Filipe Manana <fdmanana@suse.com> Link: https://bugzilla.suse.com/show_bug.cgi?id=1230641 Reported-by: Fabian Vogt <fvogt@suse.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
2024-11-11btrfs: avoid unnecessary device path update for the same deviceQu Wenruo
[PROBLEM] It is very common for udev to trigger device scan, and every time a mounted btrfs device got re-scan from different soft links, we will get some of unnecessary device path updates, this is especially common for LVM based storage: # lvs scratch1 test -wi-ao---- 10.00g scratch2 test -wi-a----- 10.00g scratch3 test -wi-a----- 10.00g scratch4 test -wi-a----- 10.00g scratch5 test -wi-a----- 10.00g test test -wi-a----- 10.00g # mkfs.btrfs -f /dev/test/scratch1 # mount /dev/test/scratch1 /mnt/btrfs # dmesg -c [ 205.705234] BTRFS: device fsid 7be2602f-9e35-4ecf-a6ff-9e91d2c182c9 devid 1 transid 6 /dev/mapper/test-scratch1 (253:4) scanned by mount (1154) [ 205.710864] BTRFS info (device dm-4): first mount of filesystem 7be2602f-9e35-4ecf-a6ff-9e91d2c182c9 [ 205.711923] BTRFS info (device dm-4): using crc32c (crc32c-intel) checksum algorithm [ 205.713856] BTRFS info (device dm-4): using free-space-tree [ 205.722324] BTRFS info (device dm-4): checking UUID tree So far so good, but even if we just touched any soft link of "dm-4", we will get quite some unnecessary device path updates. # touch /dev/mapper/test-scratch1 # dmesg -c [ 469.295796] BTRFS info: devid 1 device path /dev/mapper/test-scratch1 changed to /dev/dm-4 scanned by (udev-worker) (1221) [ 469.300494] BTRFS info: devid 1 device path /dev/dm-4 changed to /dev/mapper/test-scratch1 scanned by (udev-worker) (1221) Such device path rename is unnecessary and can lead to random path change due to the udev race. [CAUSE] Inside device_list_add(), we are using a very primitive way checking if the device has changed, strcmp(). Which can never handle links well, no matter if it's hard or soft links. So every different link of the same device will be treated as a different device, causing the unnecessary device path update. [FIX] Introduce a helper, is_same_device(), and use path_equal() to properly detect the same block device. So that the different soft links won't trigger the rename race. Reviewed-by: Filipe Manana <fdmanana@suse.com> Link: https://bugzilla.suse.com/show_bug.cgi?id=1230641 Reported-by: Fabian Vogt <fvogt@suse.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>