aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2013-07-05 14:03:47 -0400
committerChris Mason <chris.mason@fusionio.com>2013-08-09 19:30:03 -0400
commited8c4913da4951957bf8afc788522788881ff405 (patch)
treeff74a55f70c45d2f00255b4f2d43996cf1ca35d0
parent8ca15e05e6ac2745725d2d62394cfbe4ac335e84 (diff)
Btrfs: make sure the backref walker catches all refs to our extent
Because we don't mess with the offset into the extent for compressed we will properly find both extents for this case [extent a][extent b][rest of extent a] but because we already added a ref for the front half we won't add the inode information for the second half. This causes us to leak that memory and not print out the other offset when we do logical-resolve. So fix this by calling ulist_add_merge and then add our eie to the existing entry if there is one. With this patch we get both offsets out of logical-resolve. With this and the other 2 patches I've sent we now pass btrfs/276 on my vm with compress-force=lzo set. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
-rw-r--r--fs/btrfs/backref.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 30dbe1c61857..8bc5e8ccb091 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -196,7 +196,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
196 struct extent_buffer *eb; 196 struct extent_buffer *eb;
197 struct btrfs_key key; 197 struct btrfs_key key;
198 struct btrfs_file_extent_item *fi; 198 struct btrfs_file_extent_item *fi;
199 struct extent_inode_elem *eie = NULL; 199 struct extent_inode_elem *eie = NULL, *old = NULL;
200 u64 disk_byte; 200 u64 disk_byte;
201 201
202 if (level != 0) { 202 if (level != 0) {
@@ -230,6 +230,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
230 230
231 if (disk_byte == wanted_disk_byte) { 231 if (disk_byte == wanted_disk_byte) {
232 eie = NULL; 232 eie = NULL;
233 old = NULL;
233 if (extent_item_pos) { 234 if (extent_item_pos) {
234 ret = check_extent_in_eb(&key, eb, fi, 235 ret = check_extent_in_eb(&key, eb, fi,
235 *extent_item_pos, 236 *extent_item_pos,
@@ -237,18 +238,20 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
237 if (ret < 0) 238 if (ret < 0)
238 break; 239 break;
239 } 240 }
240 if (!ret) { 241 if (ret > 0)
241 ret = ulist_add(parents, eb->start, 242 goto next;
242 (uintptr_t)eie, GFP_NOFS); 243 ret = ulist_add_merge(parents, eb->start,
243 if (ret < 0) 244 (uintptr_t)eie,
244 break; 245 (u64 *)&old, GFP_NOFS);
245 if (!extent_item_pos) { 246 if (ret < 0)
246 ret = btrfs_next_old_leaf(root, path, 247 break;
247 time_seq); 248 if (!ret && extent_item_pos) {
248 continue; 249 while (old->next)
249 } 250 old = old->next;
251 old->next = eie;
250 } 252 }
251 } 253 }
254next:
252 ret = btrfs_next_old_item(root, path, time_seq); 255 ret = btrfs_next_old_item(root, path, time_seq);
253 } 256 }
254 257