All of lore.kernel.org
 help / color / mirror / Atom feed
From: fdmanana@kernel.org
To: linux-btrfs@vger.kernel.org
Subject: [PATCH 06/12] btrfs: refactor the delayed item deletion entry point
Date: Tue, 31 May 2022 16:06:37 +0100	[thread overview]
Message-ID: <abca6c38b62815d6cde425fc089e7b78bbdc8981.1654009356.git.fdmanana@suse.com> (raw)
In-Reply-To: <cover.1654009356.git.fdmanana@suse.com>

From: Filipe Manana <fdmanana@suse.com>

The delayed item deletion entry point, btrfs_delete_delayed_items(), is a
bit convoluted for a few reasons:

1) It's really a loop disguised with labels and goto statements;

2) There's a 'delete_fail' label which isn't only for error cases, we can
   jump to that label even if no error happened, if we simply don't have
   more delayed items to delete;

3) Unnecessarily keeps track of the current and previous items for no
   good reason, as after getting the next item and releasing the current
   one, it just jumps to the 'again' label just to look again for the
   first delayed item;

4) When a delayed item is not in the tree (because it was already deleted
   before), it releases the item while holding a path locked, which is
   not necessary and adds more contention to the tree, specially taking
   into account that the path came from a deletion search, meaning we have
   write locks for nodes at levels 2, 1 and 0. And releasing the item is
   not computationally trivial (rb tree deletion, a kfree() and some
   trivial things).

So refactor it to use a while loop and add some comments to make it more
obvious why we can have delayed items without a matching item in the tree
as well as why not keep the delayed node locked all the time when running
all its deletion items. This is also a preparation for some upcoming work
involving delayed items.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/delayed-inode.c | 71 ++++++++++++++++++++++------------------
 1 file changed, 39 insertions(+), 32 deletions(-)

diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
index 3c6368c29bb9..0125586fd565 100644
--- a/fs/btrfs/delayed-inode.c
+++ b/fs/btrfs/delayed-inode.c
@@ -860,45 +860,52 @@ static int btrfs_delete_delayed_items(struct btrfs_trans_handle *trans,
 				      struct btrfs_root *root,
 				      struct btrfs_delayed_node *node)
 {
-	struct btrfs_delayed_item *curr, *prev;
 	int ret = 0;
 
-do_again:
-	mutex_lock(&node->mutex);
-	curr = __btrfs_first_delayed_deletion_item(node);
-	if (!curr)
-		goto delete_fail;
+	while (ret == 0) {
+		struct btrfs_delayed_item *item;
+
+		mutex_lock(&node->mutex);
+		item = __btrfs_first_delayed_deletion_item(node);
+		if (!item) {
+			mutex_unlock(&node->mutex);
+			break;
+		}
+
+		ret = btrfs_search_slot(trans, root, &item->key, path, -1, 1);
+		if (ret > 0) {
+			/*
+			 * There's no matching item in the leaf. This means we
+			 * have already deleted this item in a past run of the
+			 * delayed items. We ignore errors when running delayed
+			 * items from an async context, through a work queue job
+			 * running btrfs_async_run_delayed_root(), and don't
+			 * release delayed items that failed to complete. This
+			 * is because we will retry later, and at transaction
+			 * commit time we always run delayed items and will
+			 * then deal with errors if they fail to run again.
+			 *
+			 * So just release delayed items for which we can't find
+			 * an item in the tree, and move to the next item.
+			 */
+			btrfs_release_path(path);
+			btrfs_release_delayed_item(item);
+			ret = 0;
+		} else if (ret == 0) {
+			ret = btrfs_batch_delete_items(trans, root, path, item);
+			btrfs_release_path(path);
+		}
 
-	ret = btrfs_search_slot(trans, root, &curr->key, path, -1, 1);
-	if (ret < 0)
-		goto delete_fail;
-	else if (ret > 0) {
 		/*
-		 * can't find the item which the node points to, so this node
-		 * is invalid, just drop it.
+		 * We unlock and relock on each iteration, this is to prevent
+		 * blocking other tasks for too long while we are being run from
+		 * the async context (work queue job). Those tasks are typically
+		 * running system calls like creat/mkdir/rename/unlink/etc which
+		 * need to add delayed items to this delayed node.
 		 */
-		prev = curr;
-		curr = __btrfs_next_delayed_item(prev);
-		btrfs_release_delayed_item(prev);
-		ret = 0;
-		btrfs_release_path(path);
-		if (curr) {
-			mutex_unlock(&node->mutex);
-			goto do_again;
-		} else
-			goto delete_fail;
+		mutex_unlock(&node->mutex);
 	}
 
-	ret = btrfs_batch_delete_items(trans, root, path, curr);
-	if (ret)
-		goto delete_fail;
-	btrfs_release_path(path);
-	mutex_unlock(&node->mutex);
-	goto do_again;
-
-delete_fail:
-	btrfs_release_path(path);
-	mutex_unlock(&node->mutex);
 	return ret;
 }
 
-- 
2.35.1


  parent reply	other threads:[~2022-05-31 15:07 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-31 15:06 [PATCH 00/12] btrfs: some improvements and cleanups around delayed items fdmanana
2022-05-31 15:06 ` [PATCH 01/12] btrfs: balance btree dirty pages and delayed items after a rename fdmanana
2022-05-31 15:16   ` Nikolay Borisov
2022-05-31 23:13   ` Anand Jain
2022-05-31 15:06 ` [PATCH 02/12] btrfs: free the path earlier when creating a new inode fdmanana
2022-05-31 15:21   ` Nikolay Borisov
2022-05-31 23:22   ` Anand Jain
2022-06-01  9:34     ` Filipe Manana
2022-06-01 11:11       ` Anand Jain
2022-06-01 11:51         ` David Sterba
2022-05-31 15:06 ` [PATCH 03/12] btrfs: balance btree dirty pages and delayed items after clone and dedupe fdmanana
2022-06-01  0:54   ` Anand Jain
2022-05-31 15:06 ` [PATCH 04/12] btrfs: add assertions when deleting batches of delayed items fdmanana
2022-06-01  1:34   ` Anand Jain
2022-05-31 15:06 ` [PATCH 05/12] btrfs: deal with deletion errors when deleting " fdmanana
2022-06-01  1:44   ` Anand Jain
2022-05-31 15:06 ` fdmanana [this message]
2022-05-31 15:06 ` [PATCH 07/12] btrfs: improve batch deletion of delayed dir index items fdmanana
2022-06-02  8:24   ` Nikolay Borisov
2022-06-02  8:55     ` Filipe Manana
2022-05-31 15:06 ` [PATCH 08/12] btrfs: assert that delayed item is a dir index item when adding it fdmanana
2022-05-31 15:06 ` [PATCH 09/12] btrfs: improve batch insertion of delayed dir index items fdmanana
2022-05-31 15:06 ` [PATCH 10/12] btrfs: do not BUG_ON() on failure to reserve metadata for delayed item fdmanana
2022-05-31 15:06 ` [PATCH 11/12] btrfs: set delayed item type when initializing it fdmanana
2022-05-31 15:06 ` [PATCH 12/12] btrfs: reduce amount of reserved metadata for delayed item insertion fdmanana
2022-06-08 15:23   ` [btrfs] 62bd8124e2: WARNING:at_fs/btrfs/block-rsv.c:#btrfs_release_global_block_rsv[btrfs] kernel test robot
2022-06-08 15:23     ` kernel test robot
2022-06-09  9:46     ` Filipe Manana
2022-06-09  9:46       ` Filipe Manana
2022-06-10  1:26       ` Oliver Sang
2022-06-10  1:26         ` Oliver Sang
2022-06-12 14:36         ` Oliver Sang
2022-06-12 14:36           ` Oliver Sang
2022-06-13 10:50           ` Filipe Manana
2022-06-13 10:50             ` Filipe Manana
2022-06-16  2:42             ` Oliver Sang
2022-06-16  2:42               ` Oliver Sang
2022-06-17 10:32               ` Filipe Manana
2022-06-17 10:32                 ` Filipe Manana
2022-06-01 18:35 ` [PATCH 00/12] btrfs: some improvements and cleanups around delayed items David Sterba
2022-06-02  9:34 ` Nikolay Borisov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=abca6c38b62815d6cde425fc089e7b78bbdc8981.1654009356.git.fdmanana@suse.com \
    --to=fdmanana@kernel.org \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.