backref.c (c7499a64dcf62bf27968b0e9cce353c490b9ada1) backref.c (6ce6ba534418132f4c727d5707fe2794c797299c)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2011 STRATO. All rights reserved.
4 */
5
6#include <linux/mm.h>
7#include <linux/rbtree.h>
8#include <trace/events/btrfs.h>

--- 21 unchanged lines hidden (view full) ---

30 u64 num_bytes;
31 struct extent_inode_elem *next;
32};
33
34static int check_extent_in_eb(const struct btrfs_key *key,
35 const struct extent_buffer *eb,
36 const struct btrfs_file_extent_item *fi,
37 u64 extent_item_pos,
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2011 STRATO. All rights reserved.
4 */
5
6#include <linux/mm.h>
7#include <linux/rbtree.h>
8#include <trace/events/btrfs.h>

--- 21 unchanged lines hidden (view full) ---

30 u64 num_bytes;
31 struct extent_inode_elem *next;
32};
33
34static int check_extent_in_eb(const struct btrfs_key *key,
35 const struct extent_buffer *eb,
36 const struct btrfs_file_extent_item *fi,
37 u64 extent_item_pos,
38 struct extent_inode_elem **eie,
39 bool ignore_offset)
38 struct extent_inode_elem **eie)
40{
41 const u64 data_len = btrfs_file_extent_num_bytes(eb, fi);
42 u64 offset = 0;
43 struct extent_inode_elem *e;
44
39{
40 const u64 data_len = btrfs_file_extent_num_bytes(eb, fi);
41 u64 offset = 0;
42 struct extent_inode_elem *e;
43
45 if (!ignore_offset &&
46 !btrfs_file_extent_compression(eb, fi) &&
44 if (!btrfs_file_extent_compression(eb, fi) &&
47 !btrfs_file_extent_encryption(eb, fi) &&
48 !btrfs_file_extent_other_encoding(eb, fi)) {
49 u64 data_offset;
50
51 data_offset = btrfs_file_extent_offset(eb, fi);
52
53 if (extent_item_pos < data_offset ||
54 extent_item_pos >= data_offset + data_len)

--- 21 unchanged lines hidden (view full) ---

76 for (; eie; eie = eie_next) {
77 eie_next = eie->next;
78 kfree(eie);
79 }
80}
81
82static int find_extent_in_eb(const struct extent_buffer *eb,
83 u64 wanted_disk_byte, u64 extent_item_pos,
45 !btrfs_file_extent_encryption(eb, fi) &&
46 !btrfs_file_extent_other_encoding(eb, fi)) {
47 u64 data_offset;
48
49 data_offset = btrfs_file_extent_offset(eb, fi);
50
51 if (extent_item_pos < data_offset ||
52 extent_item_pos >= data_offset + data_len)

--- 21 unchanged lines hidden (view full) ---

74 for (; eie; eie = eie_next) {
75 eie_next = eie->next;
76 kfree(eie);
77 }
78}
79
80static int find_extent_in_eb(const struct extent_buffer *eb,
81 u64 wanted_disk_byte, u64 extent_item_pos,
84 struct extent_inode_elem **eie,
85 bool ignore_offset)
82 struct extent_inode_elem **eie)
86{
87 u64 disk_byte;
88 struct btrfs_key key;
89 struct btrfs_file_extent_item *fi;
90 int slot;
91 int nritems;
92 int extent_type;
93 int ret;

--- 12 unchanged lines hidden (view full) ---

106 extent_type = btrfs_file_extent_type(eb, fi);
107 if (extent_type == BTRFS_FILE_EXTENT_INLINE)
108 continue;
109 /* don't skip BTRFS_FILE_EXTENT_PREALLOC, we can handle that */
110 disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
111 if (disk_byte != wanted_disk_byte)
112 continue;
113
83{
84 u64 disk_byte;
85 struct btrfs_key key;
86 struct btrfs_file_extent_item *fi;
87 int slot;
88 int nritems;
89 int extent_type;
90 int ret;

--- 12 unchanged lines hidden (view full) ---

103 extent_type = btrfs_file_extent_type(eb, fi);
104 if (extent_type == BTRFS_FILE_EXTENT_INLINE)
105 continue;
106 /* don't skip BTRFS_FILE_EXTENT_PREALLOC, we can handle that */
107 disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
108 if (disk_byte != wanted_disk_byte)
109 continue;
110
114 ret = check_extent_in_eb(&key, eb, fi, extent_item_pos, eie, ignore_offset);
111 ret = check_extent_in_eb(&key, eb, fi, extent_item_pos, eie);
115 if (ret < 0)
116 return ret;
117 }
118
119 return 0;
120}
121
122struct preftree {

--- 322 unchanged lines hidden (view full) ---

445 return 1;
446 }
447 return 0;
448}
449
450static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
451 struct ulist *parents,
452 struct preftrees *preftrees, struct prelim_ref *ref,
112 if (ret < 0)
113 return ret;
114 }
115
116 return 0;
117}
118
119struct preftree {

--- 322 unchanged lines hidden (view full) ---

442 return 1;
443 }
444 return 0;
445}
446
447static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
448 struct ulist *parents,
449 struct preftrees *preftrees, struct prelim_ref *ref,
453 int level, u64 time_seq, const u64 *extent_item_pos,
454 bool ignore_offset)
450 int level, u64 time_seq, u64 extent_item_pos)
455{
451{
452 const bool ignore_offset = (extent_item_pos == BTRFS_IGNORE_EXTENT_OFFSET);
456 int ret = 0;
457 int slot;
458 struct extent_buffer *eb;
459 struct btrfs_key key;
460 struct btrfs_key *key_for_search = &ref->key_for_search;
461 struct btrfs_file_extent_item *fi;
462 struct extent_inode_elem *eie = NULL, *old = NULL;
463 u64 disk_byte;

--- 59 unchanged lines hidden (view full) ---

523
524 if (disk_byte == wanted_disk_byte) {
525 eie = NULL;
526 old = NULL;
527 if (ref->key_for_search.offset == key.offset - data_offset)
528 count++;
529 else
530 goto next;
453 int ret = 0;
454 int slot;
455 struct extent_buffer *eb;
456 struct btrfs_key key;
457 struct btrfs_key *key_for_search = &ref->key_for_search;
458 struct btrfs_file_extent_item *fi;
459 struct extent_inode_elem *eie = NULL, *old = NULL;
460 u64 disk_byte;

--- 59 unchanged lines hidden (view full) ---

520
521 if (disk_byte == wanted_disk_byte) {
522 eie = NULL;
523 old = NULL;
524 if (ref->key_for_search.offset == key.offset - data_offset)
525 count++;
526 else
527 goto next;
531 if (extent_item_pos) {
528 if (!ignore_offset) {
532 ret = check_extent_in_eb(&key, eb, fi,
529 ret = check_extent_in_eb(&key, eb, fi,
533 *extent_item_pos,
534 &eie, ignore_offset);
530 extent_item_pos, &eie);
535 if (ret < 0)
536 break;
537 }
538 if (ret > 0)
539 goto next;
540 ret = ulist_add_merge_ptr(parents, eb->start,
541 eie, (void **)&old, GFP_NOFS);
542 if (ret < 0)
543 break;
531 if (ret < 0)
532 break;
533 }
534 if (ret > 0)
535 goto next;
536 ret = ulist_add_merge_ptr(parents, eb->start,
537 eie, (void **)&old, GFP_NOFS);
538 if (ret < 0)
539 break;
544 if (!ret && extent_item_pos) {
540 if (!ret && !ignore_offset) {
545 while (old->next)
546 old = old->next;
547 old->next = eie;
548 }
549 eie = NULL;
550 }
551next:
552 if (time_seq == BTRFS_SEQ_LAST)

--- 12 unchanged lines hidden (view full) ---

565/*
566 * resolve an indirect backref in the form (root_id, key, level)
567 * to a logical address
568 */
569static int resolve_indirect_ref(struct btrfs_fs_info *fs_info,
570 struct btrfs_path *path, u64 time_seq,
571 struct preftrees *preftrees,
572 struct prelim_ref *ref, struct ulist *parents,
541 while (old->next)
542 old = old->next;
543 old->next = eie;
544 }
545 eie = NULL;
546 }
547next:
548 if (time_seq == BTRFS_SEQ_LAST)

--- 12 unchanged lines hidden (view full) ---

561/*
562 * resolve an indirect backref in the form (root_id, key, level)
563 * to a logical address
564 */
565static int resolve_indirect_ref(struct btrfs_fs_info *fs_info,
566 struct btrfs_path *path, u64 time_seq,
567 struct preftrees *preftrees,
568 struct prelim_ref *ref, struct ulist *parents,
573 const u64 *extent_item_pos, bool ignore_offset)
569 u64 extent_item_pos)
574{
575 struct btrfs_root *root;
576 struct extent_buffer *eb;
577 int ret = 0;
578 int root_level;
579 int level = ref->level;
580 struct btrfs_key search_key = ref->key_for_search;
581

--- 77 unchanged lines hidden (view full) ---

659 ret = 1;
660 goto out;
661 }
662 level--;
663 eb = path->nodes[level];
664 }
665
666 ret = add_all_parents(root, path, parents, preftrees, ref, level,
570{
571 struct btrfs_root *root;
572 struct extent_buffer *eb;
573 int ret = 0;
574 int root_level;
575 int level = ref->level;
576 struct btrfs_key search_key = ref->key_for_search;
577

--- 77 unchanged lines hidden (view full) ---

655 ret = 1;
656 goto out;
657 }
658 level--;
659 eb = path->nodes[level];
660 }
661
662 ret = add_all_parents(root, path, parents, preftrees, ref, level,
667 time_seq, extent_item_pos, ignore_offset);
663 time_seq, extent_item_pos);
668out:
669 btrfs_put_root(root);
670out_free:
671 path->lowest_level = 0;
672 btrfs_release_path(path);
673 return ret;
674}
675

--- 31 unchanged lines hidden (view full) ---

707 *
708 * New backrefs (i.e., for parent nodes) are added to the appropriate
709 * rbtree as they are encountered. The new backrefs are subsequently
710 * resolved as above.
711 */
712static int resolve_indirect_refs(struct btrfs_fs_info *fs_info,
713 struct btrfs_path *path, u64 time_seq,
714 struct preftrees *preftrees,
664out:
665 btrfs_put_root(root);
666out_free:
667 path->lowest_level = 0;
668 btrfs_release_path(path);
669 return ret;
670}
671

--- 31 unchanged lines hidden (view full) ---

703 *
704 * New backrefs (i.e., for parent nodes) are added to the appropriate
705 * rbtree as they are encountered. The new backrefs are subsequently
706 * resolved as above.
707 */
708static int resolve_indirect_refs(struct btrfs_fs_info *fs_info,
709 struct btrfs_path *path, u64 time_seq,
710 struct preftrees *preftrees,
715 const u64 *extent_item_pos,
716 struct share_check *sc, bool ignore_offset)
711 u64 extent_item_pos,
712 struct share_check *sc)
717{
718 int err;
719 int ret = 0;
720 struct ulist *parents;
721 struct ulist_node *node;
722 struct ulist_iterator uiter;
723 struct rb_node *rnode;
724

--- 26 unchanged lines hidden (view full) ---

751 }
752
753 if (sc && ref->root_id != sc->root->root_key.objectid) {
754 free_pref(ref);
755 ret = BACKREF_FOUND_SHARED;
756 goto out;
757 }
758 err = resolve_indirect_ref(fs_info, path, time_seq, preftrees,
713{
714 int err;
715 int ret = 0;
716 struct ulist *parents;
717 struct ulist_node *node;
718 struct ulist_iterator uiter;
719 struct rb_node *rnode;
720

--- 26 unchanged lines hidden (view full) ---

747 }
748
749 if (sc && ref->root_id != sc->root->root_key.objectid) {
750 free_pref(ref);
751 ret = BACKREF_FOUND_SHARED;
752 goto out;
753 }
754 err = resolve_indirect_ref(fs_info, path, time_seq, preftrees,
759 ref, parents, extent_item_pos,
760 ignore_offset);
755 ref, parents, extent_item_pos);
761 /*
762 * we can only tolerate ENOENT,otherwise,we should catch error
763 * and return directly.
764 */
765 if (err == -ENOENT) {
766 prelim_ref_insert(fs_info, &preftrees->direct, ref,
767 NULL);
768 continue;

--- 566 unchanged lines hidden (view full) ---

1335 * commit root.
1336 * The special case is for qgroup to search roots in commit_transaction().
1337 *
1338 * @sc - if !NULL, then immediately return BACKREF_FOUND_SHARED when a
1339 * shared extent is detected.
1340 *
1341 * Otherwise this returns 0 for success and <0 for an error.
1342 *
756 /*
757 * we can only tolerate ENOENT,otherwise,we should catch error
758 * and return directly.
759 */
760 if (err == -ENOENT) {
761 prelim_ref_insert(fs_info, &preftrees->direct, ref,
762 NULL);
763 continue;

--- 566 unchanged lines hidden (view full) ---

1330 * commit root.
1331 * The special case is for qgroup to search roots in commit_transaction().
1332 *
1333 * @sc - if !NULL, then immediately return BACKREF_FOUND_SHARED when a
1334 * shared extent is detected.
1335 *
1336 * Otherwise this returns 0 for success and <0 for an error.
1337 *
1343 * If ignore_offset is set to false, only extent refs whose offsets match
1344 * extent_item_pos are returned. If true, every extent ref is returned
1345 * and extent_item_pos is ignored.
1338 * @extent_item_pos is meaningful only if we are dealing with a data extent.
1339 * If its value is not BTRFS_IGNORE_EXTENT_OFFSET, then only collect references
1340 * from file extent items that refer to a section of the data extent that
1341 * contains @extent_item_pos. If its value is BTRFS_IGNORE_EXTENT_OFFSET then
1342 * collect references for every file extent item that points to the data extent.
1346 *
1347 * FIXME some caching might speed things up
1348 */
1349static int find_parent_nodes(struct btrfs_trans_handle *trans,
1350 struct btrfs_fs_info *fs_info, u64 bytenr,
1351 u64 time_seq, struct ulist *refs,
1343 *
1344 * FIXME some caching might speed things up
1345 */
1346static int find_parent_nodes(struct btrfs_trans_handle *trans,
1347 struct btrfs_fs_info *fs_info, u64 bytenr,
1348 u64 time_seq, struct ulist *refs,
1352 struct ulist *roots, const u64 *extent_item_pos,
1353 struct share_check *sc, bool ignore_offset)
1349 struct ulist *roots, u64 extent_item_pos,
1350 struct share_check *sc)
1354{
1351{
1352 const bool ignore_offset = (extent_item_pos == BTRFS_IGNORE_EXTENT_OFFSET);
1355 struct btrfs_root *root = btrfs_extent_root(fs_info, bytenr);
1356 struct btrfs_key key;
1357 struct btrfs_path *path;
1358 struct btrfs_delayed_ref_root *delayed_refs = NULL;
1359 struct btrfs_delayed_ref_head *head;
1360 int info_level = 0;
1361 int ret;
1362 struct prelim_ref *ref;

--- 171 unchanged lines hidden (view full) ---

1534
1535 ret = add_missing_keys(fs_info, &preftrees, path->skip_locking == 0);
1536 if (ret)
1537 goto out;
1538
1539 WARN_ON(!RB_EMPTY_ROOT(&preftrees.indirect_missing_keys.root.rb_root));
1540
1541 ret = resolve_indirect_refs(fs_info, path, time_seq, &preftrees,
1353 struct btrfs_root *root = btrfs_extent_root(fs_info, bytenr);
1354 struct btrfs_key key;
1355 struct btrfs_path *path;
1356 struct btrfs_delayed_ref_root *delayed_refs = NULL;
1357 struct btrfs_delayed_ref_head *head;
1358 int info_level = 0;
1359 int ret;
1360 struct prelim_ref *ref;

--- 171 unchanged lines hidden (view full) ---

1532
1533 ret = add_missing_keys(fs_info, &preftrees, path->skip_locking == 0);
1534 if (ret)
1535 goto out;
1536
1537 WARN_ON(!RB_EMPTY_ROOT(&preftrees.indirect_missing_keys.root.rb_root));
1538
1539 ret = resolve_indirect_refs(fs_info, path, time_seq, &preftrees,
1542 extent_item_pos, sc, ignore_offset);
1540 extent_item_pos, sc);
1543 if (ret)
1544 goto out;
1545
1546 WARN_ON(!RB_EMPTY_ROOT(&preftrees.indirect.root.rb_root));
1547
1548 /*
1549 * This walks the tree of merged and resolved refs. Tree blocks are
1550 * read in as needed. Unique entries are added to the ulist, and

--- 17 unchanged lines hidden (view full) ---

1568 */
1569 if (roots && ref->count && ref->root_id && ref->parent == 0) {
1570 /* no parent == root of tree */
1571 ret = ulist_add(roots, ref->root_id, 0, GFP_NOFS);
1572 if (ret < 0)
1573 goto out;
1574 }
1575 if (ref->count && ref->parent) {
1541 if (ret)
1542 goto out;
1543
1544 WARN_ON(!RB_EMPTY_ROOT(&preftrees.indirect.root.rb_root));
1545
1546 /*
1547 * This walks the tree of merged and resolved refs. Tree blocks are
1548 * read in as needed. Unique entries are added to the ulist, and

--- 17 unchanged lines hidden (view full) ---

1566 */
1567 if (roots && ref->count && ref->root_id && ref->parent == 0) {
1568 /* no parent == root of tree */
1569 ret = ulist_add(roots, ref->root_id, 0, GFP_NOFS);
1570 if (ret < 0)
1571 goto out;
1572 }
1573 if (ref->count && ref->parent) {
1576 if (extent_item_pos && !ref->inode_list &&
1577 ref->level == 0) {
1574 if (!ignore_offset && !ref->inode_list && ref->level == 0) {
1578 struct extent_buffer *eb;
1579
1580 eb = read_tree_block(fs_info, ref->parent, 0,
1581 0, ref->level, NULL);
1582 if (IS_ERR(eb)) {
1583 ret = PTR_ERR(eb);
1584 goto out;
1585 }
1586 if (!extent_buffer_uptodate(eb)) {
1587 free_extent_buffer(eb);
1588 ret = -EIO;
1589 goto out;
1590 }
1591
1592 if (!path->skip_locking)
1593 btrfs_tree_read_lock(eb);
1594 ret = find_extent_in_eb(eb, bytenr,
1575 struct extent_buffer *eb;
1576
1577 eb = read_tree_block(fs_info, ref->parent, 0,
1578 0, ref->level, NULL);
1579 if (IS_ERR(eb)) {
1580 ret = PTR_ERR(eb);
1581 goto out;
1582 }
1583 if (!extent_buffer_uptodate(eb)) {
1584 free_extent_buffer(eb);
1585 ret = -EIO;
1586 goto out;
1587 }
1588
1589 if (!path->skip_locking)
1590 btrfs_tree_read_lock(eb);
1591 ret = find_extent_in_eb(eb, bytenr,
1595 *extent_item_pos, &eie, ignore_offset);
1592 extent_item_pos, &eie);
1596 if (!path->skip_locking)
1597 btrfs_tree_read_unlock(eb);
1598 free_extent_buffer(eb);
1599 if (ret < 0)
1600 goto out;
1601 ref->inode_list = eie;
1602 /*
1603 * We transferred the list ownership to the ref,
1604 * so set to NULL to avoid a double free in case
1605 * an error happens after this.
1606 */
1607 eie = NULL;
1608 }
1609 ret = ulist_add_merge_ptr(refs, ref->parent,
1610 ref->inode_list,
1611 (void **)&eie, GFP_NOFS);
1612 if (ret < 0)
1613 goto out;
1593 if (!path->skip_locking)
1594 btrfs_tree_read_unlock(eb);
1595 free_extent_buffer(eb);
1596 if (ret < 0)
1597 goto out;
1598 ref->inode_list = eie;
1599 /*
1600 * We transferred the list ownership to the ref,
1601 * so set to NULL to avoid a double free in case
1602 * an error happens after this.
1603 */
1604 eie = NULL;
1605 }
1606 ret = ulist_add_merge_ptr(refs, ref->parent,
1607 ref->inode_list,
1608 (void **)&eie, GFP_NOFS);
1609 if (ret < 0)
1610 goto out;
1614 if (!ret && extent_item_pos) {
1611 if (!ret && !ignore_offset) {
1615 /*
1616 * We've recorded that parent, so we must extend
1617 * its inode list here.
1618 *
1619 * However if there was corruption we may not
1620 * have found an eie, return an error in this
1621 * case.
1622 */

--- 37 unchanged lines hidden (view full) ---

1660 * free each list element). The leafs will be stored in the leafs ulist, which
1661 * must be freed with ulist_free.
1662 *
1663 * returns 0 on success, <0 on error
1664 */
1665int btrfs_find_all_leafs(struct btrfs_trans_handle *trans,
1666 struct btrfs_fs_info *fs_info, u64 bytenr,
1667 u64 time_seq, struct ulist **leafs,
1612 /*
1613 * We've recorded that parent, so we must extend
1614 * its inode list here.
1615 *
1616 * However if there was corruption we may not
1617 * have found an eie, return an error in this
1618 * case.
1619 */

--- 37 unchanged lines hidden (view full) ---

1657 * free each list element). The leafs will be stored in the leafs ulist, which
1658 * must be freed with ulist_free.
1659 *
1660 * returns 0 on success, <0 on error
1661 */
1662int btrfs_find_all_leafs(struct btrfs_trans_handle *trans,
1663 struct btrfs_fs_info *fs_info, u64 bytenr,
1664 u64 time_seq, struct ulist **leafs,
1668 const u64 *extent_item_pos, bool ignore_offset)
1665 u64 extent_item_pos)
1669{
1670 int ret;
1671
1672 *leafs = ulist_alloc(GFP_NOFS);
1673 if (!*leafs)
1674 return -ENOMEM;
1675
1676 ret = find_parent_nodes(trans, fs_info, bytenr, time_seq,
1666{
1667 int ret;
1668
1669 *leafs = ulist_alloc(GFP_NOFS);
1670 if (!*leafs)
1671 return -ENOMEM;
1672
1673 ret = find_parent_nodes(trans, fs_info, bytenr, time_seq,
1677 *leafs, NULL, extent_item_pos, NULL, ignore_offset);
1674 *leafs, NULL, extent_item_pos, NULL);
1678 if (ret < 0 && ret != -ENOENT) {
1679 free_leaf_list(*leafs);
1680 return ret;
1681 }
1682
1683 return 0;
1684}
1685

--- 7 unchanged lines hidden (view full) ---

1693 * to the list. The way we iterate the list allows adding more elements after
1694 * the current while iterating. The process stops when we reach the end of the
1695 * list. Found roots are added to the roots list.
1696 *
1697 * returns 0 on success, < 0 on error.
1698 */
1699static int btrfs_find_all_roots_safe(struct btrfs_trans_handle *trans,
1700 struct btrfs_fs_info *fs_info, u64 bytenr,
1675 if (ret < 0 && ret != -ENOENT) {
1676 free_leaf_list(*leafs);
1677 return ret;
1678 }
1679
1680 return 0;
1681}
1682

--- 7 unchanged lines hidden (view full) ---

1690 * to the list. The way we iterate the list allows adding more elements after
1691 * the current while iterating. The process stops when we reach the end of the
1692 * list. Found roots are added to the roots list.
1693 *
1694 * returns 0 on success, < 0 on error.
1695 */
1696static int btrfs_find_all_roots_safe(struct btrfs_trans_handle *trans,
1697 struct btrfs_fs_info *fs_info, u64 bytenr,
1701 u64 time_seq, struct ulist **roots,
1702 bool ignore_offset)
1698 u64 time_seq, struct ulist **roots)
1703{
1704 struct ulist *tmp;
1705 struct ulist_node *node = NULL;
1706 struct ulist_iterator uiter;
1707 int ret;
1708
1709 tmp = ulist_alloc(GFP_NOFS);
1710 if (!tmp)
1711 return -ENOMEM;
1712 *roots = ulist_alloc(GFP_NOFS);
1713 if (!*roots) {
1714 ulist_free(tmp);
1715 return -ENOMEM;
1716 }
1717
1718 ULIST_ITER_INIT(&uiter);
1719 while (1) {
1720 ret = find_parent_nodes(trans, fs_info, bytenr, time_seq,
1699{
1700 struct ulist *tmp;
1701 struct ulist_node *node = NULL;
1702 struct ulist_iterator uiter;
1703 int ret;
1704
1705 tmp = ulist_alloc(GFP_NOFS);
1706 if (!tmp)
1707 return -ENOMEM;
1708 *roots = ulist_alloc(GFP_NOFS);
1709 if (!*roots) {
1710 ulist_free(tmp);
1711 return -ENOMEM;
1712 }
1713
1714 ULIST_ITER_INIT(&uiter);
1715 while (1) {
1716 ret = find_parent_nodes(trans, fs_info, bytenr, time_seq,
1721 tmp, *roots, NULL, NULL, ignore_offset);
1717 tmp, *roots, BTRFS_IGNORE_EXTENT_OFFSET,
1718 NULL);
1722 if (ret < 0 && ret != -ENOENT) {
1723 ulist_free(tmp);
1724 ulist_free(*roots);
1725 *roots = NULL;
1726 return ret;
1727 }
1728 node = ulist_next(tmp, &uiter);
1729 if (!node)

--- 10 unchanged lines hidden (view full) ---

1740 struct btrfs_fs_info *fs_info, u64 bytenr,
1741 u64 time_seq, struct ulist **roots,
1742 bool skip_commit_root_sem)
1743{
1744 int ret;
1745
1746 if (!trans && !skip_commit_root_sem)
1747 down_read(&fs_info->commit_root_sem);
1719 if (ret < 0 && ret != -ENOENT) {
1720 ulist_free(tmp);
1721 ulist_free(*roots);
1722 *roots = NULL;
1723 return ret;
1724 }
1725 node = ulist_next(tmp, &uiter);
1726 if (!node)

--- 10 unchanged lines hidden (view full) ---

1737 struct btrfs_fs_info *fs_info, u64 bytenr,
1738 u64 time_seq, struct ulist **roots,
1739 bool skip_commit_root_sem)
1740{
1741 int ret;
1742
1743 if (!trans && !skip_commit_root_sem)
1744 down_read(&fs_info->commit_root_sem);
1748 ret = btrfs_find_all_roots_safe(trans, fs_info, bytenr,
1749 time_seq, roots, false);
1745 ret = btrfs_find_all_roots_safe(trans, fs_info, bytenr, time_seq, roots);
1750 if (!trans && !skip_commit_root_sem)
1751 up_read(&fs_info->commit_root_sem);
1752 return ret;
1753}
1754
1755struct btrfs_backref_share_check_ctx *btrfs_alloc_backref_share_check_ctx(void)
1756{
1757 struct btrfs_backref_share_check_ctx *ctx;

--- 82 unchanged lines hidden (view full) ---

1840 level = -1;
1841 ULIST_ITER_INIT(&uiter);
1842 ctx->use_path_cache = true;
1843 while (1) {
1844 bool is_shared;
1845 bool cached;
1846
1847 ret = find_parent_nodes(trans, fs_info, bytenr, elem.seq, &ctx->refs,
1746 if (!trans && !skip_commit_root_sem)
1747 up_read(&fs_info->commit_root_sem);
1748 return ret;
1749}
1750
1751struct btrfs_backref_share_check_ctx *btrfs_alloc_backref_share_check_ctx(void)
1752{
1753 struct btrfs_backref_share_check_ctx *ctx;

--- 82 unchanged lines hidden (view full) ---

1836 level = -1;
1837 ULIST_ITER_INIT(&uiter);
1838 ctx->use_path_cache = true;
1839 while (1) {
1840 bool is_shared;
1841 bool cached;
1842
1843 ret = find_parent_nodes(trans, fs_info, bytenr, elem.seq, &ctx->refs,
1848 NULL, NULL, &shared, false);
1844 NULL, BTRFS_IGNORE_EXTENT_OFFSET, &shared);
1849 if (ret == BACKREF_FOUND_SHARED ||
1850 ret == BACKREF_FOUND_NOT_SHARED) {
1851 /* If shared must return 1, otherwise return 0. */
1852 ret = (ret == BACKREF_FOUND_SHARED) ? 1 : 0;
1853 if (level >= 0)
1854 store_backref_shared_cache(ctx, root, bytenr,
1855 level, ret == 1);
1856 break;

--- 424 unchanged lines hidden (view full) ---

2281/*
2282 * calls iterate() for every inode that references the extent identified by
2283 * the given parameters.
2284 * when the iterator function returns a non-zero value, iteration stops.
2285 */
2286int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
2287 u64 extent_item_objectid, u64 extent_item_pos,
2288 int search_commit_root,
1845 if (ret == BACKREF_FOUND_SHARED ||
1846 ret == BACKREF_FOUND_NOT_SHARED) {
1847 /* If shared must return 1, otherwise return 0. */
1848 ret = (ret == BACKREF_FOUND_SHARED) ? 1 : 0;
1849 if (level >= 0)
1850 store_backref_shared_cache(ctx, root, bytenr,
1851 level, ret == 1);
1852 break;

--- 424 unchanged lines hidden (view full) ---

2277/*
2278 * calls iterate() for every inode that references the extent identified by
2279 * the given parameters.
2280 * when the iterator function returns a non-zero value, iteration stops.
2281 */
2282int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
2283 u64 extent_item_objectid, u64 extent_item_pos,
2284 int search_commit_root,
2289 iterate_extent_inodes_t *iterate, void *ctx,
2290 bool ignore_offset)
2285 iterate_extent_inodes_t *iterate, void *ctx)
2291{
2292 int ret;
2293 struct btrfs_trans_handle *trans = NULL;
2294 struct ulist *refs = NULL;
2295 struct ulist *roots = NULL;
2296 struct ulist_node *ref_node = NULL;
2297 struct ulist_node *root_node = NULL;
2298 struct btrfs_seq_list seq_elem = BTRFS_SEQ_LIST_INIT(seq_elem);

--- 14 unchanged lines hidden (view full) ---

2313 }
2314
2315 if (trans)
2316 btrfs_get_tree_mod_seq(fs_info, &seq_elem);
2317 else
2318 down_read(&fs_info->commit_root_sem);
2319
2320 ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid,
2286{
2287 int ret;
2288 struct btrfs_trans_handle *trans = NULL;
2289 struct ulist *refs = NULL;
2290 struct ulist *roots = NULL;
2291 struct ulist_node *ref_node = NULL;
2292 struct ulist_node *root_node = NULL;
2293 struct btrfs_seq_list seq_elem = BTRFS_SEQ_LIST_INIT(seq_elem);

--- 14 unchanged lines hidden (view full) ---

2308 }
2309
2310 if (trans)
2311 btrfs_get_tree_mod_seq(fs_info, &seq_elem);
2312 else
2313 down_read(&fs_info->commit_root_sem);
2314
2315 ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid,
2321 seq_elem.seq, &refs,
2322 &extent_item_pos, ignore_offset);
2316 seq_elem.seq, &refs, extent_item_pos);
2323 if (ret)
2324 goto out;
2325
2326 ULIST_ITER_INIT(&ref_uiter);
2327 while (!ret && (ref_node = ulist_next(refs, &ref_uiter))) {
2328 ret = btrfs_find_all_roots_safe(trans, fs_info, ref_node->val,
2317 if (ret)
2318 goto out;
2319
2320 ULIST_ITER_INIT(&ref_uiter);
2321 while (!ret && (ref_node = ulist_next(refs, &ref_uiter))) {
2322 ret = btrfs_find_all_roots_safe(trans, fs_info, ref_node->val,
2329 seq_elem.seq, &roots,
2330 ignore_offset);
2323 seq_elem.seq, &roots);
2331 if (ret)
2332 break;
2333 ULIST_ITER_INIT(&root_uiter);
2334 while (!ret && (root_node = ulist_next(roots, &root_uiter))) {
2335 btrfs_debug(fs_info,
2336 "root %llu references leaf %llu, data list %#llx",
2337 root_node->val, ref_node->val,
2338 ref_node->aux);

--- 51 unchanged lines hidden (view full) ---

2390
2391 ret = extent_from_logical(fs_info, logical, path, &found_key, &flags);
2392 btrfs_release_path(path);
2393 if (ret < 0)
2394 return ret;
2395 if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK)
2396 return -EINVAL;
2397
2324 if (ret)
2325 break;
2326 ULIST_ITER_INIT(&root_uiter);
2327 while (!ret && (root_node = ulist_next(roots, &root_uiter))) {
2328 btrfs_debug(fs_info,
2329 "root %llu references leaf %llu, data list %#llx",
2330 root_node->val, ref_node->val,
2331 ref_node->aux);

--- 51 unchanged lines hidden (view full) ---

2383
2384 ret = extent_from_logical(fs_info, logical, path, &found_key, &flags);
2385 btrfs_release_path(path);
2386 if (ret < 0)
2387 return ret;
2388 if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK)
2389 return -EINVAL;
2390
2398 extent_item_pos = logical - found_key.objectid;
2391 if (ignore_offset)
2392 extent_item_pos = BTRFS_IGNORE_EXTENT_OFFSET;
2393 else
2394 extent_item_pos = logical - found_key.objectid;
2395
2399 ret = iterate_extent_inodes(fs_info, found_key.objectid,
2400 extent_item_pos, search_commit_root,
2396 ret = iterate_extent_inodes(fs_info, found_key.objectid,
2397 extent_item_pos, search_commit_root,
2401 build_ino_list, ctx, ignore_offset);
2398 build_ino_list, ctx);
2402
2403 return ret;
2404}
2405
2406static int inode_to_path(u64 inum, u32 name_len, unsigned long name_off,
2407 struct extent_buffer *eb, struct inode_fs_paths *ipath);
2408
2409static int iterate_inode_refs(u64 inum, struct inode_fs_paths *ipath)

--- 1068 unchanged lines hidden ---
2399
2400 return ret;
2401}
2402
2403static int inode_to_path(u64 inum, u32 name_len, unsigned long name_off,
2404 struct extent_buffer *eb, struct inode_fs_paths *ipath);
2405
2406static int iterate_inode_refs(u64 inum, struct inode_fs_paths *ipath)

--- 1068 unchanged lines hidden ---