summaryrefslogtreecommitdiff
path: root/fs/btrfs/relocation.c
diff options
context:
space:
mode:
authorWang Shilong <wangsl.fnst@cn.fujitsu.com>2013-12-26 05:10:50 (GMT)
committerChris Mason <clm@fb.com>2014-01-28 21:20:13 (GMT)
commit25e293c2a2916b58cdafb8219c0e93d6277762d7 (patch)
tree1b7863325fbc937cc13c6439824a7d1b80537ea0 /fs/btrfs/relocation.c
parentdc4103f933291cb1a2e6742c4db432e6ed337bae (diff)
downloadlinux-25e293c2a2916b58cdafb8219c0e93d6277762d7.tar.xz
Btrfs: fix an oops when we fail to merge reloc roots
Previously, we will free reloc root memory and then force filesystem to be readonly. The problem is that there may be another thread commiting transaction which will try to access freed reloc root during merging reloc roots process. To keep consistency snapshots shared space, we should allow snapshot finished if possible, so here we don't free reloc root memory. signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com> Signed-off-by: Josef Bacik <jbacik@fb.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/relocation.c')
-rw-r--r--fs/btrfs/relocation.c10
1 files changed, 3 insertions, 7 deletions
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 277b8e3..9189f9e 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -2311,9 +2311,6 @@ void free_reloc_roots(struct list_head *list)
reloc_root = list_entry(list->next, struct btrfs_root,
root_list);
__del_reloc_root(reloc_root);
- free_extent_buffer(reloc_root->node);
- free_extent_buffer(reloc_root->commit_root);
- kfree(reloc_root);
}
}
@@ -2355,10 +2352,9 @@ again:
ret = merge_reloc_root(rc, root);
if (ret) {
- __del_reloc_root(reloc_root);
- free_extent_buffer(reloc_root->node);
- free_extent_buffer(reloc_root->commit_root);
- kfree(reloc_root);
+ if (list_empty(&reloc_root->root_list))
+ list_add_tail(&reloc_root->root_list,
+ &reloc_roots);
goto out;
}
} else {