| From fae7f06f926ca4163414cad08a187b4de4e140e5 Mon Sep 17 00:00:00 2001 |
| From: Chris Mason <chris.mason@fusionio.com> |
| Date: Wed, 25 Jul 2012 15:57:13 -0400 |
| Subject: [PATCH] Btrfs: call the ordered free operation without any locks held |
| |
| commit e9fbcb42201c862fd6ab45c48ead4f47bb2dea9d upstream. |
| |
| Each ordered operation has a free callback, and this was called with the |
| worker spinlock held. Josef made the free callback also call iput, |
| which we can't do with the spinlock. |
| |
| This drops the spinlock for the free operation and grabs it again before |
| moving through the rest of the list. We'll circle back around to this |
| and find a cleaner way that doesn't bounce the lock around so much. |
| |
| Signed-off-by: Chris Mason <chris.mason@fusionio.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| --- |
| fs/btrfs/async-thread.c | 9 ++++++++- |
| 1 file changed, 8 insertions(+), 1 deletion(-) |
| |
| diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c |
| index 462859a30141..474d1b82e38c 100644 |
| --- a/fs/btrfs/async-thread.c |
| +++ b/fs/btrfs/async-thread.c |
| @@ -212,10 +212,17 @@ static noinline int run_ordered_completions(struct btrfs_workers *workers, |
| |
| work->ordered_func(work); |
| |
| - /* now take the lock again and call the freeing code */ |
| + /* now take the lock again and drop our item from the list */ |
| spin_lock(&workers->order_lock); |
| list_del(&work->order_list); |
| + spin_unlock(&workers->order_lock); |
| + |
| + /* |
| + * we don't want to call the ordered free functions |
| + * with the lock held though |
| + */ |
| work->ordered_free(work); |
| + spin_lock(&workers->order_lock); |
| } |
| |
| spin_unlock(&workers->order_lock); |
| -- |
| 1.8.5.2 |
| |