Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 253811
b: refs/heads/master
c: 71d7aed
h: refs/heads/master
i:
  253809: b7521d4
  253807: dda7050
v: v3
  • Loading branch information
Josef Bacik committed Jun 15, 2011
1 parent e778066 commit a681b40
Show file tree
Hide file tree
Showing 7 changed files with 20 additions and 109 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: 7585717f304f5ed005cc4ad933a69aab3efbd136
refs/heads/master: 71d7aed014457147e8f71a843d5fbf03235e4a85
14 changes: 0 additions & 14 deletions trunk/fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -967,12 +967,6 @@ struct btrfs_fs_info {
struct srcu_struct subvol_srcu;

spinlock_t trans_lock;
/*
* the reloc mutex goes with the trans lock, it is taken
* during commit to protect us from the relocation code
*/
struct mutex reloc_mutex;

struct list_head trans_list;
struct list_head hashers;
struct list_head dead_roots;
Expand Down Expand Up @@ -1178,14 +1172,6 @@ struct btrfs_root {
u32 type;

u64 highest_objectid;

/* btrfs_record_root_in_trans is a multi-step process,
* and it can race with the balancing code. But the
* race is very small, and only the first time the root
* is added to each transaction. So in_trans_setup
* is used to tell us when more checks are required
*/
unsigned long in_trans_setup;
int ref_cows;
int track_dirty;
int in_radix;
Expand Down
5 changes: 1 addition & 4 deletions trunk/fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1312,9 +1312,7 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
spin_lock_init(&root->cache_lock);
init_waitqueue_head(&root->cache_wait);

ret = set_anon_super(&root->anon_super, NULL);
if (ret)
goto fail;
set_anon_super(&root->anon_super, NULL);

if (btrfs_root_refs(&root->root_item) == 0) {
ret = -ENOENT;
Expand Down Expand Up @@ -1620,7 +1618,6 @@ struct btrfs_root *open_ctree(struct super_block *sb,
spin_lock_init(&fs_info->fs_roots_radix_lock);
spin_lock_init(&fs_info->delayed_iput_lock);
spin_lock_init(&fs_info->defrag_inodes_lock);
mutex_init(&fs_info->reloc_mutex);

init_completion(&fs_info->kobj_unregister);
fs_info->tree_root = tree_root;
Expand Down
4 changes: 4 additions & 0 deletions trunk/fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -3314,6 +3314,10 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
if (reserved == 0)
return 0;

/* nothing to shrink - nothing to reclaim */
if (root->fs_info->delalloc_bytes == 0)
return 0;

max_reclaim = min(reserved, to_reclaim);

while (loops < 1024) {
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -3076,6 +3076,7 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
ret = btrfs_update_inode(trans, root, dir);
BUG_ON(ret);

btrfs_free_path(path);
return 0;
}

Expand Down
30 changes: 9 additions & 21 deletions trunk/fs/btrfs/relocation.c
Original file line number Diff line number Diff line change
Expand Up @@ -1368,7 +1368,7 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
int ret;

if (!root->reloc_root)
goto out;
return 0;

reloc_root = root->reloc_root;
root_item = &reloc_root->root_item;
Expand All @@ -1390,8 +1390,6 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
ret = btrfs_update_root(trans, root->fs_info->tree_root,
&reloc_root->root_key, root_item);
BUG_ON(ret);

out:
return 0;
}

Expand Down Expand Up @@ -2144,11 +2142,10 @@ int prepare_to_merge(struct reloc_control *rc, int err)
u64 num_bytes = 0;
int ret;

mutex_lock(&root->fs_info->reloc_mutex);
spin_lock(&root->fs_info->trans_lock);
rc->merging_rsv_size += root->nodesize * (BTRFS_MAX_LEVEL - 1) * 2;
rc->merging_rsv_size += rc->nodes_relocated * 2;
mutex_unlock(&root->fs_info->reloc_mutex);

spin_unlock(&root->fs_info->trans_lock);
again:
if (!err) {
num_bytes = rc->merging_rsv_size;
Expand Down Expand Up @@ -2217,16 +2214,9 @@ int merge_reloc_roots(struct reloc_control *rc)
int ret;
again:
root = rc->extent_root;

/*
* this serializes us with btrfs_record_root_in_transaction,
* we have to make sure nobody is in the middle of
* adding their roots to the list while we are
* doing this splice
*/
mutex_lock(&root->fs_info->reloc_mutex);
spin_lock(&root->fs_info->trans_lock);
list_splice_init(&rc->reloc_roots, &reloc_roots);
mutex_unlock(&root->fs_info->reloc_mutex);
spin_unlock(&root->fs_info->trans_lock);

while (!list_empty(&reloc_roots)) {
found = 1;
Expand Down Expand Up @@ -3600,19 +3590,17 @@ int find_next_extent(struct btrfs_trans_handle *trans,
static void set_reloc_control(struct reloc_control *rc)
{
struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;

mutex_lock(&fs_info->reloc_mutex);
spin_lock(&fs_info->trans_lock);
fs_info->reloc_ctl = rc;
mutex_unlock(&fs_info->reloc_mutex);
spin_unlock(&fs_info->trans_lock);
}

static void unset_reloc_control(struct reloc_control *rc)
{
struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;

mutex_lock(&fs_info->reloc_mutex);
spin_lock(&fs_info->trans_lock);
fs_info->reloc_ctl = NULL;
mutex_unlock(&fs_info->reloc_mutex);
spin_unlock(&fs_info->trans_lock);
}

static int check_extent_flags(u64 flags)
Expand Down
73 changes: 4 additions & 69 deletions trunk/fs/btrfs/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,85 +126,28 @@ static noinline int join_transaction(struct btrfs_root *root, int nofail)
* to make sure the old root from before we joined the transaction is deleted
* when the transaction commits
*/
static int record_root_in_trans(struct btrfs_trans_handle *trans,
int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans,
struct btrfs_root *root)
{
if (root->ref_cows && root->last_trans < trans->transid) {
WARN_ON(root == root->fs_info->extent_root);
WARN_ON(root->commit_root != root->node);

/*
* see below for in_trans_setup usage rules
* we have the reloc mutex held now, so there
* is only one writer in this function
*/
root->in_trans_setup = 1;

/* make sure readers find in_trans_setup before
* they find our root->last_trans update
*/
smp_wmb();

spin_lock(&root->fs_info->fs_roots_radix_lock);
if (root->last_trans == trans->transid) {
spin_unlock(&root->fs_info->fs_roots_radix_lock);
return 0;
}
root->last_trans = trans->transid;
radix_tree_tag_set(&root->fs_info->fs_roots_radix,
(unsigned long)root->root_key.objectid,
BTRFS_ROOT_TRANS_TAG);
spin_unlock(&root->fs_info->fs_roots_radix_lock);
root->last_trans = trans->transid;

/* this is pretty tricky. We don't want to
* take the relocation lock in btrfs_record_root_in_trans
* unless we're really doing the first setup for this root in
* this transaction.
*
* Normally we'd use root->last_trans as a flag to decide
* if we want to take the expensive mutex.
*
* But, we have to set root->last_trans before we
* init the relocation root, otherwise, we trip over warnings
* in ctree.c. The solution used here is to flag ourselves
* with root->in_trans_setup. When this is 1, we're still
* fixing up the reloc trees and everyone must wait.
*
* When this is zero, they can trust root->last_trans and fly
* through btrfs_record_root_in_trans without having to take the
* lock. smp_wmb() makes sure that all the writes above are
* done before we pop in the zero below
*/
btrfs_init_reloc_root(trans, root);
smp_wmb();
root->in_trans_setup = 0;
}
return 0;
}


int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans,
struct btrfs_root *root)
{
if (!root->ref_cows)
return 0;

/*
* see record_root_in_trans for comments about in_trans_setup usage
* and barriers
*/
smp_rmb();
if (root->last_trans == trans->transid &&
!root->in_trans_setup)
return 0;

mutex_lock(&root->fs_info->reloc_mutex);
record_root_in_trans(trans, root);
mutex_unlock(&root->fs_info->reloc_mutex);

return 0;
}

/* wait for commit against the current transaction to become unblocked
* when this is done, it is safe to start a new transaction, but the current
* transaction might not be fully on disk.
Expand Down Expand Up @@ -939,7 +882,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
parent = dget_parent(dentry);
parent_inode = parent->d_inode;
parent_root = BTRFS_I(parent_inode)->root;
record_root_in_trans(trans, parent_root);
btrfs_record_root_in_trans(trans, parent_root);

/*
* insert the directory item
Expand All @@ -957,7 +900,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
ret = btrfs_update_inode(trans, parent_root, parent_inode);
BUG_ON(ret);

record_root_in_trans(trans, root);
btrfs_record_root_in_trans(trans, root);
btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
btrfs_check_and_init_root_item(new_root_item);
Expand Down Expand Up @@ -1304,13 +1247,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
} while (atomic_read(&cur_trans->num_writers) > 1 ||
(should_grow && cur_trans->num_joined != joined));

/*
* the reloc mutex makes sure that we stop
* the balancing code from coming in and moving
* extents around in the middle of the commit
*/
mutex_lock(&root->fs_info->reloc_mutex);

ret = create_pending_snapshots(trans, root->fs_info);
BUG_ON(ret);

Expand Down Expand Up @@ -1376,7 +1312,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
root->fs_info->running_transaction = NULL;
root->fs_info->trans_no_join = 0;
spin_unlock(&root->fs_info->trans_lock);
mutex_unlock(&root->fs_info->reloc_mutex);

wake_up(&root->fs_info->transaction_wait);

Expand Down

0 comments on commit a681b40

Please sign in to comment.