backref.c (6c336b212bef66e507897c78551b3bb4e613a857) backref.c (00142756e1f8015d2f8ce96532d156689db7e448)
1/*
2 * Copyright (C) 2011 STRATO. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License v2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,

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

13 * You should have received a copy of the GNU General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 * Boston, MA 021110-1307, USA.
17 */
18
19#include <linux/mm.h>
20#include <linux/rbtree.h>
1/*
2 * Copyright (C) 2011 STRATO. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License v2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,

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

13 * You should have received a copy of the GNU General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 * Boston, MA 021110-1307, USA.
17 */
18
19#include <linux/mm.h>
20#include <linux/rbtree.h>
21#include <trace/events/btrfs.h>
21#include "ctree.h"
22#include "disk-io.h"
23#include "backref.h"
24#include "ulist.h"
25#include "transaction.h"
26#include "delayed-ref.h"
27#include "locking.h"
28

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

115 ret = check_extent_in_eb(&key, eb, fi, extent_item_pos, eie);
116 if (ret < 0)
117 return ret;
118 }
119
120 return 0;
121}
122
22#include "ctree.h"
23#include "disk-io.h"
24#include "backref.h"
25#include "ulist.h"
26#include "transaction.h"
27#include "delayed-ref.h"
28#include "locking.h"
29

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

116 ret = check_extent_in_eb(&key, eb, fi, extent_item_pos, eie);
117 if (ret < 0)
118 return ret;
119 }
120
121 return 0;
122}
123
123/*
124 * this structure records all encountered refs on the way up to the root
125 */
126struct prelim_ref {
127 struct rb_node rbnode;
128 u64 root_id;
129 struct btrfs_key key_for_search;
130 int level;
131 int count;
132 struct extent_inode_elem *inode_list;
133 u64 parent;
134 u64 wanted_disk_byte;
135};
136
137struct preftree {
138 struct rb_root root;
139 unsigned int count;
140};
141
142#define PREFTREE_INIT { .root = RB_ROOT, .count = 0 }
143
144struct preftrees {

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

207 return 0;
208}
209
210/*
211 * Add @newref to the @root rbtree, merging identical refs.
212 *
213 * Callers should assumed that newref has been freed after calling.
214 */
124struct preftree {
125 struct rb_root root;
126 unsigned int count;
127};
128
129#define PREFTREE_INIT { .root = RB_ROOT, .count = 0 }
130
131struct preftrees {

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

194 return 0;
195}
196
197/*
198 * Add @newref to the @root rbtree, merging identical refs.
199 *
200 * Callers should assumed that newref has been freed after calling.
201 */
215static void prelim_ref_insert(struct preftree *preftree,
202static void prelim_ref_insert(const struct btrfs_fs_info *fs_info,
203 struct preftree *preftree,
216 struct prelim_ref *newref)
217{
218 struct rb_root *root;
219 struct rb_node **p;
220 struct rb_node *parent = NULL;
221 struct prelim_ref *ref;
222 int result;
223

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

238
239 while (eie && eie->next)
240 eie = eie->next;
241
242 if (!eie)
243 ref->inode_list = newref->inode_list;
244 else
245 eie->next = newref->inode_list;
204 struct prelim_ref *newref)
205{
206 struct rb_root *root;
207 struct rb_node **p;
208 struct rb_node *parent = NULL;
209 struct prelim_ref *ref;
210 int result;
211

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

226
227 while (eie && eie->next)
228 eie = eie->next;
229
230 if (!eie)
231 ref->inode_list = newref->inode_list;
232 else
233 eie->next = newref->inode_list;
234 trace_btrfs_prelim_ref_merge(fs_info, ref, newref,
235 preftree->count);
246 ref->count += newref->count;
247 free_pref(newref);
248 return;
249 }
250 }
251
252 preftree->count++;
236 ref->count += newref->count;
237 free_pref(newref);
238 return;
239 }
240 }
241
242 preftree->count++;
243 trace_btrfs_prelim_ref_insert(fs_info, newref, NULL, preftree->count);
253 rb_link_node(&newref->rbnode, parent, p);
254 rb_insert_color(&newref->rbnode, root);
255}
256
257/*
258 * Release the entire tree. We don't care about internal consistency so
259 * just free everything and then reset the tree root.
260 */

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

303 * - column 1, 3: we've the parent -> done
304 * - column 2: we take the first key from the block to find the parent
305 * (see add_missing_keys)
306 * - column 4: we use the key to find the parent
307 *
308 * additional information that's available but not required to find the parent
309 * block might help in merging entries to gain some speed.
310 */
244 rb_link_node(&newref->rbnode, parent, p);
245 rb_insert_color(&newref->rbnode, root);
246}
247
248/*
249 * Release the entire tree. We don't care about internal consistency so
250 * just free everything and then reset the tree root.
251 */

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

294 * - column 1, 3: we've the parent -> done
295 * - column 2: we take the first key from the block to find the parent
296 * (see add_missing_keys)
297 * - column 4: we use the key to find the parent
298 *
299 * additional information that's available but not required to find the parent
300 * block might help in merging entries to gain some speed.
301 */
311static int add_prelim_ref(struct preftree *preftree, u64 root_id,
302static int add_prelim_ref(const struct btrfs_fs_info *fs_info,
303 struct preftree *preftree, u64 root_id,
312 const struct btrfs_key *key, int level, u64 parent,
313 u64 wanted_disk_byte, int count, gfp_t gfp_mask)
314{
315 struct prelim_ref *ref;
316
317 if (root_id == BTRFS_DATA_RELOC_TREE_OBJECTID)
318 return 0;
319

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

350 memset(&ref->key_for_search, 0, sizeof(ref->key_for_search));
351 }
352
353 ref->inode_list = NULL;
354 ref->level = level;
355 ref->count = count;
356 ref->parent = parent;
357 ref->wanted_disk_byte = wanted_disk_byte;
304 const struct btrfs_key *key, int level, u64 parent,
305 u64 wanted_disk_byte, int count, gfp_t gfp_mask)
306{
307 struct prelim_ref *ref;
308
309 if (root_id == BTRFS_DATA_RELOC_TREE_OBJECTID)
310 return 0;
311

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

342 memset(&ref->key_for_search, 0, sizeof(ref->key_for_search));
343 }
344
345 ref->inode_list = NULL;
346 ref->level = level;
347 ref->count = count;
348 ref->parent = parent;
349 ref->wanted_disk_byte = wanted_disk_byte;
358 prelim_ref_insert(preftree, ref);
350 prelim_ref_insert(fs_info, preftree, ref);
359
360 return 0;
361}
362
363/* direct refs use root == 0, key == NULL */
351
352 return 0;
353}
354
355/* direct refs use root == 0, key == NULL */
364static int add_direct_ref(struct preftrees *preftrees, int level, u64 parent,
356static int add_direct_ref(const struct btrfs_fs_info *fs_info,
357 struct preftrees *preftrees, int level, u64 parent,
365 u64 wanted_disk_byte, int count, gfp_t gfp_mask)
366{
358 u64 wanted_disk_byte, int count, gfp_t gfp_mask)
359{
367 return add_prelim_ref(&preftrees->direct, 0, NULL, level, parent,
368 wanted_disk_byte, count, gfp_mask);
360 return add_prelim_ref(fs_info, &preftrees->direct, 0, NULL, level,
361 parent, wanted_disk_byte, count, gfp_mask);
369}
370
371/* indirect refs use parent == 0 */
362}
363
364/* indirect refs use parent == 0 */
372static int add_indirect_ref(struct preftrees *preftrees, u64 root_id,
365static int add_indirect_ref(const struct btrfs_fs_info *fs_info,
366 struct preftrees *preftrees, u64 root_id,
373 const struct btrfs_key *key, int level,
374 u64 wanted_disk_byte, int count, gfp_t gfp_mask)
375{
376 struct preftree *tree = &preftrees->indirect;
377
378 if (!key)
379 tree = &preftrees->indirect_missing_keys;
367 const struct btrfs_key *key, int level,
368 u64 wanted_disk_byte, int count, gfp_t gfp_mask)
369{
370 struct preftree *tree = &preftrees->indirect;
371
372 if (!key)
373 tree = &preftrees->indirect_missing_keys;
380 return add_prelim_ref(tree, root_id, key, level, 0,
374 return add_prelim_ref(fs_info, tree, root_id, key, level, 0,
381 wanted_disk_byte, count, gfp_mask);
382}
383
384static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
385 struct ulist *parents, struct prelim_ref *ref,
386 int level, u64 time_seq, const u64 *extent_item_pos,
387 u64 total_refs)
388{

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

626 err = resolve_indirect_ref(fs_info, path, time_seq, ref,
627 parents, extent_item_pos,
628 total_refs);
629 /*
630 * we can only tolerate ENOENT,otherwise,we should catch error
631 * and return directly.
632 */
633 if (err == -ENOENT) {
375 wanted_disk_byte, count, gfp_mask);
376}
377
378static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
379 struct ulist *parents, struct prelim_ref *ref,
380 int level, u64 time_seq, const u64 *extent_item_pos,
381 u64 total_refs)
382{

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

620 err = resolve_indirect_ref(fs_info, path, time_seq, ref,
621 parents, extent_item_pos,
622 total_refs);
623 /*
624 * we can only tolerate ENOENT,otherwise,we should catch error
625 * and return directly.
626 */
627 if (err == -ENOENT) {
634 prelim_ref_insert(&preftrees->direct, ref);
628 prelim_ref_insert(fs_info, &preftrees->direct, ref);
635 continue;
636 } else if (err) {
637 free_pref(ref);
638 ret = err;
639 goto out;
640 }
641
642 /* we put the first parent into the ref at hand */

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

654 if (!new_ref) {
655 free_pref(ref);
656 ret = -ENOMEM;
657 goto out;
658 }
659 memcpy(new_ref, ref, sizeof(*ref));
660 new_ref->parent = node->val;
661 new_ref->inode_list = unode_aux_to_inode_list(node);
629 continue;
630 } else if (err) {
631 free_pref(ref);
632 ret = err;
633 goto out;
634 }
635
636 /* we put the first parent into the ref at hand */

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

648 if (!new_ref) {
649 free_pref(ref);
650 ret = -ENOMEM;
651 goto out;
652 }
653 memcpy(new_ref, ref, sizeof(*ref));
654 new_ref->parent = node->val;
655 new_ref->inode_list = unode_aux_to_inode_list(node);
662 prelim_ref_insert(&preftrees->direct, new_ref);
656 prelim_ref_insert(fs_info, &preftrees->direct, new_ref);
663 }
664
665 /* Now it's a direct ref, put it in the the direct tree */
657 }
658
659 /* Now it's a direct ref, put it in the the direct tree */
666 prelim_ref_insert(&preftrees->direct, ref);
660 prelim_ref_insert(fs_info, &preftrees->direct, ref);
667
668 ulist_reinit(parents);
669 }
670out:
671 ulist_free(parents);
672 return ret;
673}
674

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

702 }
703 btrfs_tree_read_lock(eb);
704 if (btrfs_header_level(eb) == 0)
705 btrfs_item_key_to_cpu(eb, &ref->key_for_search, 0);
706 else
707 btrfs_node_key_to_cpu(eb, &ref->key_for_search, 0);
708 btrfs_tree_read_unlock(eb);
709 free_extent_buffer(eb);
661
662 ulist_reinit(parents);
663 }
664out:
665 ulist_free(parents);
666 return ret;
667}
668

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

696 }
697 btrfs_tree_read_lock(eb);
698 if (btrfs_header_level(eb) == 0)
699 btrfs_item_key_to_cpu(eb, &ref->key_for_search, 0);
700 else
701 btrfs_node_key_to_cpu(eb, &ref->key_for_search, 0);
702 btrfs_tree_read_unlock(eb);
703 free_extent_buffer(eb);
710 prelim_ref_insert(&preftrees->indirect, ref);
704 prelim_ref_insert(fs_info, &preftrees->indirect, ref);
711 }
712 return 0;
713}
714
715/*
716 * add all currently queued delayed refs from this head whose seq nr is
717 * smaller or equal that seq to the list
718 */
705 }
706 return 0;
707}
708
709/*
710 * add all currently queued delayed refs from this head whose seq nr is
711 * smaller or equal that seq to the list
712 */
719static int add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq,
713static int add_delayed_refs(const struct btrfs_fs_info *fs_info,
714 struct btrfs_delayed_ref_head *head, u64 seq,
720 struct preftrees *preftrees, u64 *total_refs,
721 u64 inum)
722{
723 struct btrfs_delayed_ref_node *node;
724 struct btrfs_delayed_extent_op *extent_op = head->extent_op;
725 struct btrfs_key key;
726 struct btrfs_key tmp_op_key;
727 struct btrfs_key *op_key = NULL;

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

754 }
755 *total_refs += (node->ref_mod * sgn);
756 switch (node->type) {
757 case BTRFS_TREE_BLOCK_REF_KEY: {
758 /* NORMAL INDIRECT METADATA backref */
759 struct btrfs_delayed_tree_ref *ref;
760
761 ref = btrfs_delayed_node_to_tree_ref(node);
715 struct preftrees *preftrees, u64 *total_refs,
716 u64 inum)
717{
718 struct btrfs_delayed_ref_node *node;
719 struct btrfs_delayed_extent_op *extent_op = head->extent_op;
720 struct btrfs_key key;
721 struct btrfs_key tmp_op_key;
722 struct btrfs_key *op_key = NULL;

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

749 }
750 *total_refs += (node->ref_mod * sgn);
751 switch (node->type) {
752 case BTRFS_TREE_BLOCK_REF_KEY: {
753 /* NORMAL INDIRECT METADATA backref */
754 struct btrfs_delayed_tree_ref *ref;
755
756 ref = btrfs_delayed_node_to_tree_ref(node);
762 ret = add_indirect_ref(preftrees, ref->root, &tmp_op_key,
763 ref->level + 1, node->bytenr,
757 ret = add_indirect_ref(fs_info, preftrees, ref->root,
758 &tmp_op_key, ref->level + 1,
759 node->bytenr,
764 node->ref_mod * sgn,
765 GFP_ATOMIC);
766 break;
767 }
768 case BTRFS_SHARED_BLOCK_REF_KEY: {
769 /* SHARED DIRECT METADATA backref */
770 struct btrfs_delayed_tree_ref *ref;
771
772 ref = btrfs_delayed_node_to_tree_ref(node);
773
760 node->ref_mod * sgn,
761 GFP_ATOMIC);
762 break;
763 }
764 case BTRFS_SHARED_BLOCK_REF_KEY: {
765 /* SHARED DIRECT METADATA backref */
766 struct btrfs_delayed_tree_ref *ref;
767
768 ref = btrfs_delayed_node_to_tree_ref(node);
769
774 ret = add_direct_ref(preftrees, ref->level + 1,
775 ref->parent, node->bytenr,
776 node->ref_mod * sgn,
770 ret = add_direct_ref(fs_info, preftrees,
771 ref->level + 1, ref->parent,
772 node->bytenr, node->ref_mod * sgn,
777 GFP_ATOMIC);
778 break;
779 }
780 case BTRFS_EXTENT_DATA_REF_KEY: {
781 /* NORMAL INDIRECT DATA backref */
782 struct btrfs_delayed_data_ref *ref;
783 ref = btrfs_delayed_node_to_data_ref(node);
784

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

790 * Found a inum that doesn't match our known inum, we
791 * know it's shared.
792 */
793 if (inum && ref->objectid != inum) {
794 ret = BACKREF_FOUND_SHARED;
795 break;
796 }
797
773 GFP_ATOMIC);
774 break;
775 }
776 case BTRFS_EXTENT_DATA_REF_KEY: {
777 /* NORMAL INDIRECT DATA backref */
778 struct btrfs_delayed_data_ref *ref;
779 ref = btrfs_delayed_node_to_data_ref(node);
780

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

786 * Found a inum that doesn't match our known inum, we
787 * know it's shared.
788 */
789 if (inum && ref->objectid != inum) {
790 ret = BACKREF_FOUND_SHARED;
791 break;
792 }
793
798 ret = add_indirect_ref(preftrees, ref->root, &key, 0,
799 node->bytenr,
794 ret = add_indirect_ref(fs_info, preftrees, ref->root,
795 &key, 0, node->bytenr,
800 node->ref_mod * sgn,
801 GFP_ATOMIC);
802 break;
803 }
804 case BTRFS_SHARED_DATA_REF_KEY: {
805 /* SHARED DIRECT FULL backref */
806 struct btrfs_delayed_data_ref *ref;
807
808 ref = btrfs_delayed_node_to_data_ref(node);
809
796 node->ref_mod * sgn,
797 GFP_ATOMIC);
798 break;
799 }
800 case BTRFS_SHARED_DATA_REF_KEY: {
801 /* SHARED DIRECT FULL backref */
802 struct btrfs_delayed_data_ref *ref;
803
804 ref = btrfs_delayed_node_to_data_ref(node);
805
810 ret = add_direct_ref(preftrees, 0, ref->parent,
811 node->bytenr,
806 ret = add_direct_ref(fs_info, preftrees, 0,
807 ref->parent, node->bytenr,
812 node->ref_mod * sgn,
813 GFP_ATOMIC);
814 break;
815 }
816 default:
817 WARN_ON(1);
818 }
819 if (ret)
820 break;
821 }
822 spin_unlock(&head->lock);
823 return ret;
824}
825
826/*
827 * add all inline backrefs for bytenr to the list
828 */
808 node->ref_mod * sgn,
809 GFP_ATOMIC);
810 break;
811 }
812 default:
813 WARN_ON(1);
814 }
815 if (ret)
816 break;
817 }
818 spin_unlock(&head->lock);
819 return ret;
820}
821
822/*
823 * add all inline backrefs for bytenr to the list
824 */
829static int add_inline_refs(struct btrfs_path *path, u64 bytenr,
825static int add_inline_refs(const struct btrfs_fs_info *fs_info,
826 struct btrfs_path *path, u64 bytenr,
830 int *info_level, struct preftrees *preftrees,
831 u64 *total_refs, u64 inum)
832{
833 int ret = 0;
834 int slot;
835 struct extent_buffer *leaf;
836 struct btrfs_key key;
837 struct btrfs_key found_key;

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

878 int type;
879
880 iref = (struct btrfs_extent_inline_ref *)ptr;
881 type = btrfs_extent_inline_ref_type(leaf, iref);
882 offset = btrfs_extent_inline_ref_offset(leaf, iref);
883
884 switch (type) {
885 case BTRFS_SHARED_BLOCK_REF_KEY:
827 int *info_level, struct preftrees *preftrees,
828 u64 *total_refs, u64 inum)
829{
830 int ret = 0;
831 int slot;
832 struct extent_buffer *leaf;
833 struct btrfs_key key;
834 struct btrfs_key found_key;

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

875 int type;
876
877 iref = (struct btrfs_extent_inline_ref *)ptr;
878 type = btrfs_extent_inline_ref_type(leaf, iref);
879 offset = btrfs_extent_inline_ref_offset(leaf, iref);
880
881 switch (type) {
882 case BTRFS_SHARED_BLOCK_REF_KEY:
886 ret = add_direct_ref(preftrees, *info_level + 1, offset,
883 ret = add_direct_ref(fs_info, preftrees,
884 *info_level + 1, offset,
887 bytenr, 1, GFP_NOFS);
888 break;
889 case BTRFS_SHARED_DATA_REF_KEY: {
890 struct btrfs_shared_data_ref *sdref;
891 int count;
892
893 sdref = (struct btrfs_shared_data_ref *)(iref + 1);
894 count = btrfs_shared_data_ref_count(leaf, sdref);
895
885 bytenr, 1, GFP_NOFS);
886 break;
887 case BTRFS_SHARED_DATA_REF_KEY: {
888 struct btrfs_shared_data_ref *sdref;
889 int count;
890
891 sdref = (struct btrfs_shared_data_ref *)(iref + 1);
892 count = btrfs_shared_data_ref_count(leaf, sdref);
893
896 ret = add_direct_ref(preftrees, 0, offset,
894 ret = add_direct_ref(fs_info, preftrees, 0, offset,
897 bytenr, count, GFP_NOFS);
898 break;
899 }
900 case BTRFS_TREE_BLOCK_REF_KEY:
895 bytenr, count, GFP_NOFS);
896 break;
897 }
898 case BTRFS_TREE_BLOCK_REF_KEY:
901 ret = add_indirect_ref(preftrees, offset, NULL,
902 *info_level + 1, bytenr, 1,
903 GFP_NOFS);
899 ret = add_indirect_ref(fs_info, preftrees, offset,
900 NULL, *info_level + 1,
901 bytenr, 1, GFP_NOFS);
904 break;
905 case BTRFS_EXTENT_DATA_REF_KEY: {
906 struct btrfs_extent_data_ref *dref;
907 int count;
908 u64 root;
909
910 dref = (struct btrfs_extent_data_ref *)(&iref->offset);
911 count = btrfs_extent_data_ref_count(leaf, dref);

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

916
917 if (inum && key.objectid != inum) {
918 ret = BACKREF_FOUND_SHARED;
919 break;
920 }
921
922 root = btrfs_extent_data_ref_root(leaf, dref);
923
902 break;
903 case BTRFS_EXTENT_DATA_REF_KEY: {
904 struct btrfs_extent_data_ref *dref;
905 int count;
906 u64 root;
907
908 dref = (struct btrfs_extent_data_ref *)(&iref->offset);
909 count = btrfs_extent_data_ref_count(leaf, dref);

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

914
915 if (inum && key.objectid != inum) {
916 ret = BACKREF_FOUND_SHARED;
917 break;
918 }
919
920 root = btrfs_extent_data_ref_root(leaf, dref);
921
924 ret = add_indirect_ref(preftrees, root, &key, 0, bytenr,
925 count, GFP_NOFS);
922 ret = add_indirect_ref(fs_info, preftrees, root,
923 &key, 0, bytenr, count,
924 GFP_NOFS);
926 break;
927 }
928 default:
929 WARN_ON(1);
930 }
931 if (ret)
932 return ret;
933 ptr += btrfs_extent_inline_ref_size(type);

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

968 if (key.type < BTRFS_TREE_BLOCK_REF_KEY)
969 continue;
970 if (key.type > BTRFS_SHARED_DATA_REF_KEY)
971 break;
972
973 switch (key.type) {
974 case BTRFS_SHARED_BLOCK_REF_KEY:
975 /* SHARED DIRECT METADATA backref */
925 break;
926 }
927 default:
928 WARN_ON(1);
929 }
930 if (ret)
931 return ret;
932 ptr += btrfs_extent_inline_ref_size(type);

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

967 if (key.type < BTRFS_TREE_BLOCK_REF_KEY)
968 continue;
969 if (key.type > BTRFS_SHARED_DATA_REF_KEY)
970 break;
971
972 switch (key.type) {
973 case BTRFS_SHARED_BLOCK_REF_KEY:
974 /* SHARED DIRECT METADATA backref */
976 ret = add_direct_ref(preftrees, info_level + 1,
977 key.offset, bytenr, 1,
978 GFP_NOFS);
975 ret = add_direct_ref(fs_info, preftrees,
976 info_level + 1, key.offset,
977 bytenr, 1, GFP_NOFS);
979 break;
980 case BTRFS_SHARED_DATA_REF_KEY: {
981 /* SHARED DIRECT FULL backref */
982 struct btrfs_shared_data_ref *sdref;
983 int count;
984
985 sdref = btrfs_item_ptr(leaf, slot,
986 struct btrfs_shared_data_ref);
987 count = btrfs_shared_data_ref_count(leaf, sdref);
978 break;
979 case BTRFS_SHARED_DATA_REF_KEY: {
980 /* SHARED DIRECT FULL backref */
981 struct btrfs_shared_data_ref *sdref;
982 int count;
983
984 sdref = btrfs_item_ptr(leaf, slot,
985 struct btrfs_shared_data_ref);
986 count = btrfs_shared_data_ref_count(leaf, sdref);
988 ret = add_direct_ref(preftrees, 0, key.offset, bytenr,
989 count, GFP_NOFS);
987 ret = add_direct_ref(fs_info, preftrees, 0,
988 key.offset, bytenr, count,
989 GFP_NOFS);
990 break;
991 }
992 case BTRFS_TREE_BLOCK_REF_KEY:
993 /* NORMAL INDIRECT METADATA backref */
990 break;
991 }
992 case BTRFS_TREE_BLOCK_REF_KEY:
993 /* NORMAL INDIRECT METADATA backref */
994 ret = add_indirect_ref(preftrees, key.offset, NULL,
995 info_level + 1, bytenr, 1,
996 GFP_NOFS);
994 ret = add_indirect_ref(fs_info, preftrees, key.offset,
995 NULL, info_level + 1, bytenr,
996 1, GFP_NOFS);
997 break;
998 case BTRFS_EXTENT_DATA_REF_KEY: {
999 /* NORMAL INDIRECT DATA backref */
1000 struct btrfs_extent_data_ref *dref;
1001 int count;
1002 u64 root;
1003
1004 dref = btrfs_item_ptr(leaf, slot,

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

1010 key.offset = btrfs_extent_data_ref_offset(leaf, dref);
1011
1012 if (inum && key.objectid != inum) {
1013 ret = BACKREF_FOUND_SHARED;
1014 break;
1015 }
1016
1017 root = btrfs_extent_data_ref_root(leaf, dref);
997 break;
998 case BTRFS_EXTENT_DATA_REF_KEY: {
999 /* NORMAL INDIRECT DATA backref */
1000 struct btrfs_extent_data_ref *dref;
1001 int count;
1002 u64 root;
1003
1004 dref = btrfs_item_ptr(leaf, slot,

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

1010 key.offset = btrfs_extent_data_ref_offset(leaf, dref);
1011
1012 if (inum && key.objectid != inum) {
1013 ret = BACKREF_FOUND_SHARED;
1014 break;
1015 }
1016
1017 root = btrfs_extent_data_ref_root(leaf, dref);
1018 ret = add_indirect_ref(preftrees, root, &key, 0, bytenr,
1019 count, GFP_NOFS);
1018 ret = add_indirect_ref(fs_info, preftrees, root,
1019 &key, 0, bytenr, count,
1020 GFP_NOFS);
1020 break;
1021 }
1022 default:
1023 WARN_ON(1);
1024 }
1025 if (ret)
1026 return ret;
1027

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

1124 * released and try again
1125 */
1126 mutex_lock(&head->mutex);
1127 mutex_unlock(&head->mutex);
1128 btrfs_put_delayed_ref(&head->node);
1129 goto again;
1130 }
1131 spin_unlock(&delayed_refs->lock);
1021 break;
1022 }
1023 default:
1024 WARN_ON(1);
1025 }
1026 if (ret)
1027 return ret;
1028

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

1125 * released and try again
1126 */
1127 mutex_lock(&head->mutex);
1128 mutex_unlock(&head->mutex);
1129 btrfs_put_delayed_ref(&head->node);
1130 goto again;
1131 }
1132 spin_unlock(&delayed_refs->lock);
1132 ret = add_delayed_refs(head, time_seq, &preftrees,
1133 &total_refs, inum);
1133 ret = add_delayed_refs(fs_info, head, time_seq,
1134 &preftrees, &total_refs, inum);
1134 mutex_unlock(&head->mutex);
1135 if (ret)
1136 goto out;
1137 } else {
1138 spin_unlock(&delayed_refs->lock);
1139 }
1140 }
1141
1142 if (path->slots[0]) {
1143 struct extent_buffer *leaf;
1144 int slot;
1145
1146 path->slots[0]--;
1147 leaf = path->nodes[0];
1148 slot = path->slots[0];
1149 btrfs_item_key_to_cpu(leaf, &key, slot);
1150 if (key.objectid == bytenr &&
1151 (key.type == BTRFS_EXTENT_ITEM_KEY ||
1152 key.type == BTRFS_METADATA_ITEM_KEY)) {
1135 mutex_unlock(&head->mutex);
1136 if (ret)
1137 goto out;
1138 } else {
1139 spin_unlock(&delayed_refs->lock);
1140 }
1141 }
1142
1143 if (path->slots[0]) {
1144 struct extent_buffer *leaf;
1145 int slot;
1146
1147 path->slots[0]--;
1148 leaf = path->nodes[0];
1149 slot = path->slots[0];
1150 btrfs_item_key_to_cpu(leaf, &key, slot);
1151 if (key.objectid == bytenr &&
1152 (key.type == BTRFS_EXTENT_ITEM_KEY ||
1153 key.type == BTRFS_METADATA_ITEM_KEY)) {
1153 ret = add_inline_refs(path, bytenr, &info_level,
1154 &preftrees, &total_refs, inum);
1154 ret = add_inline_refs(fs_info, path, bytenr,
1155 &info_level, &preftrees,
1156 &total_refs, inum);
1155 if (ret)
1156 goto out;
1157 ret = add_keyed_refs(fs_info, path, bytenr, info_level,
1158 &preftrees, inum);
1159 if (ret)
1160 goto out;
1161 }
1162 }

--- 1000 unchanged lines hidden ---
1157 if (ret)
1158 goto out;
1159 ret = add_keyed_refs(fs_info, path, bytenr, info_level,
1160 &preftrees, inum);
1161 if (ret)
1162 goto out;
1163 }
1164 }

--- 1000 unchanged lines hidden ---