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