Loading fs/btrfs/backref.c +66 −49 Original line number Diff line number Diff line Loading @@ -116,6 +116,7 @@ add_parent: * to a logical address */ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, int search_commit_root, struct __prelim_ref *ref, struct ulist *parents) { Loading @@ -131,6 +132,7 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, path = btrfs_alloc_path(); if (!path) return -ENOMEM; path->search_commit_root = !!search_commit_root; root_key.objectid = ref->root_id; root_key.type = BTRFS_ROOT_ITEM_KEY; Loading Loading @@ -188,6 +190,7 @@ out: * resolve all indirect backrefs from the list */ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info, int search_commit_root, struct list_head *head) { int err; Loading @@ -212,7 +215,8 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info, continue; if (ref->count == 0) continue; err = __resolve_indirect_ref(fs_info, ref, parents); err = __resolve_indirect_ref(fs_info, search_commit_root, ref, parents); if (err) { if (ret == 0) ret = err; Loading Loading @@ -586,6 +590,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, struct btrfs_delayed_ref_head *head; int info_level = 0; int ret; int search_commit_root = (trans == BTRFS_BACKREF_SEARCH_COMMIT_ROOT); struct list_head prefs_delayed; struct list_head prefs; struct __prelim_ref *ref; Loading @@ -600,6 +605,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, path = btrfs_alloc_path(); if (!path) return -ENOMEM; path->search_commit_root = !!search_commit_root; /* * grab both a lock on the path and a lock on the delayed ref head. Loading @@ -614,8 +620,10 @@ again: goto out; BUG_ON(ret == 0); if (trans != BTRFS_BACKREF_SEARCH_COMMIT_ROOT) { /* * look if there are updates for this ref queued and lock the head * look if there are updates for this ref queued and lock the * head */ delayed_refs = &trans->transaction->delayed_refs; spin_lock(&delayed_refs->lock); Loading @@ -636,13 +644,15 @@ again: btrfs_put_delayed_ref(&head->node); goto again; } ret = __add_delayed_refs(head, seq, &info_key, &prefs_delayed); ret = __add_delayed_refs(head, seq, &info_key, &prefs_delayed); if (ret) { spin_unlock(&delayed_refs->lock); goto out; } } spin_unlock(&delayed_refs->lock); } if (path->slots[0]) { struct extent_buffer *leaf; Loading Loading @@ -679,7 +689,7 @@ again: if (ret) goto out; ret = __resolve_indirect_refs(fs_info, &prefs); ret = __resolve_indirect_refs(fs_info, search_commit_root, &prefs); if (ret) goto out; Loading Loading @@ -1074,8 +1084,7 @@ int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb, return 0; } static int iterate_leaf_refs(struct btrfs_fs_info *fs_info, struct btrfs_path *path, u64 logical, static int iterate_leaf_refs(struct btrfs_fs_info *fs_info, u64 logical, u64 orig_extent_item_objectid, u64 extent_item_pos, u64 root, iterate_extent_inodes_t *iterate, void *ctx) Loading Loading @@ -1143,35 +1152,38 @@ static int iterate_leaf_refs(struct btrfs_fs_info *fs_info, * calls iterate() for every inode that references the extent identified by * the given parameters. * when the iterator function returns a non-zero value, iteration stops. * path is guaranteed to be in released state when iterate() is called. */ int iterate_extent_inodes(struct btrfs_fs_info *fs_info, struct btrfs_path *path, u64 extent_item_objectid, u64 extent_item_pos, int search_commit_root, iterate_extent_inodes_t *iterate, void *ctx) { int ret; struct list_head data_refs = LIST_HEAD_INIT(data_refs); struct list_head shared_refs = LIST_HEAD_INIT(shared_refs); struct btrfs_trans_handle *trans; struct ulist *refs; struct ulist *roots; struct ulist *refs = NULL; struct ulist *roots = NULL; struct ulist_node *ref_node = NULL; struct ulist_node *root_node = NULL; struct seq_list seq_elem; struct btrfs_delayed_ref_root *delayed_refs; struct btrfs_delayed_ref_root *delayed_refs = NULL; pr_debug("resolving all inodes for extent %llu\n", extent_item_objectid); if (search_commit_root) { trans = BTRFS_BACKREF_SEARCH_COMMIT_ROOT; } else { trans = btrfs_join_transaction(fs_info->extent_root); if (IS_ERR(trans)) return PTR_ERR(trans); pr_debug("resolving all inodes for extent %llu\n", extent_item_objectid); delayed_refs = &trans->transaction->delayed_refs; spin_lock(&delayed_refs->lock); btrfs_get_delayed_seq(delayed_refs, &seq_elem); spin_unlock(&delayed_refs->lock); } ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid, extent_item_pos, seq_elem.seq, Loading @@ -1188,7 +1200,7 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info, while (!ret && (root_node = ulist_next(roots, root_node))) { pr_debug("root %llu references leaf %llu\n", root_node->val, ref_node->val); ret = iterate_leaf_refs(fs_info, path, ref_node->val, ret = iterate_leaf_refs(fs_info, ref_node->val, extent_item_objectid, extent_item_pos, root_node->val, iterate, ctx); Loading @@ -1198,8 +1210,11 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info, ulist_free(refs); ulist_free(roots); out: if (!search_commit_root) { btrfs_put_delayed_seq(delayed_refs, &seq_elem); btrfs_end_transaction(trans, fs_info->extent_root); } return ret; } Loading @@ -1210,6 +1225,7 @@ int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info, int ret; u64 extent_item_pos; struct btrfs_key found_key; int search_commit_root = path->search_commit_root; ret = extent_from_logical(fs_info, logical, path, &found_key); Loading @@ -1220,8 +1236,9 @@ int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info, return ret; extent_item_pos = logical - found_key.objectid; ret = iterate_extent_inodes(fs_info, path, found_key.objectid, extent_item_pos, iterate, ctx); ret = iterate_extent_inodes(fs_info, found_key.objectid, extent_item_pos, search_commit_root, iterate, ctx); return ret; } Loading fs/btrfs/backref.h +3 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ #include "ioctl.h" #include "ulist.h" #define BTRFS_BACKREF_SEARCH_COMMIT_ROOT ((struct btrfs_trans_handle *)0) struct inode_fs_paths { struct btrfs_path *btrfs_path; struct btrfs_root *fs_root; Loading @@ -44,9 +46,8 @@ int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb, u64 *out_root, u8 *out_level); int iterate_extent_inodes(struct btrfs_fs_info *fs_info, struct btrfs_path *path, u64 extent_item_objectid, u64 extent_offset, u64 extent_offset, int search_commit_root, iterate_extent_inodes_t *iterate, void *ctx); int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info, Loading fs/btrfs/ioctl.c +2 −2 Original line number Diff line number Diff line Loading @@ -3121,8 +3121,8 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root, goto out; extent_item_pos = loi->logical - key.objectid; ret = iterate_extent_inodes(root->fs_info, path, key.objectid, extent_item_pos, build_ino_list, ret = iterate_extent_inodes(root->fs_info, key.objectid, extent_item_pos, 0, build_ino_list, inodes); if (ret < 0) Loading fs/btrfs/scrub.c +2 −2 Original line number Diff line number Diff line Loading @@ -400,8 +400,8 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock) } while (ret != 1); } else { swarn.path = path; iterate_extent_inodes(fs_info, path, found_key.objectid, extent_item_pos, iterate_extent_inodes(fs_info, found_key.objectid, extent_item_pos, 1, scrub_print_warning_inode, &swarn); } Loading fs/btrfs/super.c +2 −0 Original line number Diff line number Diff line Loading @@ -1541,6 +1541,8 @@ static int __init init_btrfs_fs(void) if (err) goto unregister_ioctl; btrfs_init_lockdep(); printk(KERN_INFO "%s loaded\n", BTRFS_BUILD_VERSION); return 0; Loading Loading
fs/btrfs/backref.c +66 −49 Original line number Diff line number Diff line Loading @@ -116,6 +116,7 @@ add_parent: * to a logical address */ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, int search_commit_root, struct __prelim_ref *ref, struct ulist *parents) { Loading @@ -131,6 +132,7 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, path = btrfs_alloc_path(); if (!path) return -ENOMEM; path->search_commit_root = !!search_commit_root; root_key.objectid = ref->root_id; root_key.type = BTRFS_ROOT_ITEM_KEY; Loading Loading @@ -188,6 +190,7 @@ out: * resolve all indirect backrefs from the list */ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info, int search_commit_root, struct list_head *head) { int err; Loading @@ -212,7 +215,8 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info, continue; if (ref->count == 0) continue; err = __resolve_indirect_ref(fs_info, ref, parents); err = __resolve_indirect_ref(fs_info, search_commit_root, ref, parents); if (err) { if (ret == 0) ret = err; Loading Loading @@ -586,6 +590,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, struct btrfs_delayed_ref_head *head; int info_level = 0; int ret; int search_commit_root = (trans == BTRFS_BACKREF_SEARCH_COMMIT_ROOT); struct list_head prefs_delayed; struct list_head prefs; struct __prelim_ref *ref; Loading @@ -600,6 +605,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, path = btrfs_alloc_path(); if (!path) return -ENOMEM; path->search_commit_root = !!search_commit_root; /* * grab both a lock on the path and a lock on the delayed ref head. Loading @@ -614,8 +620,10 @@ again: goto out; BUG_ON(ret == 0); if (trans != BTRFS_BACKREF_SEARCH_COMMIT_ROOT) { /* * look if there are updates for this ref queued and lock the head * look if there are updates for this ref queued and lock the * head */ delayed_refs = &trans->transaction->delayed_refs; spin_lock(&delayed_refs->lock); Loading @@ -636,13 +644,15 @@ again: btrfs_put_delayed_ref(&head->node); goto again; } ret = __add_delayed_refs(head, seq, &info_key, &prefs_delayed); ret = __add_delayed_refs(head, seq, &info_key, &prefs_delayed); if (ret) { spin_unlock(&delayed_refs->lock); goto out; } } spin_unlock(&delayed_refs->lock); } if (path->slots[0]) { struct extent_buffer *leaf; Loading Loading @@ -679,7 +689,7 @@ again: if (ret) goto out; ret = __resolve_indirect_refs(fs_info, &prefs); ret = __resolve_indirect_refs(fs_info, search_commit_root, &prefs); if (ret) goto out; Loading Loading @@ -1074,8 +1084,7 @@ int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb, return 0; } static int iterate_leaf_refs(struct btrfs_fs_info *fs_info, struct btrfs_path *path, u64 logical, static int iterate_leaf_refs(struct btrfs_fs_info *fs_info, u64 logical, u64 orig_extent_item_objectid, u64 extent_item_pos, u64 root, iterate_extent_inodes_t *iterate, void *ctx) Loading Loading @@ -1143,35 +1152,38 @@ static int iterate_leaf_refs(struct btrfs_fs_info *fs_info, * calls iterate() for every inode that references the extent identified by * the given parameters. * when the iterator function returns a non-zero value, iteration stops. * path is guaranteed to be in released state when iterate() is called. */ int iterate_extent_inodes(struct btrfs_fs_info *fs_info, struct btrfs_path *path, u64 extent_item_objectid, u64 extent_item_pos, int search_commit_root, iterate_extent_inodes_t *iterate, void *ctx) { int ret; struct list_head data_refs = LIST_HEAD_INIT(data_refs); struct list_head shared_refs = LIST_HEAD_INIT(shared_refs); struct btrfs_trans_handle *trans; struct ulist *refs; struct ulist *roots; struct ulist *refs = NULL; struct ulist *roots = NULL; struct ulist_node *ref_node = NULL; struct ulist_node *root_node = NULL; struct seq_list seq_elem; struct btrfs_delayed_ref_root *delayed_refs; struct btrfs_delayed_ref_root *delayed_refs = NULL; pr_debug("resolving all inodes for extent %llu\n", extent_item_objectid); if (search_commit_root) { trans = BTRFS_BACKREF_SEARCH_COMMIT_ROOT; } else { trans = btrfs_join_transaction(fs_info->extent_root); if (IS_ERR(trans)) return PTR_ERR(trans); pr_debug("resolving all inodes for extent %llu\n", extent_item_objectid); delayed_refs = &trans->transaction->delayed_refs; spin_lock(&delayed_refs->lock); btrfs_get_delayed_seq(delayed_refs, &seq_elem); spin_unlock(&delayed_refs->lock); } ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid, extent_item_pos, seq_elem.seq, Loading @@ -1188,7 +1200,7 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info, while (!ret && (root_node = ulist_next(roots, root_node))) { pr_debug("root %llu references leaf %llu\n", root_node->val, ref_node->val); ret = iterate_leaf_refs(fs_info, path, ref_node->val, ret = iterate_leaf_refs(fs_info, ref_node->val, extent_item_objectid, extent_item_pos, root_node->val, iterate, ctx); Loading @@ -1198,8 +1210,11 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info, ulist_free(refs); ulist_free(roots); out: if (!search_commit_root) { btrfs_put_delayed_seq(delayed_refs, &seq_elem); btrfs_end_transaction(trans, fs_info->extent_root); } return ret; } Loading @@ -1210,6 +1225,7 @@ int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info, int ret; u64 extent_item_pos; struct btrfs_key found_key; int search_commit_root = path->search_commit_root; ret = extent_from_logical(fs_info, logical, path, &found_key); Loading @@ -1220,8 +1236,9 @@ int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info, return ret; extent_item_pos = logical - found_key.objectid; ret = iterate_extent_inodes(fs_info, path, found_key.objectid, extent_item_pos, iterate, ctx); ret = iterate_extent_inodes(fs_info, found_key.objectid, extent_item_pos, search_commit_root, iterate, ctx); return ret; } Loading
fs/btrfs/backref.h +3 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ #include "ioctl.h" #include "ulist.h" #define BTRFS_BACKREF_SEARCH_COMMIT_ROOT ((struct btrfs_trans_handle *)0) struct inode_fs_paths { struct btrfs_path *btrfs_path; struct btrfs_root *fs_root; Loading @@ -44,9 +46,8 @@ int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb, u64 *out_root, u8 *out_level); int iterate_extent_inodes(struct btrfs_fs_info *fs_info, struct btrfs_path *path, u64 extent_item_objectid, u64 extent_offset, u64 extent_offset, int search_commit_root, iterate_extent_inodes_t *iterate, void *ctx); int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info, Loading
fs/btrfs/ioctl.c +2 −2 Original line number Diff line number Diff line Loading @@ -3121,8 +3121,8 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root, goto out; extent_item_pos = loi->logical - key.objectid; ret = iterate_extent_inodes(root->fs_info, path, key.objectid, extent_item_pos, build_ino_list, ret = iterate_extent_inodes(root->fs_info, key.objectid, extent_item_pos, 0, build_ino_list, inodes); if (ret < 0) Loading
fs/btrfs/scrub.c +2 −2 Original line number Diff line number Diff line Loading @@ -400,8 +400,8 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock) } while (ret != 1); } else { swarn.path = path; iterate_extent_inodes(fs_info, path, found_key.objectid, extent_item_pos, iterate_extent_inodes(fs_info, found_key.objectid, extent_item_pos, 1, scrub_print_warning_inode, &swarn); } Loading
fs/btrfs/super.c +2 −0 Original line number Diff line number Diff line Loading @@ -1541,6 +1541,8 @@ static int __init init_btrfs_fs(void) if (err) goto unregister_ioctl; btrfs_init_lockdep(); printk(KERN_INFO "%s loaded\n", BTRFS_BUILD_VERSION); return 0; Loading