Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 128860
b: refs/heads/master
c: 017e536
h: refs/heads/master
v: v3
  • Loading branch information
Chris Mason committed Sep 25, 2008
1 parent b85181d commit 675d2ba
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 110 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: 31153d81284934601d08110ac7698fd9a535e4c0
refs/heads/master: 017e5369eb353559d68a11d4a718faa634533821
11 changes: 10 additions & 1 deletion trunk/fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,6 @@ struct btrfs_fs_info {

spinlock_t ref_cache_lock;
u64 total_ref_cache_size;
u64 running_ref_cache_size;

u64 avail_data_alloc_bits;
u64 avail_metadata_alloc_bits;
Expand All @@ -606,10 +605,18 @@ struct btrfs_fs_info {
void *bdev_holder;
};

struct btrfs_leaf_ref_tree {
struct rb_root root;
struct btrfs_leaf_ref *last;
struct list_head list;
spinlock_t lock;
};

/*
* in ram representation of the tree. extent_root is used for all allocations
* and for the extent tree extent_root root.
*/
struct dirty_root;
struct btrfs_root {
struct extent_buffer *node;

Expand All @@ -618,6 +625,8 @@ struct btrfs_root {

struct extent_buffer *commit_root;
struct btrfs_leaf_ref_tree *ref_tree;
struct btrfs_leaf_ref_tree ref_tree_struct;
struct dirty_root *dirty_root;

struct btrfs_root_item root_item;
struct btrfs_key root_key;
Expand Down
8 changes: 5 additions & 3 deletions trunk/fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "print-tree.h"
#include "async-thread.h"
#include "locking.h"
#include "ref-cache.h"

#if 0
static int check_tree_block(struct btrfs_root *root, struct extent_buffer *buf)
Expand Down Expand Up @@ -737,6 +738,10 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
spin_lock_init(&root->node_lock);
spin_lock_init(&root->orphan_lock);
mutex_init(&root->objectid_mutex);

btrfs_leaf_ref_tree_init(&root->ref_tree_struct);
root->ref_tree = &root->ref_tree_struct;

memset(&root->root_key, 0, sizeof(root->root_key));
memset(&root->root_item, 0, sizeof(root->root_item));
memset(&root->defrag_progress, 0, sizeof(root->defrag_progress));
Expand Down Expand Up @@ -1176,9 +1181,6 @@ static int transaction_kthread(void *arg)
goto sleep;
}

printk("btrfs: running reference cache size %Lu\n",
root->fs_info->running_ref_cache_size);

now = get_seconds();
if (now < cur->start_time || now - cur->start_time < 30) {
mutex_unlock(&root->fs_info->trans_mutex);
Expand Down
18 changes: 6 additions & 12 deletions trunk/fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -1004,8 +1004,6 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
goto out;
}

btrfs_item_key_to_cpu(buf, &ref->key, 0);

ref->bytenr = buf->start;
ref->owner = btrfs_header_owner(buf);
ref->generation = btrfs_header_generation(buf);
Expand Down Expand Up @@ -2387,19 +2385,15 @@ static void noinline reada_walk_down(struct btrfs_root *root,
}
}

/*
* we want to avoid as much random IO as we can with the alloc mutex
* held, so drop the lock and do the lookup, then do it again with the
* lock held.
*/
int drop_snap_lookup_refcount(struct btrfs_root *root, u64 start, u64 len,
u32 *refs)
{
int ret;
mutex_unlock(&root->fs_info->alloc_mutex);
lookup_extent_ref(NULL, root, start, len, refs);
ret = lookup_extent_ref(NULL, root, start, len, refs);
cond_resched();
mutex_lock(&root->fs_info->alloc_mutex);
return lookup_extent_ref(NULL, root, start, len, refs);
return ret;
}

/*
Expand Down Expand Up @@ -2468,11 +2462,11 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
BUG_ON(ret);
continue;
}

if (*level == 1) {
struct btrfs_key key;
btrfs_node_key_to_cpu(cur, &key, path->slots[*level]);
ref = btrfs_lookup_leaf_ref(root, &key);
ref = btrfs_lookup_leaf_ref(root, bytenr);
if (ref) {
ret = drop_leaf_ref(trans, root, ref);
BUG_ON(ret);
Expand All @@ -2482,7 +2476,6 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
break;
}
}

next = btrfs_find_tree_block(root, bytenr, blocksize);
if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) {
free_extent_buffer(next);
Expand Down Expand Up @@ -2672,6 +2665,7 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
ret = -EAGAIN;
break;
}
wake_up(&root->fs_info->transaction_throttle);
}
for (i = 0; i <= orig_level; i++) {
if (path->nodes[i]) {
Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/btrfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ static int noinline dirty_and_release_pages(struct btrfs_trans_handle *trans,
btrfs_update_inode(trans, root, inode);
}
failed:
err = btrfs_end_transaction_throttle(trans, root);
err = btrfs_end_transaction(trans, root);
out_unlock:
unlock_extent(io_tree, start_pos, end_of_last_block, GFP_NOFS);
return err;
Expand Down
8 changes: 4 additions & 4 deletions trunk/fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -2482,7 +2482,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
btrfs_update_inode_block_group(trans, dir);
out_unlock:
nr = trans->blocks_used;
btrfs_end_transaction_throttle(trans, root);
btrfs_end_transaction(trans, root);
fail:
if (drop_inode) {
inode_dec_link_count(inode);
Expand Down Expand Up @@ -2535,7 +2535,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
drop_inode = 1;

nr = trans->blocks_used;
btrfs_end_transaction_throttle(trans, root);
btrfs_end_transaction(trans, root);
fail:
if (drop_inode) {
inode_dec_link_count(inode);
Expand Down Expand Up @@ -2609,7 +2609,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)

out_fail:
nr = trans->blocks_used;
btrfs_end_transaction_throttle(trans, root);
btrfs_end_transaction(trans, root);

out_unlock:
if (drop_on_err)
Expand Down Expand Up @@ -3548,7 +3548,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,

out_unlock:
nr = trans->blocks_used;
btrfs_end_transaction_throttle(trans, root);
btrfs_end_transaction(trans, root);
out_fail:
if (drop_inode) {
inode_dec_link_count(inode);
Expand Down
71 changes: 15 additions & 56 deletions trunk/fs/btrfs/ref-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct btrfs_leaf_ref *btrfs_alloc_leaf_ref(int nr_extents)
if (ref) {
memset(ref, 0, sizeof(*ref));
atomic_set(&ref->usage, 1);
INIT_LIST_HEAD(&ref->list);
}
return ref;
}
Expand All @@ -44,40 +45,21 @@ void btrfs_free_leaf_ref(struct btrfs_leaf_ref *ref)
}
}

static int comp_keys(struct btrfs_key *k1, struct btrfs_key *k2)
{
if (k1->objectid > k2->objectid)
return 1;
if (k1->objectid < k2->objectid)
return -1;
if (k1->type > k2->type)
return 1;
if (k1->type < k2->type)
return -1;
if (k1->offset > k2->offset)
return 1;
if (k1->offset < k2->offset)
return -1;
return 0;
}

static struct rb_node *tree_insert(struct rb_root *root, struct btrfs_key *key,
static struct rb_node *tree_insert(struct rb_root *root, u64 bytenr,
struct rb_node *node)
{
struct rb_node ** p = &root->rb_node;
struct rb_node * parent = NULL;
struct btrfs_leaf_ref *entry;
int ret;

while(*p) {
parent = *p;
entry = rb_entry(parent, struct btrfs_leaf_ref, rb_node);
WARN_ON(!entry->in_tree);

ret = comp_keys(key, &entry->key);
if (ret < 0)
if (bytenr < entry->bytenr)
p = &(*p)->rb_left;
else if (ret > 0)
else if (bytenr > entry->bytenr)
p = &(*p)->rb_right;
else
return parent;
Expand All @@ -90,20 +72,18 @@ static struct rb_node *tree_insert(struct rb_root *root, struct btrfs_key *key,
return NULL;
}

static struct rb_node *tree_search(struct rb_root *root, struct btrfs_key *key)
static struct rb_node *tree_search(struct rb_root *root, u64 bytenr)
{
struct rb_node * n = root->rb_node;
struct btrfs_leaf_ref *entry;
int ret;

while(n) {
entry = rb_entry(n, struct btrfs_leaf_ref, rb_node);
WARN_ON(!entry->in_tree);

ret = comp_keys(key, &entry->key);
if (ret < 0)
if (bytenr < entry->bytenr)
n = n->rb_left;
else if (ret > 0)
else if (bytenr > entry->bytenr)
n = n->rb_right;
else
return n;
Expand All @@ -122,11 +102,11 @@ int btrfs_remove_leaf_refs(struct btrfs_root *root)

spin_lock(&tree->lock);
while(!btrfs_leaf_ref_tree_empty(tree)) {
tree->last = NULL;
rb = rb_first(&tree->root);
ref = rb_entry(rb, struct btrfs_leaf_ref, rb_node);
rb_erase(&ref->rb_node, &tree->root);
ref->in_tree = 0;
list_del_init(&ref->list);

spin_unlock(&tree->lock);

Expand All @@ -140,7 +120,7 @@ int btrfs_remove_leaf_refs(struct btrfs_root *root)
}

struct btrfs_leaf_ref *btrfs_lookup_leaf_ref(struct btrfs_root *root,
struct btrfs_key *key)
u64 bytenr)
{
struct rb_node *rb;
struct btrfs_leaf_ref *ref = NULL;
Expand All @@ -150,15 +130,9 @@ struct btrfs_leaf_ref *btrfs_lookup_leaf_ref(struct btrfs_root *root,
return NULL;

spin_lock(&tree->lock);
if (tree->last && comp_keys(key, &tree->last->key) == 0) {
ref = tree->last;
} else {
rb = tree_search(&tree->root, key);
if (rb) {
ref = rb_entry(rb, struct btrfs_leaf_ref, rb_node);
tree->last = ref;
}
}
rb = tree_search(&tree->root, bytenr);
if (rb)
ref = rb_entry(rb, struct btrfs_leaf_ref, rb_node);
if (ref)
atomic_inc(&ref->usage);
spin_unlock(&tree->lock);
Expand All @@ -171,21 +145,17 @@ int btrfs_add_leaf_ref(struct btrfs_root *root, struct btrfs_leaf_ref *ref)
struct rb_node *rb;
size_t size = btrfs_leaf_ref_size(ref->nritems);
struct btrfs_leaf_ref_tree *tree = root->ref_tree;
struct btrfs_transaction *trans = root->fs_info->running_transaction;

spin_lock(&tree->lock);
rb = tree_insert(&tree->root, &ref->key, &ref->rb_node);
rb = tree_insert(&tree->root, ref->bytenr, &ref->rb_node);
if (rb) {
ret = -EEXIST;
} else {
spin_lock(&root->fs_info->ref_cache_lock);
root->fs_info->total_ref_cache_size += size;
if (trans && tree->generation == trans->transid)
root->fs_info->running_ref_cache_size += size;
spin_unlock(&root->fs_info->ref_cache_lock);

tree->last = ref;
atomic_inc(&ref->usage);
list_add_tail(&ref->list, &tree->list);
}
spin_unlock(&tree->lock);
return ret;
Expand All @@ -195,28 +165,17 @@ int btrfs_remove_leaf_ref(struct btrfs_root *root, struct btrfs_leaf_ref *ref)
{
size_t size = btrfs_leaf_ref_size(ref->nritems);
struct btrfs_leaf_ref_tree *tree = root->ref_tree;
struct btrfs_transaction *trans = root->fs_info->running_transaction;

BUG_ON(!ref->in_tree);
spin_lock(&tree->lock);

spin_lock(&root->fs_info->ref_cache_lock);
root->fs_info->total_ref_cache_size -= size;
if (trans && tree->generation == trans->transid)
root->fs_info->running_ref_cache_size -= size;
spin_unlock(&root->fs_info->ref_cache_lock);

if (tree->last == ref) {
struct rb_node *next = rb_next(&ref->rb_node);
if (next) {
tree->last = rb_entry(next, struct btrfs_leaf_ref,
rb_node);
} else
tree->last = NULL;
}

rb_erase(&ref->rb_node, &tree->root);
ref->in_tree = 0;
list_del_init(&ref->list);

spin_unlock(&tree->lock);

Expand Down
Loading

0 comments on commit 675d2ba

Please sign in to comment.