backref.c (088eef2219bd1e8cb82bfcb5b32c1c687aeea6d7) backref.c (8ca15e05e6ac2745725d2d62394cfbe4ac335e84)
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,

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

31 struct extent_inode_elem *next;
32};
33
34static int check_extent_in_eb(struct btrfs_key *key, struct extent_buffer *eb,
35 struct btrfs_file_extent_item *fi,
36 u64 extent_item_pos,
37 struct extent_inode_elem **eie)
38{
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,

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

31 struct extent_inode_elem *next;
32};
33
34static int check_extent_in_eb(struct btrfs_key *key, struct extent_buffer *eb,
35 struct btrfs_file_extent_item *fi,
36 u64 extent_item_pos,
37 struct extent_inode_elem **eie)
38{
39 u64 data_offset;
40 u64 data_len;
39 u64 offset = 0;
41 struct extent_inode_elem *e;
42
40 struct extent_inode_elem *e;
41
43 data_offset = btrfs_file_extent_offset(eb, fi);
44 data_len = btrfs_file_extent_num_bytes(eb, fi);
42 if (!btrfs_file_extent_compression(eb, fi) &&
43 !btrfs_file_extent_encryption(eb, fi) &&
44 !btrfs_file_extent_other_encoding(eb, fi)) {
45 u64 data_offset;
46 u64 data_len;
45
47
46 if (extent_item_pos < data_offset ||
47 extent_item_pos >= data_offset + data_len)
48 return 1;
48 data_offset = btrfs_file_extent_offset(eb, fi);
49 data_len = btrfs_file_extent_num_bytes(eb, fi);
49
50
51 if (extent_item_pos < data_offset ||
52 extent_item_pos >= data_offset + data_len)
53 return 1;
54 offset = extent_item_pos - data_offset;
55 }
56
50 e = kmalloc(sizeof(*e), GFP_NOFS);
51 if (!e)
52 return -ENOMEM;
53
54 e->next = *eie;
55 e->inum = key->objectid;
57 e = kmalloc(sizeof(*e), GFP_NOFS);
58 if (!e)
59 return -ENOMEM;
60
61 e->next = *eie;
62 e->inum = key->objectid;
56 e->offset = key->offset + (extent_item_pos - data_offset);
63 e->offset = key->offset + offset;
57 *eie = e;
58
59 return 0;
60}
61
62static int find_extent_in_eb(struct extent_buffer *eb, u64 wanted_disk_byte,
63 u64 extent_item_pos,
64 struct extent_inode_elem **eie)

--- 185 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,
64 *eie = e;
65
66 return 0;
67}
68
69static int find_extent_in_eb(struct extent_buffer *eb, u64 wanted_disk_byte,
70 u64 extent_item_pos,
71 struct extent_inode_elem **eie)

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

257 return ret;
258}
259
260/*
261 * resolve an indirect backref in the form (root_id, key, level)
262 * to a logical address
263 */
264static 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)
265 struct btrfs_path *path, u64 time_seq,
266 struct __prelim_ref *ref,
267 struct ulist *parents,
268 const u64 *extent_item_pos)
263{
269{
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
270 struct btrfs_root *root;
271 struct btrfs_key root_key;
272 struct extent_buffer *eb;
273 int ret = 0;
274 int root_level;
275 int level = ref->level;
276
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:
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:
317 btrfs_free_path(path);
317 path->lowest_level = 0;
318 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,
319 return ret;
320}
321
322/*
323 * resolve all indirect backrefs from the list
324 */
325static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
325 int search_commit_root, u64 time_seq,
326 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;
327 struct list_head *head,
328 const u64 *extent_item_pos)
329{
330 int err;
331 int ret = 0;
332 struct __prelim_ref *ref;
333 struct __prelim_ref *ref_safe;
334 struct __prelim_ref *new_ref;

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

345 * iterating over the newly inserted items.
346 * we're also allowed to re-assign ref during iteration.
347 */
348 list_for_each_entry_safe(ref, ref_safe, head, list) {
349 if (ref->parent) /* already direct */
350 continue;
351 if (ref->count == 0)
352 continue;
352 err = __resolve_indirect_ref(fs_info, search_commit_root,
353 time_seq, ref, parents,
354 extent_item_pos);
353 err = __resolve_indirect_ref(fs_info, path, time_seq, ref,
354 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);

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

599static int __add_inline_refs(struct btrfs_fs_info *fs_info,
600 struct btrfs_path *path, u64 bytenr,
601 int *info_level, struct list_head *prefs)
602{
603 int ret = 0;
604 int slot;
605 struct extent_buffer *leaf;
606 struct btrfs_key key;
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);

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

599static int __add_inline_refs(struct btrfs_fs_info *fs_info,
600 struct btrfs_path *path, u64 bytenr,
601 int *info_level, struct list_head *prefs)
602{
603 int ret = 0;
604 int slot;
605 struct extent_buffer *leaf;
606 struct btrfs_key key;
607 struct btrfs_key found_key;
607 unsigned long ptr;
608 unsigned long end;
609 struct btrfs_extent_item *ei;
610 u64 flags;
611 u64 item_size;
612
613 /*
614 * enumerate all inline refs
615 */
616 leaf = path->nodes[0];
617 slot = path->slots[0];
618
619 item_size = btrfs_item_size_nr(leaf, slot);
620 BUG_ON(item_size < sizeof(*ei));
621
622 ei = btrfs_item_ptr(leaf, slot, struct btrfs_extent_item);
623 flags = btrfs_extent_flags(leaf, ei);
608 unsigned long ptr;
609 unsigned long end;
610 struct btrfs_extent_item *ei;
611 u64 flags;
612 u64 item_size;
613
614 /*
615 * enumerate all inline refs
616 */
617 leaf = path->nodes[0];
618 slot = path->slots[0];
619
620 item_size = btrfs_item_size_nr(leaf, slot);
621 BUG_ON(item_size < sizeof(*ei));
622
623 ei = btrfs_item_ptr(leaf, slot, struct btrfs_extent_item);
624 flags = btrfs_extent_flags(leaf, ei);
625 btrfs_item_key_to_cpu(leaf, &found_key, slot);
624
625 ptr = (unsigned long)(ei + 1);
626 end = (unsigned long)ei + item_size;
627
626
627 ptr = (unsigned long)(ei + 1);
628 end = (unsigned long)ei + item_size;
629
628 if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
630 if (found_key.type == BTRFS_EXTENT_ITEM_KEY &&
631 flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
629 struct btrfs_tree_block_info *info;
630
631 info = (struct btrfs_tree_block_info *)ptr;
632 *info_level = btrfs_tree_block_level(leaf, info);
633 ptr += sizeof(struct btrfs_tree_block_info);
634 BUG_ON(ptr > end);
632 struct btrfs_tree_block_info *info;
633
634 info = (struct btrfs_tree_block_info *)ptr;
635 *info_level = btrfs_tree_block_level(leaf, info);
636 ptr += sizeof(struct btrfs_tree_block_info);
637 BUG_ON(ptr > end);
638 } else if (found_key.type == BTRFS_METADATA_ITEM_KEY) {
639 *info_level = found_key.offset;
635 } else {
636 BUG_ON(!(flags & BTRFS_EXTENT_FLAG_DATA));
637 }
638
639 while (ptr < end) {
640 struct btrfs_extent_inline_ref *iref;
641 u64 offset;
642 int type;

--- 147 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;
640 } else {
641 BUG_ON(!(flags & BTRFS_EXTENT_FLAG_DATA));
642 }
643
644 while (ptr < end) {
645 struct btrfs_extent_inline_ref *iref;
646 u64 offset;
647 int type;

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

795 struct ulist *roots, const u64 *extent_item_pos)
796{
797 struct btrfs_key key;
798 struct btrfs_path *path;
799 struct btrfs_delayed_ref_root *delayed_refs = NULL;
800 struct btrfs_delayed_ref_head *head;
801 int info_level = 0;
802 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;
803 struct list_head prefs_delayed;
804 struct list_head prefs;
805 struct __prelim_ref *ref;
806
807 INIT_LIST_HEAD(&prefs);
808 INIT_LIST_HEAD(&prefs_delayed);
809
810 key.objectid = bytenr;
807 key.type = BTRFS_EXTENT_ITEM_KEY;
808 key.offset = (u64)-1;
811 key.offset = (u64)-1;
812 if (btrfs_fs_incompat(fs_info, SKINNY_METADATA))
813 key.type = BTRFS_METADATA_ITEM_KEY;
814 else
815 key.type = BTRFS_EXTENT_ITEM_KEY;
809
810 path = btrfs_alloc_path();
811 if (!path)
812 return -ENOMEM;
816
817 path = btrfs_alloc_path();
818 if (!path)
819 return -ENOMEM;
813 path->search_commit_root = !!search_commit_root;
820 if (!trans)
821 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
822
823 /*
824 * grab both a lock on the path and a lock on the delayed ref head.
825 * We need both to get a consistent picture of how the refs look
826 * at a specified point in time
827 */
828again:
829 head = NULL;
830
831 ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0);
832 if (ret < 0)
833 goto out;
834 BUG_ON(ret == 0);
835
828 if (trans != BTRFS_BACKREF_SEARCH_COMMIT_ROOT) {
836 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) {

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

864 struct extent_buffer *leaf;
865 int slot;
866
867 path->slots[0]--;
868 leaf = path->nodes[0];
869 slot = path->slots[0];
870 btrfs_item_key_to_cpu(leaf, &key, slot);
871 if (key.objectid == bytenr &&
837 /*
838 * look if there are updates for this ref queued and lock the
839 * head
840 */
841 delayed_refs = &trans->transaction->delayed_refs;
842 spin_lock(&delayed_refs->lock);
843 head = btrfs_find_delayed_ref_head(trans, bytenr);
844 if (head) {

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

872 struct extent_buffer *leaf;
873 int slot;
874
875 path->slots[0]--;
876 leaf = path->nodes[0];
877 slot = path->slots[0];
878 btrfs_item_key_to_cpu(leaf, &key, slot);
879 if (key.objectid == bytenr &&
872 key.type == BTRFS_EXTENT_ITEM_KEY) {
880 (key.type == BTRFS_EXTENT_ITEM_KEY ||
881 key.type == BTRFS_METADATA_ITEM_KEY)) {
873 ret = __add_inline_refs(fs_info, path, bytenr,
874 &info_level, &prefs);
875 if (ret)
876 goto out;
877 ret = __add_keyed_refs(fs_info, path, bytenr,
878 info_level, &prefs);
879 if (ret)
880 goto out;

--- 4 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
882 ret = __add_inline_refs(fs_info, path, bytenr,
883 &info_level, &prefs);
884 if (ret)
885 goto out;
886 ret = __add_keyed_refs(fs_info, path, bytenr,
887 info_level, &prefs);
888 if (ret)
889 goto out;

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

894 list_splice_init(&prefs_delayed, &prefs);
895
896 ret = __add_missing_keys(fs_info, &prefs);
897 if (ret)
898 goto out;
899
900 __merge_refs(&prefs, 1);
901
893 ret = __resolve_indirect_refs(fs_info, search_commit_root, time_seq,
894 &prefs, extent_item_pos);
902 ret = __resolve_indirect_refs(fs_info, path, time_seq, &prefs,
903 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);

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

1278 * tree blocks and <0 on error.
1279 */
1280int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
1281 struct btrfs_path *path, struct btrfs_key *found_key,
1282 u64 *flags_ret)
1283{
1284 int ret;
1285 u64 flags;
904 if (ret)
905 goto out;
906
907 __merge_refs(&prefs, 2);
908
909 while (!list_empty(&prefs)) {
910 ref = list_first_entry(&prefs, struct __prelim_ref, list);
911 list_del(&ref->list);

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

1287 * tree blocks and <0 on error.
1288 */
1289int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
1290 struct btrfs_path *path, struct btrfs_key *found_key,
1291 u64 *flags_ret)
1292{
1293 int ret;
1294 u64 flags;
1295 u64 size = 0;
1286 u32 item_size;
1287 struct extent_buffer *eb;
1288 struct btrfs_extent_item *ei;
1289 struct btrfs_key key;
1290
1296 u32 item_size;
1297 struct extent_buffer *eb;
1298 struct btrfs_extent_item *ei;
1299 struct btrfs_key key;
1300
1291 key.type = BTRFS_EXTENT_ITEM_KEY;
1301 if (btrfs_fs_incompat(fs_info, SKINNY_METADATA))
1302 key.type = BTRFS_METADATA_ITEM_KEY;
1303 else
1304 key.type = BTRFS_EXTENT_ITEM_KEY;
1292 key.objectid = logical;
1293 key.offset = (u64)-1;
1294
1295 ret = btrfs_search_slot(NULL, fs_info->extent_root, &key, path, 0, 0);
1296 if (ret < 0)
1297 return ret;
1298 ret = btrfs_previous_item(fs_info->extent_root, path,
1299 0, BTRFS_EXTENT_ITEM_KEY);
1300 if (ret < 0)
1301 return ret;
1302
1303 btrfs_item_key_to_cpu(path->nodes[0], found_key, path->slots[0]);
1305 key.objectid = logical;
1306 key.offset = (u64)-1;
1307
1308 ret = btrfs_search_slot(NULL, fs_info->extent_root, &key, path, 0, 0);
1309 if (ret < 0)
1310 return ret;
1311 ret = btrfs_previous_item(fs_info->extent_root, path,
1312 0, BTRFS_EXTENT_ITEM_KEY);
1313 if (ret < 0)
1314 return ret;
1315
1316 btrfs_item_key_to_cpu(path->nodes[0], found_key, path->slots[0]);
1304 if (found_key->type != BTRFS_EXTENT_ITEM_KEY ||
1317 if (found_key->type == BTRFS_METADATA_ITEM_KEY)
1318 size = fs_info->extent_root->leafsize;
1319 else if (found_key->type == BTRFS_EXTENT_ITEM_KEY)
1320 size = found_key->offset;
1321
1322 if ((found_key->type != BTRFS_EXTENT_ITEM_KEY &&
1323 found_key->type != BTRFS_METADATA_ITEM_KEY) ||
1305 found_key->objectid > logical ||
1324 found_key->objectid > logical ||
1306 found_key->objectid + found_key->offset <= logical) {
1325 found_key->objectid + size <= logical) {
1307 pr_debug("logical %llu is not within any extent\n",
1308 (unsigned long long)logical);
1309 return -ENOENT;
1310 }
1311
1312 eb = path->nodes[0];
1313 item_size = btrfs_item_size_nr(eb, path->slots[0]);
1314 BUG_ON(item_size < sizeof(*ei));

--- 139 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;
1326 pr_debug("logical %llu is not within any extent\n",
1327 (unsigned long long)logical);
1328 return -ENOENT;
1329 }
1330
1331 eb = path->nodes[0];
1332 item_size = btrfs_item_size_nr(eb, path->slots[0]);
1333 BUG_ON(item_size < sizeof(*ei));

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

1473 * when the iterator function returns a non-zero value, iteration stops.
1474 */
1475int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
1476 u64 extent_item_objectid, u64 extent_item_pos,
1477 int search_commit_root,
1478 iterate_extent_inodes_t *iterate, void *ctx)
1479{
1480 int ret;
1462 struct btrfs_trans_handle *trans;
1481 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
1482 struct ulist *refs = NULL;
1483 struct ulist *roots = NULL;
1484 struct ulist_node *ref_node = NULL;
1485 struct ulist_node *root_node = NULL;
1486 struct seq_list tree_mod_seq_elem = {};
1487 struct ulist_iterator ref_uiter;
1488 struct ulist_iterator root_uiter;
1489
1490 pr_debug("resolving all inodes for extent %llu\n",
1491 extent_item_objectid);
1492
1474 if (search_commit_root) {
1475 trans = BTRFS_BACKREF_SEARCH_COMMIT_ROOT;
1476 } else {
1493 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 ---
1494 trans = btrfs_join_transaction(fs_info->extent_root);
1495 if (IS_ERR(trans))
1496 return PTR_ERR(trans);
1497 btrfs_get_tree_mod_seq(fs_info, &tree_mod_seq_elem);
1498 }
1499
1500 ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid,
1501 tree_mod_seq_elem.seq, &refs,

--- 323 unchanged lines hidden ---