backref.c (b7f8f259896f669f131713b0c74ba4d008daa71d) backref.c (f3a84ccd28d0b04da0358cf1289706f3469ff9ad)
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>
9#include "ctree.h"
10#include "disk-io.h"
11#include "backref.h"
12#include "ulist.h"
13#include "transaction.h"
14#include "delayed-ref.h"
15#include "locking.h"
16#include "misc.h"
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>
9#include "ctree.h"
10#include "disk-io.h"
11#include "backref.h"
12#include "ulist.h"
13#include "transaction.h"
14#include "delayed-ref.h"
15#include "locking.h"
16#include "misc.h"
17#include "tree-mod-log.h"
17
18/* Just an arbitrary number so we can be sure this happened */
19#define BACKREF_FOUND_SHARED 6
20
21struct extent_inode_elem {
22 u64 inum;
23 u64 offset;
24 struct extent_inode_elem *next;

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

447 * 3. The leaf owner is not equal to the root we are searching
448 *
449 * For these cases, go to the next leaf before we continue.
450 */
451 eb = path->nodes[0];
452 if (path->slots[0] >= btrfs_header_nritems(eb) ||
453 is_shared_data_backref(preftrees, eb->start) ||
454 ref->root_id != btrfs_header_owner(eb)) {
18
19/* Just an arbitrary number so we can be sure this happened */
20#define BACKREF_FOUND_SHARED 6
21
22struct extent_inode_elem {
23 u64 inum;
24 u64 offset;
25 struct extent_inode_elem *next;

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

448 * 3. The leaf owner is not equal to the root we are searching
449 *
450 * For these cases, go to the next leaf before we continue.
451 */
452 eb = path->nodes[0];
453 if (path->slots[0] >= btrfs_header_nritems(eb) ||
454 is_shared_data_backref(preftrees, eb->start) ||
455 ref->root_id != btrfs_header_owner(eb)) {
455 if (time_seq == SEQ_LAST)
456 if (time_seq == BTRFS_SEQ_LAST)
456 ret = btrfs_next_leaf(root, path);
457 else
458 ret = btrfs_next_old_leaf(root, path, time_seq);
459 }
460
461 while (!ret && count < ref->count) {
462 eb = path->nodes[0];
463 slot = path->slots[0];

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

471 /*
472 * We are searching for normal backref but bytenr of this leaf
473 * matches shared data backref, OR
474 * the leaf owner is not equal to the root we are searching for
475 */
476 if (slot == 0 &&
477 (is_shared_data_backref(preftrees, eb->start) ||
478 ref->root_id != btrfs_header_owner(eb))) {
457 ret = btrfs_next_leaf(root, path);
458 else
459 ret = btrfs_next_old_leaf(root, path, time_seq);
460 }
461
462 while (!ret && count < ref->count) {
463 eb = path->nodes[0];
464 slot = path->slots[0];

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

472 /*
473 * We are searching for normal backref but bytenr of this leaf
474 * matches shared data backref, OR
475 * the leaf owner is not equal to the root we are searching for
476 */
477 if (slot == 0 &&
478 (is_shared_data_backref(preftrees, eb->start) ||
479 ref->root_id != btrfs_header_owner(eb))) {
479 if (time_seq == SEQ_LAST)
480 if (time_seq == BTRFS_SEQ_LAST)
480 ret = btrfs_next_leaf(root, path);
481 else
482 ret = btrfs_next_old_leaf(root, path, time_seq);
483 continue;
484 }
485 fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
486 disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
487 data_offset = btrfs_file_extent_offset(eb, fi);

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

509 if (!ret && extent_item_pos) {
510 while (old->next)
511 old = old->next;
512 old->next = eie;
513 }
514 eie = NULL;
515 }
516next:
481 ret = btrfs_next_leaf(root, path);
482 else
483 ret = btrfs_next_old_leaf(root, path, time_seq);
484 continue;
485 }
486 fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
487 disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
488 data_offset = btrfs_file_extent_offset(eb, fi);

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

510 if (!ret && extent_item_pos) {
511 while (old->next)
512 old = old->next;
513 old->next = eie;
514 }
515 eie = NULL;
516 }
517next:
517 if (time_seq == SEQ_LAST)
518 if (time_seq == BTRFS_SEQ_LAST)
518 ret = btrfs_next_item(root, path);
519 else
520 ret = btrfs_next_old_item(root, path, time_seq);
521 }
522
523 if (ret > 0)
524 ret = 0;
525 else if (ret < 0)

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

569
570 if (btrfs_is_testing(fs_info)) {
571 ret = -ENOENT;
572 goto out;
573 }
574
575 if (path->search_commit_root)
576 root_level = btrfs_header_level(root->commit_root);
519 ret = btrfs_next_item(root, path);
520 else
521 ret = btrfs_next_old_item(root, path, time_seq);
522 }
523
524 if (ret > 0)
525 ret = 0;
526 else if (ret < 0)

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

570
571 if (btrfs_is_testing(fs_info)) {
572 ret = -ENOENT;
573 goto out;
574 }
575
576 if (path->search_commit_root)
577 root_level = btrfs_header_level(root->commit_root);
577 else if (time_seq == SEQ_LAST)
578 else if (time_seq == BTRFS_SEQ_LAST)
578 root_level = btrfs_header_level(root->node);
579 else
580 root_level = btrfs_old_root_level(root, time_seq);
581
582 if (root_level + 1 == level)
583 goto out;
584
585 /*

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

600 * existed, but it does and a fix for the clone ioctl would touch a lot
601 * of places, cause backwards incompatibility and would not fix the
602 * problem for extents cloned with older kernels.
603 */
604 if (search_key.type == BTRFS_EXTENT_DATA_KEY &&
605 search_key.offset >= LLONG_MAX)
606 search_key.offset = 0;
607 path->lowest_level = level;
579 root_level = btrfs_header_level(root->node);
580 else
581 root_level = btrfs_old_root_level(root, time_seq);
582
583 if (root_level + 1 == level)
584 goto out;
585
586 /*

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

601 * existed, but it does and a fix for the clone ioctl would touch a lot
602 * of places, cause backwards incompatibility and would not fix the
603 * problem for extents cloned with older kernels.
604 */
605 if (search_key.type == BTRFS_EXTENT_DATA_KEY &&
606 search_key.offset >= LLONG_MAX)
607 search_key.offset = 0;
608 path->lowest_level = level;
608 if (time_seq == SEQ_LAST)
609 if (time_seq == BTRFS_SEQ_LAST)
609 ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
610 else
611 ret = btrfs_search_old_slot(root, &search_key, path, time_seq);
612
613 btrfs_debug(fs_info,
614 "search slot in root %llu (level %d, ref count %d) returned %d for key (%llu %u %llu)",
615 ref->root_id, level, ref->count, ret,
616 ref->key_for_search.objectid, ref->key_for_search.type,

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

1142}
1143
1144/*
1145 * this adds all existing backrefs (inline backrefs, backrefs and delayed
1146 * refs) for the given bytenr to the refs list, merges duplicates and resolves
1147 * indirect refs to their parent bytenr.
1148 * When roots are found, they're added to the roots list
1149 *
610 ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
611 else
612 ret = btrfs_search_old_slot(root, &search_key, path, time_seq);
613
614 btrfs_debug(fs_info,
615 "search slot in root %llu (level %d, ref count %d) returned %d for key (%llu %u %llu)",
616 ref->root_id, level, ref->count, ret,
617 ref->key_for_search.objectid, ref->key_for_search.type,

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

1143}
1144
1145/*
1146 * this adds all existing backrefs (inline backrefs, backrefs and delayed
1147 * refs) for the given bytenr to the refs list, merges duplicates and resolves
1148 * indirect refs to their parent bytenr.
1149 * When roots are found, they're added to the roots list
1150 *
1150 * If time_seq is set to SEQ_LAST, it will not search delayed_refs, and behave
1151 * much like trans == NULL case, the difference only lies in it will not
1151 * If time_seq is set to BTRFS_SEQ_LAST, it will not search delayed_refs, and
1152 * behave much like trans == NULL case, the difference only lies in it will not
1152 * commit root.
1153 * The special case is for qgroup to search roots in commit_transaction().
1154 *
1155 * @sc - if !NULL, then immediately return BACKREF_FOUND_SHARED when a
1156 * shared extent is detected.
1157 *
1158 * Otherwise this returns 0 for success and <0 for an error.
1159 *

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

1194 path = btrfs_alloc_path();
1195 if (!path)
1196 return -ENOMEM;
1197 if (!trans) {
1198 path->search_commit_root = 1;
1199 path->skip_locking = 1;
1200 }
1201
1153 * commit root.
1154 * The special case is for qgroup to search roots in commit_transaction().
1155 *
1156 * @sc - if !NULL, then immediately return BACKREF_FOUND_SHARED when a
1157 * shared extent is detected.
1158 *
1159 * Otherwise this returns 0 for success and <0 for an error.
1160 *

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

1195 path = btrfs_alloc_path();
1196 if (!path)
1197 return -ENOMEM;
1198 if (!trans) {
1199 path->search_commit_root = 1;
1200 path->skip_locking = 1;
1201 }
1202
1202 if (time_seq == SEQ_LAST)
1203 if (time_seq == BTRFS_SEQ_LAST)
1203 path->skip_locking = 1;
1204
1205 /*
1206 * grab both a lock on the path and a lock on the delayed ref head.
1207 * We need both to get a consistent picture of how the refs look
1208 * at a specified point in time
1209 */
1210again:
1211 head = NULL;
1212
1213 ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0);
1214 if (ret < 0)
1215 goto out;
1216 BUG_ON(ret == 0);
1217
1218#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
1219 if (trans && likely(trans->type != __TRANS_DUMMY) &&
1204 path->skip_locking = 1;
1205
1206 /*
1207 * grab both a lock on the path and a lock on the delayed ref head.
1208 * We need both to get a consistent picture of how the refs look
1209 * at a specified point in time
1210 */
1211again:
1212 head = NULL;
1213
1214 ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0);
1215 if (ret < 0)
1216 goto out;
1217 BUG_ON(ret == 0);
1218
1219#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
1220 if (trans && likely(trans->type != __TRANS_DUMMY) &&
1220 time_seq != SEQ_LAST) {
1221 time_seq != BTRFS_SEQ_LAST) {
1221#else
1222#else
1222 if (trans && time_seq != SEQ_LAST) {
1223 if (trans && time_seq != BTRFS_SEQ_LAST) {
1223#endif
1224 /*
1225 * look if there are updates for this ref queued and lock the
1226 * head
1227 */
1228 delayed_refs = &trans->transaction->delayed_refs;
1229 spin_lock(&delayed_refs->lock);
1230 head = btrfs_find_delayed_ref_head(delayed_refs, bytenr);

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

1522 */
1523int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr,
1524 struct ulist *roots, struct ulist *tmp)
1525{
1526 struct btrfs_fs_info *fs_info = root->fs_info;
1527 struct btrfs_trans_handle *trans;
1528 struct ulist_iterator uiter;
1529 struct ulist_node *node;
1224#endif
1225 /*
1226 * look if there are updates for this ref queued and lock the
1227 * head
1228 */
1229 delayed_refs = &trans->transaction->delayed_refs;
1230 spin_lock(&delayed_refs->lock);
1231 head = btrfs_find_delayed_ref_head(delayed_refs, bytenr);

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

1523 */
1524int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr,
1525 struct ulist *roots, struct ulist *tmp)
1526{
1527 struct btrfs_fs_info *fs_info = root->fs_info;
1528 struct btrfs_trans_handle *trans;
1529 struct ulist_iterator uiter;
1530 struct ulist_node *node;
1530 struct seq_list elem = SEQ_LIST_INIT(elem);
1531 struct btrfs_seq_list elem = BTRFS_SEQ_LIST_INIT(elem);
1531 int ret = 0;
1532 struct share_check shared = {
1533 .root_objectid = root->root_key.objectid,
1534 .inum = inum,
1535 .share_count = 0,
1536 };
1537
1538 ulist_init(roots);

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

1948 bool ignore_offset)
1949{
1950 int ret;
1951 struct btrfs_trans_handle *trans = NULL;
1952 struct ulist *refs = NULL;
1953 struct ulist *roots = NULL;
1954 struct ulist_node *ref_node = NULL;
1955 struct ulist_node *root_node = NULL;
1532 int ret = 0;
1533 struct share_check shared = {
1534 .root_objectid = root->root_key.objectid,
1535 .inum = inum,
1536 .share_count = 0,
1537 };
1538
1539 ulist_init(roots);

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

1949 bool ignore_offset)
1950{
1951 int ret;
1952 struct btrfs_trans_handle *trans = NULL;
1953 struct ulist *refs = NULL;
1954 struct ulist *roots = NULL;
1955 struct ulist_node *ref_node = NULL;
1956 struct ulist_node *root_node = NULL;
1956 struct seq_list tree_mod_seq_elem = SEQ_LIST_INIT(tree_mod_seq_elem);
1957 struct btrfs_seq_list seq_elem = BTRFS_SEQ_LIST_INIT(seq_elem);
1957 struct ulist_iterator ref_uiter;
1958 struct ulist_iterator root_uiter;
1959
1960 btrfs_debug(fs_info, "resolving all inodes for extent %llu",
1961 extent_item_objectid);
1962
1963 if (!search_commit_root) {
1964 trans = btrfs_attach_transaction(fs_info->extent_root);
1965 if (IS_ERR(trans)) {
1966 if (PTR_ERR(trans) != -ENOENT &&
1967 PTR_ERR(trans) != -EROFS)
1968 return PTR_ERR(trans);
1969 trans = NULL;
1970 }
1971 }
1972
1973 if (trans)
1958 struct ulist_iterator ref_uiter;
1959 struct ulist_iterator root_uiter;
1960
1961 btrfs_debug(fs_info, "resolving all inodes for extent %llu",
1962 extent_item_objectid);
1963
1964 if (!search_commit_root) {
1965 trans = btrfs_attach_transaction(fs_info->extent_root);
1966 if (IS_ERR(trans)) {
1967 if (PTR_ERR(trans) != -ENOENT &&
1968 PTR_ERR(trans) != -EROFS)
1969 return PTR_ERR(trans);
1970 trans = NULL;
1971 }
1972 }
1973
1974 if (trans)
1974 btrfs_get_tree_mod_seq(fs_info, &tree_mod_seq_elem);
1975 btrfs_get_tree_mod_seq(fs_info, &seq_elem);
1975 else
1976 down_read(&fs_info->commit_root_sem);
1977
1978 ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid,
1976 else
1977 down_read(&fs_info->commit_root_sem);
1978
1979 ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid,
1979 tree_mod_seq_elem.seq, &refs,
1980 seq_elem.seq, &refs,
1980 &extent_item_pos, ignore_offset);
1981 if (ret)
1982 goto out;
1983
1984 ULIST_ITER_INIT(&ref_uiter);
1985 while (!ret && (ref_node = ulist_next(refs, &ref_uiter))) {
1986 ret = btrfs_find_all_roots_safe(trans, fs_info, ref_node->val,
1981 &extent_item_pos, ignore_offset);
1982 if (ret)
1983 goto out;
1984
1985 ULIST_ITER_INIT(&ref_uiter);
1986 while (!ret && (ref_node = ulist_next(refs, &ref_uiter))) {
1987 ret = btrfs_find_all_roots_safe(trans, fs_info, ref_node->val,
1987 tree_mod_seq_elem.seq, &roots,
1988 seq_elem.seq, &roots,
1988 ignore_offset);
1989 if (ret)
1990 break;
1991 ULIST_ITER_INIT(&root_uiter);
1992 while (!ret && (root_node = ulist_next(roots, &root_uiter))) {
1993 btrfs_debug(fs_info,
1994 "root %llu references leaf %llu, data list %#llx",
1995 root_node->val, ref_node->val,

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

2002 iterate, ctx);
2003 }
2004 ulist_free(roots);
2005 }
2006
2007 free_leaf_list(refs);
2008out:
2009 if (trans) {
1989 ignore_offset);
1990 if (ret)
1991 break;
1992 ULIST_ITER_INIT(&root_uiter);
1993 while (!ret && (root_node = ulist_next(roots, &root_uiter))) {
1994 btrfs_debug(fs_info,
1995 "root %llu references leaf %llu, data list %#llx",
1996 root_node->val, ref_node->val,

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

2003 iterate, ctx);
2004 }
2005 ulist_free(roots);
2006 }
2007
2008 free_leaf_list(refs);
2009out:
2010 if (trans) {
2010 btrfs_put_tree_mod_seq(fs_info, &tree_mod_seq_elem);
2011 btrfs_put_tree_mod_seq(fs_info, &seq_elem);
2011 btrfs_end_transaction(trans);
2012 } else {
2013 up_read(&fs_info->commit_root_sem);
2014 }
2015
2016 return ret;
2017}
2018

--- 1107 unchanged lines hidden ---
2012 btrfs_end_transaction(trans);
2013 } else {
2014 up_read(&fs_info->commit_root_sem);
2015 }
2016
2017 return ret;
2018}
2019

--- 1107 unchanged lines hidden ---