diff options
author | Geyslan G. Bem <geyslan@gmail.com> | 2013-10-11 14:35:45 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-11-11 22:00:11 -0500 |
commit | 03b2f08b5f96db5d07dba54ae008e9fdf1396e05 (patch) | |
tree | 36d9e492b02fc0f6debab21632a021e26206db01 /fs | |
parent | 498456d33e2ee5150f045e604e4531b088083e7a (diff) |
btrfs: Fix memory leakage in the tree-log.c
In add_inode_ref() function:
Initializes local pointers.
Reduces the logical condition with the __add_inode_ref() return
value by using only one 'goto out'.
Centralizes the exiting, ensuring the freeing of all used memory.
Signed-off-by: Geyslan G. Bem <geyslan@gmail.com>
Reviewed-by: Stefan Behrens <sbehrens@giantdisaster.de>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/tree-log.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index f2e0531dc719..d12696db9ada 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -1113,11 +1113,11 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, | |||
1113 | struct extent_buffer *eb, int slot, | 1113 | struct extent_buffer *eb, int slot, |
1114 | struct btrfs_key *key) | 1114 | struct btrfs_key *key) |
1115 | { | 1115 | { |
1116 | struct inode *dir; | 1116 | struct inode *dir = NULL; |
1117 | struct inode *inode; | 1117 | struct inode *inode = NULL; |
1118 | unsigned long ref_ptr; | 1118 | unsigned long ref_ptr; |
1119 | unsigned long ref_end; | 1119 | unsigned long ref_end; |
1120 | char *name; | 1120 | char *name = NULL; |
1121 | int namelen; | 1121 | int namelen; |
1122 | int ret; | 1122 | int ret; |
1123 | int search_done = 0; | 1123 | int search_done = 0; |
@@ -1150,13 +1150,15 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, | |||
1150 | * care of the rest | 1150 | * care of the rest |
1151 | */ | 1151 | */ |
1152 | dir = read_one_inode(root, parent_objectid); | 1152 | dir = read_one_inode(root, parent_objectid); |
1153 | if (!dir) | 1153 | if (!dir) { |
1154 | return -ENOENT; | 1154 | ret = -ENOENT; |
1155 | goto out; | ||
1156 | } | ||
1155 | 1157 | ||
1156 | inode = read_one_inode(root, inode_objectid); | 1158 | inode = read_one_inode(root, inode_objectid); |
1157 | if (!inode) { | 1159 | if (!inode) { |
1158 | iput(dir); | 1160 | ret = -EIO; |
1159 | return -EIO; | 1161 | goto out; |
1160 | } | 1162 | } |
1161 | 1163 | ||
1162 | while (ref_ptr < ref_end) { | 1164 | while (ref_ptr < ref_end) { |
@@ -1169,14 +1171,16 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, | |||
1169 | */ | 1171 | */ |
1170 | if (!dir) | 1172 | if (!dir) |
1171 | dir = read_one_inode(root, parent_objectid); | 1173 | dir = read_one_inode(root, parent_objectid); |
1172 | if (!dir) | 1174 | if (!dir) { |
1173 | return -ENOENT; | 1175 | ret = -ENOENT; |
1176 | goto out; | ||
1177 | } | ||
1174 | } else { | 1178 | } else { |
1175 | ret = ref_get_fields(eb, ref_ptr, &namelen, &name, | 1179 | ret = ref_get_fields(eb, ref_ptr, &namelen, &name, |
1176 | &ref_index); | 1180 | &ref_index); |
1177 | } | 1181 | } |
1178 | if (ret) | 1182 | if (ret) |
1179 | return ret; | 1183 | goto out; |
1180 | 1184 | ||
1181 | /* if we already have a perfect match, we're done */ | 1185 | /* if we already have a perfect match, we're done */ |
1182 | if (!inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode), | 1186 | if (!inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode), |
@@ -1196,12 +1200,11 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, | |||
1196 | parent_objectid, | 1200 | parent_objectid, |
1197 | ref_index, name, namelen, | 1201 | ref_index, name, namelen, |
1198 | &search_done); | 1202 | &search_done); |
1199 | if (ret == 1) { | 1203 | if (ret) { |
1200 | ret = 0; | 1204 | if (ret == 1) |
1205 | ret = 0; | ||
1201 | goto out; | 1206 | goto out; |
1202 | } | 1207 | } |
1203 | if (ret) | ||
1204 | goto out; | ||
1205 | } | 1208 | } |
1206 | 1209 | ||
1207 | /* insert our name */ | 1210 | /* insert our name */ |
@@ -1215,6 +1218,7 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, | |||
1215 | 1218 | ||
1216 | ref_ptr = (unsigned long)(ref_ptr + ref_struct_size) + namelen; | 1219 | ref_ptr = (unsigned long)(ref_ptr + ref_struct_size) + namelen; |
1217 | kfree(name); | 1220 | kfree(name); |
1221 | name = NULL; | ||
1218 | if (log_ref_ver) { | 1222 | if (log_ref_ver) { |
1219 | iput(dir); | 1223 | iput(dir); |
1220 | dir = NULL; | 1224 | dir = NULL; |
@@ -1225,6 +1229,7 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, | |||
1225 | ret = overwrite_item(trans, root, path, eb, slot, key); | 1229 | ret = overwrite_item(trans, root, path, eb, slot, key); |
1226 | out: | 1230 | out: |
1227 | btrfs_release_path(path); | 1231 | btrfs_release_path(path); |
1232 | kfree(name); | ||
1228 | iput(dir); | 1233 | iput(dir); |
1229 | iput(inode); | 1234 | iput(inode); |
1230 | return ret; | 1235 | return ret; |