diff options
| -rw-r--r-- | fs/btrfs/backref.c | 25 |
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 | ||
| 69 | static 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 | |||
| 69 | static int find_extent_in_eb(struct extent_buffer *eb, u64 wanted_disk_byte, | 79 | static 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 | } |
| 279 | next: | 290 | next: |
| 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 | ||
