Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 128982
b: refs/heads/master
c: f82d02d
h: refs/heads/master
v: v3
  • Loading branch information
Yan Zheng authored and Chris Mason committed Oct 29, 2008
1 parent acb1ba4 commit e1122c1
Show file tree
Hide file tree
Showing 6 changed files with 278 additions and 200 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: c8b978188c9a0fd3d535c13debd19d522b726f1f
refs/heads/master: f82d02d9d8222183b7945e893111a6d1bf67ae4a
93 changes: 47 additions & 46 deletions trunk/fs/btrfs/ctree.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ int noinline __btrfs_cow_block(struct btrfs_trans_handle *trans,
/*
* There are only two places that can drop reference to
* tree blocks owned by living reloc trees, one is here,
* the other place is btrfs_merge_path. In both places,
* the other place is btrfs_drop_subtree. In both places,
* we check reference count while tree block is locked.
* Furthermore, if reference count is one, it won't get
* increased by someone else.
Expand All @@ -312,9 +312,6 @@ int noinline __btrfs_cow_block(struct btrfs_trans_handle *trans,
}

if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) {
ret = btrfs_add_reloc_mapping(root, buf->start,
buf->len, cow->start);
BUG_ON(ret);
ret = btrfs_reloc_tree_cache_ref(trans, root, cow, buf->start);
WARN_ON(ret);
}
Expand Down Expand Up @@ -1627,61 +1624,57 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans,
btrfs_node_key_to_cpu(eb, &key, slot);
key_match = !memcmp(&key, &node_keys[level - 1], sizeof(key));

if (generation == trans->transid) {
eb = read_tree_block(root, bytenr, blocksize,
generation);
btrfs_tree_lock(eb);
}

/*
* if node keys match and node pointer hasn't been modified
* in the running transaction, we can merge the path. for
* reloc trees, the node pointer check is skipped, this is
* because the reloc trees are fully controlled by the space
* balance code, no one else can modify them.
* blocks owened by reloc trees, the node pointer check is
* skipped, this is because these blocks are fully controlled
* by the space balance code, no one else can modify them.
*/
if (!nodes[level - 1] || !key_match ||
(generation == trans->transid &&
root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID)) {
next_level:
if (level == 1 || level == lowest_level + 1)
btrfs_header_owner(eb) != BTRFS_TREE_RELOC_OBJECTID)) {
if (level == 1 || level == lowest_level + 1) {
if (generation == trans->transid) {
btrfs_tree_unlock(eb);
free_extent_buffer(eb);
}
break;
}

eb = read_tree_block(root, bytenr, blocksize,
generation);
btrfs_tree_lock(eb);
if (generation != trans->transid) {
eb = read_tree_block(root, bytenr, blocksize,
generation);
btrfs_tree_lock(eb);
}

ret = btrfs_cow_block(trans, root, eb, parent, slot,
&eb, 0);
BUG_ON(ret);

if (root->root_key.objectid ==
BTRFS_TREE_RELOC_OBJECTID) {
if (!nodes[level - 1]) {
nodes[level - 1] = eb->start;
memcpy(&node_keys[level - 1], &key,
sizeof(node_keys[0]));
} else {
WARN_ON(1);
}
}

btrfs_tree_unlock(parent);
free_extent_buffer(parent);
parent = eb;
continue;
}

if (generation == trans->transid) {
u32 refs;
BUG_ON(btrfs_header_owner(eb) !=
BTRFS_TREE_RELOC_OBJECTID);
/*
* lock the block to keep __btrfs_cow_block from
* changing the reference count.
*/
eb = read_tree_block(root, bytenr, blocksize,
generation);
btrfs_tree_lock(eb);

ret = btrfs_lookup_extent_ref(trans, root, bytenr,
blocksize, &refs);
BUG_ON(ret);
/*
* if replace block whose reference count is one,
* we have to "drop the subtree". so skip it for
* simplicity
*/
if (refs == 1) {
btrfs_tree_unlock(eb);
free_extent_buffer(eb);
goto next_level;
}
}

btrfs_set_node_blockptr(parent, slot, nodes[level - 1]);
btrfs_set_node_ptr_generation(parent, slot, trans->transid);
btrfs_mark_buffer_dirty(parent);
Expand All @@ -1693,16 +1686,24 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans,
btrfs_header_generation(parent),
level - 1);
BUG_ON(ret);
ret = btrfs_free_extent(trans, root, bytenr,
blocksize, parent->start,
btrfs_header_owner(parent),
btrfs_header_generation(parent),
level - 1, 1);
BUG_ON(ret);

/*
* If the block was created in the running transaction,
* it's possible this is the last reference to it, so we
* should drop the subtree.
*/
if (generation == trans->transid) {
ret = btrfs_drop_subtree(trans, root, eb, parent);
BUG_ON(ret);
btrfs_tree_unlock(eb);
free_extent_buffer(eb);
} else {
ret = btrfs_free_extent(trans, root, bytenr,
blocksize, parent->start,
btrfs_header_owner(parent),
btrfs_header_generation(parent),
level - 1, 1);
BUG_ON(ret);
}
break;
}
Expand Down
13 changes: 6 additions & 7 deletions trunk/fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,6 @@ struct btrfs_fs_info {
int thread_pool_size;

/* tree relocation relocated fields */
struct extent_io_tree reloc_mapping_tree;
struct list_head dead_reloc_roots;
struct btrfs_leaf_ref_tree reloc_ref_tree;
struct btrfs_leaf_ref_tree shared_ref_tree;
Expand Down Expand Up @@ -1636,13 +1635,9 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 group_start);
int btrfs_relocate_block_group(struct btrfs_root *root, u64 group_start);
int btrfs_free_reloc_root(struct btrfs_root *root);
int btrfs_free_reloc_root(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
int btrfs_drop_dead_reloc_roots(struct btrfs_root *root);
int btrfs_add_reloc_mapping(struct btrfs_root *root, u64 orig_bytenr,
u64 num_bytes, u64 new_bytenr);
int btrfs_get_reloc_mapping(struct btrfs_root *root, u64 orig_bytenr,
u64 num_bytes, u64 *new_bytenr);
void btrfs_free_reloc_mappings(struct btrfs_root *root);
int btrfs_reloc_tree_cache_ref(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct extent_buffer *buf, u64 orig_start);
Expand Down Expand Up @@ -1726,6 +1721,10 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path);
int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf);
int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
*root);
int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct extent_buffer *node,
struct extent_buffer *parent);
/* root-item.c */
int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct btrfs_key *key);
Expand Down
2 changes: 0 additions & 2 deletions trunk/fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1448,8 +1448,6 @@ struct btrfs_root *open_ctree(struct super_block *sb,
fs_info->btree_inode->i_mapping, GFP_NOFS);
fs_info->do_barriers = 1;

extent_io_tree_init(&fs_info->reloc_mapping_tree,
fs_info->btree_inode->i_mapping, GFP_NOFS);
INIT_LIST_HEAD(&fs_info->dead_reloc_roots);
btrfs_leaf_ref_tree_init(&fs_info->reloc_ref_tree);
btrfs_leaf_ref_tree_init(&fs_info->shared_ref_tree);
Expand Down
Loading

0 comments on commit e1122c1

Please sign in to comment.