linux/fs/btrfs
Filipe Manana 4bd02d9012 btrfs: improve batch deletion of delayed dir index items
Currently we group delayed dir index items for deletion in a single batch
(single btree operation) as long as they all exist in the same leaf and as
long as their keys are sequential in the key space. For example if we have
a leaf that has dir index items with offsets:

    2, 3, 4, 6, 7, 10

And we have delayed dir index items for deleting all these indexes, and
no delayed items for any other index keys in between, then we end up
deleting in 3 batches:

1) First batch for indexes 2, 3 and 4;
2) Second batch for indexes 6 and 7;
3) Third batch for index 10.

This is a waste because we can delete all the index keys in a single
batch. What matters is that each consecutive delayed index key matches
each consecutive dir index key in a leaf.

So update the logic at btrfs_batch_delete_items() to check only for a
key match between delayed dir index items and dir index items in a leaf.
Also avoid the useless first iteration on comparing the key of the
first slot to delete with the key of the first delayed item, as it's
silly since they always match, as the delayed item's key was used for
the btree search that gave us the path we have.

This is more efficient and reduces runtime of running delayed items, as
well as lock contention on the subvolume's tree.

For example, the following test script:

  $ cat test.sh
  #!/bin/bash

  DEV=/dev/sdj
  MNT=/mnt/sdj

  mkfs.btrfs -f $DEV
  mount $DEV $MNT

  NUM_FILES=1000

  mkdir $MNT/testdir
  for ((i = 1; i <= $NUM_FILES; i++)); do
      echo -n > $MNT/testdir/file_$i
  done

  # Now delete every other file, to create gaps in the dir index keys.
  for ((i = 1; i <= $NUM_FILES; i += 2)); do
      rm -f $MNT/testdir/file_$i
  done

  # Sync to force any delayed items to be flushed to the tree.
  sync

  start=$(date +%s%N)
  rm -fr $MNT/testdir
  end=$(date +%s%N)
  dur=$(( (end - start) / 1000000 ))

  echo -e "\nrm -fr took $dur milliseconds"

  umount $MNT

Running that test script while having the following bpftrace script
running in another shell:

  $ cat bpf-measure.sh
  #!/usr/bin/bpftrace

  /* Add 'noinline' to btrfs_delete_delayed_items()'s definition. */
  k:btrfs_delete_delayed_items
  {
      @start_delete_delayed_items[tid] = nsecs;
  }

  k:btrfs_del_items
  /@start_delete_delayed_items[tid]/
  {
      @delete_batches = count();
  }

  kr:btrfs_delete_delayed_items
  /@start_delete_delayed_items[tid]/
  {
      $dur = (nsecs - @start_delete_delayed_items[tid]) / 1000;
      @btrfs_delete_delayed_items_total_time = sum($dur);
      delete(@start_delete_delayed_items[tid]);
  }

Before this change:

@btrfs_delete_delayed_items_total_time: 9563
@delete_batches: 1001

After this change:

@btrfs_delete_delayed_items_total_time: 7328
@delete_batches: 509

Reviewed-by: Nikolay Borisov <nborisov@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>
2022-07-25 17:44:35 +02:00
..
tests Revert "btrfs: turn fs_info member buffer_radix into XArray" 2022-07-15 19:14:33 +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: prevent allocation from previous data relocation BG 2022-06-21 14:43:48 +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: remove redundant calls to flush_dcache_page 2022-07-25 17:44:34 +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: factor out a btrfs_csum_ptr helper 2022-07-25 17:44:34 +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: improve batch deletion of delayed dir index items 2022-07-25 17:44:35 +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: fix typos in comments 2022-07-25 17:44:33 +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
extent_io.c btrfs: remove redundant calls to flush_dcache_page 2022-07-25 17:44:34 +02:00
extent_io.h Page cache changes for 5.19 2022-05-24 19:55:07 -07: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 for-5.19-rc7-tag 2022-07-16 13:48:55 -07:00
file-item.c btrfs: handle csum lookup errors properly on reads 2022-03-14 13:13:51 +01:00
file.c for-5.19-rc3-tag 2022-06-26 10:11:36 -07:00
free-space-cache.c Page cache changes for 5.19 2022-05-24 19:55:07 -07: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
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: free the path earlier when creating a new inode 2022-07-25 17:44:35 +02:00
ioctl.c btrfs: use btrfs_try_lock_balance in btrfs_ioctl_balance 2022-07-25 17:44:34 +02:00
Kconfig btrfs: use generic Kconfig option for 256kB page size limit 2022-01-20 08:52:55 +02:00
locking.c btrfs: don't set lock_owner when locking extent buffer for reading 2022-06-21 14:46:56 +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: fix typos in comments 2022-07-25 17:44:33 +02:00
ordered-data.h btrfs: add BTRFS_IOC_ENCODED_WRITE 2022-03-14 13:13:51 +01:00
orphan.c
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: add trace event for submitted RAID56 bio 2022-07-25 17:44:34 +02:00
raid56.h btrfs: add trace event for submitted RAID56 bio 2022-07-25 17:44:34 +02:00
rcu-string.h
ref-verify.c btrfs: stop accessing ->extent_root directly 2022-01-03 15:09:49 +01:00
ref-verify.h
reflink.c btrfs: balance btree dirty pages and delayed items after clone and dedupe 2022-07-25 17:44:35 +02:00
reflink.h
relocation.c Page cache changes for 5.19 2022-05-24 19:55:07 -07: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: use integrated bitmaps for scrub_parity::dbitmap and ebitmap 2022-07-25 17:44:34 +02:00
send.c for-5.19-rc7-tag 2022-07-16 13:48:55 -07:00
send.h btrfs: reuse existing inode from btrfs_ioctl 2022-03-14 13:13:46 +01:00
space-info.c btrfs: fix typos in comments 2022-07-25 17:44:33 +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: fix typos in comments 2022-07-25 17:44:33 +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: add trace event for submitted RAID56 bio 2022-07-25 17:44:34 +02:00
sysfs.c btrfs: fix typos in comments 2022-07-25 17:44:33 +02:00
sysfs.h btrfs: split and refactor btrfs_sysfs_remove_devices_dir 2020-10-07 12:12:21 +02:00
transaction.c Revert "btrfs: turn fs_roots_radix in btrfs_fs_info into an XArray" 2022-07-15 19:14:28 +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: fix typos in comments 2022-07-25 17:44:33 +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
ulist.h
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: quit early if the fs has no RAID56 support for raid56 related checks 2022-07-25 17:44:33 +02:00
volumes.h btrfs: add a helper to iterate through a btrfs_bio with sector sized chunks 2022-07-25 17:44:34 +02:00
xattr.c btrfs: use btrfs_for_each_slot in btrfs_listxattr 2022-05-16 17:03:08 +02:00
xattr.h
zlib.c Revert "btrfs: compression: drop kmap/kunmap from zlib" 2021-10-29 13:03:05 +02:00
zoned.c btrfs: zoned: fix comment description for sb_write_pointer logic 2022-07-25 17:44:33 +02:00
zoned.h btrfs: zoned: prevent allocation from previous data relocation BG 2022-06-21 14:43:48 +02:00
zstd.c btrfs: use non-bh spin_lock in zstd timer callback 2022-05-16 17:03:13 +02:00