Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:Update
btrfsprogs
btrfs-progs-backref-use-separate-list-for-missi...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File btrfs-progs-backref-use-separate-list-for-missing-keys.patch of Package btrfsprogs
From: Jeff Mahoney <jeffm@suse.com> Subject: btrfs-progs: backref: use separate list for missing keys Git-commit: b77ec6c6d5301ce3f663049ed8df2d1f7d320d6d Patch-mainline: v4.13.2 References: bsc#1125340 Rather than iterate over all outstanding backrefs to resolve missing keys, use a separate list that only contains refs that need missing keys resolved. Once the missing key is resolved, move the ref to the pending list. Signed-off-by: Jeff Mahoney <jeffm@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> --- backref.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/backref.c b/backref.c index 305cd053..b63a0095 100644 --- a/backref.c +++ b/backref.c @@ -137,11 +137,13 @@ static struct __prelim_ref *list_first_pref(struct list_head *head) struct pref_state { struct list_head pending; + struct list_head pending_missing_keys; }; static void init_pref_state(struct pref_state *prefstate) { INIT_LIST_HEAD(&prefstate->pending); + INIT_LIST_HEAD(&prefstate->pending_missing_keys); } /* @@ -188,7 +190,7 @@ static int __add_prelim_ref(struct pref_state *prefstate, u64 root_id, u64 parent, u64 wanted_disk_byte, int count, gfp_t gfp_mask) { - struct list_head *head = &prefstate->pending; + struct list_head *head; struct __prelim_ref *ref; if (root_id == BTRFS_DATA_RELOC_TREE_OBJECTID) @@ -199,16 +201,20 @@ static int __add_prelim_ref(struct pref_state *prefstate, u64 root_id, return -ENOMEM; ref->root_id = root_id; - if (key) + if (key) { ref->key_for_search = *key; - else + head = &prefstate->pending; + } else { memset(&ref->key_for_search, 0, sizeof(ref->key_for_search)); + head = &prefstate->pending_missing_keys; + } ref->inode_list = NULL; ref->level = level; ref->count = count; ref->parent = parent; ref->wanted_disk_byte = wanted_disk_byte; + list_add_tail(&ref->list, head); return 0; @@ -454,18 +460,16 @@ static inline int ref_for_same_block(struct __prelim_ref *ref1, static int __add_missing_keys(struct btrfs_fs_info *fs_info, struct pref_state *prefstate) { - struct list_head *head = &prefstate->pending; - struct list_head *pos; struct extent_buffer *eb; - list_for_each(pos, head) { + while (!list_empty(&prefstate->pending_missing_keys)) { struct __prelim_ref *ref; - ref = list_entry(pos, struct __prelim_ref, list); - if (ref->parent) - continue; - if (ref->key_for_search.type) - continue; + ref = list_first_pref(&prefstate->pending_missing_keys); + + ASSERT(ref->root_id); + ASSERT(!ref->parent); + ASSERT(ref->key_for_search.type); BUG_ON(!ref->wanted_disk_byte); eb = read_tree_block(fs_info->tree_root, ref->wanted_disk_byte, fs_info->tree_root->nodesize, 0); @@ -477,6 +481,7 @@ static int __add_missing_keys(struct btrfs_fs_info *fs_info, else btrfs_node_key_to_cpu(eb, &ref->key_for_search, 0); free_extent_buffer(eb); + list_move(&ref->list, &prefstate->pending); } return 0; } @@ -807,6 +812,8 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, __merge_refs(&prefstate, 2); + BUG_ON(!list_empty(&prefstate.pending_missing_keys)); + while (!list_empty(&prefstate.pending)) { ref = list_first_pref(&prefstate.pending); WARN_ON(ref->count < 0);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor