android_kernel_samsung_sm8650/fs/btrfs
Filipe Manana 152555b39c btrfs: send: avoid trashing the page cache
A send operation reads extent data using the buffered IO path for getting
extent data to send in write commands and this is both because it's simple
and to make use of the generic readahead infrastructure, which results in
a massive speedup.

However this fills the page cache with data that, most of the time, is
really only used by the send operation - once the write commands are sent,
it's not useful to have the data in the page cache anymore. For large
snapshots, bringing all data into the page cache eventually leads to the
need to evict other data from the page cache that may be more useful for
applications (and kernel subsystems).

Even if extents are shared with the subvolume on which a snapshot is based
on and the data is currently on the page cache due to being read through
the subvolume, attempting to read the data through the snapshot will
always result in bringing a new copy of the data into another location in
the page cache (there's currently no shared memory for shared extents).

So make send evict the data it has read before if when it first opened
the inode, its mapping had no pages currently loaded: when
inode->i_mapping->nr_pages has a value of 0. Do this instead of deciding
based on the return value of filemap_range_has_page() before reading an
extent because the generic readahead mechanism may read pages beyond the
range we request (and it very often does it), which means a call to
filemap_range_has_page() will return true due to the readahead that was
triggered when processing a previous extent - we don't have a simple way
to distinguish this case from the case where the data was brought into
the page cache through someone else. So checking for the mapping number
of pages being 0 when we first open the inode is simple, cheap and it
generally accomplishes the goal of not trashing the page cache - the
only exception is if part of data was previously loaded into the page
cache through the snapshot by some other process, in that case we end
up not evicting any data send brings into the page cache, just like
before this change - but that however is not the common case.

Example scenario, on a box with 32G of RAM:

  $ btrfs subvolume create /mnt/sv1
  $ xfs_io -f -c "pwrite 0 4G" /mnt/sv1/file1

  $ btrfs subvolume snapshot -r /mnt/sv1 /mnt/snap1

  $ free -m
                 total        used        free      shared  buff/cache   available
  Mem:           31937         186       26866           0        4883       31297
  Swap:           8188           0        8188

  # After this we get less 4G of free memory.
  $ btrfs send /mnt/snap1 >/dev/null

  $ free -m
                 total        used        free      shared  buff/cache   available
  Mem:           31937         186       22814           0        8935       31297
  Swap:           8188           0        8188

The same, obviously, applies to an incremental send.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2022-05-17 20:14:54 +02:00
..
tests btrfs: turn fs_roots_radix in btrfs_fs_info into an XArray 2022-05-16 17:15:57 +02:00
acl.c btrfs: reserve correct number of items for inode creation 2022-05-16 17:03:08 +02:00
async-thread.c btrfs: simplify WQ_HIGHPRI handling in struct btrfs_workqueue 2022-05-16 17:03:15 +02:00
async-thread.h btrfs: simplify WQ_HIGHPRI handling in struct btrfs_workqueue 2022-05-16 17:03:15 +02:00
backref.c btrfs: unify the error handling pattern for read_tree_block() 2022-03-14 13:13:53 +01:00
backref.h btrfs: remove ignore_offset argument from btrfs_find_all_roots() 2021-08-23 13:19:01 +02:00
block-group.c btrfs: zoned: zone finish unused block group 2022-05-16 17:17:32 +02:00
block-group.h btrfs: zoned: properly finish block group on metadata write 2022-05-16 17:17:32 +02:00
block-rsv.c btrfs: reserve extra space for the free space tree 2022-01-07 14:18:25 +01:00
block-rsv.h btrfs: init root block_rsv at init root time 2022-01-03 15:09:48 +01:00
btrfs_inode.h btrfs: move struct btrfs_dio_private to inode.c 2022-05-16 17:17:32 +02:00
check-integrity.c btrfs: check-integrity: simplify bio allocation in btrfsic_read_block 2022-05-16 17:03:12 +02:00
check-integrity.h btrfs: check-integrity: split submit_bio from btrfsic checking 2022-05-16 17:03:12 +02:00
compression.c btrfs: derive compression type from extent map during reads 2022-05-16 17:17:31 +02:00
compression.h btrfs: derive compression type from extent map during reads 2022-05-16 17:17:31 +02:00
ctree.c btrfs: sink parameter is_data to btrfs_set_disk_extent_flags 2022-05-16 17:17:31 +02:00
ctree.h btrfs: move struct btrfs_dio_private to inode.c 2022-05-16 17:17:32 +02:00
delalloc-space.c btrfs: avoid blocking on space revervation when doing nowait dio writes 2022-05-16 17:03:10 +02:00
delalloc-space.h btrfs: make btrfs_delalloc_reserve_space take btrfs_inode 2020-07-27 12:55:36 +02:00
delayed-inode.c btrfs: turn delayed_nodes_tree into an XArray 2022-05-16 17:03:16 +02:00
delayed-inode.h btrfs: make btrfs_delayed_update_inode take btrfs_inode 2020-12-08 15:54:10 +01:00
delayed-ref.c btrfs: remove btrfs_delayed_extent_op::is_data 2022-05-16 17:17:31 +02:00
delayed-ref.h btrfs: remove btrfs_delayed_extent_op::is_data 2022-05-16 17:17:31 +02:00
dev-replace.c btrfs: use a local variable for fs_devices pointer in btrfs_dev_replace_finishing 2022-05-16 17:03:08 +02:00
dev-replace.h btrfs: zoned: mark block groups to copy for device-replace 2021-02-09 02:46:07 +01:00
dir-item.c btrfs: use btrfs_for_each_slot in btrfs_search_dir_index_item 2022-05-16 17:03:07 +02:00
discard.c btrfs: fix typos in comments 2021-06-22 14:11:57 +02:00
discard.h btrfs: cleanup btrfs_discard_update_discardable usage 2020-12-08 15:54:02 +01:00
disk-io.c btrfs: remove unused parameter bio_flags from btrfs_wq_submit_bio 2022-05-16 17:17:31 +02:00
disk-io.h btrfs: remove unused parameter bio_flags from btrfs_wq_submit_bio 2022-05-16 17:17:31 +02:00
export.c btrfs: locking: rip out path->leave_spinning 2020-12-08 15:54:02 +01:00
export.h btrfs: export helpers for subvolume name/id resolution 2020-03-23 17:01:42 +01:00
extent_io.c btrfs: zoned: properly finish block group on metadata write 2022-05-16 17:17:32 +02:00
extent_io.h btrfs: zoned: properly finish block group on metadata write 2022-05-16 17:17:32 +02:00
extent_map.c btrfs: assert we have a write lock when removing and replacing extent maps 2022-03-14 13:13:50 +01:00
extent_map.h btrfs: defrag: don't use merged extent map for their generation check 2022-02-23 17:43:13 +01:00
extent-io-tree.h btrfs: Convert from invalidatepage to invalidate_folio 2022-03-15 08:23:29 -04:00
extent-tree.c btrfs: zoned: introduce btrfs_zoned_bg_is_full 2022-05-16 17:17:32 +02:00
file-item.c btrfs: handle csum lookup errors properly on reads 2022-03-14 13:13:51 +01:00
file.c btrfs: add a btrfs_dio_rw wrapper 2022-05-16 17:17:32 +02:00
free-space-cache.c btrfs: use rbtree with leftmost node cached for tracking lowest block group 2022-05-16 17:03:13 +02:00
free-space-cache.h btrfs: change name and type of private member of btrfs_free_space_ctl 2022-01-03 15:09:50 +01:00
free-space-tree.c btrfs: use rbtree with leftmost node cached for tracking lowest block group 2022-05-16 17:03:13 +02:00
free-space-tree.h btrfs: rename btrfs_block_group_cache 2019-11-18 17:51:51 +01:00
inode-item.c btrfs: make should_throttle loop local in btrfs_truncate_inode_items 2022-01-07 14:18:25 +01:00
inode-item.h btrfs: add inode to truncate control 2022-01-07 14:18:24 +01:00
inode.c btrfs: allocate the btrfs_dio_private as part of the iomap dio bio 2022-05-16 17:17:33 +02:00
ioctl.c btrfs: remove unnecessary type casts 2022-05-16 17:03:11 +02:00
Kconfig btrfs: use generic Kconfig option for 256kB page size limit 2022-01-20 08:52:55 +02:00
locking.c btrfs: fix typos in comments 2021-06-22 14:11:57 +02:00
locking.h btrfs: assert that extent buffers are write locked instead of only locked 2021-10-26 19:08:02 +02:00
lzo.c btrfs: add lzo workspace buffer length constants 2022-03-14 13:13:50 +01:00
Makefile Kbuild: add -Wno-shift-negative-value where -Wextra is used 2022-03-13 17:30:31 +09:00
misc.h btrfs: use correct header for div_u64 in misc.h 2021-09-07 14:29:50 +02:00
ordered-data.c btrfs: add BTRFS_IOC_ENCODED_WRITE 2022-03-14 13:13:51 +01:00
ordered-data.h btrfs: add BTRFS_IOC_ENCODED_WRITE 2022-03-14 13:13:51 +01:00
orphan.c btrfs: replace GPL boilerplate by SPDX -- sources 2018-04-12 16:29:51 +02:00
print-tree.c btrfs: unify the error handling pattern for read_tree_block() 2022-03-14 13:13:53 +01:00
print-tree.h btrfs: print the actual offset in btrfs_root_name 2021-01-07 17:25:05 +01:00
props.c btrfs: move common inode creation code into btrfs_create_new_inode() 2022-05-16 17:03:08 +02:00
props.h btrfs: move common inode creation code into btrfs_create_new_inode() 2022-05-16 17:03:08 +02:00
qgroup.c btrfs: avoid blocking on space revervation when doing nowait dio writes 2022-05-16 17:03:10 +02:00
qgroup.h btrfs: avoid blocking on space revervation when doing nowait dio writes 2022-05-16 17:03:10 +02:00
raid56.c btrfs: use a normal workqueue for rmw_workers 2022-05-16 17:03:16 +02:00
raid56.h btrfs: raid56: make raid56_add_scrub_pages() subpage compatible 2022-05-16 17:03:15 +02:00
rcu-string.h btrfs: rcu-string: Replace zero-length array with flexible-array member 2020-03-23 17:01:53 +01:00
ref-verify.c btrfs: stop accessing ->extent_root directly 2022-01-03 15:09:49 +01:00
ref-verify.h btrfs: ref-verify: Use btrfs_ref to refactor btrfs_ref_tree_mod() 2019-04-29 19:02:49 +02:00
reflink.c btrfs: add and use helper to assert an inode range is clean 2022-05-16 17:03:09 +02:00
reflink.h Btrfs: move all reflink implementation code into its own file 2020-03-23 17:01:54 +01:00
relocation.c btrfs: remove unnecessary check of iput argument 2022-05-16 17:03:12 +02:00
root-tree.c btrfs: avoid blocking on space revervation when doing nowait dio writes 2022-05-16 17:03:10 +02:00
scrub.c btrfs: scrub: move scrub_remap_extent() call into scrub_extent() 2022-05-16 17:17:31 +02:00
send.c btrfs: send: avoid trashing the page cache 2022-05-17 20:14:54 +02:00
send.h btrfs: reuse existing inode from btrfs_ioctl 2022-03-14 13:13:46 +01:00
space-info.c btrfs: make the bg_reclaim_threshold per-space info 2022-05-16 17:03:11 +02:00
space-info.h btrfs: move definition of btrfs_raid_types to volumes.h 2022-05-16 17:03:16 +02:00
struct-funcs.c btrfs: add special case to setget helpers for 64k pages 2021-08-23 13:18:58 +02:00
subpage.c btrfs: remove unnecessary type casts 2022-05-16 17:03:11 +02:00
subpage.h btrfs: make nodesize >= PAGE_SIZE case to reuse the non-subpage routine 2022-05-16 17:03:11 +02:00
super.c btrfs: use normal workqueues for scrub 2022-05-16 17:03:15 +02:00
sysfs.c btrfs: change the bg_reclaim_threshold valid region from 0 to 100 2022-05-16 17:03:11 +02:00
sysfs.h btrfs: split and refactor btrfs_sysfs_remove_devices_dir 2020-10-07 12:12:21 +02:00
transaction.c btrfs: turn fs_roots_radix in btrfs_fs_info into an XArray 2022-05-16 17:15:57 +02:00
transaction.h btrfs: pass btrfs_fs_info for deleting snapshots and cleaner 2022-03-14 13:13:52 +01:00
tree-checker.c btrfs: tree-checker: check extent buffer owner against owner rootid 2022-05-16 17:03:09 +02:00
tree-checker.h btrfs: tree-checker: check extent buffer owner against owner rootid 2022-05-16 17:03:09 +02:00
tree-defrag.c btrfs: remove unnecessary extent root check in btrfs_defrag_leaves 2022-01-03 15:09:48 +01:00
tree-log.c btrfs: remove unnecessary check of iput argument 2022-05-16 17:03:12 +02:00
tree-log.h btrfs: avoid inode logging during rename and link when possible 2022-03-14 13:13:48 +01:00
tree-mod-log.c btrfs: fix race when picking most recent mod log operation for an old root 2021-04-20 19:27:17 +02:00
tree-mod-log.h btrfs: add and use helper to get lowest sequence number for the tree mod log 2021-04-19 17:25:17 +02:00
ulist.c btrfs: replace GPL boilerplate by SPDX -- sources 2018-04-12 16:29:51 +02:00
ulist.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
uuid-tree.c btrfs: drop the _nr from the item helpers 2022-01-03 15:09:43 +01:00
verity.c btrfs: drop the _nr from the item helpers 2022-01-03 15:09:43 +01:00
volumes.c btrfs: use ilog2() to replace if () branches for btrfs_bg_flags_to_raid_index() 2022-05-16 17:03:16 +02:00
volumes.h btrfs: use ilog2() to replace if () branches for btrfs_bg_flags_to_raid_index() 2022-05-16 17:03:16 +02:00
xattr.c btrfs: use btrfs_for_each_slot in btrfs_listxattr 2022-05-16 17:03:08 +02:00
xattr.h btrfs: cleanup btrfs_setxattr_trans and drop transaction parameter 2019-04-29 19:02:44 +02:00
zlib.c Revert "btrfs: compression: drop kmap/kunmap from zlib" 2021-10-29 13:03:05 +02:00
zoned.c btrfs: zoned: properly finish block group on metadata write 2022-05-16 17:17:32 +02:00
zoned.h btrfs: zoned: properly finish block group on metadata write 2022-05-16 17:17:32 +02:00
zstd.c btrfs: use non-bh spin_lock in zstd timer callback 2022-05-16 17:03:13 +02:00