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.c149
1 files changed, 75 insertions, 74 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 8f7d1237b7a0..a256f3b2a845 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -179,61 +179,74 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id,
179 179
180static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, 180static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
181 struct ulist *parents, int level, 181 struct ulist *parents, int level,
182 struct btrfs_key *key, u64 time_seq, 182 struct btrfs_key *key_for_search, u64 time_seq,
183 u64 wanted_disk_byte, 183 u64 wanted_disk_byte,
184 const u64 *extent_item_pos) 184 const u64 *extent_item_pos)
185{ 185{
186 int ret; 186 int ret = 0;
187 int slot = path->slots[level]; 187 int slot;
188 struct extent_buffer *eb = path->nodes[level]; 188 struct extent_buffer *eb;
189 struct btrfs_key key;
189 struct btrfs_file_extent_item *fi; 190 struct btrfs_file_extent_item *fi;
190 struct extent_inode_elem *eie = NULL; 191 struct extent_inode_elem *eie = NULL;
191 u64 disk_byte; 192 u64 disk_byte;
192 u64 wanted_objectid = key->objectid;
193 193
194add_parent: 194 if (level != 0) {
195 if (level == 0 && extent_item_pos) { 195 eb = path->nodes[level];
196 fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item); 196 ret = ulist_add(parents, eb->start, 0, GFP_NOFS);
197 ret = check_extent_in_eb(key, eb, fi, *extent_item_pos, &eie);
198 if (ret < 0) 197 if (ret < 0)
199 return ret; 198 return ret;
200 }
201 ret = ulist_add(parents, eb->start, (unsigned long)eie, GFP_NOFS);
202 if (ret < 0)
203 return ret;
204
205 if (level != 0)
206 return 0; 199 return 0;
200 }
207 201
208 /* 202 /*
209 * if the current leaf is full with EXTENT_DATA items, we must 203 * We normally enter this function with the path already pointing to
210 * check the next one if that holds a reference as well. 204 * the first item to check. But sometimes, we may enter it with
211 * ref->count cannot be used to skip this check. 205 * slot==nritems. In that case, go to the next leaf before we continue.
212 * repeat this until we don't find any additional EXTENT_DATA items.
213 */ 206 */
214 while (1) { 207 if (path->slots[0] >= btrfs_header_nritems(path->nodes[0]))
215 eie = NULL;
216 ret = btrfs_next_old_leaf(root, path, time_seq); 208 ret = btrfs_next_old_leaf(root, path, time_seq);
217 if (ret < 0)
218 return ret;
219 if (ret)
220 return 0;
221 209
210 while (!ret) {
222 eb = path->nodes[0]; 211 eb = path->nodes[0];
223 for (slot = 0; slot < btrfs_header_nritems(eb); ++slot) { 212 slot = path->slots[0];
224 btrfs_item_key_to_cpu(eb, key, slot); 213
225 if (key->objectid != wanted_objectid || 214 btrfs_item_key_to_cpu(eb, &key, slot);
226 key->type != BTRFS_EXTENT_DATA_KEY) 215
227 return 0; 216 if (key.objectid != key_for_search->objectid ||
228 fi = btrfs_item_ptr(eb, slot, 217 key.type != BTRFS_EXTENT_DATA_KEY)
229 struct btrfs_file_extent_item); 218 break;
230 disk_byte = btrfs_file_extent_disk_bytenr(eb, fi); 219
231 if (disk_byte == wanted_disk_byte) 220 fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
232 goto add_parent; 221 disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
222
223 if (disk_byte == wanted_disk_byte) {
224 eie = NULL;
225 if (extent_item_pos) {
226 ret = check_extent_in_eb(&key, eb, fi,
227 *extent_item_pos,
228 &eie);
229 if (ret < 0)
230 break;
231 }
232 if (!ret) {
233 ret = ulist_add(parents, eb->start,
234 (unsigned long)eie, GFP_NOFS);
235 if (ret < 0)
236 break;
237 if (!extent_item_pos) {
238 ret = btrfs_next_old_leaf(root, path,
239 time_seq);
240 continue;
241 }
242 }
233 } 243 }
244 ret = btrfs_next_old_item(root, path, time_seq);
234 } 245 }
235 246
236 return 0; 247 if (ret > 0)
248 ret = 0;
249 return ret;
237} 250}
238 251
239/* 252/*
@@ -250,7 +263,6 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
250 struct btrfs_path *path; 263 struct btrfs_path *path;
251 struct btrfs_root *root; 264 struct btrfs_root *root;
252 struct btrfs_key root_key; 265 struct btrfs_key root_key;
253 struct btrfs_key key = {0};
254 struct extent_buffer *eb; 266 struct extent_buffer *eb;
255 int ret = 0; 267 int ret = 0;
256 int root_level; 268 int root_level;
@@ -289,17 +301,19 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
289 goto out; 301 goto out;
290 302
291 eb = path->nodes[level]; 303 eb = path->nodes[level];
292 if (!eb) { 304 while (!eb) {
293 WARN_ON(1); 305 if (!level) {
294 ret = 1; 306 WARN_ON(1);
295 goto out; 307 ret = 1;
308 goto out;
309 }
310 level--;
311 eb = path->nodes[level];
296 } 312 }
297 313
298 if (level == 0) 314 ret = add_all_parents(root, path, parents, level, &ref->key_for_search,
299 btrfs_item_key_to_cpu(eb, &key, path->slots[0]); 315 time_seq, ref->wanted_disk_byte,
300 316 extent_item_pos);
301 ret = add_all_parents(root, path, parents, level, &key, time_seq,
302 ref->wanted_disk_byte, extent_item_pos);
303out: 317out:
304 btrfs_free_path(path); 318 btrfs_free_path(path);
305 return ret; 319 return ret;
@@ -759,9 +773,8 @@ static int __add_keyed_refs(struct btrfs_fs_info *fs_info,
759 */ 773 */
760static int find_parent_nodes(struct btrfs_trans_handle *trans, 774static int find_parent_nodes(struct btrfs_trans_handle *trans,
761 struct btrfs_fs_info *fs_info, u64 bytenr, 775 struct btrfs_fs_info *fs_info, u64 bytenr,
762 u64 delayed_ref_seq, u64 time_seq, 776 u64 time_seq, struct ulist *refs,
763 struct ulist *refs, struct ulist *roots, 777 struct ulist *roots, const u64 *extent_item_pos)
764 const u64 *extent_item_pos)
765{ 778{
766 struct btrfs_key key; 779 struct btrfs_key key;
767 struct btrfs_path *path; 780 struct btrfs_path *path;
@@ -823,8 +836,9 @@ again:
823 btrfs_put_delayed_ref(&head->node); 836 btrfs_put_delayed_ref(&head->node);
824 goto again; 837 goto again;
825 } 838 }
826 ret = __add_delayed_refs(head, delayed_ref_seq, 839 ret = __add_delayed_refs(head, time_seq,
827 &prefs_delayed); 840 &prefs_delayed);
841 mutex_unlock(&head->mutex);
828 if (ret) { 842 if (ret) {
829 spin_unlock(&delayed_refs->lock); 843 spin_unlock(&delayed_refs->lock);
830 goto out; 844 goto out;
@@ -918,8 +932,6 @@ again:
918 } 932 }
919 933
920out: 934out:
921 if (head)
922 mutex_unlock(&head->mutex);
923 btrfs_free_path(path); 935 btrfs_free_path(path);
924 while (!list_empty(&prefs)) { 936 while (!list_empty(&prefs)) {
925 ref = list_first_entry(&prefs, struct __prelim_ref, list); 937 ref = list_first_entry(&prefs, struct __prelim_ref, list);
@@ -968,8 +980,7 @@ static void free_leaf_list(struct ulist *blocks)
968 */ 980 */
969static int btrfs_find_all_leafs(struct btrfs_trans_handle *trans, 981static int btrfs_find_all_leafs(struct btrfs_trans_handle *trans,
970 struct btrfs_fs_info *fs_info, u64 bytenr, 982 struct btrfs_fs_info *fs_info, u64 bytenr,
971 u64 delayed_ref_seq, u64 time_seq, 983 u64 time_seq, struct ulist **leafs,
972 struct ulist **leafs,
973 const u64 *extent_item_pos) 984 const u64 *extent_item_pos)
974{ 985{
975 struct ulist *tmp; 986 struct ulist *tmp;
@@ -984,7 +995,7 @@ static int btrfs_find_all_leafs(struct btrfs_trans_handle *trans,
984 return -ENOMEM; 995 return -ENOMEM;
985 } 996 }
986 997
987 ret = find_parent_nodes(trans, fs_info, bytenr, delayed_ref_seq, 998 ret = find_parent_nodes(trans, fs_info, bytenr,
988 time_seq, *leafs, tmp, extent_item_pos); 999 time_seq, *leafs, tmp, extent_item_pos);
989 ulist_free(tmp); 1000 ulist_free(tmp);
990 1001
@@ -1011,8 +1022,7 @@ static int btrfs_find_all_leafs(struct btrfs_trans_handle *trans,
1011 */ 1022 */
1012int btrfs_find_all_roots(struct btrfs_trans_handle *trans, 1023int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
1013 struct btrfs_fs_info *fs_info, u64 bytenr, 1024 struct btrfs_fs_info *fs_info, u64 bytenr,
1014 u64 delayed_ref_seq, u64 time_seq, 1025 u64 time_seq, struct ulist **roots)
1015 struct ulist **roots)
1016{ 1026{
1017 struct ulist *tmp; 1027 struct ulist *tmp;
1018 struct ulist_node *node = NULL; 1028 struct ulist_node *node = NULL;
@@ -1030,7 +1040,7 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
1030 1040
1031 ULIST_ITER_INIT(&uiter); 1041 ULIST_ITER_INIT(&uiter);
1032 while (1) { 1042 while (1) {
1033 ret = find_parent_nodes(trans, fs_info, bytenr, delayed_ref_seq, 1043 ret = find_parent_nodes(trans, fs_info, bytenr,
1034 time_seq, tmp, *roots, NULL); 1044 time_seq, tmp, *roots, NULL);
1035 if (ret < 0 && ret != -ENOENT) { 1045 if (ret < 0 && ret != -ENOENT) {
1036 ulist_free(tmp); 1046 ulist_free(tmp);
@@ -1112,10 +1122,10 @@ static int inode_ref_info(u64 inum, u64 ioff, struct btrfs_root *fs_root,
1112 * required for the path to fit into the buffer. in that case, the returned 1122 * required for the path to fit into the buffer. in that case, the returned
1113 * value will be smaller than dest. callers must check this! 1123 * value will be smaller than dest. callers must check this!
1114 */ 1124 */
1115static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, 1125char *btrfs_iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
1116 struct btrfs_inode_ref *iref, 1126 struct btrfs_inode_ref *iref,
1117 struct extent_buffer *eb_in, u64 parent, 1127 struct extent_buffer *eb_in, u64 parent,
1118 char *dest, u32 size) 1128 char *dest, u32 size)
1119{ 1129{
1120 u32 len; 1130 u32 len;
1121 int slot; 1131 int slot;
@@ -1363,11 +1373,9 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
1363 struct ulist *roots = NULL; 1373 struct ulist *roots = NULL;
1364 struct ulist_node *ref_node = NULL; 1374 struct ulist_node *ref_node = NULL;
1365 struct ulist_node *root_node = NULL; 1375 struct ulist_node *root_node = NULL;
1366 struct seq_list seq_elem = {};
1367 struct seq_list tree_mod_seq_elem = {}; 1376 struct seq_list tree_mod_seq_elem = {};
1368 struct ulist_iterator ref_uiter; 1377 struct ulist_iterator ref_uiter;
1369 struct ulist_iterator root_uiter; 1378 struct ulist_iterator root_uiter;
1370 struct btrfs_delayed_ref_root *delayed_refs = NULL;
1371 1379
1372 pr_debug("resolving all inodes for extent %llu\n", 1380 pr_debug("resolving all inodes for extent %llu\n",
1373 extent_item_objectid); 1381 extent_item_objectid);
@@ -1378,16 +1386,11 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
1378 trans = btrfs_join_transaction(fs_info->extent_root); 1386 trans = btrfs_join_transaction(fs_info->extent_root);
1379 if (IS_ERR(trans)) 1387 if (IS_ERR(trans))
1380 return PTR_ERR(trans); 1388 return PTR_ERR(trans);
1381
1382 delayed_refs = &trans->transaction->delayed_refs;
1383 spin_lock(&delayed_refs->lock);
1384 btrfs_get_delayed_seq(delayed_refs, &seq_elem);
1385 spin_unlock(&delayed_refs->lock);
1386 btrfs_get_tree_mod_seq(fs_info, &tree_mod_seq_elem); 1389 btrfs_get_tree_mod_seq(fs_info, &tree_mod_seq_elem);
1387 } 1390 }
1388 1391
1389 ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid, 1392 ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid,
1390 seq_elem.seq, tree_mod_seq_elem.seq, &refs, 1393 tree_mod_seq_elem.seq, &refs,
1391 &extent_item_pos); 1394 &extent_item_pos);
1392 if (ret) 1395 if (ret)
1393 goto out; 1396 goto out;
@@ -1395,8 +1398,7 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
1395 ULIST_ITER_INIT(&ref_uiter); 1398 ULIST_ITER_INIT(&ref_uiter);
1396 while (!ret && (ref_node = ulist_next(refs, &ref_uiter))) { 1399 while (!ret && (ref_node = ulist_next(refs, &ref_uiter))) {
1397 ret = btrfs_find_all_roots(trans, fs_info, ref_node->val, 1400 ret = btrfs_find_all_roots(trans, fs_info, ref_node->val,
1398 seq_elem.seq, 1401 tree_mod_seq_elem.seq, &roots);
1399 tree_mod_seq_elem.seq, &roots);
1400 if (ret) 1402 if (ret)
1401 break; 1403 break;
1402 ULIST_ITER_INIT(&root_uiter); 1404 ULIST_ITER_INIT(&root_uiter);
@@ -1418,7 +1420,6 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
1418out: 1420out:
1419 if (!search_commit_root) { 1421 if (!search_commit_root) {
1420 btrfs_put_tree_mod_seq(fs_info, &tree_mod_seq_elem); 1422 btrfs_put_tree_mod_seq(fs_info, &tree_mod_seq_elem);
1421 btrfs_put_delayed_seq(delayed_refs, &seq_elem);
1422 btrfs_end_transaction(trans, fs_info->extent_root); 1423 btrfs_end_transaction(trans, fs_info->extent_root);
1423 } 1424 }
1424 1425
@@ -1530,7 +1531,7 @@ static int inode_to_path(u64 inum, struct btrfs_inode_ref *iref,
1530 ipath->fspath->bytes_left - s_ptr : 0; 1531 ipath->fspath->bytes_left - s_ptr : 0;
1531 1532
1532 fspath_min = (char *)ipath->fspath->val + (i + 1) * s_ptr; 1533 fspath_min = (char *)ipath->fspath->val + (i + 1) * s_ptr;
1533 fspath = iref_to_path(ipath->fs_root, ipath->btrfs_path, iref, eb, 1534 fspath = btrfs_iref_to_path(ipath->fs_root, ipath->btrfs_path, iref, eb,
1534 inum, fspath_min, bytes_left); 1535 inum, fspath_min, bytes_left);
1535 if (IS_ERR(fspath)) 1536 if (IS_ERR(fspath))
1536 return PTR_ERR(fspath); 1537 return PTR_ERR(fspath);