mirror of
https://github.com/kdave/btrfs-progs
synced 2024-12-26 08:02:21 +00:00
btrfs-progs: copy btrfs_root::state from kernel
We changed from members in the root for all the different flags to a bit based flag system. In order to make syncing the kernel code into btrfs-progs easier go ahead and sync in the bits we use and update all the users of the old ->track_dirty and ->ref_cows to use the state bits. Signed-off-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
c6b160c4e4
commit
8e427ada49
@ -31,6 +31,7 @@
|
||||
#include "kernel-lib/list.h"
|
||||
#include "kernel-lib/rbtree.h"
|
||||
#include "kernel-lib/rbtree_types.h"
|
||||
#include "kernel-lib/bitops.h"
|
||||
#include "kernel-shared/uapi/btrfs.h"
|
||||
#include "kernel-shared/extent_io.h"
|
||||
#include "kernel-shared/ctree.h"
|
||||
@ -467,7 +468,7 @@ static void record_root_in_trans(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root)
|
||||
{
|
||||
if (root->last_trans != trans->transid) {
|
||||
root->track_dirty = 1;
|
||||
set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);
|
||||
root->last_trans = trans->transid;
|
||||
root->commit_root = root->node;
|
||||
extent_buffer_get(root->node);
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "kernel-shared/disk-io.h"
|
||||
#include "kernel-shared/transaction.h"
|
||||
#include "kernel-shared/print-tree.h"
|
||||
#include "kernel-lib/bitops.h"
|
||||
#include "crypto/crc32c.h"
|
||||
#include "common/internal.h"
|
||||
#include "common/messages.h"
|
||||
@ -119,7 +120,8 @@ void btrfs_release_path(struct btrfs_path *p)
|
||||
|
||||
void add_root_to_dirty_list(struct btrfs_root *root)
|
||||
{
|
||||
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);
|
||||
}
|
||||
@ -155,9 +157,10 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
|
||||
memcpy(new_root, root, sizeof(*new_root));
|
||||
new_root->root_key.objectid = new_root_objectid;
|
||||
|
||||
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_SHAREABLE, &root->state) &&
|
||||
trans->transid != root->fs_info->running_transaction->transid);
|
||||
WARN_ON(test_bit(BTRFS_ROOT_SHAREABLE, &root->state) &&
|
||||
trans->transid != root->last_trans);
|
||||
|
||||
level = btrfs_header_level(buf);
|
||||
if (level == 0)
|
||||
@ -219,7 +222,7 @@ int btrfs_create_root(struct btrfs_trans_handle *trans,
|
||||
|
||||
btrfs_setup_root(new_root, fs_info, objectid);
|
||||
if (!is_fstree(objectid))
|
||||
new_root->track_dirty = 1;
|
||||
set_bit(BTRFS_ROOT_TRACK_DIRTY, &new_root->state);
|
||||
add_root_to_dirty_list(new_root);
|
||||
|
||||
new_root->objectid = objectid;
|
||||
@ -332,7 +335,7 @@ static 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_SHAREABLE, &root->state) &&
|
||||
buf != root->node && buf != root->commit_root &&
|
||||
(btrfs_header_generation(buf) <=
|
||||
btrfs_root_last_snapshot(&root->root_item) ||
|
||||
@ -446,9 +449,10 @@ int __btrfs_cow_block(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_disk_key disk_key;
|
||||
int level;
|
||||
|
||||
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_SHAREABLE, &root->state) &&
|
||||
trans->transid != root->fs_info->running_transaction->transid);
|
||||
WARN_ON(test_bit(BTRFS_ROOT_SHAREABLE, &root->state) &&
|
||||
trans->transid != root->last_trans);
|
||||
|
||||
level = btrfs_header_level(buf);
|
||||
|
||||
|
@ -388,6 +388,68 @@ static inline bool btrfs_is_zoned(const struct btrfs_fs_info *fs_info)
|
||||
return fs_info->zoned != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The state of btrfs root
|
||||
*/
|
||||
enum {
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
BTRFS_ROOT_IN_TRANS_SETUP,
|
||||
|
||||
/*
|
||||
* Set if tree blocks of this root can be shared by other roots.
|
||||
* Only subvolume trees and their reloc trees have this bit set.
|
||||
* Conflicts with TRACK_DIRTY bit.
|
||||
*
|
||||
* This affects two things:
|
||||
*
|
||||
* - How balance works
|
||||
* For shareable roots, we need to use reloc tree and do path
|
||||
* replacement for balance, and need various pre/post hooks for
|
||||
* snapshot creation to handle them.
|
||||
*
|
||||
* While for non-shareable trees, we just simply do a tree search
|
||||
* with COW.
|
||||
*
|
||||
* - How dirty roots are tracked
|
||||
* For shareable roots, btrfs_record_root_in_trans() is needed to
|
||||
* track them, while non-subvolume roots have TRACK_DIRTY bit, they
|
||||
* don't need to set this manually.
|
||||
*/
|
||||
BTRFS_ROOT_SHAREABLE,
|
||||
BTRFS_ROOT_TRACK_DIRTY,
|
||||
BTRFS_ROOT_IN_RADIX,
|
||||
BTRFS_ROOT_ORPHAN_ITEM_INSERTED,
|
||||
BTRFS_ROOT_DEFRAG_RUNNING,
|
||||
BTRFS_ROOT_FORCE_COW,
|
||||
BTRFS_ROOT_MULTI_LOG_TASKS,
|
||||
BTRFS_ROOT_DIRTY,
|
||||
BTRFS_ROOT_DELETING,
|
||||
|
||||
/*
|
||||
* Reloc tree is orphan, only kept here for qgroup delayed subtree scan
|
||||
*
|
||||
* Set for the subvolume tree owning the reloc tree.
|
||||
*/
|
||||
BTRFS_ROOT_DEAD_RELOC_TREE,
|
||||
/* Mark dead root stored on device whose cleanup needs to be resumed */
|
||||
BTRFS_ROOT_DEAD_TREE,
|
||||
/* The root has a log tree. Used for subvolume roots and the tree root. */
|
||||
BTRFS_ROOT_HAS_LOG_TREE,
|
||||
/* Qgroup flushing is in progress */
|
||||
BTRFS_ROOT_QGROUP_FLUSHING,
|
||||
/* We started the orphan cleanup for this root. */
|
||||
BTRFS_ROOT_ORPHAN_CLEANUP,
|
||||
/* This root has a drop operation that was started previously. */
|
||||
BTRFS_ROOT_UNFINISHED_DROP,
|
||||
/* This reloc root needs to have its buffers lockdep class reset. */
|
||||
BTRFS_ROOT_RESET_LOCKDEP_CLASS,
|
||||
};
|
||||
|
||||
/*
|
||||
* in ram representation of the tree. extent_root is used for all allocations
|
||||
* and for the extent tree extent_root root.
|
||||
@ -401,9 +463,7 @@ struct btrfs_root {
|
||||
u64 objectid;
|
||||
u64 last_trans;
|
||||
|
||||
int ref_cows;
|
||||
int track_dirty;
|
||||
|
||||
unsigned long state;
|
||||
|
||||
u32 type;
|
||||
u64 last_inode_alloc;
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "crypto/crc32c.h"
|
||||
#include "common/utils.h"
|
||||
#include "kernel-shared/print-tree.h"
|
||||
#include "kernel-lib/bitops.h"
|
||||
#include "common/rbtree-utils.h"
|
||||
#include "common/device-scan.h"
|
||||
#include "common/device-utils.h"
|
||||
@ -491,8 +492,7 @@ void btrfs_setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info,
|
||||
{
|
||||
root->node = NULL;
|
||||
root->commit_root = NULL;
|
||||
root->ref_cows = 0;
|
||||
root->track_dirty = 0;
|
||||
root->state = 0;
|
||||
|
||||
root->fs_info = fs_info;
|
||||
root->objectid = objectid;
|
||||
@ -654,9 +654,9 @@ out:
|
||||
}
|
||||
insert:
|
||||
if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID)
|
||||
root->track_dirty = 1;
|
||||
set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);
|
||||
if (is_fstree(root->root_key.objectid))
|
||||
root->ref_cows = 1;
|
||||
set_bit(BTRFS_ROOT_SHAREABLE, &root->state);
|
||||
return root;
|
||||
}
|
||||
|
||||
@ -1062,7 +1062,7 @@ static int load_global_roots_objectid(struct btrfs_fs_info *fs_info,
|
||||
free(root);
|
||||
break;
|
||||
}
|
||||
root->track_dirty = 1;
|
||||
set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);
|
||||
|
||||
ret = btrfs_global_root_insert(fs_info, root);
|
||||
if (ret) {
|
||||
@ -1099,7 +1099,7 @@ static int load_global_roots_objectid(struct btrfs_fs_info *fs_info,
|
||||
root->root_key.objectid = objectid;
|
||||
root->root_key.type = BTRFS_ROOT_ITEM_KEY;
|
||||
root->root_key.offset = i;
|
||||
root->track_dirty = 1;
|
||||
set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);
|
||||
root->node = btrfs_find_create_tree_block(fs_info, 0);
|
||||
if (!root->node) {
|
||||
free(root);
|
||||
@ -1232,7 +1232,8 @@ int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr,
|
||||
error("couldn't load block group tree");
|
||||
return -EIO;
|
||||
}
|
||||
fs_info->block_group_root->track_dirty = 1;
|
||||
set_bit(BTRFS_ROOT_TRACK_DIRTY,
|
||||
&fs_info->block_group_root->state);
|
||||
}
|
||||
|
||||
ret = btrfs_find_and_setup_root(root, fs_info,
|
||||
@ -1242,7 +1243,7 @@ int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr,
|
||||
printk("Couldn't setup device tree\n");
|
||||
return -EIO;
|
||||
}
|
||||
fs_info->dev_root->track_dirty = 1;
|
||||
set_bit(BTRFS_ROOT_TRACK_DIRTY, &fs_info->dev_root->state);
|
||||
|
||||
ret = btrfs_find_and_setup_root(root, fs_info,
|
||||
BTRFS_UUID_TREE_OBJECTID,
|
||||
@ -1251,7 +1252,7 @@ int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr,
|
||||
free(fs_info->uuid_root);
|
||||
fs_info->uuid_root = NULL;
|
||||
} else {
|
||||
fs_info->uuid_root->track_dirty = 1;
|
||||
set_bit(BTRFS_ROOT_TRACK_DIRTY, &fs_info->uuid_root->state);
|
||||
}
|
||||
|
||||
ret = btrfs_find_and_setup_root(root, fs_info,
|
||||
@ -2355,7 +2356,7 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
|
||||
|
||||
extent_buffer_get(root->node);
|
||||
root->commit_root = root->node;
|
||||
root->track_dirty = 1;
|
||||
set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);
|
||||
|
||||
root->root_item.flags = 0;
|
||||
root->root_item.byte_limit = 0;
|
||||
|
@ -1470,7 +1470,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_SHAREABLE, &root->state) && level == 0)
|
||||
return 0;
|
||||
|
||||
if (inc)
|
||||
@ -2358,11 +2358,11 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans,
|
||||
}
|
||||
|
||||
/*
|
||||
* Also preallocate metadata for csum tree and fs trees (root->ref_cows
|
||||
* already set), as they can consume a lot of metadata space.
|
||||
* Pre-allocate to avoid unexpected ENOSPC.
|
||||
* Also preallocate metadata for csum tree and fs trees
|
||||
* (BTRFS_ROOT_SHAREABLE already set) as they can consume a lot of
|
||||
* metadata space. Pre-allocate to avoid unexpected ENOSPC.
|
||||
*/
|
||||
if (root->ref_cows ||
|
||||
if (test_bit(BTRFS_ROOT_SHAREABLE, &root->state) ||
|
||||
root->root_key.objectid == BTRFS_CSUM_TREE_OBJECTID) {
|
||||
if (!(profile & BTRFS_BLOCK_GROUP_METADATA)) {
|
||||
ret = do_chunk_alloc(trans, info,
|
||||
|
Loading…
Reference in New Issue
Block a user