Skip to content

Commit

Permalink
Btrfs: use bitfield instead of integer data type for the some variant…
Browse files Browse the repository at this point in the history
…s 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>
  • Loading branch information
Miao Xie authored and Chris Mason committed Jun 10, 2014
1 parent f959492 commit 27cdeb7
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 94 deletions.
25 changes: 14 additions & 11 deletions fs/btrfs/ctree.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,8 @@ static struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root)
static void add_root_to_dirty_list(struct btrfs_root *root)
{
spin_lock(&root->fs_info->trans_lock);
if (root->track_dirty && list_empty(&root->dirty_list)) {
if (test_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state) &&
list_empty(&root->dirty_list)) {
list_add(&root->dirty_list,
&root->fs_info->dirty_cowonly_roots);
}
Expand All @@ -246,9 +247,10 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
int level;
struct btrfs_disk_key disk_key;

WARN_ON(root->ref_cows && trans->transid !=
root->fs_info->running_transaction->transid);
WARN_ON(root->ref_cows && trans->transid != root->last_trans);
WARN_ON(test_bit(BTRFS_ROOT_REF_COWS, &root->state) &&
trans->transid != root->fs_info->running_transaction->transid);
WARN_ON(test_bit(BTRFS_ROOT_REF_COWS, &root->state) &&
trans->transid != root->last_trans);

level = btrfs_header_level(buf);
if (level == 0)
Expand Down Expand Up @@ -997,14 +999,14 @@ int btrfs_block_can_be_shared(struct btrfs_root *root,
* snapshot and the block was not allocated by tree relocation,
* we know the block is not shared.
*/
if (root->ref_cows &&
if (test_bit(BTRFS_ROOT_REF_COWS, &root->state) &&
buf != root->node && buf != root->commit_root &&
(btrfs_header_generation(buf) <=
btrfs_root_last_snapshot(&root->root_item) ||
btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC)))
return 1;
#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
if (root->ref_cows &&
if (test_bit(BTRFS_ROOT_REF_COWS, &root->state) &&
btrfs_header_backref_rev(buf) < BTRFS_MIXED_BACKREF_REV)
return 1;
#endif
Expand Down Expand Up @@ -1146,9 +1148,10 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,

btrfs_assert_tree_locked(buf);

WARN_ON(root->ref_cows && trans->transid !=
root->fs_info->running_transaction->transid);
WARN_ON(root->ref_cows && trans->transid != root->last_trans);
WARN_ON(test_bit(BTRFS_ROOT_REF_COWS, &root->state) &&
trans->transid != root->fs_info->running_transaction->transid);
WARN_ON(test_bit(BTRFS_ROOT_REF_COWS, &root->state) &&
trans->transid != root->last_trans);

level = btrfs_header_level(buf);

Expand Down Expand Up @@ -1193,7 +1196,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
return ret;
}

if (root->ref_cows) {
if (test_bit(BTRFS_ROOT_REF_COWS, &root->state)) {
ret = btrfs_reloc_cow_block(trans, root, buf, cow);
if (ret)
return ret;
Expand Down Expand Up @@ -1556,7 +1559,7 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans,
!btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN) &&
!(root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID &&
btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC)) &&
!root->force_cow)
!test_bit(BTRFS_ROOT_FORCE_COW, &root->state))
return 0;
return 1;
}
Expand Down
39 changes: 21 additions & 18 deletions fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -1710,6 +1710,26 @@ struct btrfs_subvolume_writers {
wait_queue_head_t wait;
};

/*
* The state of btrfs root
*/
/*
* 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
*/
#define BTRFS_ROOT_IN_TRANS_SETUP 0
#define BTRFS_ROOT_REF_COWS 1
#define BTRFS_ROOT_TRACK_DIRTY 2
#define BTRFS_ROOT_IN_RADIX 3
#define BTRFS_ROOT_DUMMY_ROOT 4
#define BTRFS_ROOT_ORPHAN_ITEM_INSERTED 5
#define BTRFS_ROOT_DEFRAG_RUNNING 6
#define BTRFS_ROOT_FORCE_COW 7
#define BTRFS_ROOT_MULTI_LOG_TASKS 8

/*
* in ram representation of the tree. extent_root is used for all allocations
* and for the extent tree extent_root root.
Expand All @@ -1721,6 +1741,7 @@ struct btrfs_root {
struct btrfs_root *log_root;
struct btrfs_root *reloc_root;

unsigned long state;
struct btrfs_root_item root_item;
struct btrfs_key root_key;
struct btrfs_fs_info *fs_info;
Expand Down Expand Up @@ -1755,7 +1776,6 @@ struct btrfs_root {
/* Just be updated when the commit succeeds. */
int last_log_commit;
pid_t log_start_pid;
bool log_multiple_pids;

u64 objectid;
u64 last_trans;
Expand All @@ -1775,23 +1795,9 @@ struct btrfs_root {

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;
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
int dummy_root;
#endif
u64 defrag_trans_start;
struct btrfs_key defrag_progress;
struct btrfs_key defrag_max;
int defrag_running;
char *name;

/* the dirty list is only used by non-reference counted roots */
Expand All @@ -1805,7 +1811,6 @@ struct btrfs_root {
spinlock_t orphan_lock;
atomic_t orphan_inodes;
struct btrfs_block_rsv *orphan_block_rsv;
int orphan_item_inserted;
int orphan_cleanup_state;

spinlock_t inode_lock;
Expand All @@ -1823,8 +1828,6 @@ struct btrfs_root {
*/
dev_t anon_dev;

int force_cow;

spinlock_t root_item_lock;
atomic_t refs;

Expand Down
33 changes: 15 additions & 18 deletions fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1201,10 +1201,7 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
root->nodesize = nodesize;
root->leafsize = leafsize;
root->stripesize = stripesize;
root->ref_cows = 0;
root->track_dirty = 0;
root->in_radix = 0;
root->orphan_item_inserted = 0;
root->state = 0;
root->orphan_cleanup_state = 0;

root->objectid = objectid;
Expand Down Expand Up @@ -1265,7 +1262,6 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
else
root->defrag_trans_start = 0;
init_completion(&root->kobj_unregister);
root->defrag_running = 0;
root->root_key.objectid = objectid;
root->anon_dev = 0;

Expand All @@ -1290,7 +1286,7 @@ struct btrfs_root *btrfs_alloc_dummy_root(void)
if (!root)
return ERR_PTR(-ENOMEM);
__setup_root(4096, 4096, 4096, 4096, root, NULL, 1);
root->dummy_root = 1;
set_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state);

return root;
}
Expand Down Expand Up @@ -1341,8 +1337,7 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
btrfs_mark_buffer_dirty(leaf);

root->commit_root = btrfs_root_node(root);
root->track_dirty = 1;

set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);

root->root_item.flags = 0;
root->root_item.byte_limit = 0;
Expand Down Expand Up @@ -1396,13 +1391,15 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans,
root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID;
root->root_key.type = BTRFS_ROOT_ITEM_KEY;
root->root_key.offset = BTRFS_TREE_LOG_OBJECTID;

/*
* DON'T set REF_COWS for log trees
*
* log trees do not get reference counted because they go away
* before a real commit is actually done. They do store pointers
* to file data extents, and those reference counts still get
* updated (along with back refs to the log tree).
*/
root->ref_cows = 0;

leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0,
BTRFS_TREE_LOG_OBJECTID, NULL,
Expand Down Expand Up @@ -1536,7 +1533,7 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_root *tree_root,
return root;

if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
root->ref_cows = 1;
set_bit(BTRFS_ROOT_REF_COWS, &root->state);
btrfs_check_and_init_root_item(&root->root_item);
}

Expand Down Expand Up @@ -1606,7 +1603,7 @@ int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info,
(unsigned long)root->root_key.objectid,
root);
if (ret == 0)
root->in_radix = 1;
set_bit(BTRFS_ROOT_IN_RADIX, &root->state);
spin_unlock(&fs_info->fs_roots_radix_lock);
radix_tree_preload_end();

Expand Down Expand Up @@ -1662,7 +1659,7 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
if (ret < 0)
goto fail;
if (ret == 0)
root->orphan_item_inserted = 1;
set_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state);

ret = btrfs_insert_fs_root(fs_info, root);
if (ret) {
Expand Down Expand Up @@ -2101,7 +2098,7 @@ static void del_fs_roots(struct btrfs_fs_info *fs_info)
struct btrfs_root, root_list);
list_del(&gang[0]->root_list);

if (gang[0]->in_radix) {
if (test_bit(BTRFS_ROOT_IN_RADIX, &gang[0]->state)) {
btrfs_drop_and_free_fs_root(fs_info, gang[0]);
} else {
free_extent_buffer(gang[0]->node);
Expand Down Expand Up @@ -2694,7 +2691,7 @@ int open_ctree(struct super_block *sb,
ret = PTR_ERR(extent_root);
goto recovery_tree_root;
}
extent_root->track_dirty = 1;
set_bit(BTRFS_ROOT_TRACK_DIRTY, &extent_root->state);
fs_info->extent_root = extent_root;

location.objectid = BTRFS_DEV_TREE_OBJECTID;
Expand All @@ -2703,7 +2700,7 @@ int open_ctree(struct super_block *sb,
ret = PTR_ERR(dev_root);
goto recovery_tree_root;
}
dev_root->track_dirty = 1;
set_bit(BTRFS_ROOT_TRACK_DIRTY, &dev_root->state);
fs_info->dev_root = dev_root;
btrfs_init_devices_late(fs_info);

Expand All @@ -2713,13 +2710,13 @@ int open_ctree(struct super_block *sb,
ret = PTR_ERR(csum_root);
goto recovery_tree_root;
}
csum_root->track_dirty = 1;
set_bit(BTRFS_ROOT_TRACK_DIRTY, &csum_root->state);
fs_info->csum_root = csum_root;

location.objectid = BTRFS_QUOTA_TREE_OBJECTID;
quota_root = btrfs_read_tree_root(tree_root, &location);
if (!IS_ERR(quota_root)) {
quota_root->track_dirty = 1;
set_bit(BTRFS_ROOT_TRACK_DIRTY, &quota_root->state);
fs_info->quota_enabled = 1;
fs_info->pending_quota_state = 1;
fs_info->quota_root = quota_root;
Expand All @@ -2734,7 +2731,7 @@ int open_ctree(struct super_block *sb,
create_uuid_tree = true;
check_uuid_tree = false;
} else {
uuid_root->track_dirty = 1;
set_bit(BTRFS_ROOT_TRACK_DIRTY, &uuid_root->state);
fs_info->uuid_root = uuid_root;
create_uuid_tree = false;
check_uuid_tree =
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 @@ -2983,7 +2983,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
nritems = btrfs_header_nritems(buf);
level = btrfs_header_level(buf);

if (!root->ref_cows && level == 0)
if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state) && level == 0)
return 0;

if (inc)
Expand Down Expand Up @@ -4472,7 +4472,7 @@ static struct btrfs_block_rsv *get_block_rsv(
{
struct btrfs_block_rsv *block_rsv = NULL;

if (root->ref_cows)
if (test_bit(BTRFS_ROOT_REF_COWS, &root->state))
block_rsv = trans->block_rsv;

if (root == root->fs_info->csum_root && trans->adding_csums)
Expand Down Expand Up @@ -7838,7 +7838,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
}
}

if (root->in_radix) {
if (test_bit(BTRFS_ROOT_IN_RADIX, &root->state)) {
btrfs_drop_and_free_fs_root(tree_root->fs_info, root);
} else {
free_extent_buffer(root->node);
Expand Down
4 changes: 3 additions & 1 deletion fs/btrfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ int __btrfs_drop_extents(struct btrfs_trans_handle *trans,
int recow;
int ret;
int modify_tree = -1;
int update_refs = (root->ref_cows || root == root->fs_info->tree_root);
int update_refs;
int found = 0;
int leafs_visited = 0;

Expand All @@ -724,6 +724,8 @@ int __btrfs_drop_extents(struct btrfs_trans_handle *trans,
if (start >= BTRFS_I(inode)->disk_i_size && !replace_extent)
modify_tree = 0;

update_refs = (test_bit(BTRFS_ROOT_REF_COWS, &root->state) ||
root == root->fs_info->tree_root);
while (1) {
recow = 0;
ret = btrfs_lookup_file_extent(trans, root, path, ino,
Expand Down
Loading

0 comments on commit 27cdeb7

Please sign in to comment.