Skip to content

Commit 0f873ec

Browse files
committed
btrfs: fix deadlock in delayed_ref_async_start
"Btrfs: track transid for delayed ref flushing" was deadlocking on btrfs_attach_transaction because its not safe to call from the async delayed ref start code. This commit brings back btrfs_join_transaction instead and checks for a blocked commit. Signed-off-by: Josef Bacik <[email protected]> Signed-off-by: Chris Mason <[email protected]>
1 parent 31b9655 commit 0f873ec

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

fs/btrfs/extent-tree.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2851,16 +2851,13 @@ static void delayed_ref_async_start(struct btrfs_work *work)
28512851

28522852
async = container_of(work, struct async_delayed_refs, work);
28532853

2854-
trans = btrfs_attach_transaction(async->root);
2855-
if (IS_ERR(trans)) {
2856-
if (PTR_ERR(trans) != -ENOENT)
2857-
async->error = PTR_ERR(trans);
2854+
/* if the commit is already started, we don't need to wait here */
2855+
if (btrfs_transaction_blocked(async->root->fs_info))
28582856
goto done;
2859-
}
28602857

2861-
/* Don't bother flushing if we got into a different transaction */
2862-
if (trans->transid != async->transid) {
2863-
btrfs_end_transaction(trans, async->root);
2858+
trans = btrfs_join_transaction(async->root);
2859+
if (IS_ERR(trans)) {
2860+
async->error = PTR_ERR(trans);
28642861
goto done;
28652862
}
28662863

@@ -2869,10 +2866,15 @@ static void delayed_ref_async_start(struct btrfs_work *work)
28692866
* wait on delayed refs
28702867
*/
28712868
trans->sync = true;
2869+
2870+
/* Don't bother flushing if we got into a different transaction */
2871+
if (trans->transid > async->transid)
2872+
goto end;
2873+
28722874
ret = btrfs_run_delayed_refs(trans, async->root, async->count);
28732875
if (ret)
28742876
async->error = ret;
2875-
2877+
end:
28762878
ret = btrfs_end_transaction(trans, async->root);
28772879
if (ret && !async->error)
28782880
async->error = ret;

0 commit comments

Comments
 (0)