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 --- |