linux-block.git
5 months agobtrfs: remove redundant variables from __process_folios_contig() and lock_delalloc_fo...
David Sterba [Thu, 9 Jan 2025 10:24:45 +0000 (11:24 +0100)]
btrfs: remove redundant variables from __process_folios_contig() and lock_delalloc_folios()

Same pattern in both functions, we really only use index, start_index is
redundant.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: split waiting from read_extent_buffer_pages(), drop parameter wait
David Sterba [Thu, 9 Jan 2025 10:24:43 +0000 (11:24 +0100)]
btrfs: split waiting from read_extent_buffer_pages(), drop parameter wait

There are only 2 WAIT_* values left for wait parameter, we can encode
this to the function name if the waiting functionality is split.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: remove unused define WAIT_PAGE_LOCK for extent io
David Sterba [Thu, 9 Jan 2025 10:24:40 +0000 (11:24 +0100)]
btrfs: remove unused define WAIT_PAGE_LOCK for extent io

Last use was in the readahead code that got removed by f26c9238602856
("btrfs: remove reada infrastructure").

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: unwrap folio locking helpers
David Sterba [Thu, 9 Jan 2025 10:24:38 +0000 (11:24 +0100)]
btrfs: unwrap folio locking helpers

Another conversion to folio API, use the folio locking directly instead
of back and forth page <-> folio conversions.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: change return type to bool type of check_eb_alignment()
David Sterba [Thu, 9 Jan 2025 10:24:35 +0000 (11:24 +0100)]
btrfs: change return type to bool type of check_eb_alignment()

The check function pattern is supposed to return true/false, currently
there's only one error code.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: switch grab_extent_buffer() to folios
David Sterba [Thu, 9 Jan 2025 10:24:29 +0000 (11:24 +0100)]
btrfs: switch grab_extent_buffer() to folios

Use the folio API, remove page_folio/folio_page conversions.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: rename btrfs_release_extent_buffer_pages() to mention folios
David Sterba [Thu, 9 Jan 2025 10:24:27 +0000 (11:24 +0100)]
btrfs: rename btrfs_release_extent_buffer_pages() to mention folios

Continue page to folio updates, sync what the function does with it's
name.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: open code __free_extent_buffer()
David Sterba [Thu, 9 Jan 2025 10:24:24 +0000 (11:24 +0100)]
btrfs: open code __free_extent_buffer()

Using the kmem cache freeing directly is clear enough, we don't need to
wrap it.  All the users are in the same file.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: drop one time used local variable in end_bbio_meta_write()
David Sterba [Thu, 9 Jan 2025 10:24:22 +0000 (11:24 +0100)]
btrfs: drop one time used local variable in end_bbio_meta_write()

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: make wait_on_extent_buffer_writeback() static inline
David Sterba [Thu, 9 Jan 2025 10:24:19 +0000 (11:24 +0100)]
btrfs: make wait_on_extent_buffer_writeback() static inline

The simple helper can be inlined, no need for the separate function.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: use btrfs_inode in extent_writepage()
David Sterba [Thu, 9 Jan 2025 10:24:17 +0000 (11:24 +0100)]
btrfs: use btrfs_inode in extent_writepage()

As extent_writepage() is internal helper we should use our inode type,
so change it from struct inode.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: rename __get_extent_map() and pass btrfs_inode
David Sterba [Thu, 9 Jan 2025 10:24:15 +0000 (11:24 +0100)]
btrfs: rename __get_extent_map() and pass btrfs_inode

The double underscore naming scheme does not apply here, there's only
only get_extent_map(). As the definition is changed also pass the struct
btrfs_inode.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: open code set_page_extent_mapped()
David Sterba [Thu, 9 Jan 2025 10:24:12 +0000 (11:24 +0100)]
btrfs: open code set_page_extent_mapped()

The function set_page_extent_mapped() is now a simple wrapper so use the
folio helper.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: rename __unlock_for_delalloc() and drop underscores
David Sterba [Thu, 9 Jan 2025 10:24:10 +0000 (11:24 +0100)]
btrfs: rename __unlock_for_delalloc() and drop underscores

Drop the leading underscores in '__unlock_for_delalloc()' and rename it
to 'unlock_delalloc_folio()'. This also ensures naming parity with
'lock_delalloc_folios()'.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: use SECTOR_SIZE defines in btrfs_issue_discard()
David Sterba [Thu, 9 Jan 2025 10:24:07 +0000 (11:24 +0100)]
btrfs: use SECTOR_SIZE defines in btrfs_issue_discard()

Use the existing define for single sector size.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: remove stray comment about SRCU
David Sterba [Thu, 9 Jan 2025 10:24:01 +0000 (11:24 +0100)]
btrfs: remove stray comment about SRCU

The subvol_srcu was removed in c75e839414d361 ("btrfs: kill the
subvol_srcu") years ago.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: drop unused parameter fs_info to btrfs_delete_delayed_insertion_item()
David Sterba [Thu, 9 Jan 2025 10:23:59 +0000 (11:23 +0100)]
btrfs: drop unused parameter fs_info to btrfs_delete_delayed_insertion_item()

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: pass write-hint for buffered IO
Jing Xia [Tue, 3 Sep 2024 05:40:12 +0000 (13:40 +0800)]
btrfs: pass write-hint for buffered IO

Commit 449813515d3e ("block, fs: Restore the per-bio/request data
lifetime fields") restored write-hint support in btrfs. But that is
applicable only for direct IO. This patch supports passing
write-hint for buffered IO from btrfs file system to block layer
by filling bi_write_hint of struct bio in alloc_new_bio().

There's an ongoing discussion which devices can use that,
https://lore.kernel.org/all/20240910150200.6589-6-joshi.k@samsung.com,
in SCSI there's support using sd_group_number() and
sd_setup_rw32_cmnd().

The hint goes from the application directly to the block device so it's
up to the application to set up everything properly to utilize the
different hint classes.

Link: https://lore.kernel.org/all/20240910150200.6589-6-joshi.k@samsung.com
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Jing Xia <j.xia@samsung.com>
[ Add more context and use case. ]
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: print read policy on module load
Anand Jain [Wed, 1 Jan 2025 18:06:39 +0000 (02:06 +0800)]
btrfs: print read policy on module load

Print the read read policy if set as module parameter (with
CONFIG_BTRFS_EXPERIMENTAL).

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: configure read policy via module parameter
Anand Jain [Wed, 1 Jan 2025 18:06:38 +0000 (02:06 +0800)]
btrfs: configure read policy via module parameter

For testing purposes allow to configure the read policy via module
parameter from the beginning. Available only with CONFIG_BTRFS_EXPERIMENTAL

Examples:

- Set the RAID1 balancing method to round-robin with a custom
  min_contig_read of 4k:
  $ modprobe btrfs read_policy=round-robin:4096

- Set the round-robin balancing method with the default
  min_contiguous_read:
  $ modprobe btrfs read_policy=round-robin

- Set the "devid" balancing method, defaulting to the latest device:
  $ modprobe btrfs read_policy=devid

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: print status of experimental mode when loading module
Anand Jain [Wed, 1 Jan 2025 18:06:37 +0000 (02:06 +0800)]
btrfs: print status of experimental mode when loading module

Commit c9c49e8f157e ("btrfs: split out CONFIG_BTRFS_EXPERIMENTAL from
CONFIG_BTRFS_DEBUG") introduces a way to enable or disable experimental
features, print its status during module load, like:

  Btrfs loaded, experimental=on, debug=on, assert=on, zoned=yes, fsverity=yes

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: add read policy to set a preferred device
Anand Jain [Wed, 1 Jan 2025 18:06:36 +0000 (02:06 +0800)]
btrfs: add read policy to set a preferred device

Add read policy that will force all reads to go to the given device
(specified by devid) on the RAID1 profiles.

This will be used for testing, e.g. to read from stale device. Users may
find other use cases.

Can be set in sysfs, the value format is "devid:<devid>" to the file

  /sys/fs/btrfs/FSID/read_policy

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: introduce RAID1 round-robin read balancing
Anand Jain [Wed, 1 Jan 2025 18:06:35 +0000 (02:06 +0800)]
btrfs: introduce RAID1 round-robin read balancing

Add round-robin read policy that balances reads over available devices
(all RAID1 block group profiles). Switch to the next devices is done
after a number of blocks is read, which is 256K by default and is
configurable in sysfs.

The format is "round-robin:<min-contig-read>" and can be set in file

  /sys/fs/btrfs/FSID/read_policy

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: add tracking of read blocks for read policy
Anand Jain [Wed, 1 Jan 2025 18:06:34 +0000 (02:06 +0800)]
btrfs: add tracking of read blocks for read policy

Track number of read blocks in the whole filesystem. The counter is
initialized when devices are opened. The counter is increased at
btrfs_submit_dev_bio() if the stats tracking is enabled (depends on the
read policy).  Stats tracking is disabled by default and is enabled
through fs_devices::collect_fs_stats when required.

The code is not under the EXPERIMENTAL define, as stats can be expanded
to include write counts and other performance counters, with the user
interface independent of its internal use.

This is an in-memory-only feature, not related to the dev error stats.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: sysfs: handle value associated with read balancing policy
Anand Jain [Wed, 1 Jan 2025 18:06:33 +0000 (02:06 +0800)]
btrfs: sysfs: handle value associated with read balancing policy

Enable specifying additional configuration values along the RAID1
balancing read policy in a single input string.

Update btrfs_read_policy_to_enum() to parse and handle a value
associated with the policy in the format "policy:value", the value part
if present is converted to 64-bit integer.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: sysfs: add btrfs_read_policy_to_enum() helper and refactor read policy store
Anand Jain [Wed, 1 Jan 2025 18:06:32 +0000 (02:06 +0800)]
btrfs: sysfs: add btrfs_read_policy_to_enum() helper and refactor read policy store

Introduce btrfs_read_policy_to_enum() helper to simplify the conversion
of a string read policy to its corresponding enum value. This reduces
duplication and improves code clarity in btrfs_read_policy_store().

The parameter is copied locally to allow modification, enabling the
separation of the method and its value. This prepares for the addition of
more functionality in subsequent patches.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: sysfs: refactor output formatting in btrfs_read_policy_show()
Anand Jain [Wed, 1 Jan 2025 18:06:31 +0000 (02:06 +0800)]
btrfs: sysfs: refactor output formatting in btrfs_read_policy_show()

Refactor the logic in btrfs_read_policy_show() for easier extension with
more balancing methods.  Streamline the space and bracket handling
around the active policy without altering the functional output.  This
is in preparation to add more methods.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: initialize fs_devices->fs_info earlier in btrfs_init_devices_late()
Anand Jain [Wed, 1 Jan 2025 18:06:30 +0000 (02:06 +0800)]
btrfs: initialize fs_devices->fs_info earlier in btrfs_init_devices_late()

Currently, fs_devices->fs_info is initialized in btrfs_init_devices_late(),
but this occurs too late for find_live_mirror(), which is invoked by
load_super_root() much earlier than btrfs_init_devices_late().

Fix this by moving the initialization to open_ctree(), before load_super_root().

Reviewed-by: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: xattr: remove unnecessary call to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 13:04:01 +0000 (13:04 +0000)]
btrfs: xattr: remove unnecessary call to btrfs_mark_buffer_dirty()

The call to btrfs_mark_buffer_dirty() at btrfs_setxattr() is not
necessary as we have a path setup for writing with btrfs_search_slot()
having a 'cow' argument set to 1.

This just makes the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove it.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: volumes: remove unnecessary calls to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 13:02:59 +0000 (13:02 +0000)]
btrfs: volumes: remove unnecessary calls to btrfs_mark_buffer_dirty()

We have several places explicitly calling btrfs_mark_buffer_dirty() but
that is not necessarily since the target leaf came from a path that was
obtained for a btree search function that modifies the btree, something
like btrfs_insert_empty_item() or anything else that ends up calling
btrfs_search_slot() with a value of 1 for its 'cow' argument.

These just make the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove them.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: uuid-tree: remove unnecessary call to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:59:51 +0000 (12:59 +0000)]
btrfs: uuid-tree: remove unnecessary call to btrfs_mark_buffer_dirty()

The call to btrfs_mark_buffer_dirty() at btrfs_uuid_tree_add() is not
necessary as we have a path setup for writing with btrfs_search_slot()
having a 'cow' argument set to 1 (through btrfs_insert_empty_item()).

This just makes the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove it.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: root-tree: remove unnecessary calls to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:57:56 +0000 (12:57 +0000)]
btrfs: root-tree: remove unnecessary calls to btrfs_mark_buffer_dirty()

We have several places explicitly calling btrfs_mark_buffer_dirty() but
that is not necessarily since the target leaf came from a path that was
obtained for a btree search function that modifies the btree, something
like btrfs_insert_empty_item() or anything else that ends up calling
btrfs_search_slot() with a value of 1 for its 'cow' argument.

These just make the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove them.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: relocation: remove unnecessary calls to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:56:38 +0000 (12:56 +0000)]
btrfs: relocation: remove unnecessary calls to btrfs_mark_buffer_dirty()

We have several places explicitly calling btrfs_mark_buffer_dirty() but
that is not necessarily since the target leaf came from a path that was
obtained for a btree search function that modifies the btree, something
like btrfs_insert_empty_item() or anything else that ends up calling
btrfs_search_slot() with a value of 1 for its 'cow' argument.

These just make the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove them.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: raid-stripe-tree: remove unnecessary call to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:52:28 +0000 (12:52 +0000)]
btrfs: raid-stripe-tree: remove unnecessary call to btrfs_mark_buffer_dirty()

The call to btrfs_mark_buffer_dirty() at update_raid_extent_item() is not
necessary as we have a path setup for writing with btrfs_search_slot()
having a 'cow' argument set to 1.

This just makes the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove it.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: qgroup: remove unnecessary calls to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:51:20 +0000 (12:51 +0000)]
btrfs: qgroup: remove unnecessary calls to btrfs_mark_buffer_dirty()

We have several places explicitly calling btrfs_mark_buffer_dirty() but
that is not necessarily since the target leaf came from a path that was
obtained for a btree search function that modifies the btree, something
like btrfs_insert_empty_item() or anything else that ends up calling
btrfs_search_slot() with a value of 1 for its 'cow' argument.

These just make the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove them.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: ioctl: remove unnecessary call to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:48:39 +0000 (12:48 +0000)]
btrfs: ioctl: remove unnecessary call to btrfs_mark_buffer_dirty()

The call to btrfs_mark_buffer_dirty() at btrfs_ioctl_default_subvol() is
not necessary as we have a path setup for writing with btrfs_search_slot()
having a 'cow' argument set to 1.

This just makes the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove it.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: inode-item: remove unnecessary calls to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:47:23 +0000 (12:47 +0000)]
btrfs: inode-item: remove unnecessary calls to btrfs_mark_buffer_dirty()

We have several places explicitly calling btrfs_mark_buffer_dirty() but
that is not necessarily since the target leaf came from a path that was
obtained for a btree search function that modifies the btree, something
like btrfs_insert_empty_item() or anything else that ends up calling
btrfs_search_slot() with a value of 1 for its 'cow' argument.

These just make the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove them.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: inode: remove unnecessary calls to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:46:03 +0000 (12:46 +0000)]
btrfs: inode: remove unnecessary calls to btrfs_mark_buffer_dirty()

We have several places explicitly calling btrfs_mark_buffer_dirty() but
that is not necessarily since the target leaf came from a path that was
obtained for a btree search function that modifies the btree, something
like btrfs_insert_empty_item() or anything else that ends up calling
btrfs_search_slot() with a value of 1 for its 'cow' argument.

These just make the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove them.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: free-space-cache: remove unnecessary calls to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:44:10 +0000 (12:44 +0000)]
btrfs: free-space-cache: remove unnecessary calls to btrfs_mark_buffer_dirty()

We have several places explicitly calling btrfs_mark_buffer_dirty() but
that is not necessarily since the target leaf came from a path that was
obtained for a btree search function that modifies the btree, something
like btrfs_insert_empty_item() or anything else that ends up calling
btrfs_search_slot() with a value of 1 for its 'cow' argument.

These just make the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove them.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: file-item: remove unnecessary calls to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:42:21 +0000 (12:42 +0000)]
btrfs: file-item: remove unnecessary calls to btrfs_mark_buffer_dirty()

We have several places explicitly calling btrfs_mark_buffer_dirty() but
that is not necessarily since the target leaf came from a path that was
obtained for a btree search function that modifies the btree, something
like btrfs_insert_empty_item() or anything else that ends up calling
btrfs_search_slot() with a value of 1 for its 'cow' argument.

These just make the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove them.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: file: remove unnecessary calls to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:41:17 +0000 (12:41 +0000)]
btrfs: file: remove unnecessary calls to btrfs_mark_buffer_dirty()

We have several places explicitly calling btrfs_mark_buffer_dirty() but
that is not necessarily since the target leaf came from a path that was
obtained for a btree search function that modifies the btree, something
like btrfs_insert_empty_item() or anything else that ends up calling
btrfs_search_slot() with a value of 1 for its 'cow' argument.

These just make the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove them.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: dir-item: remove unnecessary calls to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:36:21 +0000 (12:36 +0000)]
btrfs: dir-item: remove unnecessary calls to btrfs_mark_buffer_dirty()

We have several places explicitly calling btrfs_mark_buffer_dirty() but
that is not necessarily since the target leaf came from a path that was
obtained for a btree search function that modifies the btree, something
like btrfs_insert_empty_item() or anything else that ends up calling
btrfs_search_slot() with a value of 1 for its 'cow' argument.

These just make the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove them.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: dev-replace: remove unnecessary call to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:33:50 +0000 (12:33 +0000)]
btrfs: dev-replace: remove unnecessary call to btrfs_mark_buffer_dirty()

The call to btrfs_mark_buffer_dirty() at btrfs_run_dev_replace() is not
necessary as we have a path setup for writing with btrfs_search_slot()
having a 'cow' argument set to 1.

This just makes the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove it.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: delayed-inode: remove unnecessary call to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:26:42 +0000 (12:26 +0000)]
btrfs: delayed-inode: remove unnecessary call to btrfs_mark_buffer_dirty()

The call to btrfs_mark_buffer_dirty() at __btrfs_update_delayed_inode() is
not necessary as we have a path setup for writing with btrfs_search_slot()
having a 'cow' argument set to 1.

This just makes the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove it.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: block-group: remove unnecessary calls to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:21:15 +0000 (12:21 +0000)]
btrfs: block-group: remove unnecessary calls to btrfs_mark_buffer_dirty()

We have several places explicitly calling btrfs_mark_buffer_dirty() but
that is not necessarily since the target leaf came from a path that was
obtained for a btree search function that modifies the btree, something
like btrfs_insert_empty_item() or anything else that ends up calling
btrfs_search_slot() with a value of 1 for its 'cow' argument.

These just make the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove them.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: extent-tree: remove unnecessary calls to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:19:10 +0000 (12:19 +0000)]
btrfs: extent-tree: remove unnecessary calls to btrfs_mark_buffer_dirty()

We have several places explicitly calling btrfs_mark_buffer_dirty() but
that is not necessarily since the target leaf came from a path that was
obtained for a btree search function that modifies the btree, something
like btrfs_insert_empty_item() or anything else that ends up calling
btrfs_search_slot() with a value of 1 for its 'cow' argument.

These just make the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove them.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: free-space-tree: remove unnecessary calls to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:10:56 +0000 (12:10 +0000)]
btrfs: free-space-tree: remove unnecessary calls to btrfs_mark_buffer_dirty()

We have several places explicitly calling btrfs_mark_buffer_dirty() but
that is not necessarily since the target leaf came from a path that was
obtained for a btree search function that modifies the btree, something
ike btrfs_insert_empty_item() or anything else that ends up calling
btrfs_search_slot() with a value of 1 for its 'cow' argument.

These just make the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove them.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: tree-log: remove unnecessary calls to btrfs_mark_buffer_dirty()
Filipe Manana [Wed, 18 Dec 2024 12:02:16 +0000 (12:02 +0000)]
btrfs: tree-log: remove unnecessary calls to btrfs_mark_buffer_dirty()

We have several places explicitly calling btrfs_mark_buffer_dirty() but
that is not necessarily since the target leaf came from a path that was
obtained for a btree search function that modifies the btree, something
like btrfs_insert_empty_item() or anything else that ends up calling
btrfs_search_slot() with a value of 1 for its 'cow' argument.

These just make the code more verbose, confusing and add a little extra
overhead and well as increase the module's text size, so remove them.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: uncollapse transaction aborts during renames
Filipe Manana [Mon, 6 Jan 2025 12:09:50 +0000 (12:09 +0000)]
btrfs: uncollapse transaction aborts during renames

During renames we are grouping transaction aborts that can be due to a
failure of one of several function calls. While this makes the code less
verbose, it makes it harder to debug as we end up not knowing from which
function call we got an error.

So change this to trigger a transaction abort after each function call
failure, so that when we get a transaction abort message we know exactly
which function call failed, helping us to debug issues.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: validate system chunk array at btrfs_validate_super()
Qu Wenruo [Sat, 21 Dec 2024 05:45:19 +0000 (16:15 +1030)]
btrfs: validate system chunk array at btrfs_validate_super()

Currently btrfs_validate_super() only does a very basic check on the
array chunk size (not too large than the available space, but not too
small to contain no chunk).

The more comprehensive checks (the regular chunk checks and size check
inside the system chunk array) are all done inside btrfs_read_sys_array().

It's not a big deal, but it also means we do not do any validation on
the system chunk array at super block writeback time either.

Do the following modification to centralize the system chunk array
checks into btrfs_validate_super():

- Make chunk_err() helper accept stack chunk pointer
  If @leaf parameter is NULL, then the @chunk pointer will be a pointer
  to the chunk item, other than the offset inside the leaf.

  And since @leaf can be NULL, add a new @fs_info parameter for that
  case.

- Make btrfs_check_chunk_valid() handle stack chunk pointer
  The same as chunk_err(), a new @fs_info parameter, and if @leaf is
  NULL, then @chunk will be a pointer to a stack chunk.

  If @chunk is NULL, then all needed btrfs_chunk members will be read
  using the stack helper instead of the leaf helper.
  This means we need to read out all the needed member at the beginning
  of the function.

  Furthermore, at super block read time, fs_info->sectorsize is not yet
  initialized, we need one extra @sectorsize parameter to grab the
  correct sectorsize.

- Introduce a helper validate_sys_chunk_array()
  * Validate the disk key.
  * Validate the size before we access the full chunk items.
  * Do the full chunk item validation.

- Call validate_sys_chunk_array() at btrfs_validate_super()

- Simplify the checks inside btrfs_read_sys_array()
  Now the checks will be converted to an ASSERT().

- Simplify the checks inside read_one_chunk()
  Now that all chunk items inside system chunk array and chunk tree are
  verified, there is no need to verify them again inside read_one_chunk().

This change has the following advantages:

- More comprehensive checks at write time
  And unlike the sys_chunk_array read routine, this time we do not need
  to allocate a dummy extent buffer to do the check.
  All the checks done here require no new memory allocation.

- Slightly improved readability when iterating the system chunk array

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: update tree_insert() to use rb helpers
Roger L. Beckermeyer III [Tue, 17 Dec 2024 21:58:55 +0000 (08:28 +1030)]
btrfs: update tree_insert() to use rb helpers

Update tree_insert() to use rb_find_add_cached().
add cmp_refs_node in rb_find_add_cached() to compare.

Since we're here, also make comp_data_refs() and comp_refs() accept
both parameters as const.

Signed-off-by: Roger L. Beckermeyer III <beckerlee3@gmail.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: update btrfs_add_chunk_map() to use rb helpers
Roger L. Beckermeyer III [Tue, 17 Dec 2024 21:58:54 +0000 (08:28 +1030)]
btrfs: update btrfs_add_chunk_map() to use rb helpers

Update btrfs_add_chunk_map() to use rb_find_add_cached().

Signed-off-by: Roger L. Beckermeyer III <beckerlee3@gmail.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: update __btrfs_add_delayed_item() to use rb helper
Roger L. Beckermeyer III [Tue, 17 Dec 2024 21:58:53 +0000 (08:28 +1030)]
btrfs: update __btrfs_add_delayed_item() to use rb helper

Update __btrfs_add_delayed_item() to use rb_find_add_cached().

Signed-off-by: Roger L. Beckermeyer III <beckerlee3@gmail.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: update prelim_ref_insert() to use rb helpers
Roger L. Beckermeyer III [Tue, 17 Dec 2024 21:58:52 +0000 (08:28 +1030)]
btrfs: update prelim_ref_insert() to use rb helpers

Update prelim_ref_insert() to use rb_find_add_cached().

There is a special change that the existing prelim_ref_compare() is
called with the first parameter as the existing ref in the rbtree.

But the newer rb_find_add_cached() expects the cmp() function to have
the first parameter as the to-be-added node, thus the new helper
prelim_ref_rb_add_cmp() need to adapt this new order.

Signed-off-by: Roger L. Beckermeyer III <beckerlee3@gmail.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: update btrfs_add_block_group_cache() to use rb helper
Roger L. Beckermeyer III [Tue, 17 Dec 2024 21:58:51 +0000 (08:28 +1030)]
btrfs: update btrfs_add_block_group_cache() to use rb helper

Update fs/btrfs/block-group.c to use rb_find_add_cached().

Suggested-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Roger L. Beckermeyer III <beckerlee3@gmail.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agorbtree: add rb_find_add_cached() to rbtree.h
Roger L. Beckermeyer III [Tue, 17 Dec 2024 21:58:50 +0000 (08:28 +1030)]
rbtree: add rb_find_add_cached() to rbtree.h

Adds rb_find_add_cached() as a helper function for use with red-black
trees. Used in btrfs to reduce boilerplate code.

And since it's a new helper, the cmp() function will require both
parameter to be const rb_node pointers.

Suggested-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Roger L. Beckermeyer III <beckerlee3@gmail.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: don't include linux/rwlock_types.h directly
Wolfram Sang [Tue, 17 Dec 2024 07:05:43 +0000 (08:05 +0100)]
btrfs: don't include linux/rwlock_types.h directly

The header clearly states that it does not want to be included directly,
only via linux/spinlock_types.h. Drop this as we can simply use the
spinlock.h which is already included.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: handle free space tree rebuild in multiple transactions
Qu Wenruo [Thu, 19 Dec 2024 04:34:08 +0000 (15:04 +1030)]
btrfs: handle free space tree rebuild in multiple transactions

During free space tree rebuild, we're holding a transaction handle for
the whole rebuild process.

This can lead to blocked task warning, e.g. btrfs-transaction kthread
(which is already created before btrfs_start_pre_rw_mount()) can be
waked up to join and commit the current transaction.

But the free space tree rebuild process may need to go through thousands
block groups, this will block btrfs-transaction kthread for a long time.

Fix the problem by calling btrfs_should_end_transaction() after each
block group, so that we won't hold the transaction handle too long.

And since the free-space-tree rebuild can be split into
multiple transactions, we need to consider the safety when the rebuild
process is interrupted.

Thankfully since we only set the FREE_SPACE_TREE compat_ro flag without
FREE_SPACE_TREE_VALID flag, even if the rebuild is interrupted, on the
next RW mount, we will still go rebuild the free space tree, by deleting
any items we have and re-starting the rebuild from scratch.

Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: use uuid_is_null() to verify if an uuid is empty
Filipe Manana [Tue, 17 Dec 2024 12:00:39 +0000 (12:00 +0000)]
btrfs: use uuid_is_null() to verify if an uuid is empty

At btrfs_is_empty_uuid() we have our custom code to check if an uuid is
empty, however there a kernel uuid library that has a function named
uuid_is_null() which does the same and probably more efficient.

So change btrfs_is_empty_uuid() to use uuid_is_null(), which is almost
a directly replacement, it just wraps the necessary casting since our
uuid types are u8 arrays while the uuid kernel library uses the uuid_t
type, which is just a typedef of an u8 array of 16 elements as well.

Also since the function is now to trivial, make it a static inline
function in fs.h.

Suggested-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: remove pointless comment from ctree.h
Filipe Manana [Mon, 16 Dec 2024 16:36:19 +0000 (16:36 +0000)]
btrfs: remove pointless comment from ctree.h

It's pointless to have a comment above the prototype declarations of
btrfs_ctree_init() and btrfs_ctree_exit() mentioning that they are
declared in ctree.c. This is from the old days when ctree.h was used
to place anything that didn't fit in any other file. So remove it.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: move extent-tree function declarations out of ctree.h
Filipe Manana [Mon, 16 Dec 2024 16:29:45 +0000 (16:29 +0000)]
btrfs: move extent-tree function declarations out of ctree.h

We have 3 functions that have their prototypes declared in ctree.h but
they are defined at extent-tree.c and they are unrelated to the btree
data structure. Move the prototypes out of ctree.h and into extent-tree.h.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: move btrfs_alloc_write_mask() into fs.h
Filipe Manana [Mon, 16 Dec 2024 16:22:54 +0000 (16:22 +0000)]
btrfs: move btrfs_alloc_write_mask() into fs.h

Currently btrfs_alloc_write_mask() is defined in ctree.h but it's not
related at all to the btree data structure, so move it into fs.h.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: move BTRFS_BYTES_TO_BLKS() into fs.h
Filipe Manana [Mon, 16 Dec 2024 16:18:35 +0000 (16:18 +0000)]
btrfs: move BTRFS_BYTES_TO_BLKS() into fs.h

Currently BTRFS_BYTES_TO_BLKS() is defined in ctree.h but it's not related
at all to the btree data structure, so move it into fs.h.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: move the folio ordered helpers from ctree.h into fs.h
Filipe Manana [Mon, 16 Dec 2024 12:58:09 +0000 (12:58 +0000)]
btrfs: move the folio ordered helpers from ctree.h into fs.h

The folio ordered helper macros are defined at ctree.h but this is not
the best place since ctree.{h,c} is all about the btree data structure
implementation and not a generic module. So move these macros into the
fs.h header.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: move btrfs_is_empty_uuid() from ioctl.c into fs.c
Filipe Manana [Mon, 16 Dec 2024 12:27:07 +0000 (12:27 +0000)]
btrfs: move btrfs_is_empty_uuid() from ioctl.c into fs.c

It's a generic helper not specific to ioctls and used in several places,
so move it out from ioctl.c and into fs.c. While at it change its return
type from int to bool and declare the loop variable in the loop itself.

This also slightly reduces the module's size.

Before this change:

  $ size fs/btrfs/btrfs.ko
     text    data     bss     dec     hex filename
  1781492  161037   16920 1959449  1de619 fs/btrfs/btrfs.ko

After this change:

  $ size fs/btrfs/btrfs.ko
     text    data     bss     dec     hex filename
  1781340  161037   16920 1959297  1de581 fs/btrfs/btrfs.ko

Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: move the exclusive operation functions into fs.c
Filipe Manana [Mon, 16 Dec 2024 12:10:19 +0000 (12:10 +0000)]
btrfs: move the exclusive operation functions into fs.c

The declarations for the exclusive operation functions are located at fs.h
but their definitions are in ioctl.c, which doesn't make much sense since
(most of them) are used in several files other than ioctl.c. Since they
are used in several files and they are generic enough, move them out of
ioctl.c and into fs.c, even the ones that are currently only used at
ioctl.c, for the sake of having them all in the same C file.

This also reduces the module's size.

Before this change:

  $ size fs/btrfs/btrfs.ko
     text    data     bss     dec     hex filename
  1782094  161045   16920 1960059  1de87b fs/btrfs/btrfs.ko

After this change:

  $ size fs/btrfs/btrfs.ko
     text    data     bss     dec     hex filename
  1781492  161037   16920 1959449  1de619 fs/btrfs/btrfs.ko

Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: move csum related functions from ctree.c into fs.c
Filipe Manana [Mon, 16 Dec 2024 11:38:30 +0000 (11:38 +0000)]
btrfs: move csum related functions from ctree.c into fs.c

The ctree module is about the implementation of the btree data structure
and not a place holder for generic filesystem things like the csum
algorithm details. Move the functions related to the csum algorithm
details away from ctree.c and into fs.c, which is a far better place for
them. Also fix missing punctuation in comments and change one multiline
comment to a single line comment since everything fits in under 80
characters.

For some reason this also slightly reduces the module's size.

Before this change:

  $ size fs/btrfs/btrfs.ko
     text    data     bss     dec     hex filename
  1782126  161045   16920 1960091  1de89b fs/btrfs/btrfs.ko

After this change:

  $ size fs/btrfs/btrfs.ko
     text    data     bss     dec     hex filename
  1782094  161045   16920 1960059  1de87b fs/btrfs/btrfs.ko

Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: move abort_should_print_stack() to transaction.h
Filipe Manana [Mon, 16 Dec 2024 11:26:35 +0000 (11:26 +0000)]
btrfs: move abort_should_print_stack() to transaction.h

The function abort_should_print_stack() is declared in transaction.h but
its definition is in ctree.c, which doesn't make sense since ctree.c is
the btree implementation and the function is related to the transaction
code. Move its definition into transaction.h as an inline function since
it's a very short and trivial function, and also add the 'btrfs_' prefix
into its name.

This change also reduces the module size.

Before this change:

  $ size fs/btrfs/btrfs.ko
     text    data     bss     dec     hex filename
  1783148  161137   16920 1961205  1decf5 fs/btrfs/btrfs.ko

After this change:

  $ size fs/btrfs/btrfs.ko
     text    data     bss     dec     hex filename
  1782126  161045   16920 1960091  1de89b fs/btrfs/btrfs.ko

Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: pass btrfs_io_geometry to is_single_device_io
Johannes Thumshirn [Mon, 16 Dec 2024 08:10:41 +0000 (09:10 +0100)]
btrfs: pass btrfs_io_geometry to is_single_device_io

Now that we have the stripe tree decision saved in struct
btrfs_io_geometry we can pass it into is_single_device_io() and get rid of
another call to btrfs_need_raid_stripe_tree_update().

Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: cache RAID stripe tree decision in btrfs_io_context
Johannes Thumshirn [Mon, 16 Dec 2024 08:10:40 +0000 (09:10 +0100)]
btrfs: cache RAID stripe tree decision in btrfs_io_context

Cache the decision if a particular I/O needs to update RAID stripe tree
entries in struct btrfs_io_context.

Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: cache stripe tree usage in struct btrfs_io_geometry
Johannes Thumshirn [Mon, 16 Dec 2024 08:10:39 +0000 (09:10 +0100)]
btrfs: cache stripe tree usage in struct btrfs_io_geometry

Cache the return of btrfs_need_stripe_tree_update() in struct
btrfs_io_geometry starting from btrfs_map_block().

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>
5 months agobtrfs: add assertions and comment about path expectations to btrfs_cross_ref_exist()
Filipe Manana [Tue, 10 Dec 2024 11:51:11 +0000 (11:51 +0000)]
btrfs: add assertions and comment about path expectations to btrfs_cross_ref_exist()

We should always call check_delayed_ref() with a path having a locked leaf
from the extent tree where either the extent item is located or where it
should be located in case it doesn't exist yet (when there's a pending
unflushed delayed ref to do it), as we need to lock any existing delayed
ref head while holding such leaf locked in order to avoid races with
flushing delayed references, which could make us think an extent is not
shared when it really is.

So add some assertions and a comment about such expectations to
btrfs_cross_ref_exist(), which is the only caller of check_delayed_ref().

Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: add function comment for check_committed_ref()
Filipe Manana [Tue, 10 Dec 2024 11:41:33 +0000 (11:41 +0000)]
btrfs: add function comment for check_committed_ref()

There are some not immediately obvious details about the operation of
check_committed_ref(), namely that when it returns 0 it must return with
the path having a locked leaf from the extent tree that contains the
extent's extent item, so that we can later check for delayed refs when
calling check_delayed_ref() in a way that doesn't race with a task running
delayed references. For similar reasons, it must also return with a locked
leaf when the extent item is not found, and that leaf is where the extent
item should be located, because we may have delayed references that are
going to create the extent item. Also document that the function can
return false positives in order to not be too slow, and that the most
important is to not return false negatives.

So add a function comment to check_committed_ref().

Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: simplify arguments for btrfs_cross_ref_exist()
Filipe Manana [Mon, 9 Dec 2024 16:59:23 +0000 (16:59 +0000)]
btrfs: simplify arguments for btrfs_cross_ref_exist()

Instead of passing a root and an objectid which matches an inode number,
pass the inode instead, since the root is always the root associated to
the inode and the objectid is the number of that inode.

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>
5 months agobtrfs: simplify return logic at check_committed_ref()
Filipe Manana [Mon, 9 Dec 2024 16:24:30 +0000 (16:24 +0000)]
btrfs: simplify return logic at check_committed_ref()

Instead of setting the value to return in a local variable 'ret' and then
jumping into a label named 'out' that does nothing but return that value,
simplify everything by getting rid of the label and directly returning a
value.

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>
5 months agobtrfs: avoid redundant call to get inline ref type at check_committed_ref()
Filipe Manana [Mon, 9 Dec 2024 16:07:12 +0000 (16:07 +0000)]
btrfs: avoid redundant call to get inline ref type at check_committed_ref()

At check_committed_ref() we are calling btrfs_get_extent_inline_ref_type()
twice, once before we check if have an inline extent owner ref (for simple
qgroups) and then once again sometime after that check. This second call
is redundant when we have simple quotas disabled or we found an inline ref
that is not of the owner ref type. So avoid this second call unless we
have simple quotas enabled and found an owner ref, saving a function call
that does inline ref validation again.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: remove the snapshot check from check_committed_ref()
Filipe Manana [Mon, 9 Dec 2024 15:52:13 +0000 (15:52 +0000)]
btrfs: remove the snapshot check from check_committed_ref()

At check_committed_ref() we have this check to see if the data extent was
created in a generation lower than or equals to the generation where the
last snapshot for the root was created, and if so we return immediately
with 1, since it's very likely the extent is shared, referenced by other
root.

The only call chain for check_committed_ref() is the following:

   can_nocow_file_extent()
      btrfs_cross_ref_exist()
         check_committed_ref()

And we already do that snapshot check at can_nocow_file_extent(), before
we call btrfs_cross_ref_exist(). This makes the check done at
check_committed_ref() redundant, so remove it.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: remove no longer needed strict argument from can_nocow_extent()
Filipe Manana [Mon, 9 Dec 2024 14:54:51 +0000 (14:54 +0000)]
btrfs: remove no longer needed strict argument from can_nocow_extent()

All callers of can_nocow_extent() now pass a value of false for its
'strict' argument, making it redundant. So remove the argument from
can_nocow_extent() as well as can_nocow_file_extent(),
btrfs_cross_ref_exist() and check_committed_ref(), because this
argument was used just to influence the behavior of check_committed_ref().
Also remove the 'strict' field from struct can_nocow_file_extent_args,
which is now always false as well, as its value is taken from the
argument to can_nocow_extent().

Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: remove unused variable length in btrfs_insert_one_raid_extent()
Johannes Thumshirn [Thu, 12 Dec 2024 12:56:06 +0000 (13:56 +0100)]
btrfs: remove unused variable length in btrfs_insert_one_raid_extent()

Remove the variable length in btrfs_insert_one_raid_extent() as it is
unused.

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>
5 months agobtrfs: output the reason for open_ctree() failure
Qu Wenruo [Tue, 10 Dec 2024 04:53:06 +0000 (15:23 +1030)]
btrfs: output the reason for open_ctree() failure

There is a recent ML report that mounting a large fs backed by hardware
RAID56 controller (with one device missing) took too much time, and
systemd seems to kill the mount attempt.

In that case, the only error message is:

  BTRFS error (device sdj): open_ctree failed

There is no reason on why the failure happened, making it very hard to
understand the reason.

At least output the error number (in the particular case it should be
-EINTR) to provide some clue.

Link: https://lore.kernel.org/linux-btrfs/9b9c4d2810abcca2f9f76e32220ed9a90febb235.camel@scientia.org/
Reported-by: Christoph Anton Mitterer <calestyo@scientia.org>
Cc: stable@vger.kernel.org
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: open-code btrfs_copy_from_user()
Qu Wenruo [Thu, 7 Nov 2024 04:05:07 +0000 (14:35 +1030)]
btrfs: open-code btrfs_copy_from_user()

The function btrfs_copy_from_user() handles the folio dirtying for
buffered write. The original design is to allow that function to handle
multiple folios, but since commit c87c299776e4 ("btrfs: make buffered
write to copy one page a time") there is no need to support multiple
folios.

So here open-code btrfs_copy_from_user() to
copy_folio_from_iter_atomic() and flush_dcache_folio() calls.

The short-copy check and revert are still kept as-is.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: improve the warning and error message for btrfs_remove_qgroup()
Qu Wenruo [Sun, 10 Nov 2024 20:59:07 +0000 (07:29 +1030)]
btrfs: improve the warning and error message for btrfs_remove_qgroup()

[WARNING]
There are several warnings about the recently introduced qgroup
auto-removal that it triggers WARN_ON() for the non-zero rfer/excl
numbers, e.g:

 ------------[ cut here ]------------
 WARNING: CPU: 67 PID: 2882 at fs/btrfs/qgroup.c:1854 btrfs_remove_qgroup+0x3df/0x450
 CPU: 67 UID: 0 PID: 2882 Comm: btrfs-cleaner Kdump: loaded Not tainted 6.11.6-300.fc41.x86_64 #1
 RIP: 0010:btrfs_remove_qgroup+0x3df/0x450
 Call Trace:
  <TASK>
  btrfs_qgroup_cleanup_dropped_subvolume+0x97/0xc0
  btrfs_drop_snapshot+0x44e/0xa80
  btrfs_clean_one_deleted_snapshot+0xc3/0x110
  cleaner_kthread+0xd8/0x130
  kthread+0xd2/0x100
  ret_from_fork+0x34/0x50
  ret_from_fork_asm+0x1a/0x30
  </TASK>
 ---[ end trace 0000000000000000 ]---
 BTRFS warning (device sda): to be deleted qgroup 0/319 has non-zero numbers, rfer 258478080 rfer_cmpr 258478080 excl 0 excl_cmpr 0

[CAUSE]
Although the root cause is still unclear, as if qgroup is consistent a
fully dropped subvolume (with extra transaction committed) should lead
to all zero numbers for the qgroup.

My current guess is the subvolume drop triggered the new subtree drop
threshold thus marked qgroup inconsistent, then rescan cleared it but
some corner case is not properly handled during subvolume dropping.

But at least for this particular case, since it's only the rfer/excl not
properly reset to 0, and qgroup is already marked inconsistent, there is
nothing to be worried for the end users.

The user space tool utilizing qgroup would queue a rescan to handle
everything, so the kernel wanring is a little overkilled.

[ENHANCEMENT]
Enhance the warning inside btrfs_remove_qgroup() by:

- Only do WARN() if CONFIG_BTRFS_DEBUG is enabled
  As explained the kernel can handle inconsistent qgroups by simply do a
  rescan, there is nothing to bother the end users.

- Treat the reserved space leak the same as non-zero numbers
  By outputting the values and trigger a WARN() if it's a debug build.
  So far I haven't experienced any case related to reserved space so I
  hope we will never need to bother them.

Fixes: 839d6ea4f86d ("btrfs: automatically remove the subvolume qgroup")
Link: https://github.com/kdave/btrfs-progs/issues/922
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: remove detached list from struct btrfs_backref_cache
Josef Bacik [Thu, 3 Oct 2024 15:43:12 +0000 (11:43 -0400)]
btrfs: remove detached list from struct btrfs_backref_cache

We don't ever look at this list, remove it.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: remove the ->lowest and ->leaves members from struct btrfs_backref_node
Josef Bacik [Thu, 3 Oct 2024 15:43:11 +0000 (11:43 -0400)]
btrfs: remove the ->lowest and ->leaves members from struct btrfs_backref_node

Before we were keeping all of our nodes on various lists in order to
make sure everything got cleaned up correctly.  We used node->lowest to
indicate that node->lower was linked into the cache->leaves list.  Now
that we do cleanup based on the rb-tree both the list and the flag are
useless, so delete them both.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: simplify btrfs_backref_release_cache()
Josef Bacik [Thu, 3 Oct 2024 15:43:10 +0000 (11:43 -0400)]
btrfs: simplify btrfs_backref_release_cache()

We rely on finding all our nodes on the various lists in the backref
cache, when they are all also in the rbtree.  Instead just search
through the rbtree and free everything.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: do not handle non-shareable roots in backref cache
Josef Bacik [Thu, 3 Oct 2024 15:43:09 +0000 (11:43 -0400)]
btrfs: do not handle non-shareable roots in backref cache

Now that we handle relocation for non-shareable roots without using the
backref cache, remove the ->cowonly field from the backref nodes and
update the handling to throw an error.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: don't build backref tree for COW-only blocks
Josef Bacik [Thu, 3 Oct 2024 15:43:08 +0000 (11:43 -0400)]
btrfs: don't build backref tree for COW-only blocks

We already determine the owner for any blocks we find when we're
relocating, and for COW-only blocks (and the data reloc tree) we COW
down to the block and call it good enough.  However we still build a
whole backref tree for them, even though we're not going to use it, and
then just don't put these blocks in the cache.

Rework the code to check if the block belongs to a COW-only root or the
data reloc root, and then just cow down to the block, skipping the
backref cache generation.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: remove clone_backref_node() from relocation
Josef Bacik [Thu, 3 Oct 2024 15:43:07 +0000 (11:43 -0400)]
btrfs: remove clone_backref_node() from relocation

Since we no longer maintain backref cache across transactions, and this
is only called when we're creating the reloc root for a newly created
snapshot in the transaction critical section, we will end up doing a
bunch of work that will just get thrown away when we start the
transaction in the relocation loop.  Delete this code as it no longer
does anything for us.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: simplify loop in select_reloc_root()
Josef Bacik [Thu, 3 Oct 2024 15:43:06 +0000 (11:43 -0400)]
btrfs: simplify loop in select_reloc_root()

We have this setup as a loop, but in reality we will never walk back up
the backref tree, if we do then it's a bug.  Get rid of the loop and
handle the case where we have node->new_bytenr set at all.  Previous
check was only if node->new_bytenr != root->node->start, but if it did
then we would hit the WARN_ON() and walk back up the tree.

Instead we want to just return error if ->new_bytenr is set, and then do
the normal updating of the node for the reloc root and carry on.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: add a comment for new_bytenr in backref_cache_node
Josef Bacik [Thu, 3 Oct 2024 15:43:05 +0000 (11:43 -0400)]
btrfs: add a comment for new_bytenr in backref_cache_node

Add a comment for this field so we know what it is used for.  Previously
we used it to update the backref cache, so people may mistakenly think
it is useless, but in fact exists to make sure the backref cache makes
sense.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: remove the changed list for backref cache
Josef Bacik [Thu, 3 Oct 2024 15:43:04 +0000 (11:43 -0400)]
btrfs: remove the changed list for backref cache

Now that we're not updating the backref cache when we switch transids we
can remove the changed list.

We're going to keep the new_bytenr field because it serves as a good
sanity check for the backref cache and relocation, and can prevent us
from making extent tree corruption worse.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: convert BUG_ON in btrfs_reloc_cow_block() to proper error handling
Josef Bacik [Thu, 3 Oct 2024 15:43:03 +0000 (11:43 -0400)]
btrfs: convert BUG_ON in btrfs_reloc_cow_block() to proper error handling

This BUG_ON is meant to catch backref cache problems, but these can
arise from either bugs in the backref cache or corruption in the extent
tree.  Fix it to be a proper error.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: fix data race when accessing the inode's disk_i_size at btrfs_drop_extents()
Hao-ran Zheng [Tue, 3 Dec 2024 07:56:51 +0000 (15:56 +0800)]
btrfs: fix data race when accessing the inode's disk_i_size at btrfs_drop_extents()

A data race occurs when the function `insert_ordered_extent_file_extent()`
and the function `btrfs_inode_safe_disk_i_size_write()` are executed
concurrently. The function `insert_ordered_extent_file_extent()` is not
locked when reading inode->disk_i_size, causing
`btrfs_inode_safe_disk_i_size_write()` to cause data competition when
writing inode->disk_i_size, thus affecting the value of `modify_tree`.

The specific call stack that appears during testing is as follows:

  ============DATA_RACE============
   btrfs_drop_extents+0x89a/0xa060 [btrfs]
   insert_reserved_file_extent+0xb54/0x2960 [btrfs]
   insert_ordered_extent_file_extent+0xff5/0x1760 [btrfs]
   btrfs_finish_one_ordered+0x1b85/0x36a0 [btrfs]
   btrfs_finish_ordered_io+0x37/0x60 [btrfs]
   finish_ordered_fn+0x3e/0x50 [btrfs]
   btrfs_work_helper+0x9c9/0x27a0 [btrfs]
   process_scheduled_works+0x716/0xf10
   worker_thread+0xb6a/0x1190
   kthread+0x292/0x330
   ret_from_fork+0x4d/0x80
   ret_from_fork_asm+0x1a/0x30
  ============OTHER_INFO============
   btrfs_inode_safe_disk_i_size_write+0x4ec/0x600 [btrfs]
   btrfs_finish_one_ordered+0x24c7/0x36a0 [btrfs]
   btrfs_finish_ordered_io+0x37/0x60 [btrfs]
   finish_ordered_fn+0x3e/0x50 [btrfs]
   btrfs_work_helper+0x9c9/0x27a0 [btrfs]
   process_scheduled_works+0x716/0xf10
   worker_thread+0xb6a/0x1190
   kthread+0x292/0x330
   ret_from_fork+0x4d/0x80
   ret_from_fork_asm+0x1a/0x30
  =================================

The main purpose of the check of the inode's disk_i_size is to avoid
taking write locks on a btree path when we have a write at or beyond
EOF, since in these cases we don't expect to find extent items in the
root to drop. However if we end up taking write locks due to a data
race on disk_i_size, everything is still correct, we only add extra
lock contention on the tree in case there's concurrency from other tasks.
If the race causes us to not take write locks when we actually need them,
then everything is functionally correct as well, since if we find out we
have extent items to drop and we took read locks (modify_tree set to 0),
we release the path and retry again with write locks.

Since this data race does not affect the correctness of the function,
it is a harmless data race, use data_race() to check inode->disk_i_size.

Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Hao-ran Zheng <zhenghaoran154@gmail.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: don't BUG_ON() in btrfs_drop_extents()
Johannes Thumshirn [Mon, 2 Dec 2024 05:48:53 +0000 (21:48 -0800)]
btrfs: don't BUG_ON() in btrfs_drop_extents()

btrfs_drop_extents() calls BUG_ON() in case the counter of to be deleted
extents is greater than 0. But all of these code paths can handle errors,
so there's no need to crash the kernel. Instead WARN() that the condition
has been met and gracefully bail out.

Reviewed-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: zoned: reclaim unused zone by zone resetting
Naohiro Aota [Thu, 14 Nov 2024 08:04:29 +0000 (17:04 +0900)]
btrfs: zoned: reclaim unused zone by zone resetting

On the zoned mode, once used and freed region is still not reusable after the
freeing. The underlying zone needs to be reset before reusing. Btrfs resets a
zone when it removes a block group, and then new block group is allocated on
the zones to reuse the zones. But, it is sometime too late to catch up with a
write side.

This commit introduces a new space-info reclaim method ZONE_RESET. That will
pick a block group from the unused list and reset its zone to reuse the
zone_unusable space. It is faster than removing the block group and re-creating
a new block group on the same zones.

For the first implementation, the ZONE_RESET is only applied to a block group
whose region is fully zone_unusable. Reclaiming partial zone_unusable block
group could be implemented later.

Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: drop fs_info argument from btrfs_update_space_info_*()
Naohiro Aota [Thu, 14 Nov 2024 08:04:28 +0000 (17:04 +0900)]
btrfs: drop fs_info argument from btrfs_update_space_info_*()

Since commit e1e577aafe41 ("btrfs: store fs_info in space_info"), we have
the fs_info in a space_info. So, we can drop fs_info argument from
btrfs_update_space_info_*. There is no behavior change.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: factor out btrfs_return_free_space()
Naohiro Aota [Thu, 14 Nov 2024 08:04:27 +0000 (17:04 +0900)]
btrfs: factor out btrfs_return_free_space()

Factor out a part of unpin_extent_range() that returns space back to the
space info, prioritizing global block reserve.  Also, move the "len"
variable into the loop to clarify we don't need to carry it beyond an
iteration.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: handle FS_IOC_READ_VERITY_METADATA ioctl
Allison Karlitskaya [Tue, 26 Nov 2024 15:23:31 +0000 (16:23 +0100)]
btrfs: handle FS_IOC_READ_VERITY_METADATA ioctl

Commit 146054090b08 ("btrfs: initial fsverity support") introduced
fs-verity support for btrfs, but didn't add support for
FS_IOC_READ_VERITY_METADATA to directly query the Merkle tree,
descriptor and signature blocks for fs-verity enabled files.

Add the (trival) implementation: we just need to wire it through to the
fs-verity code, the same way as is done in the other two filesystems
which support this ioctl (ext4, f2fs). The fs-verity code already has
access to the required data.

This is also safe to backport to older stable trees (5.15+) if needed.

Signed-off-by: Allison Karlitskaya <allison.karlitskaya@redhat.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: send: remove redundant assignments to variable ret
Colin Ian King [Wed, 13 Nov 2024 13:00:12 +0000 (13:00 +0000)]
btrfs: send: remove redundant assignments to variable ret

The variable ret is being initialized to zero and also later re-assigned
to zero. In both cases the assignment is redundant since the value is
never read after the assignment and hence they can be removed.

Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
5 months agobtrfs: use PTR_ERR() instead of PTR_ERR_OR_ZERO() for btrfs_get_extent()
Qu Wenruo [Sun, 24 Nov 2024 22:43:24 +0000 (09:13 +1030)]
btrfs: use PTR_ERR() instead of PTR_ERR_OR_ZERO() for btrfs_get_extent()

The function btrfs_get_extent() will only return an PTR_ERR() or a valid
extent map pointer. It will not return NULL.

Thus the usage of PTR_ERR_OR_ZERO() inside submit_one_sector() is not
needed, use plain PTR_ERR() instead, and that is the only usage of
PTR_ERR_OR_ZERO() after btrfs_get_extent().

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>