aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2014-04-02 07:51:05 -0400
committerChris Mason <clm@fb.com>2014-06-09 20:20:40 -0400
commit27cdeb7096b86f05ad018a24cdb63acdf0850a5d (patch)
tree1e795214fd0456f83c85843bea354d7331328bd1 /fs
parentf959492fc15b60d874a9cbf55ae4760f2ef261ed (diff)
Btrfs: use bitfield instead of integer data type for the some variants in btrfs_root
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ctree.c25
-rw-r--r--fs/btrfs/ctree.h39
-rw-r--r--fs/btrfs/disk-io.c33
-rw-r--r--fs/btrfs/extent-tree.c6
-rw-r--r--fs/btrfs/file.c4
-rw-r--r--fs/btrfs/inode.c29
-rw-r--r--fs/btrfs/ioctl.c4
-rw-r--r--fs/btrfs/relocation.c17
-rw-r--r--fs/btrfs/root-tree.c2
-rw-r--r--fs/btrfs/transaction.c33
-rw-r--r--fs/btrfs/tree-defrag.c2
-rw-r--r--fs/btrfs/tree-log.c9
12 files changed, 109 insertions, 94 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 1bcfcdb23cf4..2f10e12ae94c 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -224,7 +224,8 @@ static struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root)
224static void add_root_to_dirty_list(struct btrfs_root *root) 224static void add_root_to_dirty_list(struct btrfs_root *root)
225{ 225{
226 spin_lock(&root->fs_info->trans_lock); 226 spin_lock(&root->fs_info->trans_lock);
227 if (root->track_dirty && list_empty(&root->dirty_list)) { 227 if (test_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state) &&
228 list_empty(&root->dirty_list)) {
228 list_add(&root->dirty_list, 229 list_add(&root->dirty_list,
229 &root->fs_info->dirty_cowonly_roots); 230 &root->fs_info->dirty_cowonly_roots);
230 } 231 }
@@ -246,9 +247,10 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
246 int level; 247 int level;
247 struct btrfs_disk_key disk_key; 248 struct btrfs_disk_key disk_key;
248 249
249 WARN_ON(root->ref_cows && trans->transid != 250 WARN_ON(test_bit(BTRFS_ROOT_REF_COWS, &root->state) &&
250 root->fs_info->running_transaction->transid); 251 trans->transid != root->fs_info->running_transaction->transid);
251 WARN_ON(root->ref_cows && trans->transid != root->last_trans); 252 WARN_ON(test_bit(BTRFS_ROOT_REF_COWS, &root->state) &&
253 trans->transid != root->last_trans);
252 254
253 level = btrfs_header_level(buf); 255 level = btrfs_header_level(buf);
254 if (level == 0) 256 if (level == 0)
@@ -997,14 +999,14 @@ int btrfs_block_can_be_shared(struct btrfs_root *root,
997 * snapshot and the block was not allocated by tree relocation, 999 * snapshot and the block was not allocated by tree relocation,
998 * we know the block is not shared. 1000 * we know the block is not shared.
999 */ 1001 */
1000 if (root->ref_cows && 1002 if (test_bit(BTRFS_ROOT_REF_COWS, &root->state) &&
1001 buf != root->node && buf != root->commit_root && 1003 buf != root->node && buf != root->commit_root &&
1002 (btrfs_header_generation(buf) <= 1004 (btrfs_header_generation(buf) <=
1003 btrfs_root_last_snapshot(&root->root_item) || 1005 btrfs_root_last_snapshot(&root->root_item) ||
1004 btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC))) 1006 btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC)))
1005 return 1; 1007 return 1;
1006#ifdef BTRFS_COMPAT_EXTENT_TREE_V0 1008#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
1007 if (root->ref_cows && 1009 if (test_bit(BTRFS_ROOT_REF_COWS, &root->state) &&
1008 btrfs_header_backref_rev(buf) < BTRFS_MIXED_BACKREF_REV) 1010 btrfs_header_backref_rev(buf) < BTRFS_MIXED_BACKREF_REV)
1009 return 1; 1011 return 1;
1010#endif 1012#endif
@@ -1146,9 +1148,10 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
1146 1148
1147 btrfs_assert_tree_locked(buf); 1149 btrfs_assert_tree_locked(buf);
1148 1150
1149 WARN_ON(root->ref_cows && trans->transid != 1151 WARN_ON(test_bit(BTRFS_ROOT_REF_COWS, &root->state) &&
1150 root->fs_info->running_transaction->transid); 1152 trans->transid != root->fs_info->running_transaction->transid);
1151 WARN_ON(root->ref_cows && trans->transid != root->last_trans); 1153 WARN_ON(test_bit(BTRFS_ROOT_REF_COWS, &root->state) &&
1154 trans->transid != root->last_trans);
1152 1155
1153 level = btrfs_header_level(buf); 1156 level = btrfs_header_level(buf);
1154 1157
@@ -1193,7 +1196,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
1193 return ret; 1196 return ret;
1194 } 1197 }
1195 1198
1196 if (root->ref_cows) { 1199 if (test_bit(BTRFS_ROOT_REF_COWS, &root->state)) {
1197 ret = btrfs_reloc_cow_block(trans, root, buf, cow); 1200 ret = btrfs_reloc_cow_block(trans, root, buf, cow);
1198 if (ret) 1201 if (ret)
1199 return ret; 1202 return ret;
@@ -1556,7 +1559,7 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans,
1556 !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN) && 1559 !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN) &&
1557 !(root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID && 1560 !(root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID &&
1558 btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC)) && 1561 btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC)) &&
1559 !root->force_cow) 1562 !test_bit(BTRFS_ROOT_FORCE_COW, &root->state))
1560 return 0; 1563 return 0;
1561 return 1; 1564 return 1;
1562} 1565}
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 0a805b8d61cc..efd3bf61696d 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1711,6 +1711,26 @@ struct btrfs_subvolume_writers {
1711}; 1711};
1712 1712
1713/* 1713/*
1714 * The state of btrfs root
1715 */
1716/*
1717 * btrfs_record_root_in_trans is a multi-step process,
1718 * and it can race with the balancing code. But the
1719 * race is very small, and only the first time the root
1720 * is added to each transaction. So IN_TRANS_SETUP
1721 * is used to tell us when more checks are required
1722 */
1723#define BTRFS_ROOT_IN_TRANS_SETUP 0
1724#define BTRFS_ROOT_REF_COWS 1
1725#define BTRFS_ROOT_TRACK_DIRTY 2
1726#define BTRFS_ROOT_IN_RADIX 3
1727#define BTRFS_ROOT_DUMMY_ROOT 4
1728#define BTRFS_ROOT_ORPHAN_ITEM_INSERTED 5
1729#define BTRFS_ROOT_DEFRAG_RUNNING 6
1730#define BTRFS_ROOT_FORCE_COW 7
1731#define BTRFS_ROOT_MULTI_LOG_TASKS 8
1732
1733/*
1714 * in ram representation of the tree. extent_root is used for all allocations 1734 * in ram representation of the tree. extent_root is used for all allocations
1715 * and for the extent tree extent_root root. 1735 * and for the extent tree extent_root root.
1716 */ 1736 */
@@ -1721,6 +1741,7 @@ struct btrfs_root {
1721 struct btrfs_root *log_root; 1741 struct btrfs_root *log_root;
1722 struct btrfs_root *reloc_root; 1742 struct btrfs_root *reloc_root;
1723 1743
1744 unsigned long state;
1724 struct btrfs_root_item root_item; 1745 struct btrfs_root_item root_item;
1725 struct btrfs_key root_key; 1746 struct btrfs_key root_key;
1726 struct btrfs_fs_info *fs_info; 1747 struct btrfs_fs_info *fs_info;
@@ -1755,7 +1776,6 @@ struct btrfs_root {
1755 /* Just be updated when the commit succeeds. */ 1776 /* Just be updated when the commit succeeds. */
1756 int last_log_commit; 1777 int last_log_commit;
1757 pid_t log_start_pid; 1778 pid_t log_start_pid;
1758 bool log_multiple_pids;
1759 1779
1760 u64 objectid; 1780 u64 objectid;
1761 u64 last_trans; 1781 u64 last_trans;
@@ -1775,23 +1795,9 @@ struct btrfs_root {
1775 1795
1776 u64 highest_objectid; 1796 u64 highest_objectid;
1777 1797
1778 /* btrfs_record_root_in_trans is a multi-step process,
1779 * and it can race with the balancing code. But the
1780 * race is very small, and only the first time the root
1781 * is added to each transaction. So in_trans_setup
1782 * is used to tell us when more checks are required
1783 */
1784 unsigned long in_trans_setup;
1785 int ref_cows;
1786 int track_dirty;
1787 int in_radix;
1788#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
1789 int dummy_root;
1790#endif
1791 u64 defrag_trans_start; 1798 u64 defrag_trans_start;
1792 struct btrfs_key defrag_progress; 1799 struct btrfs_key defrag_progress;
1793 struct btrfs_key defrag_max; 1800 struct btrfs_key defrag_max;
1794 int defrag_running;
1795 char *name; 1801 char *name;
1796 1802
1797 /* the dirty list is only used by non-reference counted roots */ 1803 /* the dirty list is only used by non-reference counted roots */
@@ -1805,7 +1811,6 @@ struct btrfs_root {
1805 spinlock_t orphan_lock; 1811 spinlock_t orphan_lock;
1806 atomic_t orphan_inodes; 1812 atomic_t orphan_inodes;
1807 struct btrfs_block_rsv *orphan_block_rsv; 1813 struct btrfs_block_rsv *orphan_block_rsv;
1808 int orphan_item_inserted;
1809 int orphan_cleanup_state; 1814 int orphan_cleanup_state;
1810 1815
1811 spinlock_t inode_lock; 1816 spinlock_t inode_lock;
@@ -1823,8 +1828,6 @@ struct btrfs_root {
1823 */ 1828 */
1824 dev_t anon_dev; 1829 dev_t anon_dev;
1825 1830
1826 int force_cow;
1827
1828 spinlock_t root_item_lock; 1831 spinlock_t root_item_lock;
1829 atomic_t refs; 1832 atomic_t refs;
1830 1833
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 85f514483bd1..cf8427a7a615 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1201,10 +1201,7 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
1201 root->nodesize = nodesize; 1201 root->nodesize = nodesize;
1202 root->leafsize = leafsize; 1202 root->leafsize = leafsize;
1203 root->stripesize = stripesize; 1203 root->stripesize = stripesize;
1204 root->ref_cows = 0; 1204 root->state = 0;
1205 root->track_dirty = 0;
1206 root->in_radix = 0;
1207 root->orphan_item_inserted = 0;
1208 root->orphan_cleanup_state = 0; 1205 root->orphan_cleanup_state = 0;
1209 1206
1210 root->objectid = objectid; 1207 root->objectid = objectid;
@@ -1265,7 +1262,6 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
1265 else 1262 else
1266 root->defrag_trans_start = 0; 1263 root->defrag_trans_start = 0;
1267 init_completion(&root->kobj_unregister); 1264 init_completion(&root->kobj_unregister);
1268 root->defrag_running = 0;
1269 root->root_key.objectid = objectid; 1265 root->root_key.objectid = objectid;
1270 root->anon_dev = 0; 1266 root->anon_dev = 0;
1271 1267
@@ -1290,7 +1286,7 @@ struct btrfs_root *btrfs_alloc_dummy_root(void)
1290 if (!root) 1286 if (!root)
1291 return ERR_PTR(-ENOMEM); 1287 return ERR_PTR(-ENOMEM);
1292 __setup_root(4096, 4096, 4096, 4096, root, NULL, 1); 1288 __setup_root(4096, 4096, 4096, 4096, root, NULL, 1);
1293 root->dummy_root = 1; 1289 set_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state);
1294 1290
1295 return root; 1291 return root;
1296} 1292}
@@ -1341,8 +1337,7 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
1341 btrfs_mark_buffer_dirty(leaf); 1337 btrfs_mark_buffer_dirty(leaf);
1342 1338
1343 root->commit_root = btrfs_root_node(root); 1339 root->commit_root = btrfs_root_node(root);
1344 root->track_dirty = 1; 1340 set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);
1345
1346 1341
1347 root->root_item.flags = 0; 1342 root->root_item.flags = 0;
1348 root->root_item.byte_limit = 0; 1343 root->root_item.byte_limit = 0;
@@ -1396,13 +1391,15 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans,
1396 root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID; 1391 root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID;
1397 root->root_key.type = BTRFS_ROOT_ITEM_KEY; 1392 root->root_key.type = BTRFS_ROOT_ITEM_KEY;
1398 root->root_key.offset = BTRFS_TREE_LOG_OBJECTID; 1393 root->root_key.offset = BTRFS_TREE_LOG_OBJECTID;
1394
1399 /* 1395 /*
1396 * DON'T set REF_COWS for log trees
1397 *
1400 * log trees do not get reference counted because they go away 1398 * log trees do not get reference counted because they go away
1401 * before a real commit is actually done. They do store pointers 1399 * before a real commit is actually done. They do store pointers
1402 * to file data extents, and those reference counts still get 1400 * to file data extents, and those reference counts still get
1403 * updated (along with back refs to the log tree). 1401 * updated (along with back refs to the log tree).
1404 */ 1402 */
1405 root->ref_cows = 0;
1406 1403
1407 leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0, 1404 leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0,
1408 BTRFS_TREE_LOG_OBJECTID, NULL, 1405 BTRFS_TREE_LOG_OBJECTID, NULL,
@@ -1536,7 +1533,7 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_root *tree_root,
1536 return root; 1533 return root;
1537 1534
1538 if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { 1535 if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
1539 root->ref_cows = 1; 1536 set_bit(BTRFS_ROOT_REF_COWS, &root->state);
1540 btrfs_check_and_init_root_item(&root->root_item); 1537 btrfs_check_and_init_root_item(&root->root_item);
1541 } 1538 }
1542 1539
@@ -1606,7 +1603,7 @@ int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info,
1606 (unsigned long)root->root_key.objectid, 1603 (unsigned long)root->root_key.objectid,
1607 root); 1604 root);
1608 if (ret == 0) 1605 if (ret == 0)
1609 root->in_radix = 1; 1606 set_bit(BTRFS_ROOT_IN_RADIX, &root->state);
1610 spin_unlock(&fs_info->fs_roots_radix_lock); 1607 spin_unlock(&fs_info->fs_roots_radix_lock);
1611 radix_tree_preload_end(); 1608 radix_tree_preload_end();
1612 1609
@@ -1662,7 +1659,7 @@ again:
1662 if (ret < 0) 1659 if (ret < 0)
1663 goto fail; 1660 goto fail;
1664 if (ret == 0) 1661 if (ret == 0)
1665 root->orphan_item_inserted = 1; 1662 set_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state);
1666 1663
1667 ret = btrfs_insert_fs_root(fs_info, root); 1664 ret = btrfs_insert_fs_root(fs_info, root);
1668 if (ret) { 1665 if (ret) {
@@ -2101,7 +2098,7 @@ static void del_fs_roots(struct btrfs_fs_info *fs_info)
2101 struct btrfs_root, root_list); 2098 struct btrfs_root, root_list);
2102 list_del(&gang[0]->root_list); 2099 list_del(&gang[0]->root_list);
2103 2100
2104 if (gang[0]->in_radix) { 2101 if (test_bit(BTRFS_ROOT_IN_RADIX, &gang[0]->state)) {
2105 btrfs_drop_and_free_fs_root(fs_info, gang[0]); 2102 btrfs_drop_and_free_fs_root(fs_info, gang[0]);
2106 } else { 2103 } else {
2107 free_extent_buffer(gang[0]->node); 2104 free_extent_buffer(gang[0]->node);
@@ -2694,7 +2691,7 @@ retry_root_backup:
2694 ret = PTR_ERR(extent_root); 2691 ret = PTR_ERR(extent_root);
2695 goto recovery_tree_root; 2692 goto recovery_tree_root;
2696 } 2693 }
2697 extent_root->track_dirty = 1; 2694 set_bit(BTRFS_ROOT_TRACK_DIRTY, &extent_root->state);
2698 fs_info->extent_root = extent_root; 2695 fs_info->extent_root = extent_root;
2699 2696
2700 location.objectid = BTRFS_DEV_TREE_OBJECTID; 2697 location.objectid = BTRFS_DEV_TREE_OBJECTID;
@@ -2703,7 +2700,7 @@ retry_root_backup:
2703 ret = PTR_ERR(dev_root); 2700 ret = PTR_ERR(dev_root);
2704 goto recovery_tree_root; 2701 goto recovery_tree_root;
2705 } 2702 }
2706 dev_root->track_dirty = 1; 2703 set_bit(BTRFS_ROOT_TRACK_DIRTY, &dev_root->state);
2707 fs_info->dev_root = dev_root; 2704 fs_info->dev_root = dev_root;
2708 btrfs_init_devices_late(fs_info); 2705 btrfs_init_devices_late(fs_info);
2709 2706
@@ -2713,13 +2710,13 @@ retry_root_backup:
2713 ret = PTR_ERR(csum_root); 2710 ret = PTR_ERR(csum_root);
2714 goto recovery_tree_root; 2711 goto recovery_tree_root;
2715 } 2712 }
2716 csum_root->track_dirty = 1; 2713 set_bit(BTRFS_ROOT_TRACK_DIRTY, &csum_root->state);
2717 fs_info->csum_root = csum_root; 2714 fs_info->csum_root = csum_root;
2718 2715
2719 location.objectid = BTRFS_QUOTA_TREE_OBJECTID; 2716 location.objectid = BTRFS_QUOTA_TREE_OBJECTID;
2720 quota_root = btrfs_read_tree_root(tree_root, &location); 2717 quota_root = btrfs_read_tree_root(tree_root, &location);
2721 if (!IS_ERR(quota_root)) { 2718 if (!IS_ERR(quota_root)) {
2722 quota_root->track_dirty = 1; 2719 set_bit(BTRFS_ROOT_TRACK_DIRTY, &quota_root->state);
2723 fs_info->quota_enabled = 1; 2720 fs_info->quota_enabled = 1;
2724 fs_info->pending_quota_state = 1; 2721 fs_info->pending_quota_state = 1;
2725 fs_info->quota_root = quota_root; 2722 fs_info->quota_root = quota_root;
@@ -2734,7 +2731,7 @@ retry_root_backup:
2734 create_uuid_tree = true; 2731 create_uuid_tree = true;
2735 check_uuid_tree = false; 2732 check_uuid_tree = false;
2736 } else { 2733 } else {
2737 uuid_root->track_dirty = 1; 2734 set_bit(BTRFS_ROOT_TRACK_DIRTY, &uuid_root->state);
2738 fs_info->uuid_root = uuid_root; 2735 fs_info->uuid_root = uuid_root;
2739 create_uuid_tree = false; 2736 create_uuid_tree = false;
2740 check_uuid_tree = 2737 check_uuid_tree =
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 15467e3f5876..7c18566fd2b4 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2983,7 +2983,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
2983 nritems = btrfs_header_nritems(buf); 2983 nritems = btrfs_header_nritems(buf);
2984 level = btrfs_header_level(buf); 2984 level = btrfs_header_level(buf);
2985 2985
2986 if (!root->ref_cows && level == 0) 2986 if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state) && level == 0)
2987 return 0; 2987 return 0;
2988 2988
2989 if (inc) 2989 if (inc)
@@ -4472,7 +4472,7 @@ static struct btrfs_block_rsv *get_block_rsv(
4472{ 4472{
4473 struct btrfs_block_rsv *block_rsv = NULL; 4473 struct btrfs_block_rsv *block_rsv = NULL;
4474 4474
4475 if (root->ref_cows) 4475 if (test_bit(BTRFS_ROOT_REF_COWS, &root->state))
4476 block_rsv = trans->block_rsv; 4476 block_rsv = trans->block_rsv;
4477 4477
4478 if (root == root->fs_info->csum_root && trans->adding_csums) 4478 if (root == root->fs_info->csum_root && trans->adding_csums)
@@ -7838,7 +7838,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
7838 } 7838 }
7839 } 7839 }
7840 7840
7841 if (root->in_radix) { 7841 if (test_bit(BTRFS_ROOT_IN_RADIX, &root->state)) {
7842 btrfs_drop_and_free_fs_root(tree_root->fs_info, root); 7842 btrfs_drop_and_free_fs_root(tree_root->fs_info, root);
7843 } else { 7843 } else {
7844 free_extent_buffer(root->node); 7844 free_extent_buffer(root->node);
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 3029925e96d7..5c6947dbc948 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -714,7 +714,7 @@ int __btrfs_drop_extents(struct btrfs_trans_handle *trans,
714 int recow; 714 int recow;
715 int ret; 715 int ret;
716 int modify_tree = -1; 716 int modify_tree = -1;
717 int update_refs = (root->ref_cows || root == root->fs_info->tree_root); 717 int update_refs;
718 int found = 0; 718 int found = 0;
719 int leafs_visited = 0; 719 int leafs_visited = 0;
720 720
@@ -724,6 +724,8 @@ int __btrfs_drop_extents(struct btrfs_trans_handle *trans,
724 if (start >= BTRFS_I(inode)->disk_i_size && !replace_extent) 724 if (start >= BTRFS_I(inode)->disk_i_size && !replace_extent)
725 modify_tree = 0; 725 modify_tree = 0;
726 726
727 update_refs = (test_bit(BTRFS_ROOT_REF_COWS, &root->state) ||
728 root == root->fs_info->tree_root);
727 while (1) { 729 while (1) {
728 recow = 0; 730 recow = 0;
729 ret = btrfs_lookup_file_extent(trans, root, path, ino, 731 ret = btrfs_lookup_file_extent(trans, root, path, ino,
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 36c13e391ae3..ef3bd3deca12 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2947,14 +2947,15 @@ void btrfs_orphan_commit_root(struct btrfs_trans_handle *trans,
2947 root->orphan_block_rsv = NULL; 2947 root->orphan_block_rsv = NULL;
2948 spin_unlock(&root->orphan_lock); 2948 spin_unlock(&root->orphan_lock);
2949 2949
2950 if (root->orphan_item_inserted && 2950 if (test_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state) &&
2951 btrfs_root_refs(&root->root_item) > 0) { 2951 btrfs_root_refs(&root->root_item) > 0) {
2952 ret = btrfs_del_orphan_item(trans, root->fs_info->tree_root, 2952 ret = btrfs_del_orphan_item(trans, root->fs_info->tree_root,
2953 root->root_key.objectid); 2953 root->root_key.objectid);
2954 if (ret) 2954 if (ret)
2955 btrfs_abort_transaction(trans, root, ret); 2955 btrfs_abort_transaction(trans, root, ret);
2956 else 2956 else
2957 root->orphan_item_inserted = 0; 2957 clear_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED,
2958 &root->state);
2958 } 2959 }
2959 2960
2960 if (block_rsv) { 2961 if (block_rsv) {
@@ -3271,7 +3272,8 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
3271 btrfs_block_rsv_release(root, root->orphan_block_rsv, 3272 btrfs_block_rsv_release(root, root->orphan_block_rsv,
3272 (u64)-1); 3273 (u64)-1);
3273 3274
3274 if (root->orphan_block_rsv || root->orphan_item_inserted) { 3275 if (root->orphan_block_rsv ||
3276 test_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state)) {
3275 trans = btrfs_join_transaction(root); 3277 trans = btrfs_join_transaction(root);
3276 if (!IS_ERR(trans)) 3278 if (!IS_ERR(trans))
3277 btrfs_end_transaction(trans, root); 3279 btrfs_end_transaction(trans, root);
@@ -3998,7 +4000,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
3998 * not block aligned since we will be keeping the last block of the 4000 * not block aligned since we will be keeping the last block of the
3999 * extent just the way it is. 4001 * extent just the way it is.
4000 */ 4002 */
4001 if (root->ref_cows || root == root->fs_info->tree_root) 4003 if (test_bit(BTRFS_ROOT_REF_COWS, &root->state) ||
4004 root == root->fs_info->tree_root)
4002 btrfs_drop_extent_cache(inode, ALIGN(new_size, 4005 btrfs_drop_extent_cache(inode, ALIGN(new_size,
4003 root->sectorsize), (u64)-1, 0); 4006 root->sectorsize), (u64)-1, 0);
4004 4007
@@ -4091,7 +4094,9 @@ search_again:
4091 extent_num_bytes); 4094 extent_num_bytes);
4092 num_dec = (orig_num_bytes - 4095 num_dec = (orig_num_bytes -
4093 extent_num_bytes); 4096 extent_num_bytes);
4094 if (root->ref_cows && extent_start != 0) 4097 if (test_bit(BTRFS_ROOT_REF_COWS,
4098 &root->state) &&
4099 extent_start != 0)
4095 inode_sub_bytes(inode, num_dec); 4100 inode_sub_bytes(inode, num_dec);
4096 btrfs_mark_buffer_dirty(leaf); 4101 btrfs_mark_buffer_dirty(leaf);
4097 } else { 4102 } else {
@@ -4105,7 +4110,8 @@ search_again:
4105 num_dec = btrfs_file_extent_num_bytes(leaf, fi); 4110 num_dec = btrfs_file_extent_num_bytes(leaf, fi);
4106 if (extent_start != 0) { 4111 if (extent_start != 0) {
4107 found_extent = 1; 4112 found_extent = 1;
4108 if (root->ref_cows) 4113 if (test_bit(BTRFS_ROOT_REF_COWS,
4114 &root->state))
4109 inode_sub_bytes(inode, num_dec); 4115 inode_sub_bytes(inode, num_dec);
4110 } 4116 }
4111 } 4117 }
@@ -4120,10 +4126,9 @@ search_again:
4120 btrfs_file_extent_other_encoding(leaf, fi) == 0) { 4126 btrfs_file_extent_other_encoding(leaf, fi) == 0) {
4121 u32 size = new_size - found_key.offset; 4127 u32 size = new_size - found_key.offset;
4122 4128
4123 if (root->ref_cows) { 4129 if (test_bit(BTRFS_ROOT_REF_COWS, &root->state))
4124 inode_sub_bytes(inode, item_end + 1 - 4130 inode_sub_bytes(inode, item_end + 1 -
4125 new_size); 4131 new_size);
4126 }
4127 4132
4128 /* 4133 /*
4129 * update the ram bytes to properly reflect 4134 * update the ram bytes to properly reflect
@@ -4133,7 +4138,8 @@ search_again:
4133 size = 4138 size =
4134 btrfs_file_extent_calc_inline_size(size); 4139 btrfs_file_extent_calc_inline_size(size);
4135 btrfs_truncate_item(root, path, size, 1); 4140 btrfs_truncate_item(root, path, size, 1);
4136 } else if (root->ref_cows) { 4141 } else if (test_bit(BTRFS_ROOT_REF_COWS,
4142 &root->state)) {
4137 inode_sub_bytes(inode, item_end + 1 - 4143 inode_sub_bytes(inode, item_end + 1 -
4138 found_key.offset); 4144 found_key.offset);
4139 } 4145 }
@@ -4155,8 +4161,9 @@ delete:
4155 } else { 4161 } else {
4156 break; 4162 break;
4157 } 4163 }
4158 if (found_extent && (root->ref_cows || 4164 if (found_extent &&
4159 root == root->fs_info->tree_root)) { 4165 (test_bit(BTRFS_ROOT_REF_COWS, &root->state) ||
4166 root == root->fs_info->tree_root)) {
4160 btrfs_set_path_blocking(path); 4167 btrfs_set_path_blocking(path);
4161 ret = btrfs_free_extent(trans, root, extent_start, 4168 ret = btrfs_free_extent(trans, root, extent_start,
4162 extent_num_bytes, 0, 4169 extent_num_bytes, 0,
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index ebac486f59af..242a37cd26b2 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -638,7 +638,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
638 struct btrfs_trans_handle *trans; 638 struct btrfs_trans_handle *trans;
639 int ret; 639 int ret;
640 640
641 if (!root->ref_cows) 641 if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state))
642 return -EINVAL; 642 return -EINVAL;
643 643
644 atomic_inc(&root->will_be_snapshoted); 644 atomic_inc(&root->will_be_snapshoted);
@@ -2369,7 +2369,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
2369 dest->root_item.drop_level = 0; 2369 dest->root_item.drop_level = 0;
2370 btrfs_set_root_refs(&dest->root_item, 0); 2370 btrfs_set_root_refs(&dest->root_item, 0);
2371 2371
2372 if (!xchg(&dest->orphan_item_inserted, 1)) { 2372 if (!test_and_set_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &dest->state)) {
2373 ret = btrfs_insert_orphan_item(trans, 2373 ret = btrfs_insert_orphan_item(trans,
2374 root->fs_info->tree_root, 2374 root->fs_info->tree_root,
2375 dest->root_key.objectid); 2375 dest->root_key.objectid);
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 7f92ab1daa87..b9cf0f522513 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -528,7 +528,7 @@ static int should_ignore_root(struct btrfs_root *root)
528{ 528{
529 struct btrfs_root *reloc_root; 529 struct btrfs_root *reloc_root;
530 530
531 if (!root->ref_cows) 531 if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state))
532 return 0; 532 return 0;
533 533
534 reloc_root = root->reloc_root; 534 reloc_root = root->reloc_root;
@@ -610,7 +610,7 @@ struct btrfs_root *find_tree_root(struct reloc_control *rc,
610 root = read_fs_root(rc->extent_root->fs_info, root_objectid); 610 root = read_fs_root(rc->extent_root->fs_info, root_objectid);
611 BUG_ON(IS_ERR(root)); 611 BUG_ON(IS_ERR(root));
612 612
613 if (root->ref_cows && 613 if (test_bit(BTRFS_ROOT_REF_COWS, &root->state) &&
614 generation != btrfs_root_generation(&root->root_item)) 614 generation != btrfs_root_generation(&root->root_item))
615 return NULL; 615 return NULL;
616 616
@@ -887,7 +887,7 @@ again:
887 goto out; 887 goto out;
888 } 888 }
889 889
890 if (!root->ref_cows) 890 if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state))
891 cur->cowonly = 1; 891 cur->cowonly = 1;
892 892
893 if (btrfs_root_level(&root->root_item) == cur->level) { 893 if (btrfs_root_level(&root->root_item) == cur->level) {
@@ -954,7 +954,8 @@ again:
954 upper->bytenr = eb->start; 954 upper->bytenr = eb->start;
955 upper->owner = btrfs_header_owner(eb); 955 upper->owner = btrfs_header_owner(eb);
956 upper->level = lower->level + 1; 956 upper->level = lower->level + 1;
957 if (!root->ref_cows) 957 if (!test_bit(BTRFS_ROOT_REF_COWS,
958 &root->state))
958 upper->cowonly = 1; 959 upper->cowonly = 1;
959 960
960 /* 961 /*
@@ -2441,7 +2442,7 @@ struct btrfs_root *select_reloc_root(struct btrfs_trans_handle *trans,
2441 next = walk_up_backref(next, edges, &index); 2442 next = walk_up_backref(next, edges, &index);
2442 root = next->root; 2443 root = next->root;
2443 BUG_ON(!root); 2444 BUG_ON(!root);
2444 BUG_ON(!root->ref_cows); 2445 BUG_ON(!test_bit(BTRFS_ROOT_REF_COWS, &root->state));
2445 2446
2446 if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) { 2447 if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) {
2447 record_reloc_root_in_trans(trans, root); 2448 record_reloc_root_in_trans(trans, root);
@@ -2506,7 +2507,7 @@ struct btrfs_root *select_one_root(struct btrfs_trans_handle *trans,
2506 BUG_ON(!root); 2507 BUG_ON(!root);
2507 2508
2508 /* no other choice for non-references counted tree */ 2509 /* no other choice for non-references counted tree */
2509 if (!root->ref_cows) 2510 if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state))
2510 return root; 2511 return root;
2511 2512
2512 if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) 2513 if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID)
@@ -2893,14 +2894,14 @@ static int relocate_tree_block(struct btrfs_trans_handle *trans,
2893 goto out; 2894 goto out;
2894 } 2895 }
2895 2896
2896 if (!root || root->ref_cows) { 2897 if (!root || test_bit(BTRFS_ROOT_REF_COWS, &root->state)) {
2897 ret = reserve_metadata_space(trans, rc, node); 2898 ret = reserve_metadata_space(trans, rc, node);
2898 if (ret) 2899 if (ret)
2899 goto out; 2900 goto out;
2900 } 2901 }
2901 2902
2902 if (root) { 2903 if (root) {
2903 if (root->ref_cows) { 2904 if (test_bit(BTRFS_ROOT_REF_COWS, &root->state)) {
2904 BUG_ON(node->new_bytenr); 2905 BUG_ON(node->new_bytenr);
2905 BUG_ON(!list_empty(&node->list)); 2906 BUG_ON(!list_empty(&node->list));
2906 btrfs_record_root_in_trans(trans, root); 2907 btrfs_record_root_in_trans(trans, root);
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 38bb47e7d6b1..360a728a639f 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -306,7 +306,7 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
306 break; 306 break;
307 } 307 }
308 308
309 root->orphan_item_inserted = 1; 309 set_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state);
310 310
311 err = btrfs_insert_fs_root(root->fs_info, root); 311 err = btrfs_insert_fs_root(root->fs_info, root);
312 if (err) { 312 if (err) {
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index c30815e79235..7c4c049da871 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -241,18 +241,19 @@ loop:
241static int record_root_in_trans(struct btrfs_trans_handle *trans, 241static int record_root_in_trans(struct btrfs_trans_handle *trans,
242 struct btrfs_root *root) 242 struct btrfs_root *root)
243{ 243{
244 if (root->ref_cows && root->last_trans < trans->transid) { 244 if (test_bit(BTRFS_ROOT_REF_COWS, &root->state) &&
245 root->last_trans < trans->transid) {
245 WARN_ON(root == root->fs_info->extent_root); 246 WARN_ON(root == root->fs_info->extent_root);
246 WARN_ON(root->commit_root != root->node); 247 WARN_ON(root->commit_root != root->node);
247 248
248 /* 249 /*
249 * see below for in_trans_setup usage rules 250 * see below for IN_TRANS_SETUP usage rules
250 * we have the reloc mutex held now, so there 251 * we have the reloc mutex held now, so there
251 * is only one writer in this function 252 * is only one writer in this function
252 */ 253 */
253 root->in_trans_setup = 1; 254 set_bit(BTRFS_ROOT_IN_TRANS_SETUP, &root->state);
254 255
255 /* make sure readers find in_trans_setup before 256 /* make sure readers find IN_TRANS_SETUP before
256 * they find our root->last_trans update 257 * they find our root->last_trans update
257 */ 258 */
258 smp_wmb(); 259 smp_wmb();
@@ -279,7 +280,7 @@ static int record_root_in_trans(struct btrfs_trans_handle *trans,
279 * But, we have to set root->last_trans before we 280 * But, we have to set root->last_trans before we
280 * init the relocation root, otherwise, we trip over warnings 281 * init the relocation root, otherwise, we trip over warnings
281 * in ctree.c. The solution used here is to flag ourselves 282 * in ctree.c. The solution used here is to flag ourselves
282 * with root->in_trans_setup. When this is 1, we're still 283 * with root IN_TRANS_SETUP. When this is 1, we're still
283 * fixing up the reloc trees and everyone must wait. 284 * fixing up the reloc trees and everyone must wait.
284 * 285 *
285 * When this is zero, they can trust root->last_trans and fly 286 * When this is zero, they can trust root->last_trans and fly
@@ -288,8 +289,8 @@ static int record_root_in_trans(struct btrfs_trans_handle *trans,
288 * done before we pop in the zero below 289 * done before we pop in the zero below
289 */ 290 */
290 btrfs_init_reloc_root(trans, root); 291 btrfs_init_reloc_root(trans, root);
291 smp_wmb(); 292 smp_mb__before_clear_bit();
292 root->in_trans_setup = 0; 293 clear_bit(BTRFS_ROOT_IN_TRANS_SETUP, &root->state);
293 } 294 }
294 return 0; 295 return 0;
295} 296}
@@ -298,16 +299,16 @@ static int record_root_in_trans(struct btrfs_trans_handle *trans,
298int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans, 299int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans,
299 struct btrfs_root *root) 300 struct btrfs_root *root)
300{ 301{
301 if (!root->ref_cows) 302 if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state))
302 return 0; 303 return 0;
303 304
304 /* 305 /*
305 * see record_root_in_trans for comments about in_trans_setup usage 306 * see record_root_in_trans for comments about IN_TRANS_SETUP usage
306 * and barriers 307 * and barriers
307 */ 308 */
308 smp_rmb(); 309 smp_rmb();
309 if (root->last_trans == trans->transid && 310 if (root->last_trans == trans->transid &&
310 !root->in_trans_setup) 311 !test_bit(BTRFS_ROOT_IN_TRANS_SETUP, &root->state))
311 return 0; 312 return 0;
312 313
313 mutex_lock(&root->fs_info->reloc_mutex); 314 mutex_lock(&root->fs_info->reloc_mutex);
@@ -365,7 +366,7 @@ static int may_wait_transaction(struct btrfs_root *root, int type)
365static inline bool need_reserve_reloc_root(struct btrfs_root *root) 366static inline bool need_reserve_reloc_root(struct btrfs_root *root)
366{ 367{
367 if (!root->fs_info->reloc_ctl || 368 if (!root->fs_info->reloc_ctl ||
368 !root->ref_cows || 369 !test_bit(BTRFS_ROOT_REF_COWS, &root->state) ||
369 root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID || 370 root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID ||
370 root->reloc_root) 371 root->reloc_root)
371 return false; 372 return false;
@@ -1049,8 +1050,8 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans,
1049 btrfs_save_ino_cache(root, trans); 1050 btrfs_save_ino_cache(root, trans);
1050 1051
1051 /* see comments in should_cow_block() */ 1052 /* see comments in should_cow_block() */
1052 root->force_cow = 0; 1053 clear_bit(BTRFS_ROOT_FORCE_COW, &root->state);
1053 smp_wmb(); 1054 smp_mb__after_clear_bit();
1054 1055
1055 if (root->commit_root != root->node) { 1056 if (root->commit_root != root->node) {
1056 list_add_tail(&root->dirty_list, 1057 list_add_tail(&root->dirty_list,
@@ -1081,7 +1082,7 @@ int btrfs_defrag_root(struct btrfs_root *root)
1081 struct btrfs_trans_handle *trans; 1082 struct btrfs_trans_handle *trans;
1082 int ret; 1083 int ret;
1083 1084
1084 if (xchg(&root->defrag_running, 1)) 1085 if (test_and_set_bit(BTRFS_ROOT_DEFRAG_RUNNING, &root->state))
1085 return 0; 1086 return 0;
1086 1087
1087 while (1) { 1088 while (1) {
@@ -1104,7 +1105,7 @@ int btrfs_defrag_root(struct btrfs_root *root)
1104 break; 1105 break;
1105 } 1106 }
1106 } 1107 }
1107 root->defrag_running = 0; 1108 clear_bit(BTRFS_ROOT_DEFRAG_RUNNING, &root->state);
1108 return ret; 1109 return ret;
1109} 1110}
1110 1111
@@ -1271,7 +1272,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
1271 } 1272 }
1272 1273
1273 /* see comments in should_cow_block() */ 1274 /* see comments in should_cow_block() */
1274 root->force_cow = 1; 1275 set_bit(BTRFS_ROOT_FORCE_COW, &root->state);
1275 smp_wmb(); 1276 smp_wmb();
1276 1277
1277 btrfs_set_root_node(new_root_item, tmp); 1278 btrfs_set_root_node(new_root_item, tmp);
diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c
index 76928ca97741..a63719cc9578 100644
--- a/fs/btrfs/tree-defrag.c
+++ b/fs/btrfs/tree-defrag.c
@@ -49,7 +49,7 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
49 goto out; 49 goto out;
50 } 50 }
51 51
52 if (root->ref_cows == 0) 52 if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state))
53 goto out; 53 goto out;
54 54
55 if (btrfs_test_opt(root, SSD)) 55 if (btrfs_test_opt(root, SSD))
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index e2f45fc02610..ffee15856130 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -152,9 +152,9 @@ static int start_log_trans(struct btrfs_trans_handle *trans,
152 152
153 if (!root->log_start_pid) { 153 if (!root->log_start_pid) {
154 root->log_start_pid = current->pid; 154 root->log_start_pid = current->pid;
155 root->log_multiple_pids = false; 155 clear_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state);
156 } else if (root->log_start_pid != current->pid) { 156 } else if (root->log_start_pid != current->pid) {
157 root->log_multiple_pids = true; 157 set_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state);
158 } 158 }
159 159
160 atomic_inc(&root->log_batch); 160 atomic_inc(&root->log_batch);
@@ -181,7 +181,7 @@ static int start_log_trans(struct btrfs_trans_handle *trans,
181 if (ret) 181 if (ret)
182 goto out; 182 goto out;
183 } 183 }
184 root->log_multiple_pids = false; 184 clear_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state);
185 root->log_start_pid = current->pid; 185 root->log_start_pid = current->pid;
186 atomic_inc(&root->log_batch); 186 atomic_inc(&root->log_batch);
187 atomic_inc(&root->log_writers); 187 atomic_inc(&root->log_writers);
@@ -2500,7 +2500,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2500 while (1) { 2500 while (1) {
2501 int batch = atomic_read(&root->log_batch); 2501 int batch = atomic_read(&root->log_batch);
2502 /* when we're on an ssd, just kick the log commit out */ 2502 /* when we're on an ssd, just kick the log commit out */
2503 if (!btrfs_test_opt(root, SSD) && root->log_multiple_pids) { 2503 if (!btrfs_test_opt(root, SSD) &&
2504 test_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state)) {
2504 mutex_unlock(&root->log_mutex); 2505 mutex_unlock(&root->log_mutex);
2505 schedule_timeout_uninterruptible(1); 2506 schedule_timeout_uninterruptible(1);
2506 mutex_lock(&root->log_mutex); 2507 mutex_lock(&root->log_mutex);