Skip to content

Commit

Permalink
Btrfs: preserve commit_root for async caching
Browse files Browse the repository at this point in the history
The async block group caching code uses the commit_root pointer
to get a stable version of the extent allocation tree for scanning.
This copy of the tree root isn't going to change and it significantly
reduces the complexity of the scanning code.

During a commit, we have a loop where we update the extent allocation
tree root.  We need to loop because updating the root pointer in
the tree of tree roots may allocate blocks which may change the
extent allocation tree.

Right now the commit_root pointer is changed inside this loop.  It
is more correct to change the commit_root pointer only after all the
looping is done.

Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
  • Loading branch information
Yan Zheng authored and Chris Mason committed Jul 30, 2009
1 parent f25784b commit 276e680
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 10 deletions.
4 changes: 1 addition & 3 deletions fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,7 @@ struct btrfs_fs_info {
struct mutex drop_mutex;
struct mutex volume_mutex;
struct mutex tree_reloc_mutex;
struct rw_semaphore extent_commit_sem;

/*
* this protects the ordered operations list only while we are
Expand Down Expand Up @@ -961,9 +962,6 @@ struct btrfs_root {
/* the node lock is held while changing the node pointer */
spinlock_t node_lock;

/* taken when updating the commit root */
struct rw_semaphore commit_root_sem;

struct extent_buffer *commit_root;
struct btrfs_root *log_root;
struct btrfs_root *reloc_root;
Expand Down
2 changes: 1 addition & 1 deletion fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -907,7 +907,6 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
spin_lock_init(&root->inode_lock);
mutex_init(&root->objectid_mutex);
mutex_init(&root->log_mutex);
init_rwsem(&root->commit_root_sem);
init_waitqueue_head(&root->log_writer_wait);
init_waitqueue_head(&root->log_commit_wait[0]);
init_waitqueue_head(&root->log_commit_wait[1]);
Expand Down Expand Up @@ -1624,6 +1623,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
mutex_init(&fs_info->cleaner_mutex);
mutex_init(&fs_info->volume_mutex);
mutex_init(&fs_info->tree_reloc_mutex);
init_rwsem(&fs_info->extent_commit_sem);

btrfs_init_free_cluster(&fs_info->meta_alloc_cluster);
btrfs_init_free_cluster(&fs_info->data_alloc_cluster);
Expand Down
6 changes: 3 additions & 3 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ static int caching_kthread(void *data)
last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET);
again:
/* need to make sure the commit_root doesn't disappear */
down_read(&fs_info->extent_root->commit_root_sem);
down_read(&fs_info->extent_commit_sem);

/*
* We don't want to deadlock with somebody trying to allocate a new
Expand Down Expand Up @@ -304,7 +304,7 @@ static int caching_kthread(void *data)

if (need_resched()) {
btrfs_release_path(fs_info->extent_root, path);
up_read(&fs_info->extent_root->commit_root_sem);
up_read(&fs_info->extent_commit_sem);
cond_resched();
goto again;
}
Expand Down Expand Up @@ -345,7 +345,7 @@ static int caching_kthread(void *data)

err:
btrfs_free_path(path);
up_read(&fs_info->extent_root->commit_root_sem);
up_read(&fs_info->extent_commit_sem);
atomic_dec(&block_group->space_info->caching_threads);
wake_up(&block_group->caching_q);

Expand Down
12 changes: 9 additions & 3 deletions fs/btrfs/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,8 @@ static noinline void put_transaction(struct btrfs_transaction *transaction)

static noinline void switch_commit_root(struct btrfs_root *root)
{
down_write(&root->commit_root_sem);
free_extent_buffer(root->commit_root);
root->commit_root = btrfs_root_node(root);
up_write(&root->commit_root_sem);
}

/*
Expand Down Expand Up @@ -466,7 +464,10 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans,
ret = btrfs_write_dirty_block_groups(trans, root);
BUG_ON(ret);
}
switch_commit_root(root);

if (root != root->fs_info->extent_root)
switch_commit_root(root);

return 0;
}

Expand Down Expand Up @@ -499,6 +500,11 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans,

update_cowonly_root(trans, root);
}

down_write(&fs_info->extent_commit_sem);
switch_commit_root(fs_info->extent_root);
up_write(&fs_info->extent_commit_sem);

return 0;
}

Expand Down

0 comments on commit 276e680

Please sign in to comment.