Btrfs: hold trans_mutex when using btrfs_record_root_in_trans
authorYan Zheng <zheng.yan@oracle.com>
Thu, 12 Feb 2009 19:14:53 +0000 (14:14 -0500)
committerChris Mason <chris.mason@oracle.com>
Thu, 12 Feb 2009 19:14:53 +0000 (14:14 -0500)
btrfs_record_root_in_trans needs the trans_mutex held to make sure two
callers don't race to setup the root in a given transaction.  This adds
it to all the places that were missing it.

Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
fs/btrfs/extent-tree.c
fs/btrfs/transaction.c
fs/btrfs/tree-log.c

index cd86bffbdc9fac6efa8b2afb5e7fca596c79fb8c..0a5d796c9f7ee3086bd3c8bccdfc63b59d674e0f 100644 (file)
@@ -5658,7 +5658,9 @@ static noinline int relocate_one_extent(struct btrfs_root *extent_root,
                        prev_block = block_start;
                }
 
+               mutex_lock(&extent_root->fs_info->trans_mutex);
                btrfs_record_root_in_trans(found_root);
+               mutex_unlock(&extent_root->fs_info->trans_mutex);
                if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) {
                        /*
                         * try to update data extent references while
index 919172de5c9aa9ce64630f593f74a7942e8292fd..4112d53d4f4dad195636c6ffa93deaded831af6e 100644 (file)
@@ -688,7 +688,9 @@ static noinline int drop_dirty_roots(struct btrfs_root *tree_root,
                num_bytes -= btrfs_root_used(&dirty->root->root_item);
                bytes_used = btrfs_root_used(&root->root_item);
                if (num_bytes) {
+                       mutex_lock(&root->fs_info->trans_mutex);
                        btrfs_record_root_in_trans(root);
+                       mutex_unlock(&root->fs_info->trans_mutex);
                        btrfs_set_root_used(&root->root_item,
                                            bytes_used - num_bytes);
                }
index 20794290256b4f977f14a5ea95810781edc7bbad..9c462fbd60fac14ad17f192afb08c37794295d36 100644 (file)
@@ -2832,7 +2832,9 @@ again:
                BUG_ON(!wc.replay_dest);
 
                wc.replay_dest->log_root = log;
+               mutex_lock(&fs_info->trans_mutex);
                btrfs_record_root_in_trans(wc.replay_dest);
+               mutex_unlock(&fs_info->trans_mutex);
                ret = walk_log_tree(trans, log, &wc);
                BUG_ON(ret);