aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorWang Shilong <wangsl.fnst@cn.fujitsu.com>2014-01-28 06:13:38 -0500
committerChris Mason <clm@fb.com>2014-01-29 10:06:26 -0500
commitf05c474688762f186b16a26366755b6ef0bfed0c (patch)
treebc808f97ce526c8eaf80473ca5dd5de8a8fece8e /fs/btrfs
parentbf54f412f0624786ac8a115110b5203430a9eebb (diff)
Btrfs: fix memory leaks on walking backrefs failure
When walking backrefs, we may iterate every inode's extent and add/merge them into ulist, and the caller will free memory from ulist. However, if we fail to allocate inode's extents element memory or ulist_add() fail to allocate memory, we won't add allocated memory into ulist, and the caller won't free some allocated memory thus memory leaks happen. 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')
-rw-r--r--fs/btrfs/backref.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 7966acd5dc7f..aded3ef3d3d4 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -66,6 +66,16 @@ static int check_extent_in_eb(struct btrfs_key *key, struct extent_buffer *eb,
66 return 0; 66 return 0;
67} 67}
68 68
69static void free_inode_elem_list(struct extent_inode_elem *eie)
70{
71 struct extent_inode_elem *eie_next;
72
73 for (; eie; eie = eie_next) {
74 eie_next = eie->next;
75 kfree(eie);
76 }
77}
78
69static int find_extent_in_eb(struct extent_buffer *eb, u64 wanted_disk_byte, 79static int find_extent_in_eb(struct extent_buffer *eb, u64 wanted_disk_byte,
70 u64 extent_item_pos, 80 u64 extent_item_pos,
71 struct extent_inode_elem **eie) 81 struct extent_inode_elem **eie)
@@ -275,6 +285,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
275 old = old->next; 285 old = old->next;
276 old->next = eie; 286 old->next = eie;
277 } 287 }
288 eie = NULL;
278 } 289 }
279next: 290next:
280 ret = btrfs_next_old_item(root, path, time_seq); 291 ret = btrfs_next_old_item(root, path, time_seq);
@@ -282,6 +293,8 @@ next:
282 293
283 if (ret > 0) 294 if (ret > 0)
284 ret = 0; 295 ret = 0;
296 else if (ret < 0)
297 free_inode_elem_list(eie);
285 return ret; 298 return ret;
286} 299}
287 300
@@ -845,6 +858,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
845 struct list_head prefs_delayed; 858 struct list_head prefs_delayed;
846 struct list_head prefs; 859 struct list_head prefs;
847 struct __prelim_ref *ref; 860 struct __prelim_ref *ref;
861 struct extent_inode_elem *eie = NULL;
848 862
849 INIT_LIST_HEAD(&prefs); 863 INIT_LIST_HEAD(&prefs);
850 INIT_LIST_HEAD(&prefs_delayed); 864 INIT_LIST_HEAD(&prefs_delayed);
@@ -958,7 +972,6 @@ again:
958 goto out; 972 goto out;
959 } 973 }
960 if (ref->count && ref->parent) { 974 if (ref->count && ref->parent) {
961 struct extent_inode_elem *eie = NULL;
962 if (extent_item_pos && !ref->inode_list) { 975 if (extent_item_pos && !ref->inode_list) {
963 u32 bsz; 976 u32 bsz;
964 struct extent_buffer *eb; 977 struct extent_buffer *eb;
@@ -993,6 +1006,7 @@ again:
993 eie = eie->next; 1006 eie = eie->next;
994 eie->next = ref->inode_list; 1007 eie->next = ref->inode_list;
995 } 1008 }
1009 eie = NULL;
996 } 1010 }
997 list_del(&ref->list); 1011 list_del(&ref->list);
998 kmem_cache_free(btrfs_prelim_ref_cache, ref); 1012 kmem_cache_free(btrfs_prelim_ref_cache, ref);
@@ -1011,7 +1025,8 @@ out:
1011 list_del(&ref->list); 1025 list_del(&ref->list);
1012 kmem_cache_free(btrfs_prelim_ref_cache, ref); 1026 kmem_cache_free(btrfs_prelim_ref_cache, ref);
1013 } 1027 }
1014 1028 if (ret < 0)
1029 free_inode_elem_list(eie);
1015 return ret; 1030 return ret;
1016} 1031}
1017 1032
@@ -1019,7 +1034,6 @@ static void free_leaf_list(struct ulist *blocks)
1019{ 1034{
1020 struct ulist_node *node = NULL; 1035 struct ulist_node *node = NULL;
1021 struct extent_inode_elem *eie; 1036 struct extent_inode_elem *eie;
1022 struct extent_inode_elem *eie_next;
1023 struct ulist_iterator uiter; 1037 struct ulist_iterator uiter;
1024 1038
1025 ULIST_ITER_INIT(&uiter); 1039 ULIST_ITER_INIT(&uiter);
@@ -1027,10 +1041,7 @@ static void free_leaf_list(struct ulist *blocks)
1027 if (!node->aux) 1041 if (!node->aux)
1028 continue; 1042 continue;
1029 eie = (struct extent_inode_elem *)(uintptr_t)node->aux; 1043 eie = (struct extent_inode_elem *)(uintptr_t)node->aux;
1030 for (; eie; eie = eie_next) { 1044 free_inode_elem_list(eie);
1031 eie_next = eie->next;
1032 kfree(eie);
1033 }
1034 node->aux = 0; 1045 node->aux = 0;
1035 } 1046 }
1036 1047