b3e744fe6d
During fiemap, whenever we find a hole or prealloc extent, we will look for delalloc in that range, and one of the things we do for that is to find out ranges in the inode's io_tree marked with EXTENT_DELALLOC, using calls to count_range_bits(). Since we process file extents from left to right, if we have a file with several holes or prealloc extents, we benefit from keeping a cached extent state record for calls to count_range_bits(). Most of the time the last extent state record we visited in one call to count_range_bits() matches the first extent state record we will use in the next call to count_range_bits(), so there's a benefit here. So use an extent state record to cache results from count_range_bits() calls during fiemap. This change is part of a patchset that has the goal to make performance better for applications that use lseek's SEEK_HOLE and SEEK_DATA modes to iterate over the extents of a file. Two examples are the cp program from coreutils 9.0+ and the tar program (when using its --sparse / -S option). A sample test and results are listed in the changelog of the last patch in the series: 1/9 btrfs: remove leftover setting of EXTENT_UPTODATE state in an inode's io_tree 2/9 btrfs: add an early exit when searching for delalloc range for lseek/fiemap 3/9 btrfs: skip unnecessary delalloc searches during lseek/fiemap 4/9 btrfs: search for delalloc more efficiently during lseek/fiemap 5/9 btrfs: remove no longer used btrfs_next_extent_map() 6/9 btrfs: allow passing a cached state record to count_range_bits() 7/9 btrfs: update stale comment for count_range_bits() 8/9 btrfs: use cached state when looking for delalloc ranges with fiemap 9/9 btrfs: use cached state when looking for delalloc ranges with lseek Reported-by: Wang Yugui <wangyugui@e16-tech.com> Link: https://lore.kernel.org/linux-btrfs/20221106073028.71F9.409509F4@e16-tech.com/ Link: https://lore.kernel.org/linux-btrfs/CAL3q7H5NSVicm7nYBJ7x8fFkDpno8z3PYt5aPU43Bajc1H0h1Q@mail.gmail.com/ Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
34 lines
1.5 KiB
C
34 lines
1.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
#ifndef BTRFS_FILE_H
|
|
#define BTRFS_FILE_H
|
|
|
|
extern const struct file_operations btrfs_file_operations;
|
|
|
|
int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync);
|
|
int btrfs_drop_extents(struct btrfs_trans_handle *trans,
|
|
struct btrfs_root *root, struct btrfs_inode *inode,
|
|
struct btrfs_drop_extents_args *args);
|
|
int btrfs_replace_file_extents(struct btrfs_inode *inode,
|
|
struct btrfs_path *path, const u64 start,
|
|
const u64 end,
|
|
struct btrfs_replace_extent_info *extent_info,
|
|
struct btrfs_trans_handle **trans_out);
|
|
int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
|
|
struct btrfs_inode *inode, u64 start, u64 end);
|
|
ssize_t btrfs_do_write_iter(struct kiocb *iocb, struct iov_iter *from,
|
|
const struct btrfs_ioctl_encoded_io_args *encoded);
|
|
int btrfs_release_file(struct inode *inode, struct file *file);
|
|
int btrfs_dirty_pages(struct btrfs_inode *inode, struct page **pages,
|
|
size_t num_pages, loff_t pos, size_t write_bytes,
|
|
struct extent_state **cached, bool noreserve);
|
|
int btrfs_fdatawrite_range(struct inode *inode, loff_t start, loff_t end);
|
|
int btrfs_check_nocow_lock(struct btrfs_inode *inode, loff_t pos,
|
|
size_t *write_bytes, bool nowait);
|
|
void btrfs_check_nocow_unlock(struct btrfs_inode *inode);
|
|
bool btrfs_find_delalloc_in_range(struct btrfs_inode *inode, u64 start, u64 end,
|
|
struct extent_state **cached_state,
|
|
u64 *delalloc_start_ret, u64 *delalloc_end_ret);
|
|
|
|
#endif
|