aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/backref.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/backref.c')
-rw-r--r--fs/btrfs/backref.c48
1 files changed, 29 insertions, 19 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index eaf133384a8f..8bc5e8ccb091 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -36,16 +36,23 @@ static int check_extent_in_eb(struct btrfs_key *key, struct extent_buffer *eb,
36 u64 extent_item_pos, 36 u64 extent_item_pos,
37 struct extent_inode_elem **eie) 37 struct extent_inode_elem **eie)
38{ 38{
39 u64 data_offset; 39 u64 offset = 0;
40 u64 data_len;
41 struct extent_inode_elem *e; 40 struct extent_inode_elem *e;
42 41
43 data_offset = btrfs_file_extent_offset(eb, fi); 42 if (!btrfs_file_extent_compression(eb, fi) &&
44 data_len = btrfs_file_extent_num_bytes(eb, fi); 43 !btrfs_file_extent_encryption(eb, fi) &&
44 !btrfs_file_extent_other_encoding(eb, fi)) {
45 u64 data_offset;
46 u64 data_len;
45 47
46 if (extent_item_pos < data_offset || 48 data_offset = btrfs_file_extent_offset(eb, fi);
47 extent_item_pos >= data_offset + data_len) 49 data_len = btrfs_file_extent_num_bytes(eb, fi);
48 return 1; 50
51 if (extent_item_pos < data_offset ||
52 extent_item_pos >= data_offset + data_len)
53 return 1;
54 offset = extent_item_pos - data_offset;
55 }
49 56
50 e = kmalloc(sizeof(*e), GFP_NOFS); 57 e = kmalloc(sizeof(*e), GFP_NOFS);
51 if (!e) 58 if (!e)
@@ -53,7 +60,7 @@ static int check_extent_in_eb(struct btrfs_key *key, struct extent_buffer *eb,
53 60
54 e->next = *eie; 61 e->next = *eie;
55 e->inum = key->objectid; 62 e->inum = key->objectid;
56 e->offset = key->offset + (extent_item_pos - data_offset); 63 e->offset = key->offset + offset;
57 *eie = e; 64 *eie = e;
58 65
59 return 0; 66 return 0;
@@ -189,7 +196,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
189 struct extent_buffer *eb; 196 struct extent_buffer *eb;
190 struct btrfs_key key; 197 struct btrfs_key key;
191 struct btrfs_file_extent_item *fi; 198 struct btrfs_file_extent_item *fi;
192 struct extent_inode_elem *eie = NULL; 199 struct extent_inode_elem *eie = NULL, *old = NULL;
193 u64 disk_byte; 200 u64 disk_byte;
194 201
195 if (level != 0) { 202 if (level != 0) {
@@ -223,6 +230,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
223 230
224 if (disk_byte == wanted_disk_byte) { 231 if (disk_byte == wanted_disk_byte) {
225 eie = NULL; 232 eie = NULL;
233 old = NULL;
226 if (extent_item_pos) { 234 if (extent_item_pos) {
227 ret = check_extent_in_eb(&key, eb, fi, 235 ret = check_extent_in_eb(&key, eb, fi,
228 *extent_item_pos, 236 *extent_item_pos,
@@ -230,18 +238,20 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
230 if (ret < 0) 238 if (ret < 0)
231 break; 239 break;
232 } 240 }
233 if (!ret) { 241 if (ret > 0)
234 ret = ulist_add(parents, eb->start, 242 goto next;
235 (uintptr_t)eie, GFP_NOFS); 243 ret = ulist_add_merge(parents, eb->start,
236 if (ret < 0) 244 (uintptr_t)eie,
237 break; 245 (u64 *)&old, GFP_NOFS);
238 if (!extent_item_pos) { 246 if (ret < 0)
239 ret = btrfs_next_old_leaf(root, path, 247 break;
240 time_seq); 248 if (!ret && extent_item_pos) {
241 continue; 249 while (old->next)
242 } 250 old = old->next;
251 old->next = eie;
243 } 252 }
244 } 253 }
254next:
245 ret = btrfs_next_old_item(root, path, time_seq); 255 ret = btrfs_next_old_item(root, path, time_seq);
246 } 256 }
247 257