All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Sterba <dsterba@suse.com>
To: linux-btrfs@vger.kernel.org
Cc: David Sterba <dsterba@suse.com>
Subject: [PATCH 3/4] btrfs: replace async commit by pending actions
Date: Thu,  3 Jun 2021 17:20:26 +0200	[thread overview]
Message-ID: <808c557f1ae3034fdfa2d2361e864aac90ba5a94.1622733245.git.dsterba@suse.com> (raw)
In-Reply-To: <cover.1622733245.git.dsterba@suse.com>

Note: this is a semantic change of what the async transaction ioctl
does. This used to be utilized by ceph, together with the now removed
user transaction ioctls. Last external code that can be found using this
ioctl is a test in ceph testsuite. As btrfs and ceph have taken
independent routes, we don't need to keep the code around.

The btrfs-progs use the start and wait transaction ioctls in a simpler
way, that does not require to block new transaction on the start. The
new semantics is to eventually get transaction id of the running
transaction if there is anything pending for a commit. The wait for
transaction ioctl will block until it's finished.

If there's nothing to be done since start, wait will return
immediately. This effectively implements "wait for current transaction,
if any".

Any action started before the start, like deleting a subvolume, may take
long time to finish. In case it's fast enough to finish before the
start, the following wait will also finish immediately. A long running
operation will catch the transaction and block at wait call until it's
done. Both cases are expected and shall be the new semantics.

This is implemented by the pending action infrastructure, that allows to
asynchronously and safely request a commit by just setting a bit and
waking the transaction kthread.

This is different, because originally start would block, but now it
returns immediately. However, the new behaviour still corresponds with
the documentation of libbtrfsutil so this should not cause any
surprises.

This also simplifies a few transaction commit things:

- another quirky freezing protection removed
- fs_info::transaction_blocked_wait is now never populated, so it's a
  no-op and can be simplified as well
- one less current->journal_info usage, that's been problematic in some
  cases

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/ioctl.c       | 12 +++----
 fs/btrfs/transaction.c | 74 ------------------------------------------
 fs/btrfs/transaction.h |  1 -
 3 files changed, 5 insertions(+), 82 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index f83eb4a225cc..445bb19d8a57 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3629,9 +3629,9 @@ static long btrfs_ioctl_space_info(struct btrfs_fs_info *fs_info,
 static noinline long btrfs_ioctl_start_sync(struct btrfs_root *root,
 					    void __user *argp)
 {
+	struct btrfs_fs_info *fs_info = root->fs_info;
 	struct btrfs_trans_handle *trans;
 	u64 transid;
-	int ret;
 
 	trans = btrfs_attach_transaction_barrier(root);
 	if (IS_ERR(trans)) {
@@ -3639,15 +3639,13 @@ static noinline long btrfs_ioctl_start_sync(struct btrfs_root *root,
 			return PTR_ERR(trans);
 
 		/* No running transaction, don't bother */
-		transid = root->fs_info->last_trans_committed;
+		transid = fs_info->last_trans_committed;
 		goto out;
 	}
 	transid = trans->transid;
-	ret = btrfs_commit_transaction_async(trans);
-	if (ret) {
-		btrfs_end_transaction(trans);
-		return ret;
-	}
+	/* Trigger commit via the pending action */
+	btrfs_set_pending(fs_info, COMMIT);
+	wake_up_process(fs_info->transaction_kthread);
 out:
 	if (argp)
 		if (copy_to_user(argp, &transid, sizeof(transid)))
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 73df8b81496e..5f3c95c876c8 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1870,80 +1870,6 @@ int btrfs_transaction_blocked(struct btrfs_fs_info *info)
 	return ret;
 }
 
-/*
- * commit transactions asynchronously. once btrfs_commit_transaction_async
- * returns, any subsequent transaction will not be allowed to join.
- */
-struct btrfs_async_commit {
-	struct btrfs_trans_handle *newtrans;
-	struct work_struct work;
-};
-
-static void do_async_commit(struct work_struct *work)
-{
-	struct btrfs_async_commit *ac =
-		container_of(work, struct btrfs_async_commit, work);
-
-	/*
-	 * We've got freeze protection passed with the transaction.
-	 * Tell lockdep about it.
-	 */
-	if (ac->newtrans->type & __TRANS_FREEZABLE)
-		__sb_writers_acquired(ac->newtrans->fs_info->sb, SB_FREEZE_FS);
-
-	current->journal_info = ac->newtrans;
-
-	btrfs_commit_transaction(ac->newtrans);
-	kfree(ac);
-}
-
-int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans)
-{
-	struct btrfs_fs_info *fs_info = trans->fs_info;
-	struct btrfs_async_commit *ac;
-	struct btrfs_transaction *cur_trans;
-
-	ac = kmalloc(sizeof(*ac), GFP_NOFS);
-	if (!ac)
-		return -ENOMEM;
-
-	INIT_WORK(&ac->work, do_async_commit);
-	ac->newtrans = btrfs_join_transaction(trans->root);
-	if (IS_ERR(ac->newtrans)) {
-		int err = PTR_ERR(ac->newtrans);
-		kfree(ac);
-		return err;
-	}
-
-	/* take transaction reference */
-	cur_trans = trans->transaction;
-	refcount_inc(&cur_trans->use_count);
-
-	btrfs_end_transaction(trans);
-
-	/*
-	 * Tell lockdep we've released the freeze rwsem, since the
-	 * async commit thread will be the one to unlock it.
-	 */
-	if (ac->newtrans->type & __TRANS_FREEZABLE)
-		__sb_writers_release(fs_info->sb, SB_FREEZE_FS);
-
-	schedule_work(&ac->work);
-	/*
-	 * Wait for the current transaction commit to start and block
-	 * subsequent transaction joins
-	 */
-	wait_event(fs_info->transaction_blocked_wait,
-		   cur_trans->state >= TRANS_STATE_COMMIT_START ||
-		   TRANS_ABORTED(cur_trans));
-	if (current->journal_info == trans)
-		current->journal_info = NULL;
-
-	btrfs_put_transaction(cur_trans);
-	return 0;
-}
-
-
 static void cleanup_transaction(struct btrfs_trans_handle *trans, int err)
 {
 	struct btrfs_fs_info *fs_info = trans->fs_info;
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
index 0702e8d9b30e..0bdb804fddcb 100644
--- a/fs/btrfs/transaction.h
+++ b/fs/btrfs/transaction.h
@@ -226,7 +226,6 @@ void btrfs_add_dead_root(struct btrfs_root *root);
 int btrfs_defrag_root(struct btrfs_root *root);
 int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root);
 int btrfs_commit_transaction(struct btrfs_trans_handle *trans);
-int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans);
 int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans);
 bool btrfs_should_end_transaction(struct btrfs_trans_handle *trans);
 void btrfs_throttle(struct btrfs_fs_info *fs_info);
-- 
2.31.1


  parent reply	other threads:[~2021-06-03 15:23 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-03 15:20 [PATCH 0/4] Slightly how START_SYNC and WAIT_SYNC work David Sterba
2021-06-03 15:20 ` [PATCH 1/4] btrfs: sink wait_for_unblock parameter to async commit David Sterba
2021-06-04 12:35   ` Anand Jain
2021-06-03 15:20 ` [PATCH 2/4] btrfs: inline wait_current_trans_commit_start in its caller David Sterba
2021-06-04 12:37   ` Anand Jain
2021-06-03 15:20 ` David Sterba [this message]
2021-06-03 15:20 ` [PATCH 4/4] btrfs: remove fs_info::transaction_blocked_wait David Sterba
2021-06-04 10:59 ` [PATCH 0/4] Slightly how START_SYNC and WAIT_SYNC work David Sterba

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=808c557f1ae3034fdfa2d2361e864aac90ba5a94.1622733245.git.dsterba@suse.com \
    --to=dsterba@suse.com \
    --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.