Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 311182
b: refs/heads/master
c: 69bca40
h: refs/heads/master
v: v3
  • Loading branch information
Alexander Block authored and Chris Mason committed Jun 21, 2012
1 parent df23228 commit 4b0568b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 43 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1c8f52a5e9539600543347bcdefafa1854e07986
refs/heads/master: 69bca40d41c613927b150c5392505f1894fe3010
94 changes: 52 additions & 42 deletions trunk/fs/btrfs/backref.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,61 +179,74 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id,

static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
struct ulist *parents, int level,
struct btrfs_key *key, u64 time_seq,
struct btrfs_key *key_for_search, u64 time_seq,
u64 wanted_disk_byte,
const u64 *extent_item_pos)
{
int ret;
int slot = path->slots[level];
struct extent_buffer *eb = path->nodes[level];
int ret = 0;
int slot;
struct extent_buffer *eb;
struct btrfs_key key;
struct btrfs_file_extent_item *fi;
struct extent_inode_elem *eie = NULL;
u64 disk_byte;
u64 wanted_objectid = key->objectid;

add_parent:
if (level == 0 && extent_item_pos) {
fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
ret = check_extent_in_eb(key, eb, fi, *extent_item_pos, &eie);
if (level != 0) {
eb = path->nodes[level];
ret = ulist_add(parents, eb->start, 0, GFP_NOFS);
if (ret < 0)
return ret;
}
ret = ulist_add(parents, eb->start, (unsigned long)eie, GFP_NOFS);
if (ret < 0)
return ret;

if (level != 0)
return 0;
}

/*
* if the current leaf is full with EXTENT_DATA items, we must
* check the next one if that holds a reference as well.
* ref->count cannot be used to skip this check.
* repeat this until we don't find any additional EXTENT_DATA items.
* We normally enter this function with the path already pointing to
* the first item to check. But sometimes, we may enter it with
* slot==nritems. In that case, go to the next leaf before we continue.
*/
while (1) {
eie = NULL;
if (path->slots[0] >= btrfs_header_nritems(path->nodes[0]))
ret = btrfs_next_old_leaf(root, path, time_seq);
if (ret < 0)
return ret;
if (ret)
return 0;

while (!ret) {
eb = path->nodes[0];
for (slot = 0; slot < btrfs_header_nritems(eb); ++slot) {
btrfs_item_key_to_cpu(eb, key, slot);
if (key->objectid != wanted_objectid ||
key->type != BTRFS_EXTENT_DATA_KEY)
return 0;
fi = btrfs_item_ptr(eb, slot,
struct btrfs_file_extent_item);
disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
if (disk_byte == wanted_disk_byte)
goto add_parent;
slot = path->slots[0];

btrfs_item_key_to_cpu(eb, &key, slot);

if (key.objectid != key_for_search->objectid ||
key.type != BTRFS_EXTENT_DATA_KEY)
break;

fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);

if (disk_byte == wanted_disk_byte) {
eie = NULL;
if (extent_item_pos) {
ret = check_extent_in_eb(&key, eb, fi,
*extent_item_pos,
&eie);
if (ret < 0)
break;
}
if (!ret) {
ret = ulist_add(parents, eb->start,
(unsigned long)eie, GFP_NOFS);
if (ret < 0)
break;
if (!extent_item_pos) {
ret = btrfs_next_old_leaf(root, path,
time_seq);
continue;
}
}
}
ret = btrfs_next_old_item(root, path, time_seq);
}

return 0;
if (ret > 0)
ret = 0;
return ret;
}

/*
Expand All @@ -250,7 +263,6 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
struct btrfs_path *path;
struct btrfs_root *root;
struct btrfs_key root_key;
struct btrfs_key key = {0};
struct extent_buffer *eb;
int ret = 0;
int root_level;
Expand Down Expand Up @@ -295,11 +307,9 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
goto out;
}

if (level == 0)
btrfs_item_key_to_cpu(eb, &key, path->slots[0]);

ret = add_all_parents(root, path, parents, level, &key, time_seq,
ref->wanted_disk_byte, extent_item_pos);
ret = add_all_parents(root, path, parents, level, &ref->key_for_search,
time_seq, ref->wanted_disk_byte,
extent_item_pos);
out:
btrfs_free_path(path);
return ret;
Expand Down

0 comments on commit 4b0568b

Please sign in to comment.