backref.c (9f84b6267ccde1bebe3f9cd40a91716b5ece5e20) | backref.c (da61d31a78dc2116fa725c92d4eca36dfbc3da8b) |
---|---|
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, --- 241 unchanged lines hidden (view full) --- 250 return ret; 251} 252 253/* 254 * resolve an indirect backref in the form (root_id, key, level) 255 * to a logical address 256 */ 257static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, | 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, --- 241 unchanged lines hidden (view full) --- 250 return ret; 251} 252 253/* 254 * resolve an indirect backref in the form (root_id, key, level) 255 * to a logical address 256 */ 257static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, |
258 int search_commit_root, 259 u64 time_seq, 260 struct __prelim_ref *ref, 261 struct ulist *parents, 262 const u64 *extent_item_pos) | 258 struct btrfs_path *path, u64 time_seq, 259 struct __prelim_ref *ref, 260 struct ulist *parents, 261 const u64 *extent_item_pos) |
263{ | 262{ |
264 struct btrfs_path *path; | |
265 struct btrfs_root *root; 266 struct btrfs_key root_key; 267 struct extent_buffer *eb; 268 int ret = 0; 269 int root_level; 270 int level = ref->level; 271 | 263 struct btrfs_root *root; 264 struct btrfs_key root_key; 265 struct extent_buffer *eb; 266 int ret = 0; 267 int root_level; 268 int level = ref->level; 269 |
272 path = btrfs_alloc_path(); 273 if (!path) 274 return -ENOMEM; 275 path->search_commit_root = !!search_commit_root; 276 | |
277 root_key.objectid = ref->root_id; 278 root_key.type = BTRFS_ROOT_ITEM_KEY; 279 root_key.offset = (u64)-1; 280 root = btrfs_read_fs_root_no_name(fs_info, &root_key); 281 if (IS_ERR(root)) { 282 ret = PTR_ERR(root); 283 goto out; 284 } --- 24 unchanged lines hidden (view full) --- 309 level--; 310 eb = path->nodes[level]; 311 } 312 313 ret = add_all_parents(root, path, parents, level, &ref->key_for_search, 314 time_seq, ref->wanted_disk_byte, 315 extent_item_pos); 316out: | 270 root_key.objectid = ref->root_id; 271 root_key.type = BTRFS_ROOT_ITEM_KEY; 272 root_key.offset = (u64)-1; 273 root = btrfs_read_fs_root_no_name(fs_info, &root_key); 274 if (IS_ERR(root)) { 275 ret = PTR_ERR(root); 276 goto out; 277 } --- 24 unchanged lines hidden (view full) --- 302 level--; 303 eb = path->nodes[level]; 304 } 305 306 ret = add_all_parents(root, path, parents, level, &ref->key_for_search, 307 time_seq, ref->wanted_disk_byte, 308 extent_item_pos); 309out: |
317 btrfs_free_path(path); | 310 path->lowest_level = 0; 311 btrfs_release_path(path); |
318 return ret; 319} 320 321/* 322 * resolve all indirect backrefs from the list 323 */ 324static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info, | 312 return ret; 313} 314 315/* 316 * resolve all indirect backrefs from the list 317 */ 318static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info, |
325 int search_commit_root, u64 time_seq, | 319 struct btrfs_path *path, u64 time_seq, |
326 struct list_head *head, 327 const u64 *extent_item_pos) 328{ 329 int err; 330 int ret = 0; 331 struct __prelim_ref *ref; 332 struct __prelim_ref *ref_safe; 333 struct __prelim_ref *new_ref; --- 10 unchanged lines hidden (view full) --- 344 * iterating over the newly inserted items. 345 * we're also allowed to re-assign ref during iteration. 346 */ 347 list_for_each_entry_safe(ref, ref_safe, head, list) { 348 if (ref->parent) /* already direct */ 349 continue; 350 if (ref->count == 0) 351 continue; | 320 struct list_head *head, 321 const u64 *extent_item_pos) 322{ 323 int err; 324 int ret = 0; 325 struct __prelim_ref *ref; 326 struct __prelim_ref *ref_safe; 327 struct __prelim_ref *new_ref; --- 10 unchanged lines hidden (view full) --- 338 * iterating over the newly inserted items. 339 * we're also allowed to re-assign ref during iteration. 340 */ 341 list_for_each_entry_safe(ref, ref_safe, head, list) { 342 if (ref->parent) /* already direct */ 343 continue; 344 if (ref->count == 0) 345 continue; |
352 err = __resolve_indirect_ref(fs_info, search_commit_root, 353 time_seq, ref, parents, 354 extent_item_pos); | 346 err = __resolve_indirect_ref(fs_info, path, time_seq, ref, 347 parents, extent_item_pos); |
355 if (err == -ENOMEM) 356 goto out; 357 if (err) 358 continue; 359 360 /* we put the first parent into the ref at hand */ 361 ULIST_ITER_INIT(&uiter); 362 node = ulist_next(parents, &uiter); --- 427 unchanged lines hidden (view full) --- 790 struct ulist *roots, const u64 *extent_item_pos) 791{ 792 struct btrfs_key key; 793 struct btrfs_path *path; 794 struct btrfs_delayed_ref_root *delayed_refs = NULL; 795 struct btrfs_delayed_ref_head *head; 796 int info_level = 0; 797 int ret; | 348 if (err == -ENOMEM) 349 goto out; 350 if (err) 351 continue; 352 353 /* we put the first parent into the ref at hand */ 354 ULIST_ITER_INIT(&uiter); 355 node = ulist_next(parents, &uiter); --- 427 unchanged lines hidden (view full) --- 783 struct ulist *roots, const u64 *extent_item_pos) 784{ 785 struct btrfs_key key; 786 struct btrfs_path *path; 787 struct btrfs_delayed_ref_root *delayed_refs = NULL; 788 struct btrfs_delayed_ref_head *head; 789 int info_level = 0; 790 int ret; |
798 int search_commit_root = (trans == BTRFS_BACKREF_SEARCH_COMMIT_ROOT); | |
799 struct list_head prefs_delayed; 800 struct list_head prefs; 801 struct __prelim_ref *ref; 802 803 INIT_LIST_HEAD(&prefs); 804 INIT_LIST_HEAD(&prefs_delayed); 805 806 key.objectid = bytenr; 807 key.type = BTRFS_EXTENT_ITEM_KEY; 808 key.offset = (u64)-1; 809 810 path = btrfs_alloc_path(); 811 if (!path) 812 return -ENOMEM; | 791 struct list_head prefs_delayed; 792 struct list_head prefs; 793 struct __prelim_ref *ref; 794 795 INIT_LIST_HEAD(&prefs); 796 INIT_LIST_HEAD(&prefs_delayed); 797 798 key.objectid = bytenr; 799 key.type = BTRFS_EXTENT_ITEM_KEY; 800 key.offset = (u64)-1; 801 802 path = btrfs_alloc_path(); 803 if (!path) 804 return -ENOMEM; |
813 path->search_commit_root = !!search_commit_root; | 805 if (!trans) 806 path->search_commit_root = 1; |
814 815 /* 816 * grab both a lock on the path and a lock on the delayed ref head. 817 * We need both to get a consistent picture of how the refs look 818 * at a specified point in time 819 */ 820again: 821 head = NULL; 822 823 ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0); 824 if (ret < 0) 825 goto out; 826 BUG_ON(ret == 0); 827 | 807 808 /* 809 * grab both a lock on the path and a lock on the delayed ref head. 810 * We need both to get a consistent picture of how the refs look 811 * at a specified point in time 812 */ 813again: 814 head = NULL; 815 816 ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0); 817 if (ret < 0) 818 goto out; 819 BUG_ON(ret == 0); 820 |
828 if (trans != BTRFS_BACKREF_SEARCH_COMMIT_ROOT) { | 821 if (trans) { |
829 /* 830 * look if there are updates for this ref queued and lock the 831 * head 832 */ 833 delayed_refs = &trans->transaction->delayed_refs; 834 spin_lock(&delayed_refs->lock); 835 head = btrfs_find_delayed_ref_head(trans, bytenr); 836 if (head) { --- 48 unchanged lines hidden (view full) --- 885 list_splice_init(&prefs_delayed, &prefs); 886 887 ret = __add_missing_keys(fs_info, &prefs); 888 if (ret) 889 goto out; 890 891 __merge_refs(&prefs, 1); 892 | 822 /* 823 * look if there are updates for this ref queued and lock the 824 * head 825 */ 826 delayed_refs = &trans->transaction->delayed_refs; 827 spin_lock(&delayed_refs->lock); 828 head = btrfs_find_delayed_ref_head(trans, bytenr); 829 if (head) { --- 48 unchanged lines hidden (view full) --- 878 list_splice_init(&prefs_delayed, &prefs); 879 880 ret = __add_missing_keys(fs_info, &prefs); 881 if (ret) 882 goto out; 883 884 __merge_refs(&prefs, 1); 885 |
893 ret = __resolve_indirect_refs(fs_info, search_commit_root, time_seq, 894 &prefs, extent_item_pos); | 886 ret = __resolve_indirect_refs(fs_info, path, time_seq, &prefs, 887 extent_item_pos); |
895 if (ret) 896 goto out; 897 898 __merge_refs(&prefs, 2); 899 900 while (!list_empty(&prefs)) { 901 ref = list_first_entry(&prefs, struct __prelim_ref, list); 902 list_del(&ref->list); --- 551 unchanged lines hidden (view full) --- 1454 * when the iterator function returns a non-zero value, iteration stops. 1455 */ 1456int iterate_extent_inodes(struct btrfs_fs_info *fs_info, 1457 u64 extent_item_objectid, u64 extent_item_pos, 1458 int search_commit_root, 1459 iterate_extent_inodes_t *iterate, void *ctx) 1460{ 1461 int ret; | 888 if (ret) 889 goto out; 890 891 __merge_refs(&prefs, 2); 892 893 while (!list_empty(&prefs)) { 894 ref = list_first_entry(&prefs, struct __prelim_ref, list); 895 list_del(&ref->list); --- 551 unchanged lines hidden (view full) --- 1447 * when the iterator function returns a non-zero value, iteration stops. 1448 */ 1449int iterate_extent_inodes(struct btrfs_fs_info *fs_info, 1450 u64 extent_item_objectid, u64 extent_item_pos, 1451 int search_commit_root, 1452 iterate_extent_inodes_t *iterate, void *ctx) 1453{ 1454 int ret; |
1462 struct btrfs_trans_handle *trans; | 1455 struct btrfs_trans_handle *trans = NULL; |
1463 struct ulist *refs = NULL; 1464 struct ulist *roots = NULL; 1465 struct ulist_node *ref_node = NULL; 1466 struct ulist_node *root_node = NULL; 1467 struct seq_list tree_mod_seq_elem = {}; 1468 struct ulist_iterator ref_uiter; 1469 struct ulist_iterator root_uiter; 1470 1471 pr_debug("resolving all inodes for extent %llu\n", 1472 extent_item_objectid); 1473 | 1456 struct ulist *refs = NULL; 1457 struct ulist *roots = NULL; 1458 struct ulist_node *ref_node = NULL; 1459 struct ulist_node *root_node = NULL; 1460 struct seq_list tree_mod_seq_elem = {}; 1461 struct ulist_iterator ref_uiter; 1462 struct ulist_iterator root_uiter; 1463 1464 pr_debug("resolving all inodes for extent %llu\n", 1465 extent_item_objectid); 1466 |
1474 if (search_commit_root) { 1475 trans = BTRFS_BACKREF_SEARCH_COMMIT_ROOT; 1476 } else { | 1467 if (!search_commit_root) { |
1477 trans = btrfs_join_transaction(fs_info->extent_root); 1478 if (IS_ERR(trans)) 1479 return PTR_ERR(trans); 1480 btrfs_get_tree_mod_seq(fs_info, &tree_mod_seq_elem); 1481 } 1482 1483 ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid, 1484 tree_mod_seq_elem.seq, &refs, --- 323 unchanged lines hidden --- | 1468 trans = btrfs_join_transaction(fs_info->extent_root); 1469 if (IS_ERR(trans)) 1470 return PTR_ERR(trans); 1471 btrfs_get_tree_mod_seq(fs_info, &tree_mod_seq_elem); 1472 } 1473 1474 ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid, 1475 tree_mod_seq_elem.seq, &refs, --- 323 unchanged lines hidden --- |