| From b8d0c69b9469ffd33df30fee3e990f2d4aa68a09 Mon Sep 17 00:00:00 2001 |
| From: Josef Bacik <jbacik@fusionio.com> |
| Date: Thu, 22 Aug 2013 17:03:29 -0400 |
| Subject: Btrfs: remove ourselves from the cluster list under lock |
| |
| From: Josef Bacik <jbacik@fusionio.com> |
| |
| commit b8d0c69b9469ffd33df30fee3e990f2d4aa68a09 upstream. |
| |
| A user was reporting weird warnings from btrfs_put_delayed_ref() and I noticed |
| that we were doing this list_del_init() on our head ref outside of |
| delayed_refs->lock. This is a problem if we have people still on the list, we |
| could end up modifying old pointers and such. Fix this by removing us from the |
| list before we do our run_delayed_ref on our head ref. Thanks, |
| |
| Signed-off-by: Josef Bacik <jbacik@fusionio.com> |
| Signed-off-by: Chris Mason <chris.mason@fusionio.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/btrfs/extent-tree.c | 3 ++- |
| 1 file changed, 2 insertions(+), 1 deletion(-) |
| |
| --- a/fs/btrfs/extent-tree.c |
| +++ b/fs/btrfs/extent-tree.c |
| @@ -2402,6 +2402,8 @@ static noinline int run_clustered_refs(s |
| default: |
| WARN_ON(1); |
| } |
| + } else { |
| + list_del_init(&locked_ref->cluster); |
| } |
| spin_unlock(&delayed_refs->lock); |
| |
| @@ -2424,7 +2426,6 @@ static noinline int run_clustered_refs(s |
| * list before we release it. |
| */ |
| if (btrfs_delayed_ref_is_head(ref)) { |
| - list_del_init(&locked_ref->cluster); |
| btrfs_delayed_ref_unlock(locked_ref); |
| locked_ref = NULL; |
| } |