aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/backref.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/backref.c')
-rw-r--r--fs/btrfs/backref.c195
1 files changed, 111 insertions, 84 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 3775947429b2..aded3ef3d3d4 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -66,6 +66,16 @@ static int check_extent_in_eb(struct btrfs_key *key, struct extent_buffer *eb,
66 return 0; 66 return 0;
67} 67}
68 68
69static void free_inode_elem_list(struct extent_inode_elem *eie)
70{
71 struct extent_inode_elem *eie_next;
72
73 for (; eie; eie = eie_next) {
74 eie_next = eie->next;
75 kfree(eie);
76 }
77}
78
69static int find_extent_in_eb(struct extent_buffer *eb, u64 wanted_disk_byte, 79static int find_extent_in_eb(struct extent_buffer *eb, u64 wanted_disk_byte,
70 u64 extent_item_pos, 80 u64 extent_item_pos,
71 struct extent_inode_elem **eie) 81 struct extent_inode_elem **eie)
@@ -209,18 +219,19 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id,
209} 219}
210 220
211static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, 221static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
212 struct ulist *parents, int level, 222 struct ulist *parents, struct __prelim_ref *ref,
213 struct btrfs_key *key_for_search, u64 time_seq, 223 int level, u64 time_seq, const u64 *extent_item_pos)
214 u64 wanted_disk_byte,
215 const u64 *extent_item_pos)
216{ 224{
217 int ret = 0; 225 int ret = 0;
218 int slot; 226 int slot;
219 struct extent_buffer *eb; 227 struct extent_buffer *eb;
220 struct btrfs_key key; 228 struct btrfs_key key;
229 struct btrfs_key *key_for_search = &ref->key_for_search;
221 struct btrfs_file_extent_item *fi; 230 struct btrfs_file_extent_item *fi;
222 struct extent_inode_elem *eie = NULL, *old = NULL; 231 struct extent_inode_elem *eie = NULL, *old = NULL;
223 u64 disk_byte; 232 u64 disk_byte;
233 u64 wanted_disk_byte = ref->wanted_disk_byte;
234 u64 count = 0;
224 235
225 if (level != 0) { 236 if (level != 0) {
226 eb = path->nodes[level]; 237 eb = path->nodes[level];
@@ -238,7 +249,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
238 if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) 249 if (path->slots[0] >= btrfs_header_nritems(path->nodes[0]))
239 ret = btrfs_next_old_leaf(root, path, time_seq); 250 ret = btrfs_next_old_leaf(root, path, time_seq);
240 251
241 while (!ret) { 252 while (!ret && count < ref->count) {
242 eb = path->nodes[0]; 253 eb = path->nodes[0];
243 slot = path->slots[0]; 254 slot = path->slots[0];
244 255
@@ -254,6 +265,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
254 if (disk_byte == wanted_disk_byte) { 265 if (disk_byte == wanted_disk_byte) {
255 eie = NULL; 266 eie = NULL;
256 old = NULL; 267 old = NULL;
268 count++;
257 if (extent_item_pos) { 269 if (extent_item_pos) {
258 ret = check_extent_in_eb(&key, eb, fi, 270 ret = check_extent_in_eb(&key, eb, fi,
259 *extent_item_pos, 271 *extent_item_pos,
@@ -273,6 +285,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
273 old = old->next; 285 old = old->next;
274 old->next = eie; 286 old->next = eie;
275 } 287 }
288 eie = NULL;
276 } 289 }
277next: 290next:
278 ret = btrfs_next_old_item(root, path, time_seq); 291 ret = btrfs_next_old_item(root, path, time_seq);
@@ -280,6 +293,8 @@ next:
280 293
281 if (ret > 0) 294 if (ret > 0)
282 ret = 0; 295 ret = 0;
296 else if (ret < 0)
297 free_inode_elem_list(eie);
283 return ret; 298 return ret;
284} 299}
285 300
@@ -299,23 +314,34 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
299 int ret = 0; 314 int ret = 0;
300 int root_level; 315 int root_level;
301 int level = ref->level; 316 int level = ref->level;
317 int index;
302 318
303 root_key.objectid = ref->root_id; 319 root_key.objectid = ref->root_id;
304 root_key.type = BTRFS_ROOT_ITEM_KEY; 320 root_key.type = BTRFS_ROOT_ITEM_KEY;
305 root_key.offset = (u64)-1; 321 root_key.offset = (u64)-1;
322
323 index = srcu_read_lock(&fs_info->subvol_srcu);
324
306 root = btrfs_read_fs_root_no_name(fs_info, &root_key); 325 root = btrfs_read_fs_root_no_name(fs_info, &root_key);
307 if (IS_ERR(root)) { 326 if (IS_ERR(root)) {
327 srcu_read_unlock(&fs_info->subvol_srcu, index);
308 ret = PTR_ERR(root); 328 ret = PTR_ERR(root);
309 goto out; 329 goto out;
310 } 330 }
311 331
312 root_level = btrfs_old_root_level(root, time_seq); 332 root_level = btrfs_old_root_level(root, time_seq);
313 333
314 if (root_level + 1 == level) 334 if (root_level + 1 == level) {
335 srcu_read_unlock(&fs_info->subvol_srcu, index);
315 goto out; 336 goto out;
337 }
316 338
317 path->lowest_level = level; 339 path->lowest_level = level;
318 ret = btrfs_search_old_slot(root, &ref->key_for_search, path, time_seq); 340 ret = btrfs_search_old_slot(root, &ref->key_for_search, path, time_seq);
341
342 /* root node has been locked, we can release @subvol_srcu safely here */
343 srcu_read_unlock(&fs_info->subvol_srcu, index);
344
319 pr_debug("search slot in root %llu (level %d, ref count %d) returned " 345 pr_debug("search slot in root %llu (level %d, ref count %d) returned "
320 "%d for key (%llu %u %llu)\n", 346 "%d for key (%llu %u %llu)\n",
321 ref->root_id, level, ref->count, ret, 347 ref->root_id, level, ref->count, ret,
@@ -334,9 +360,8 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
334 eb = path->nodes[level]; 360 eb = path->nodes[level];
335 } 361 }
336 362
337 ret = add_all_parents(root, path, parents, level, &ref->key_for_search, 363 ret = add_all_parents(root, path, parents, ref, level, time_seq,
338 time_seq, ref->wanted_disk_byte, 364 extent_item_pos);
339 extent_item_pos);
340out: 365out:
341 path->lowest_level = 0; 366 path->lowest_level = 0;
342 btrfs_release_path(path); 367 btrfs_release_path(path);
@@ -376,10 +401,16 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
376 continue; 401 continue;
377 err = __resolve_indirect_ref(fs_info, path, time_seq, ref, 402 err = __resolve_indirect_ref(fs_info, path, time_seq, ref,
378 parents, extent_item_pos); 403 parents, extent_item_pos);
379 if (err == -ENOMEM) 404 /*
380 goto out; 405 * we can only tolerate ENOENT,otherwise,we should catch error
381 if (err) 406 * and return directly.
407 */
408 if (err == -ENOENT) {
382 continue; 409 continue;
410 } else if (err) {
411 ret = err;
412 goto out;
413 }
383 414
384 /* we put the first parent into the ref at hand */ 415 /* we put the first parent into the ref at hand */
385 ULIST_ITER_INIT(&uiter); 416 ULIST_ITER_INIT(&uiter);
@@ -538,14 +569,13 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq,
538 if (extent_op && extent_op->update_key) 569 if (extent_op && extent_op->update_key)
539 btrfs_disk_key_to_cpu(&op_key, &extent_op->key); 570 btrfs_disk_key_to_cpu(&op_key, &extent_op->key);
540 571
541 while ((n = rb_prev(n))) { 572 spin_lock(&head->lock);
573 n = rb_first(&head->ref_root);
574 while (n) {
542 struct btrfs_delayed_ref_node *node; 575 struct btrfs_delayed_ref_node *node;
543 node = rb_entry(n, struct btrfs_delayed_ref_node, 576 node = rb_entry(n, struct btrfs_delayed_ref_node,
544 rb_node); 577 rb_node);
545 if (node->bytenr != head->node.bytenr) 578 n = rb_next(n);
546 break;
547 WARN_ON(node->is_head);
548
549 if (node->seq > seq) 579 if (node->seq > seq)
550 continue; 580 continue;
551 581
@@ -612,10 +642,10 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq,
612 WARN_ON(1); 642 WARN_ON(1);
613 } 643 }
614 if (ret) 644 if (ret)
615 return ret; 645 break;
616 } 646 }
617 647 spin_unlock(&head->lock);
618 return 0; 648 return ret;
619} 649}
620 650
621/* 651/*
@@ -828,6 +858,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
828 struct list_head prefs_delayed; 858 struct list_head prefs_delayed;
829 struct list_head prefs; 859 struct list_head prefs;
830 struct __prelim_ref *ref; 860 struct __prelim_ref *ref;
861 struct extent_inode_elem *eie = NULL;
831 862
832 INIT_LIST_HEAD(&prefs); 863 INIT_LIST_HEAD(&prefs);
833 INIT_LIST_HEAD(&prefs_delayed); 864 INIT_LIST_HEAD(&prefs_delayed);
@@ -882,15 +913,15 @@ again:
882 btrfs_put_delayed_ref(&head->node); 913 btrfs_put_delayed_ref(&head->node);
883 goto again; 914 goto again;
884 } 915 }
916 spin_unlock(&delayed_refs->lock);
885 ret = __add_delayed_refs(head, time_seq, 917 ret = __add_delayed_refs(head, time_seq,
886 &prefs_delayed); 918 &prefs_delayed);
887 mutex_unlock(&head->mutex); 919 mutex_unlock(&head->mutex);
888 if (ret) { 920 if (ret)
889 spin_unlock(&delayed_refs->lock);
890 goto out; 921 goto out;
891 } 922 } else {
923 spin_unlock(&delayed_refs->lock);
892 } 924 }
893 spin_unlock(&delayed_refs->lock);
894 } 925 }
895 926
896 if (path->slots[0]) { 927 if (path->slots[0]) {
@@ -941,7 +972,6 @@ again:
941 goto out; 972 goto out;
942 } 973 }
943 if (ref->count && ref->parent) { 974 if (ref->count && ref->parent) {
944 struct extent_inode_elem *eie = NULL;
945 if (extent_item_pos && !ref->inode_list) { 975 if (extent_item_pos && !ref->inode_list) {
946 u32 bsz; 976 u32 bsz;
947 struct extent_buffer *eb; 977 struct extent_buffer *eb;
@@ -976,6 +1006,7 @@ again:
976 eie = eie->next; 1006 eie = eie->next;
977 eie->next = ref->inode_list; 1007 eie->next = ref->inode_list;
978 } 1008 }
1009 eie = NULL;
979 } 1010 }
980 list_del(&ref->list); 1011 list_del(&ref->list);
981 kmem_cache_free(btrfs_prelim_ref_cache, ref); 1012 kmem_cache_free(btrfs_prelim_ref_cache, ref);
@@ -994,7 +1025,8 @@ out:
994 list_del(&ref->list); 1025 list_del(&ref->list);
995 kmem_cache_free(btrfs_prelim_ref_cache, ref); 1026 kmem_cache_free(btrfs_prelim_ref_cache, ref);
996 } 1027 }
997 1028 if (ret < 0)
1029 free_inode_elem_list(eie);
998 return ret; 1030 return ret;
999} 1031}
1000 1032
@@ -1002,7 +1034,6 @@ static void free_leaf_list(struct ulist *blocks)
1002{ 1034{
1003 struct ulist_node *node = NULL; 1035 struct ulist_node *node = NULL;
1004 struct extent_inode_elem *eie; 1036 struct extent_inode_elem *eie;
1005 struct extent_inode_elem *eie_next;
1006 struct ulist_iterator uiter; 1037 struct ulist_iterator uiter;
1007 1038
1008 ULIST_ITER_INIT(&uiter); 1039 ULIST_ITER_INIT(&uiter);
@@ -1010,10 +1041,7 @@ static void free_leaf_list(struct ulist *blocks)
1010 if (!node->aux) 1041 if (!node->aux)
1011 continue; 1042 continue;
1012 eie = (struct extent_inode_elem *)(uintptr_t)node->aux; 1043 eie = (struct extent_inode_elem *)(uintptr_t)node->aux;
1013 for (; eie; eie = eie_next) { 1044 free_inode_elem_list(eie);
1014 eie_next = eie->next;
1015 kfree(eie);
1016 }
1017 node->aux = 0; 1045 node->aux = 0;
1018 } 1046 }
1019 1047
@@ -1101,44 +1129,13 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
1101 if (!node) 1129 if (!node)
1102 break; 1130 break;
1103 bytenr = node->val; 1131 bytenr = node->val;
1132 cond_resched();
1104 } 1133 }
1105 1134
1106 ulist_free(tmp); 1135 ulist_free(tmp);
1107 return 0; 1136 return 0;
1108} 1137}
1109 1138
1110
1111static int __inode_info(u64 inum, u64 ioff, u8 key_type,
1112 struct btrfs_root *fs_root, struct btrfs_path *path,
1113 struct btrfs_key *found_key)
1114{
1115 int ret;
1116 struct btrfs_key key;
1117 struct extent_buffer *eb;
1118
1119 key.type = key_type;
1120 key.objectid = inum;
1121 key.offset = ioff;
1122
1123 ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0);
1124 if (ret < 0)
1125 return ret;
1126
1127 eb = path->nodes[0];
1128 if (ret && path->slots[0] >= btrfs_header_nritems(eb)) {
1129 ret = btrfs_next_leaf(fs_root, path);
1130 if (ret)
1131 return ret;
1132 eb = path->nodes[0];
1133 }
1134
1135 btrfs_item_key_to_cpu(eb, found_key, path->slots[0]);
1136 if (found_key->type != key.type || found_key->objectid != key.objectid)
1137 return 1;
1138
1139 return 0;
1140}
1141
1142/* 1139/*
1143 * this makes the path point to (inum INODE_ITEM ioff) 1140 * this makes the path point to (inum INODE_ITEM ioff)
1144 */ 1141 */
@@ -1146,16 +1143,16 @@ int inode_item_info(u64 inum, u64 ioff, struct btrfs_root *fs_root,
1146 struct btrfs_path *path) 1143 struct btrfs_path *path)
1147{ 1144{
1148 struct btrfs_key key; 1145 struct btrfs_key key;
1149 return __inode_info(inum, ioff, BTRFS_INODE_ITEM_KEY, fs_root, path, 1146 return btrfs_find_item(fs_root, path, inum, ioff,
1150 &key); 1147 BTRFS_INODE_ITEM_KEY, &key);
1151} 1148}
1152 1149
1153static int inode_ref_info(u64 inum, u64 ioff, struct btrfs_root *fs_root, 1150static int inode_ref_info(u64 inum, u64 ioff, struct btrfs_root *fs_root,
1154 struct btrfs_path *path, 1151 struct btrfs_path *path,
1155 struct btrfs_key *found_key) 1152 struct btrfs_key *found_key)
1156{ 1153{
1157 return __inode_info(inum, ioff, BTRFS_INODE_REF_KEY, fs_root, path, 1154 return btrfs_find_item(fs_root, path, inum, ioff,
1158 found_key); 1155 BTRFS_INODE_REF_KEY, found_key);
1159} 1156}
1160 1157
1161int btrfs_find_one_extref(struct btrfs_root *root, u64 inode_objectid, 1158int btrfs_find_one_extref(struct btrfs_root *root, u64 inode_objectid,
@@ -1335,20 +1332,45 @@ int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
1335 ret = btrfs_search_slot(NULL, fs_info->extent_root, &key, path, 0, 0); 1332 ret = btrfs_search_slot(NULL, fs_info->extent_root, &key, path, 0, 0);
1336 if (ret < 0) 1333 if (ret < 0)
1337 return ret; 1334 return ret;
1338 ret = btrfs_previous_item(fs_info->extent_root, path,
1339 0, BTRFS_EXTENT_ITEM_KEY);
1340 if (ret < 0)
1341 return ret;
1342 1335
1343 btrfs_item_key_to_cpu(path->nodes[0], found_key, path->slots[0]); 1336 while (1) {
1337 u32 nritems;
1338 if (path->slots[0] == 0) {
1339 btrfs_set_path_blocking(path);
1340 ret = btrfs_prev_leaf(fs_info->extent_root, path);
1341 if (ret != 0) {
1342 if (ret > 0) {
1343 pr_debug("logical %llu is not within "
1344 "any extent\n", logical);
1345 ret = -ENOENT;
1346 }
1347 return ret;
1348 }
1349 } else {
1350 path->slots[0]--;
1351 }
1352 nritems = btrfs_header_nritems(path->nodes[0]);
1353 if (nritems == 0) {
1354 pr_debug("logical %llu is not within any extent\n",
1355 logical);
1356 return -ENOENT;
1357 }
1358 if (path->slots[0] == nritems)
1359 path->slots[0]--;
1360
1361 btrfs_item_key_to_cpu(path->nodes[0], found_key,
1362 path->slots[0]);
1363 if (found_key->type == BTRFS_EXTENT_ITEM_KEY ||
1364 found_key->type == BTRFS_METADATA_ITEM_KEY)
1365 break;
1366 }
1367
1344 if (found_key->type == BTRFS_METADATA_ITEM_KEY) 1368 if (found_key->type == BTRFS_METADATA_ITEM_KEY)
1345 size = fs_info->extent_root->leafsize; 1369 size = fs_info->extent_root->leafsize;
1346 else if (found_key->type == BTRFS_EXTENT_ITEM_KEY) 1370 else if (found_key->type == BTRFS_EXTENT_ITEM_KEY)
1347 size = found_key->offset; 1371 size = found_key->offset;
1348 1372
1349 if ((found_key->type != BTRFS_EXTENT_ITEM_KEY && 1373 if (found_key->objectid > logical ||
1350 found_key->type != BTRFS_METADATA_ITEM_KEY) ||
1351 found_key->objectid > logical ||
1352 found_key->objectid + size <= logical) { 1374 found_key->objectid + size <= logical) {
1353 pr_debug("logical %llu is not within any extent\n", logical); 1375 pr_debug("logical %llu is not within any extent\n", logical);
1354 return -ENOENT; 1376 return -ENOENT;
@@ -1601,7 +1623,6 @@ static int iterate_inode_refs(u64 inum, struct btrfs_root *fs_root,
1601 struct btrfs_key found_key; 1623 struct btrfs_key found_key;
1602 1624
1603 while (!ret) { 1625 while (!ret) {
1604 path->leave_spinning = 1;
1605 ret = inode_ref_info(inum, parent ? parent+1 : 0, fs_root, path, 1626 ret = inode_ref_info(inum, parent ? parent+1 : 0, fs_root, path,
1606 &found_key); 1627 &found_key);
1607 if (ret < 0) 1628 if (ret < 0)
@@ -1614,9 +1635,12 @@ static int iterate_inode_refs(u64 inum, struct btrfs_root *fs_root,
1614 1635
1615 parent = found_key.offset; 1636 parent = found_key.offset;
1616 slot = path->slots[0]; 1637 slot = path->slots[0];
1617 eb = path->nodes[0]; 1638 eb = btrfs_clone_extent_buffer(path->nodes[0]);
1618 /* make sure we can use eb after releasing the path */ 1639 if (!eb) {
1619 atomic_inc(&eb->refs); 1640 ret = -ENOMEM;
1641 break;
1642 }
1643 extent_buffer_get(eb);
1620 btrfs_tree_read_lock(eb); 1644 btrfs_tree_read_lock(eb);
1621 btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); 1645 btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
1622 btrfs_release_path(path); 1646 btrfs_release_path(path);
@@ -1674,17 +1698,20 @@ static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root,
1674 ++found; 1698 ++found;
1675 1699
1676 slot = path->slots[0]; 1700 slot = path->slots[0];
1677 eb = path->nodes[0]; 1701 eb = btrfs_clone_extent_buffer(path->nodes[0]);
1678 /* make sure we can use eb after releasing the path */ 1702 if (!eb) {
1679 atomic_inc(&eb->refs); 1703 ret = -ENOMEM;
1704 break;
1705 }
1706 extent_buffer_get(eb);
1680 1707
1681 btrfs_tree_read_lock(eb); 1708 btrfs_tree_read_lock(eb);
1682 btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); 1709 btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
1683 btrfs_release_path(path); 1710 btrfs_release_path(path);
1684 1711
1685 leaf = path->nodes[0]; 1712 leaf = path->nodes[0];
1686 item_size = btrfs_item_size_nr(leaf, path->slots[0]); 1713 item_size = btrfs_item_size_nr(leaf, slot);
1687 ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); 1714 ptr = btrfs_item_ptr_offset(leaf, slot);
1688 cur_offset = 0; 1715 cur_offset = 0;
1689 1716
1690 while (cur_offset < item_size) { 1717 while (cur_offset < item_size) {