Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 309923
b: refs/heads/master
c: 3301958
h: refs/heads/master
i:
  309921: 74a0508
  309919: 56a42e7
v: v3
  • Loading branch information
Jan Schmidt committed May 31, 2012
1 parent 2ec055f commit bdf7f2f
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 7 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: 95a06077f7edbd00d32612562be4d857a5b7df54
refs/heads/master: 3301958b7c1dae8f0f5ded63aa881e0b71e78464
36 changes: 31 additions & 5 deletions trunk/fs/btrfs/backref.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ struct __prelim_ref {
struct btrfs_key key_for_search;
int level;
int count;
struct extent_inode_elem *inode_list;
u64 parent;
u64 wanted_disk_byte;
};
Expand Down Expand Up @@ -166,6 +167,7 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id,
else
memset(&ref->key_for_search, 0, sizeof(ref->key_for_search));

ref->inode_list = NULL;
ref->level = level;
ref->count = count;
ref->parent = parent;
Expand All @@ -181,14 +183,21 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
const u64 *extent_item_pos)
{
int ret;
int slot;
int slot = path->slots[level];
struct extent_buffer *eb = path->nodes[level];
struct btrfs_file_extent_item *fi;
struct extent_inode_elem *eie = NULL;
u64 disk_byte;
u64 wanted_objectid = key->objectid;

add_parent:
ret = ulist_add(parents, eb->start, 0, GFP_NOFS);
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 (ret < 0)
return ret;
}
ret = ulist_add(parents, eb->start, (unsigned long)eie, GFP_NOFS);
if (ret < 0)
return ret;

Expand All @@ -202,6 +211,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
* repeat this until we don't find any additional EXTENT_DATA items.
*/
while (1) {
eie = NULL;
ret = btrfs_next_leaf(root, path);
if (ret < 0)
return ret;
Expand Down Expand Up @@ -346,6 +356,8 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
ULIST_ITER_INIT(&uiter);
node = ulist_next(parents, &uiter);
ref->parent = node ? node->val : 0;
ref->inode_list =
node ? (struct extent_inode_elem *)node->aux : 0;

/* additional parents require new refs being added here */
while ((node = ulist_next(parents, &uiter))) {
Expand All @@ -356,6 +368,8 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
}
memcpy(new_ref, ref, sizeof(*ref));
new_ref->parent = node->val;
new_ref->inode_list =
(struct extent_inode_elem *)node->aux;
list_add(&new_ref->list, &ref->list);
}
ulist_reinit(parents);
Expand Down Expand Up @@ -879,7 +893,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
}
if (ref->count && ref->parent) {
struct extent_inode_elem *eie = NULL;
if (extent_item_pos) {
if (extent_item_pos && !ref->inode_list) {
u32 bsz;
struct extent_buffer *eb;
bsz = btrfs_level_size(fs_info->extent_root,
Expand All @@ -889,10 +903,22 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
BUG_ON(!eb);
ret = find_extent_in_eb(eb, bytenr,
*extent_item_pos, &eie);
ref->inode_list = eie;
free_extent_buffer(eb);
}
ret = ulist_add(refs, ref->parent,
(unsigned long)eie, GFP_NOFS);
ret = ulist_add_merge(refs, ref->parent,
(unsigned long)ref->inode_list,
(unsigned long *)&eie, GFP_NOFS);
if (!ret && extent_item_pos) {
/*
* we've recorded that parent, so we must extend
* its inode list here
*/
BUG_ON(!eie);
while (eie->next)
eie = eie->next;
eie->next = ref->inode_list;
}
BUG_ON(ret < 0);
}
kfree(ref);
Expand Down
11 changes: 10 additions & 1 deletion trunk/fs/btrfs/ulist.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,21 @@ EXPORT_SYMBOL(ulist_free);
*/
int ulist_add(struct ulist *ulist, u64 val, unsigned long aux,
unsigned long gfp_mask)
{
return ulist_add_merge(ulist, val, aux, NULL, gfp_mask);
}

int ulist_add_merge(struct ulist *ulist, u64 val, unsigned long aux,
unsigned long *old_aux, unsigned long gfp_mask)
{
int i;

for (i = 0; i < ulist->nnodes; ++i) {
if (ulist->nodes[i].val == val)
if (ulist->nodes[i].val == val) {
if (old_aux)
*old_aux = ulist->nodes[i].aux;
return 0;
}
}

if (ulist->nnodes >= ulist->nodes_alloced) {
Expand Down
2 changes: 2 additions & 0 deletions trunk/fs/btrfs/ulist.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ struct ulist *ulist_alloc(unsigned long gfp_mask);
void ulist_free(struct ulist *ulist);
int ulist_add(struct ulist *ulist, u64 val, unsigned long aux,
unsigned long gfp_mask);
int ulist_add_merge(struct ulist *ulist, u64 val, unsigned long aux,
unsigned long *old_aux, unsigned long gfp_mask);
struct ulist_node *ulist_next(struct ulist *ulist,
struct ulist_iterator *uiter);

Expand Down

0 comments on commit bdf7f2f

Please sign in to comment.