Commit f3a84ccd authored by Filipe Manana's avatar Filipe Manana Committed by David Sterba

btrfs: move the tree mod log code into its own file

The tree modification log, which records modifications done to btrees, is
quite large and currently spread all over ctree.c, which is a huge file
already.

To make things better organized, move all that code into its own separate
source and header files. Functions and definitions that are used outside
of the module (mostly by ctree.c) are renamed so that they start with a
"btrfs_" prefix. Everything else remains unchanged.

This makes it easier to go over the tree modification log code every
time I need to go read it to fix a bug.
Reviewed-by: default avatarAnand Jain <anand.jain@oracle.com>
Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
[ minor comment updates ]
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 9a002d53
...@@ -30,7 +30,7 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \ ...@@ -30,7 +30,7 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \
reada.o backref.o ulist.o qgroup.o send.o dev-replace.o raid56.o \ reada.o backref.o ulist.o qgroup.o send.o dev-replace.o raid56.o \
uuid-tree.o props.o free-space-tree.o tree-checker.o space-info.o \ uuid-tree.o props.o free-space-tree.o tree-checker.o space-info.o \
block-rsv.o delalloc-space.o block-group.o discard.o reflink.o \ block-rsv.o delalloc-space.o block-group.o discard.o reflink.o \
subpage.o subpage.o tree-mod-log.o
btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o
btrfs-$(CONFIG_BTRFS_FS_CHECK_INTEGRITY) += check-integrity.o btrfs-$(CONFIG_BTRFS_FS_CHECK_INTEGRITY) += check-integrity.o
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "delayed-ref.h" #include "delayed-ref.h"
#include "locking.h" #include "locking.h"
#include "misc.h" #include "misc.h"
#include "tree-mod-log.h"
/* Just an arbitrary number so we can be sure this happened */ /* Just an arbitrary number so we can be sure this happened */
#define BACKREF_FOUND_SHARED 6 #define BACKREF_FOUND_SHARED 6
...@@ -452,7 +453,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, ...@@ -452,7 +453,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
if (path->slots[0] >= btrfs_header_nritems(eb) || if (path->slots[0] >= btrfs_header_nritems(eb) ||
is_shared_data_backref(preftrees, eb->start) || is_shared_data_backref(preftrees, eb->start) ||
ref->root_id != btrfs_header_owner(eb)) { ref->root_id != btrfs_header_owner(eb)) {
if (time_seq == SEQ_LAST) if (time_seq == BTRFS_SEQ_LAST)
ret = btrfs_next_leaf(root, path); ret = btrfs_next_leaf(root, path);
else else
ret = btrfs_next_old_leaf(root, path, time_seq); ret = btrfs_next_old_leaf(root, path, time_seq);
...@@ -476,7 +477,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, ...@@ -476,7 +477,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
if (slot == 0 && if (slot == 0 &&
(is_shared_data_backref(preftrees, eb->start) || (is_shared_data_backref(preftrees, eb->start) ||
ref->root_id != btrfs_header_owner(eb))) { ref->root_id != btrfs_header_owner(eb))) {
if (time_seq == SEQ_LAST) if (time_seq == BTRFS_SEQ_LAST)
ret = btrfs_next_leaf(root, path); ret = btrfs_next_leaf(root, path);
else else
ret = btrfs_next_old_leaf(root, path, time_seq); ret = btrfs_next_old_leaf(root, path, time_seq);
...@@ -514,7 +515,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, ...@@ -514,7 +515,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
eie = NULL; eie = NULL;
} }
next: next:
if (time_seq == SEQ_LAST) if (time_seq == BTRFS_SEQ_LAST)
ret = btrfs_next_item(root, path); ret = btrfs_next_item(root, path);
else else
ret = btrfs_next_old_item(root, path, time_seq); ret = btrfs_next_old_item(root, path, time_seq);
...@@ -574,7 +575,7 @@ static int resolve_indirect_ref(struct btrfs_fs_info *fs_info, ...@@ -574,7 +575,7 @@ static int resolve_indirect_ref(struct btrfs_fs_info *fs_info,
if (path->search_commit_root) if (path->search_commit_root)
root_level = btrfs_header_level(root->commit_root); root_level = btrfs_header_level(root->commit_root);
else if (time_seq == SEQ_LAST) else if (time_seq == BTRFS_SEQ_LAST)
root_level = btrfs_header_level(root->node); root_level = btrfs_header_level(root->node);
else else
root_level = btrfs_old_root_level(root, time_seq); root_level = btrfs_old_root_level(root, time_seq);
...@@ -605,7 +606,7 @@ static int resolve_indirect_ref(struct btrfs_fs_info *fs_info, ...@@ -605,7 +606,7 @@ static int resolve_indirect_ref(struct btrfs_fs_info *fs_info,
search_key.offset >= LLONG_MAX) search_key.offset >= LLONG_MAX)
search_key.offset = 0; search_key.offset = 0;
path->lowest_level = level; path->lowest_level = level;
if (time_seq == SEQ_LAST) if (time_seq == BTRFS_SEQ_LAST)
ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
else else
ret = btrfs_search_old_slot(root, &search_key, path, time_seq); ret = btrfs_search_old_slot(root, &search_key, path, time_seq);
...@@ -1147,8 +1148,8 @@ static int add_keyed_refs(struct btrfs_fs_info *fs_info, ...@@ -1147,8 +1148,8 @@ static int add_keyed_refs(struct btrfs_fs_info *fs_info,
* indirect refs to their parent bytenr. * indirect refs to their parent bytenr.
* When roots are found, they're added to the roots list * When roots are found, they're added to the roots list
* *
* If time_seq is set to SEQ_LAST, it will not search delayed_refs, and behave * If time_seq is set to BTRFS_SEQ_LAST, it will not search delayed_refs, and
* much like trans == NULL case, the difference only lies in it will not * behave much like trans == NULL case, the difference only lies in it will not
* commit root. * commit root.
* The special case is for qgroup to search roots in commit_transaction(). * The special case is for qgroup to search roots in commit_transaction().
* *
...@@ -1199,7 +1200,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, ...@@ -1199,7 +1200,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
path->skip_locking = 1; path->skip_locking = 1;
} }
if (time_seq == SEQ_LAST) if (time_seq == BTRFS_SEQ_LAST)
path->skip_locking = 1; path->skip_locking = 1;
/* /*
...@@ -1217,9 +1218,9 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, ...@@ -1217,9 +1218,9 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
if (trans && likely(trans->type != __TRANS_DUMMY) && if (trans && likely(trans->type != __TRANS_DUMMY) &&
time_seq != SEQ_LAST) { time_seq != BTRFS_SEQ_LAST) {
#else #else
if (trans && time_seq != SEQ_LAST) { if (trans && time_seq != BTRFS_SEQ_LAST) {
#endif #endif
/* /*
* look if there are updates for this ref queued and lock the * look if there are updates for this ref queued and lock the
...@@ -1527,7 +1528,7 @@ int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr, ...@@ -1527,7 +1528,7 @@ int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr,
struct btrfs_trans_handle *trans; struct btrfs_trans_handle *trans;
struct ulist_iterator uiter; struct ulist_iterator uiter;
struct ulist_node *node; struct ulist_node *node;
struct seq_list elem = SEQ_LIST_INIT(elem); struct btrfs_seq_list elem = BTRFS_SEQ_LIST_INIT(elem);
int ret = 0; int ret = 0;
struct share_check shared = { struct share_check shared = {
.root_objectid = root->root_key.objectid, .root_objectid = root->root_key.objectid,
...@@ -1953,7 +1954,7 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info, ...@@ -1953,7 +1954,7 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
struct ulist *roots = NULL; struct ulist *roots = NULL;
struct ulist_node *ref_node = NULL; struct ulist_node *ref_node = NULL;
struct ulist_node *root_node = NULL; struct ulist_node *root_node = NULL;
struct seq_list tree_mod_seq_elem = SEQ_LIST_INIT(tree_mod_seq_elem); struct btrfs_seq_list seq_elem = BTRFS_SEQ_LIST_INIT(seq_elem);
struct ulist_iterator ref_uiter; struct ulist_iterator ref_uiter;
struct ulist_iterator root_uiter; struct ulist_iterator root_uiter;
...@@ -1971,12 +1972,12 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info, ...@@ -1971,12 +1972,12 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
} }
if (trans) if (trans)
btrfs_get_tree_mod_seq(fs_info, &tree_mod_seq_elem); btrfs_get_tree_mod_seq(fs_info, &seq_elem);
else else
down_read(&fs_info->commit_root_sem); down_read(&fs_info->commit_root_sem);
ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid, ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid,
tree_mod_seq_elem.seq, &refs, seq_elem.seq, &refs,
&extent_item_pos, ignore_offset); &extent_item_pos, ignore_offset);
if (ret) if (ret)
goto out; goto out;
...@@ -1984,7 +1985,7 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info, ...@@ -1984,7 +1985,7 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
ULIST_ITER_INIT(&ref_uiter); ULIST_ITER_INIT(&ref_uiter);
while (!ret && (ref_node = ulist_next(refs, &ref_uiter))) { while (!ret && (ref_node = ulist_next(refs, &ref_uiter))) {
ret = btrfs_find_all_roots_safe(trans, fs_info, ref_node->val, ret = btrfs_find_all_roots_safe(trans, fs_info, ref_node->val,
tree_mod_seq_elem.seq, &roots, seq_elem.seq, &roots,
ignore_offset); ignore_offset);
if (ret) if (ret)
break; break;
...@@ -2007,7 +2008,7 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info, ...@@ -2007,7 +2008,7 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
free_leaf_list(refs); free_leaf_list(refs);
out: out:
if (trans) { if (trans) {
btrfs_put_tree_mod_seq(fs_info, &tree_mod_seq_elem); btrfs_put_tree_mod_seq(fs_info, &seq_elem);
btrfs_end_transaction(trans); btrfs_end_transaction(trans);
} else { } else {
up_read(&fs_info->commit_root_sem); up_read(&fs_info->commit_root_sem);
......
This diff is collapsed.
...@@ -482,16 +482,6 @@ struct btrfs_discard_ctl { ...@@ -482,16 +482,6 @@ struct btrfs_discard_ctl {
atomic64_t discard_bytes_saved; atomic64_t discard_bytes_saved;
}; };
/* delayed seq elem */
struct seq_list {
struct list_head list;
u64 seq;
};
#define SEQ_LIST_INIT(name) { .list = LIST_HEAD_INIT((name).list), .seq = 0 }
#define SEQ_LAST ((u64)-1)
enum btrfs_orphan_cleanup_state { enum btrfs_orphan_cleanup_state {
ORPHAN_CLEANUP_STARTED = 1, ORPHAN_CLEANUP_STARTED = 1,
ORPHAN_CLEANUP_DONE = 2, ORPHAN_CLEANUP_DONE = 2,
...@@ -2928,13 +2918,6 @@ static inline void btrfs_clear_sb_rdonly(struct super_block *sb) ...@@ -2928,13 +2918,6 @@ static inline void btrfs_clear_sb_rdonly(struct super_block *sb)
clear_bit(BTRFS_FS_STATE_RO, &btrfs_sb(sb)->fs_state); clear_bit(BTRFS_FS_STATE_RO, &btrfs_sb(sb)->fs_state);
} }
/* tree mod log functions from ctree.c */
u64 btrfs_get_tree_mod_seq(struct btrfs_fs_info *fs_info,
struct seq_list *elem);
void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info,
struct seq_list *elem);
int btrfs_old_root_level(struct btrfs_root *root, u64 time_seq);
/* root-item.c */ /* root-item.c */
int btrfs_add_root_ref(struct btrfs_trans_handle *trans, u64 root_id, int btrfs_add_root_ref(struct btrfs_trans_handle *trans, u64 root_id,
u64 ref_id, u64 dirid, u64 sequence, const char *name, u64 ref_id, u64 dirid, u64 sequence, const char *name,
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "transaction.h" #include "transaction.h"
#include "qgroup.h" #include "qgroup.h"
#include "space-info.h" #include "space-info.h"
#include "tree-mod-log.h"
struct kmem_cache *btrfs_delayed_ref_head_cachep; struct kmem_cache *btrfs_delayed_ref_head_cachep;
struct kmem_cache *btrfs_delayed_tree_ref_cachep; struct kmem_cache *btrfs_delayed_tree_ref_cachep;
...@@ -496,10 +497,10 @@ void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans, ...@@ -496,10 +497,10 @@ void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans,
read_lock(&fs_info->tree_mod_log_lock); read_lock(&fs_info->tree_mod_log_lock);
if (!list_empty(&fs_info->tree_mod_seq_list)) { if (!list_empty(&fs_info->tree_mod_seq_list)) {
struct seq_list *elem; struct btrfs_seq_list *elem;
elem = list_first_entry(&fs_info->tree_mod_seq_list, elem = list_first_entry(&fs_info->tree_mod_seq_list,
struct seq_list, list); struct btrfs_seq_list, list);
seq = elem->seq; seq = elem->seq;
} }
read_unlock(&fs_info->tree_mod_log_lock); read_unlock(&fs_info->tree_mod_log_lock);
...@@ -517,13 +518,13 @@ void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans, ...@@ -517,13 +518,13 @@ void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans,
int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info, u64 seq) int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info, u64 seq)
{ {
struct seq_list *elem; struct btrfs_seq_list *elem;
int ret = 0; int ret = 0;
read_lock(&fs_info->tree_mod_log_lock); read_lock(&fs_info->tree_mod_log_lock);
if (!list_empty(&fs_info->tree_mod_seq_list)) { if (!list_empty(&fs_info->tree_mod_seq_list)) {
elem = list_first_entry(&fs_info->tree_mod_seq_list, elem = list_first_entry(&fs_info->tree_mod_seq_list,
struct seq_list, list); struct btrfs_seq_list, list);
if (seq >= elem->seq) { if (seq >= elem->seq) {
btrfs_debug(fs_info, btrfs_debug(fs_info,
"holding back delayed_ref %#x.%x, lowest is %#x.%x", "holding back delayed_ref %#x.%x, lowest is %#x.%x",
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "qgroup.h" #include "qgroup.h"
#include "block-group.h" #include "block-group.h"
#include "sysfs.h" #include "sysfs.h"
#include "tree-mod-log.h"
/* TODO XXX FIXME /* TODO XXX FIXME
* - subvol delete -> delete when ref goes to 0? delete limits also? * - subvol delete -> delete when ref goes to 0? delete limits also?
...@@ -2639,12 +2640,12 @@ int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans) ...@@ -2639,12 +2640,12 @@ int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans)
record->data_rsv, record->data_rsv,
BTRFS_QGROUP_RSV_DATA); BTRFS_QGROUP_RSV_DATA);
/* /*
* Use SEQ_LAST as time_seq to do special search, which * Use BTRFS_SEQ_LAST as time_seq to do special search,
* doesn't lock tree or delayed_refs and search current * which doesn't lock tree or delayed_refs and search
* root. It's safe inside commit_transaction(). * current root. It's safe inside commit_transaction().
*/ */
ret = btrfs_find_all_roots(trans, fs_info, ret = btrfs_find_all_roots(trans, fs_info,
record->bytenr, SEQ_LAST, &new_roots, false); record->bytenr, BTRFS_SEQ_LAST, &new_roots, false);
if (ret < 0) if (ret < 0)
goto cleanup; goto cleanup;
if (qgroup_to_skip) { if (qgroup_to_skip) {
......
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0
#ifndef BTRFS_TREE_MOD_LOG_H
#define BTRFS_TREE_MOD_LOG_H
#include "ctree.h"
/* Represents a tree mod log user. */
struct btrfs_seq_list {
struct list_head list;
u64 seq;
};
#define BTRFS_SEQ_LIST_INIT(name) { .list = LIST_HEAD_INIT((name).list), .seq = 0 }
#define BTRFS_SEQ_LAST ((u64)-1)
enum btrfs_mod_log_op {
BTRFS_MOD_LOG_KEY_REPLACE,
BTRFS_MOD_LOG_KEY_ADD,
BTRFS_MOD_LOG_KEY_REMOVE,
BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING,
BTRFS_MOD_LOG_KEY_REMOVE_WHILE_MOVING,
BTRFS_MOD_LOG_MOVE_KEYS,
BTRFS_MOD_LOG_ROOT_REPLACE,
};
u64 btrfs_get_tree_mod_seq(struct btrfs_fs_info *fs_info,
struct btrfs_seq_list *elem);
void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info,
struct btrfs_seq_list *elem);
int btrfs_tree_mod_log_insert_root(struct extent_buffer *old_root,
struct extent_buffer *new_root,
int log_removal);
int btrfs_tree_mod_log_insert_key(struct extent_buffer *eb, int slot,
enum btrfs_mod_log_op op, gfp_t flags);
int btrfs_tree_mod_log_free_eb(struct extent_buffer *eb);
struct extent_buffer *btrfs_tree_mod_log_rewind(struct btrfs_fs_info *fs_info,
struct btrfs_path *path,
struct extent_buffer *eb,
u64 time_seq);
struct extent_buffer *btrfs_get_old_root(struct btrfs_root *root, u64 time_seq);
int btrfs_old_root_level(struct btrfs_root *root, u64 time_seq);
int btrfs_tree_mod_log_eb_copy(struct extent_buffer *dst,
struct extent_buffer *src,
unsigned long dst_offset,
unsigned long src_offset,
int nr_items);
int btrfs_tree_mod_log_insert_move(struct extent_buffer *eb,
int dst_slot, int src_slot,
int nr_items);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment