aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2017-01-27 20:47:56 -0500
committerFilipe Manana <fdmanana@suse.com>2017-02-23 19:36:55 -0500
commit6f546216e9f9e95d6783547ce6113eb13e2daa54 (patch)
tree3397961fab5e75ffff0643bc1262671ea5cce255
parent0191410158840d6176de3267daa4604ad6a773fb (diff)
Btrfs: bulk delete checksum items in the same leaf
Very often we have the checksums for an extent spread in multiple items in the checksums tree, and currently the algorithm to delete them starts by looking for them one by one and then deleting them one by one, which is not optimal since each deletion involves shifting all the other items in the leaf and when the leaf reaches some low threshold, to move items off the leaf into its left and right neighbor leafs. Also, after each item deletion we release our search path and start a new search for other checksums items. So optimize this by deleting in bulk all the items in the same leaf that contain checksums for the extent being freed. Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: Liu Bo <bo.li.liu@oracle.com>
-rw-r--r--fs/btrfs/file-item.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index f7b9a92ad56d..e35df48b4383 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -643,7 +643,33 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans,
643 643
644 /* delete the entire item, it is inside our range */ 644 /* delete the entire item, it is inside our range */
645 if (key.offset >= bytenr && csum_end <= end_byte) { 645 if (key.offset >= bytenr && csum_end <= end_byte) {
646 ret = btrfs_del_item(trans, root, path); 646 int del_nr = 1;
647
648 /*
649 * Check how many csum items preceding this one in this
650 * leaf correspond to our range and then delete them all
651 * at once.
652 */
653 if (key.offset > bytenr && path->slots[0] > 0) {
654 int slot = path->slots[0] - 1;
655
656 while (slot >= 0) {
657 struct btrfs_key pk;
658
659 btrfs_item_key_to_cpu(leaf, &pk, slot);
660 if (pk.offset < bytenr ||
661 pk.type != BTRFS_EXTENT_CSUM_KEY ||
662 pk.objectid !=
663 BTRFS_EXTENT_CSUM_OBJECTID)
664 break;
665 path->slots[0] = slot;
666 del_nr++;
667 key.offset = pk.offset;
668 slot--;
669 }
670 }
671 ret = btrfs_del_items(trans, root, path,
672 path->slots[0], del_nr);
647 if (ret) 673 if (ret)
648 goto out; 674 goto out;
649 if (key.offset == bytenr) 675 if (key.offset == bytenr)