Lines Matching +full:no +full:- +full:memory +full:- +full:wc

1 // SPDX-License-Identifier: GPL-2.0
13 #include "tree-log.h"
14 #include "disk-io.h"
19 #include "block-group.h"
20 #include "space-info.h"
21 #include "inode-item.h"
24 #include "extent-tree.h"
25 #include "root-tree.h"
26 #include "dir-item.h"
27 #include "file-item.h"
30 #include "print-tree.h"
31 #include "tree-checker.h"
52 * ---> record transid of last unlink/rename per directory
65 * log. ---> check inode while renaming/linking.
69 * ---> check inode and old parent dir during rename
75 * of zero and redo the rm -rf
79 * rm -rf f1/foo
83 * called on f1, only its parent dir. After a crash the rm -rf must
153 struct walk_control *wc, u64 gen, int level);
171 static void do_abort_log_replay(struct walk_control *wc, const char *function, in do_abort_log_replay() argument
174 struct btrfs_fs_info *fs_info = wc->trans->fs_info; in do_abort_log_replay()
183 * are outside of tree-log.c that can abort transactions (such as in do_abort_log_replay()
187 if (test_and_set_bit(BTRFS_FS_STATE_LOG_REPLAY_ABORTED, &fs_info->fs_state)) in do_abort_log_replay()
190 btrfs_abort_transaction(wc->trans, error); in do_abort_log_replay()
192 if (wc->subvol_path->nodes[0]) { in do_abort_log_replay()
195 btrfs_root_id(wc->root)); in do_abort_log_replay()
196 btrfs_print_leaf(wc->subvol_path->nodes[0]); in do_abort_log_replay()
199 if (wc->log_leaf) { in do_abort_log_replay()
202 btrfs_root_id(wc->root), wc->log_slot, in do_abort_log_replay()
203 wc->log_key.objectid, wc->log_key.type, wc->log_key.offset); in do_abort_log_replay()
204 btrfs_print_leaf(wc->log_leaf); in do_abort_log_replay()
213 function, line, btrfs_root_id(wc->root), wc->stage, error, &vaf); in do_abort_log_replay()
224 #define btrfs_abort_log_replay(wc, error, fmt, args...) \ argument
225 do_abort_log_replay((wc), __func__, __LINE__, (error), fmt, ##args)
231 static int link_to_fixup_dir(struct walk_control *wc, u64 objectid);
232 static noinline int replay_dir_deletes(struct walk_control *wc,
242 * extent tree an 4x-6x higher write load than ext3.
250 * After a crash, items are copied out of the log-tree back into the
252 * allocation tree, and the log-tree freed.
290 struct btrfs_fs_info *fs_info = root->fs_info; in start_log_trans()
291 struct btrfs_root *tree_root = fs_info->tree_root; in start_log_trans()
300 if (!test_bit(BTRFS_ROOT_HAS_LOG_TREE, &tree_root->state)) { in start_log_trans()
301 mutex_lock(&tree_root->log_mutex); in start_log_trans()
302 if (!fs_info->log_root_tree) { in start_log_trans()
305 set_bit(BTRFS_ROOT_HAS_LOG_TREE, &tree_root->state); in start_log_trans()
309 mutex_unlock(&tree_root->log_mutex); in start_log_trans()
314 mutex_lock(&root->log_mutex); in start_log_trans()
317 if (root->log_root) { in start_log_trans()
318 int index = (root->log_transid + 1) % 2; in start_log_trans()
325 if (zoned && atomic_read(&root->log_commit[index])) { in start_log_trans()
326 wait_log_commit(root, root->log_transid - 1); in start_log_trans()
330 if (!root->log_start_pid) { in start_log_trans()
331 clear_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state); in start_log_trans()
332 root->log_start_pid = current->pid; in start_log_trans()
333 } else if (root->log_start_pid != current->pid) { in start_log_trans()
334 set_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state); in start_log_trans()
338 * This means fs_info->log_root_tree was already created in start_log_trans()
352 set_bit(BTRFS_ROOT_HAS_LOG_TREE, &root->state); in start_log_trans()
353 clear_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state); in start_log_trans()
354 root->log_start_pid = current->pid; in start_log_trans()
357 atomic_inc(&root->log_writers); in start_log_trans()
358 if (!ctx->logging_new_name) { in start_log_trans()
359 int index = root->log_transid % 2; in start_log_trans()
360 list_add_tail(&ctx->list, &root->log_ctxs[index]); in start_log_trans()
361 ctx->log_transid = root->log_transid; in start_log_trans()
365 mutex_unlock(&root->log_mutex); in start_log_trans()
371 * to join, or returns -ENOENT if there were not transactions
376 const bool zoned = btrfs_is_zoned(root->fs_info); in join_running_log_trans()
377 int ret = -ENOENT; in join_running_log_trans()
379 if (!test_bit(BTRFS_ROOT_HAS_LOG_TREE, &root->state)) in join_running_log_trans()
382 mutex_lock(&root->log_mutex); in join_running_log_trans()
384 if (root->log_root) { in join_running_log_trans()
385 int index = (root->log_transid + 1) % 2; in join_running_log_trans()
388 if (zoned && atomic_read(&root->log_commit[index])) { in join_running_log_trans()
389 wait_log_commit(root, root->log_transid - 1); in join_running_log_trans()
392 atomic_inc(&root->log_writers); in join_running_log_trans()
394 mutex_unlock(&root->log_mutex); in join_running_log_trans()
405 atomic_inc(&root->log_writers); in btrfs_pin_log_trans()
414 if (atomic_dec_and_test(&root->log_writers)) { in btrfs_end_log_trans()
416 cond_wake_up_nomb(&root->log_writer_wait); in btrfs_end_log_trans()
424 struct walk_control *wc, u64 gen, int level) in process_one_buffer() argument
426 struct btrfs_root *log = wc->log; in process_one_buffer()
427 struct btrfs_trans_handle *trans = wc->trans; in process_one_buffer()
428 struct btrfs_fs_info *fs_info = log->fs_info; in process_one_buffer()
451 if (wc->pin) { in process_one_buffer()
483 static int overwrite_item(struct walk_control *wc) in overwrite_item() argument
485 struct btrfs_trans_handle *trans = wc->trans; in overwrite_item()
486 struct btrfs_root *root = wc->root; in overwrite_item()
495 const bool is_inode_item = (wc->log_key.type == BTRFS_INODE_ITEM_KEY); in overwrite_item()
506 item_size = btrfs_item_size(wc->log_leaf, wc->log_slot); in overwrite_item()
507 src_ptr = btrfs_item_ptr_offset(wc->log_leaf, wc->log_slot); in overwrite_item()
510 ret = btrfs_search_slot(NULL, root, &wc->log_key, wc->subvol_path, 0, 0); in overwrite_item()
512 btrfs_abort_log_replay(wc, ret, in overwrite_item()
514 wc->log_key.objectid, wc->log_key.type, in overwrite_item()
515 wc->log_key.offset, btrfs_root_id(root)); in overwrite_item()
519 dst_eb = wc->subvol_path->nodes[0]; in overwrite_item()
520 dst_slot = wc->subvol_path->slots[0]; in overwrite_item()
530 btrfs_release_path(wc->subvol_path); in overwrite_item()
535 btrfs_abort_log_replay(wc, -ENOMEM, in overwrite_item()
536 "failed to allocate memory for log leaf item"); in overwrite_item()
537 return -ENOMEM; in overwrite_item()
540 read_extent_buffer(wc->log_leaf, src_copy, src_ptr, item_size); in overwrite_item()
552 btrfs_release_path(wc->subvol_path); in overwrite_item()
568 item = btrfs_item_ptr(wc->log_leaf, wc->log_slot, in overwrite_item()
570 btrfs_set_inode_nbytes(wc->log_leaf, item, nbytes); in overwrite_item()
577 mode = btrfs_inode_mode(wc->log_leaf, item); in overwrite_item()
579 btrfs_set_inode_size(wc->log_leaf, item, 0); in overwrite_item()
589 item = btrfs_item_ptr(wc->log_leaf, wc->log_slot, struct btrfs_inode_item); in overwrite_item()
590 btrfs_set_inode_nbytes(wc->log_leaf, item, 0); in overwrite_item()
597 mode = btrfs_inode_mode(wc->log_leaf, item); in overwrite_item()
599 btrfs_set_inode_size(wc->log_leaf, item, 0); in overwrite_item()
602 btrfs_release_path(wc->subvol_path); in overwrite_item()
604 wc->subvol_path->skip_release_on_error = 1; in overwrite_item()
605 ret = btrfs_insert_empty_item(trans, root, wc->subvol_path, &wc->log_key, item_size); in overwrite_item()
606 wc->subvol_path->skip_release_on_error = 0; in overwrite_item()
608 dst_eb = wc->subvol_path->nodes[0]; in overwrite_item()
609 dst_slot = wc->subvol_path->slots[0]; in overwrite_item()
612 if (ret == -EEXIST || ret == -EOVERFLOW) { in overwrite_item()
616 btrfs_truncate_item(trans, wc->subvol_path, item_size, 1); in overwrite_item()
618 btrfs_extend_item(trans, wc->subvol_path, item_size - found_size); in overwrite_item()
620 btrfs_abort_log_replay(wc, ret, in overwrite_item()
622 wc->log_key.objectid, wc->log_key.type, in overwrite_item()
623 wc->log_key.offset); in overwrite_item()
637 if (is_inode_item && ret == -EEXIST) { in overwrite_item()
644 if (btrfs_inode_generation(wc->log_leaf, src_item) == 0) { in overwrite_item()
645 const u64 ino_size = btrfs_inode_size(wc->log_leaf, src_item); in overwrite_item()
654 if (S_ISREG(btrfs_inode_mode(wc->log_leaf, src_item)) && in overwrite_item()
661 if (S_ISDIR(btrfs_inode_mode(wc->log_leaf, src_item)) && in overwrite_item()
668 copy_extent_buffer(dst_eb, wc->log_leaf, dst_ptr, src_ptr, item_size); in overwrite_item()
683 btrfs_set_inode_generation(dst_eb, dst_item, trans->transid); in overwrite_item()
686 btrfs_release_path(wc->subvol_path); in overwrite_item()
697 return -ENOMEM; in read_alloc_one_name()
700 name->name = buf; in read_alloc_one_name()
701 name->len = len; in read_alloc_one_name()
717 static noinline int replay_one_extent(struct walk_control *wc) in replay_one_extent() argument
719 struct btrfs_trans_handle *trans = wc->trans; in replay_one_extent()
720 struct btrfs_root *root = wc->root; in replay_one_extent()
722 struct btrfs_fs_info *fs_info = root->fs_info; in replay_one_extent()
725 const u64 start = wc->log_key.offset; in replay_one_extent()
737 item = btrfs_item_ptr(wc->log_leaf, wc->log_slot, struct btrfs_file_extent_item); in replay_one_extent()
738 found_type = btrfs_file_extent_type(wc->log_leaf, item); in replay_one_extent()
742 extent_end = start + btrfs_file_extent_num_bytes(wc->log_leaf, item); in replay_one_extent()
744 if (btrfs_file_extent_disk_bytenr(wc->log_leaf, item) != 0) in replay_one_extent()
745 nbytes = btrfs_file_extent_num_bytes(wc->log_leaf, item); in replay_one_extent()
747 nbytes = btrfs_file_extent_ram_bytes(wc->log_leaf, item); in replay_one_extent()
748 extent_end = ALIGN(start + nbytes, fs_info->sectorsize); in replay_one_extent()
750 btrfs_abort_log_replay(wc, -EUCLEAN, in replay_one_extent()
753 wc->log_key.objectid, wc->log_key.offset); in replay_one_extent()
754 return -EUCLEAN; in replay_one_extent()
757 inode = btrfs_iget_logging(wc->log_key.objectid, root); in replay_one_extent()
760 btrfs_abort_log_replay(wc, ret, in replay_one_extent()
762 wc->log_key.objectid, btrfs_root_id(root)); in replay_one_extent()
771 ret = btrfs_lookup_file_extent(trans, root, wc->subvol_path, in replay_one_extent()
777 struct extent_buffer *leaf = wc->subvol_path->nodes[0]; in replay_one_extent()
781 ptr = btrfs_item_ptr_offset(leaf, wc->subvol_path->slots[0]); in replay_one_extent()
788 if (memcmp_extent_buffer(wc->log_leaf, &existing, (unsigned long)item, in replay_one_extent()
790 btrfs_release_path(wc->subvol_path); in replay_one_extent()
794 btrfs_release_path(wc->subvol_path); in replay_one_extent()
800 drop_args.path = wc->subvol_path; in replay_one_extent()
803 btrfs_abort_log_replay(wc, ret, in replay_one_extent()
805 wc->log_key.objectid, start, extent_end, in replay_one_extent()
812 ret = overwrite_item(wc); in replay_one_extent()
820 * We have checked that above and returned -EUCLEAN if not. in replay_one_extent()
824 if (btrfs_file_extent_disk_bytenr(wc->log_leaf, item) == 0 && in replay_one_extent()
828 ret = btrfs_insert_empty_item(trans, root, wc->subvol_path, in replay_one_extent()
829 &wc->log_key, sizeof(*item)); in replay_one_extent()
831 btrfs_abort_log_replay(wc, ret, in replay_one_extent()
833 wc->log_key.objectid, wc->log_key.type, in replay_one_extent()
834 wc->log_key.offset, btrfs_root_id(root)); in replay_one_extent()
837 dest_offset = btrfs_item_ptr_offset(wc->subvol_path->nodes[0], in replay_one_extent()
838 wc->subvol_path->slots[0]); in replay_one_extent()
839 copy_extent_buffer(wc->subvol_path->nodes[0], wc->log_leaf, dest_offset, in replay_one_extent()
848 if (btrfs_file_extent_disk_bytenr(wc->log_leaf, item) == 0) { in replay_one_extent()
849 btrfs_release_path(wc->subvol_path); in replay_one_extent()
853 ins.objectid = btrfs_file_extent_disk_bytenr(wc->log_leaf, item); in replay_one_extent()
855 ins.offset = btrfs_file_extent_disk_num_bytes(wc->log_leaf, item); in replay_one_extent()
856 offset = wc->log_key.offset - btrfs_file_extent_offset(wc->log_leaf, item); in replay_one_extent()
867 btrfs_abort_log_replay(wc, ret, in replay_one_extent()
870 wc->log_key.objectid, btrfs_root_id(root)); in replay_one_extent()
880 btrfs_abort_log_replay(wc, ret, in replay_one_extent()
883 wc->log_key.objectid, btrfs_root_id(root)); in replay_one_extent()
894 btrfs_init_data_ref(&ref, wc->log_key.objectid, offset, 0, false); in replay_one_extent()
897 btrfs_abort_log_replay(wc, ret, in replay_one_extent()
900 wc->log_key.objectid, in replay_one_extent()
907 wc->log_key.objectid, offset, &ins); in replay_one_extent()
909 btrfs_abort_log_replay(wc, ret, in replay_one_extent()
912 wc->log_key.objectid, btrfs_root_id(root)); in replay_one_extent()
917 btrfs_release_path(wc->subvol_path); in replay_one_extent()
919 if (btrfs_file_extent_compression(wc->log_leaf, item)) { in replay_one_extent()
923 csum_start = ins.objectid + btrfs_file_extent_offset(wc->log_leaf, item); in replay_one_extent()
924 csum_end = csum_start + btrfs_file_extent_num_bytes(wc->log_leaf, item); in replay_one_extent()
927 ret = btrfs_lookup_csums_list(root->log_root, csum_start, csum_end - 1, in replay_one_extent()
930 btrfs_abort_log_replay(wc, ret, in replay_one_extent()
932 csum_start, csum_end, wc->log_key.objectid, in replay_one_extent()
967 * Which covers the 20K sub-range starting at offset 20K of our extent. in replay_one_extent()
986 csum_root = btrfs_csum_root(fs_info, sums->logical); in replay_one_extent()
988 ret = btrfs_del_csums(trans, csum_root, sums->logical, in replay_one_extent()
989 sums->len); in replay_one_extent()
991 btrfs_abort_log_replay(wc, ret, in replay_one_extent()
993 sums->logical, in replay_one_extent()
994 sums->logical + sums->len, in replay_one_extent()
995 wc->log_key.objectid, in replay_one_extent()
1001 btrfs_abort_log_replay(wc, ret, in replay_one_extent()
1003 sums->logical, in replay_one_extent()
1004 sums->logical + sums->len, in replay_one_extent()
1005 wc->log_key.objectid, in replay_one_extent()
1008 list_del(&sums->list); in replay_one_extent()
1015 ret = btrfs_inode_set_file_extent_range(inode, start, extent_end - start); in replay_one_extent()
1017 btrfs_abort_log_replay(wc, ret, in replay_one_extent()
1019 start, extent_end, wc->log_key.objectid, in replay_one_extent()
1027 btrfs_abort_log_replay(wc, ret, in replay_one_extent()
1029 wc->log_key.objectid, btrfs_root_id(root)); in replay_one_extent()
1031 iput(&inode->vfs_inode); in replay_one_extent()
1035 static int unlink_inode_for_log_replay(struct walk_control *wc, in unlink_inode_for_log_replay() argument
1040 struct btrfs_trans_handle *trans = wc->trans; in unlink_inode_for_log_replay()
1045 btrfs_abort_log_replay(wc, ret, in unlink_inode_for_log_replay()
1047 btrfs_ino(inode), btrfs_ino(dir), name->len, in unlink_inode_for_log_replay()
1048 name->name, btrfs_root_id(inode->root)); in unlink_inode_for_log_replay()
1059 btrfs_abort_log_replay(wc, ret, in unlink_inode_for_log_replay()
1061 btrfs_ino(inode), btrfs_ino(dir), name->len, in unlink_inode_for_log_replay()
1062 name->name, btrfs_root_id(inode->root)); in unlink_inode_for_log_replay()
1075 static noinline int drop_one_dir_item(struct walk_control *wc, in drop_one_dir_item() argument
1079 struct btrfs_root *root = dir->root; in drop_one_dir_item()
1082 struct extent_buffer *leaf = wc->subvol_path->nodes[0]; in drop_one_dir_item()
1089 btrfs_abort_log_replay(wc, ret, in drop_one_dir_item()
1095 btrfs_release_path(wc->subvol_path); in drop_one_dir_item()
1100 btrfs_abort_log_replay(wc, ret, in drop_one_dir_item()
1108 ret = link_to_fixup_dir(wc, location.objectid); in drop_one_dir_item()
1112 ret = unlink_inode_for_log_replay(wc, dir, inode, &name); in drop_one_dir_item()
1116 iput(&inode->vfs_inode); in drop_one_dir_item()
1142 btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location); in inode_in_dir()
1155 btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location); in inode_in_dir()
1184 return -ENOMEM; in backref_in_log()
1192 if (key->type == BTRFS_INODE_EXTREF_KEY) in backref_in_log()
1193 ret = !!btrfs_find_name_in_ext_backref(path->nodes[0], in backref_in_log()
1194 path->slots[0], in backref_in_log()
1197 ret = !!btrfs_find_name_in_backref(path->nodes[0], in backref_in_log()
1198 path->slots[0], name); in backref_in_log()
1202 static int unlink_refs_not_in_log(struct walk_control *wc, in unlink_refs_not_in_log() argument
1207 struct extent_buffer *leaf = wc->subvol_path->nodes[0]; in unlink_refs_not_in_log()
1216 ptr = btrfs_item_ptr_offset(leaf, wc->subvol_path->slots[0]); in unlink_refs_not_in_log()
1217 ptr_end = ptr + btrfs_item_size(leaf, wc->subvol_path->slots[0]); in unlink_refs_not_in_log()
1228 btrfs_abort_log_replay(wc, ret, in unlink_refs_not_in_log()
1231 btrfs_root_id(inode->root)); in unlink_refs_not_in_log()
1235 ret = backref_in_log(wc->log, search_key, btrfs_ino(dir), &victim_name); in unlink_refs_not_in_log()
1238 btrfs_abort_log_replay(wc, ret, in unlink_refs_not_in_log()
1242 btrfs_root_id(inode->root)); in unlink_refs_not_in_log()
1251 inc_nlink(&inode->vfs_inode); in unlink_refs_not_in_log()
1252 btrfs_release_path(wc->subvol_path); in unlink_refs_not_in_log()
1254 ret = unlink_inode_for_log_replay(wc, dir, inode, &victim_name); in unlink_refs_not_in_log()
1258 return -EAGAIN; in unlink_refs_not_in_log()
1264 static int unlink_extrefs_not_in_log(struct walk_control *wc, in unlink_extrefs_not_in_log() argument
1269 struct extent_buffer *leaf = wc->subvol_path->nodes[0]; in unlink_extrefs_not_in_log()
1270 const unsigned long base = btrfs_item_ptr_offset(leaf, wc->subvol_path->slots[0]); in unlink_extrefs_not_in_log()
1271 const u32 item_size = btrfs_item_size(leaf, wc->subvol_path->slots[0]); in unlink_extrefs_not_in_log()
1275 struct btrfs_root *log_root = wc->log; in unlink_extrefs_not_in_log()
1286 ret = read_alloc_one_name(leaf, &extref->name, victim_name.len, in unlink_extrefs_not_in_log()
1289 btrfs_abort_log_replay(wc, ret, in unlink_extrefs_not_in_log()
1292 btrfs_root_id(inode->root)); in unlink_extrefs_not_in_log()
1296 search_key->objectid = btrfs_ino(inode); in unlink_extrefs_not_in_log()
1297 search_key->type = BTRFS_INODE_EXTREF_KEY; in unlink_extrefs_not_in_log()
1298 search_key->offset = btrfs_extref_hash(btrfs_ino(dir), in unlink_extrefs_not_in_log()
1304 btrfs_abort_log_replay(wc, ret, in unlink_extrefs_not_in_log()
1308 btrfs_root_id(inode->root)); in unlink_extrefs_not_in_log()
1318 inc_nlink(&inode->vfs_inode); in unlink_extrefs_not_in_log()
1319 btrfs_release_path(wc->subvol_path); in unlink_extrefs_not_in_log()
1321 ret = unlink_inode_for_log_replay(wc, dir, inode, &victim_name); in unlink_extrefs_not_in_log()
1325 return -EAGAIN; in unlink_extrefs_not_in_log()
1331 static inline int __add_inode_ref(struct walk_control *wc, in __add_inode_ref() argument
1337 struct btrfs_trans_handle *trans = wc->trans; in __add_inode_ref()
1338 struct btrfs_root *root = wc->root; in __add_inode_ref()
1348 ret = btrfs_search_slot(NULL, root, &search_key, wc->subvol_path, 0, 0); in __add_inode_ref()
1350 btrfs_abort_log_replay(wc, ret, in __add_inode_ref()
1363 ret = unlink_refs_not_in_log(wc, &search_key, dir, inode); in __add_inode_ref()
1364 if (ret == -EAGAIN) in __add_inode_ref()
1369 btrfs_release_path(wc->subvol_path); in __add_inode_ref()
1372 extref = btrfs_lookup_inode_extref(root, wc->subvol_path, name, in __add_inode_ref()
1377 ret = unlink_extrefs_not_in_log(wc, &search_key, dir, inode); in __add_inode_ref()
1378 if (ret == -EAGAIN) in __add_inode_ref()
1383 btrfs_release_path(wc->subvol_path); in __add_inode_ref()
1386 di = btrfs_lookup_dir_index_item(trans, root, wc->subvol_path, btrfs_ino(dir), in __add_inode_ref()
1390 btrfs_abort_log_replay(wc, ret, in __add_inode_ref()
1392 btrfs_ino(dir), ref_index, name->len, in __add_inode_ref()
1393 name->name, btrfs_root_id(root)); in __add_inode_ref()
1396 ret = drop_one_dir_item(wc, dir, di); in __add_inode_ref()
1400 btrfs_release_path(wc->subvol_path); in __add_inode_ref()
1403 di = btrfs_lookup_dir_item(trans, root, wc->subvol_path, btrfs_ino(dir), name, 0); in __add_inode_ref()
1406 btrfs_abort_log_replay(wc, ret, in __add_inode_ref()
1408 btrfs_ino(dir), name->len, name->name, in __add_inode_ref()
1412 ret = drop_one_dir_item(wc, dir, di); in __add_inode_ref()
1416 btrfs_release_path(wc->subvol_path); in __add_inode_ref()
1430 ret = read_alloc_one_name(eb, &extref->name, in extref_get_fields()
1469 static int unlink_old_inode_refs(struct walk_control *wc, struct btrfs_inode *inode) in unlink_old_inode_refs() argument
1471 struct btrfs_root *root = wc->root; in unlink_old_inode_refs()
1478 btrfs_release_path(wc->subvol_path); in unlink_old_inode_refs()
1479 ret = btrfs_search_slot(NULL, root, &wc->log_key, wc->subvol_path, 0, 0); in unlink_old_inode_refs()
1485 btrfs_abort_log_replay(wc, ret, in unlink_old_inode_refs()
1487 wc->log_key.objectid, wc->log_key.type, in unlink_old_inode_refs()
1488 wc->log_key.offset, btrfs_root_id(root)); in unlink_old_inode_refs()
1492 eb = wc->subvol_path->nodes[0]; in unlink_old_inode_refs()
1493 ref_ptr = btrfs_item_ptr_offset(eb, wc->subvol_path->slots[0]); in unlink_old_inode_refs()
1494 ref_end = ref_ptr + btrfs_item_size(eb, wc->subvol_path->slots[0]); in unlink_old_inode_refs()
1499 if (wc->log_key.type == BTRFS_INODE_EXTREF_KEY) { in unlink_old_inode_refs()
1503 btrfs_abort_log_replay(wc, ret, in unlink_old_inode_refs()
1510 parent_id = wc->log_key.offset; in unlink_old_inode_refs()
1513 btrfs_abort_log_replay(wc, ret, in unlink_old_inode_refs()
1521 if (wc->log_key.type == BTRFS_INODE_EXTREF_KEY) in unlink_old_inode_refs()
1522 ret = !!btrfs_find_name_in_ext_backref(wc->log_leaf, wc->log_slot, in unlink_old_inode_refs()
1525 ret = !!btrfs_find_name_in_backref(wc->log_leaf, wc->log_slot, in unlink_old_inode_refs()
1531 btrfs_release_path(wc->subvol_path); in unlink_old_inode_refs()
1536 btrfs_abort_log_replay(wc, ret, in unlink_old_inode_refs()
1541 ret = unlink_inode_for_log_replay(wc, dir, inode, &name); in unlink_old_inode_refs()
1543 iput(&dir->vfs_inode); in unlink_old_inode_refs()
1551 if (wc->log_key.type == BTRFS_INODE_EXTREF_KEY) in unlink_old_inode_refs()
1558 btrfs_release_path(wc->subvol_path); in unlink_old_inode_refs()
1566 static noinline int add_inode_ref(struct walk_control *wc) in add_inode_ref() argument
1568 struct btrfs_trans_handle *trans = wc->trans; in add_inode_ref()
1569 struct btrfs_root *root = wc->root; in add_inode_ref()
1576 const bool is_extref_item = (wc->log_key.type == BTRFS_INODE_EXTREF_KEY); in add_inode_ref()
1582 ref_ptr = btrfs_item_ptr_offset(wc->log_leaf, wc->log_slot); in add_inode_ref()
1583 ref_end = ref_ptr + btrfs_item_size(wc->log_leaf, wc->log_slot); in add_inode_ref()
1590 parent_objectid = btrfs_inode_extref_parent(wc->log_leaf, r); in add_inode_ref()
1593 parent_objectid = wc->log_key.offset; in add_inode_ref()
1595 inode_objectid = wc->log_key.objectid; in add_inode_ref()
1606 if (ret == -ENOENT) in add_inode_ref()
1609 btrfs_abort_log_replay(wc, ret, in add_inode_ref()
1619 btrfs_abort_log_replay(wc, ret, in add_inode_ref()
1628 ret = extref_get_fields(wc->log_leaf, ref_ptr, &name, in add_inode_ref()
1631 btrfs_abort_log_replay(wc, ret, in add_inode_ref()
1653 if (ret == -ENOENT) { in add_inode_ref()
1662 btrfs_abort_log_replay(wc, ret, in add_inode_ref()
1671 ret = ref_get_fields(wc->log_leaf, ref_ptr, &name, &ref_index); in add_inode_ref()
1673 btrfs_abort_log_replay(wc, ret, in add_inode_ref()
1682 ret = inode_in_dir(root, wc->subvol_path, btrfs_ino(dir), in add_inode_ref()
1685 btrfs_abort_log_replay(wc, ret, in add_inode_ref()
1699 ret = __add_inode_ref(wc, dir, inode, ref_index, &name); in add_inode_ref()
1709 btrfs_abort_log_replay(wc, ret, in add_inode_ref()
1720 btrfs_abort_log_replay(wc, ret, in add_inode_ref()
1734 iput(&dir->vfs_inode); in add_inode_ref()
1744 * dir index entries exist for a name but there is no inode reference in add_inode_ref()
1747 ret = unlink_old_inode_refs(wc, inode); in add_inode_ref()
1752 ret = overwrite_item(wc); in add_inode_ref()
1754 btrfs_release_path(wc->subvol_path); in add_inode_ref()
1757 iput(&dir->vfs_inode); in add_inode_ref()
1759 iput(&inode->vfs_inode); in add_inode_ref()
1777 ret = btrfs_find_one_extref(inode->root, inode_objectid, offset, in count_inode_extrefs()
1782 leaf = path->nodes[0]; in count_inode_extrefs()
1783 item_size = btrfs_item_size(leaf, path->slots[0]); in count_inode_extrefs()
1784 ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); in count_inode_extrefs()
1801 if (ret < 0 && ret != -ENOENT) in count_inode_extrefs()
1818 key.offset = (u64)-1; in count_inode_refs()
1821 ret = btrfs_search_slot(NULL, inode->root, &key, path, 0, 0); in count_inode_refs()
1825 if (path->slots[0] == 0) in count_inode_refs()
1827 path->slots[0]--; in count_inode_refs()
1830 btrfs_item_key_to_cpu(path->nodes[0], &key, in count_inode_refs()
1831 path->slots[0]); in count_inode_refs()
1835 ptr = btrfs_item_ptr_offset(path->nodes[0], path->slots[0]); in count_inode_refs()
1836 ptr_end = ptr + btrfs_item_size(path->nodes[0], in count_inode_refs()
1837 path->slots[0]); in count_inode_refs()
1842 name_len = btrfs_inode_ref_name_len(path->nodes[0], in count_inode_refs()
1850 if (path->slots[0] > 0) { in count_inode_refs()
1851 path->slots[0]--; in count_inode_refs()
1854 key.offset--; in count_inode_refs()
1872 static noinline int fixup_inode_link_count(struct walk_control *wc, in fixup_inode_link_count() argument
1875 struct btrfs_trans_handle *trans = wc->trans; in fixup_inode_link_count()
1876 struct btrfs_root *root = inode->root; in fixup_inode_link_count()
1881 ret = count_inode_refs(inode, wc->subvol_path); in fixup_inode_link_count()
1887 ret = count_inode_extrefs(inode, wc->subvol_path); in fixup_inode_link_count()
1895 if (nlink != inode->vfs_inode.i_nlink) { in fixup_inode_link_count()
1896 set_nlink(&inode->vfs_inode, nlink); in fixup_inode_link_count()
1901 if (S_ISDIR(inode->vfs_inode.i_mode)) in fixup_inode_link_count()
1902 inode->index_cnt = (u64)-1; in fixup_inode_link_count()
1904 if (inode->vfs_inode.i_nlink == 0) { in fixup_inode_link_count()
1905 if (S_ISDIR(inode->vfs_inode.i_mode)) { in fixup_inode_link_count()
1906 ret = replay_dir_deletes(wc, ino, true); in fixup_inode_link_count()
1911 if (ret == -EEXIST) in fixup_inode_link_count()
1916 btrfs_release_path(wc->subvol_path); in fixup_inode_link_count()
1920 static noinline int fixup_inode_link_counts(struct walk_control *wc) in fixup_inode_link_counts() argument
1927 key.offset = (u64)-1; in fixup_inode_link_counts()
1929 struct btrfs_trans_handle *trans = wc->trans; in fixup_inode_link_counts()
1930 struct btrfs_root *root = wc->root; in fixup_inode_link_counts()
1933 ret = btrfs_search_slot(trans, root, &key, wc->subvol_path, -1, 1); in fixup_inode_link_counts()
1939 if (wc->subvol_path->slots[0] == 0) in fixup_inode_link_counts()
1941 wc->subvol_path->slots[0]--; in fixup_inode_link_counts()
1944 btrfs_item_key_to_cpu(wc->subvol_path->nodes[0], &key, wc->subvol_path->slots[0]); in fixup_inode_link_counts()
1949 ret = btrfs_del_item(trans, root, wc->subvol_path); in fixup_inode_link_counts()
1953 btrfs_release_path(wc->subvol_path); in fixup_inode_link_counts()
1960 ret = fixup_inode_link_count(wc, inode); in fixup_inode_link_counts()
1961 iput(&inode->vfs_inode); in fixup_inode_link_counts()
1970 key.offset = (u64)-1; in fixup_inode_link_counts()
1972 btrfs_release_path(wc->subvol_path); in fixup_inode_link_counts()
1982 static noinline int link_to_fixup_dir(struct walk_control *wc, u64 objectid) in link_to_fixup_dir() argument
1984 struct btrfs_trans_handle *trans = wc->trans; in link_to_fixup_dir()
1985 struct btrfs_root *root = wc->root; in link_to_fixup_dir()
1994 btrfs_abort_log_replay(wc, ret, in link_to_fixup_dir()
2000 vfs_inode = &inode->vfs_inode; in link_to_fixup_dir()
2005 ret = btrfs_insert_empty_item(trans, root, wc->subvol_path, &key, 0); in link_to_fixup_dir()
2007 btrfs_release_path(wc->subvol_path); in link_to_fixup_dir()
2009 if (!vfs_inode->i_nlink) in link_to_fixup_dir()
2015 btrfs_abort_log_replay(wc, ret, in link_to_fixup_dir()
2018 } else if (ret == -EEXIST) { in link_to_fixup_dir()
2021 btrfs_abort_log_replay(wc, ret, in link_to_fixup_dir()
2045 inode = btrfs_iget_logging(location->objectid, root); in insert_one_name()
2051 iput(&inode->vfs_inode); in insert_one_name()
2059 iput(&inode->vfs_inode); in insert_one_name()
2060 iput(&dir->vfs_inode); in insert_one_name()
2064 static int delete_conflicting_dir_entry(struct walk_control *wc, in delete_conflicting_dir_entry() argument
2073 btrfs_dir_item_key_to_cpu(wc->subvol_path->nodes[0], dst_di, &found_key); in delete_conflicting_dir_entry()
2075 if (found_key.objectid == log_key->objectid && in delete_conflicting_dir_entry()
2076 found_key.type == log_key->type && in delete_conflicting_dir_entry()
2077 found_key.offset == log_key->offset && in delete_conflicting_dir_entry()
2078 btrfs_dir_flags(wc->subvol_path->nodes[0], dst_di) == log_flags) in delete_conflicting_dir_entry()
2088 return drop_one_dir_item(wc, dir, dst_di); in delete_conflicting_dir_entry()
2105 * non-existing inode) and 1 if the name was replayed.
2107 static noinline int replay_one_name(struct walk_control *wc, struct btrfs_dir_item *di) in replay_one_name() argument
2109 struct btrfs_trans_handle *trans = wc->trans; in replay_one_name()
2110 struct btrfs_root *root = wc->root; in replay_one_name()
2125 dir = btrfs_iget_logging(wc->log_key.objectid, root); in replay_one_name()
2128 btrfs_abort_log_replay(wc, ret, in replay_one_name()
2130 wc->log_key.objectid, btrfs_root_id(root)); in replay_one_name()
2134 ret = read_alloc_one_name(wc->log_leaf, di + 1, in replay_one_name()
2135 btrfs_dir_name_len(wc->log_leaf, di), &name); in replay_one_name()
2137 btrfs_abort_log_replay(wc, ret, in replay_one_name()
2143 log_flags = btrfs_dir_flags(wc->log_leaf, di); in replay_one_name()
2144 btrfs_dir_item_key_to_cpu(wc->log_leaf, di, &log_key); in replay_one_name()
2145 ret = btrfs_lookup_inode(trans, root, wc->subvol_path, &log_key, 0); in replay_one_name()
2146 btrfs_release_path(wc->subvol_path); in replay_one_name()
2148 btrfs_abort_log_replay(wc, ret, in replay_one_name()
2156 dir_dst_di = btrfs_lookup_dir_item(trans, root, wc->subvol_path, in replay_one_name()
2157 wc->log_key.objectid, &name, 1); in replay_one_name()
2160 btrfs_abort_log_replay(wc, ret, in replay_one_name()
2162 wc->log_key.objectid, name.len, name.name, in replay_one_name()
2166 ret = delete_conflicting_dir_entry(wc, dir, dir_dst_di, in replay_one_name()
2169 btrfs_abort_log_replay(wc, ret, in replay_one_name()
2178 btrfs_release_path(wc->subvol_path); in replay_one_name()
2180 index_dst_di = btrfs_lookup_dir_index_item(trans, root, wc->subvol_path, in replay_one_name()
2181 wc->log_key.objectid, in replay_one_name()
2182 wc->log_key.offset, &name, 1); in replay_one_name()
2185 btrfs_abort_log_replay(wc, ret, in replay_one_name()
2187 wc->log_key.objectid, name.len, name.name, in replay_one_name()
2191 ret = delete_conflicting_dir_entry(wc, dir, index_dst_di, in replay_one_name()
2194 btrfs_abort_log_replay(wc, ret, in replay_one_name()
2203 btrfs_release_path(wc->subvol_path); in replay_one_name()
2217 search_key.offset = wc->log_key.objectid; in replay_one_name()
2218 ret = backref_in_log(root->log_root, &search_key, 0, &name); in replay_one_name()
2220 btrfs_abort_log_replay(wc, ret, in replay_one_name()
2234 search_key.offset = btrfs_extref_hash(wc->log_key.objectid, name.name, name.len); in replay_one_name()
2235 ret = backref_in_log(root->log_root, &search_key, wc->log_key.objectid, &name); in replay_one_name()
2237 btrfs_abort_log_replay(wc, ret, in replay_one_name()
2248 ret = insert_one_name(trans, root, wc->log_key.objectid, wc->log_key.offset, in replay_one_name()
2250 if (ret && ret != -ENOENT && ret != -EEXIST) { in replay_one_name()
2251 btrfs_abort_log_replay(wc, ret, in replay_one_name()
2264 btrfs_i_size_write(dir, dir->vfs_inode.i_size + name.len * 2); in replay_one_name()
2267 btrfs_abort_log_replay(wc, ret, in replay_one_name()
2272 iput(&dir->vfs_inode); in replay_one_name()
2279 static noinline int replay_one_dir_item(struct walk_control *wc) in replay_one_dir_item() argument
2285 ASSERT(wc->log_key.type == BTRFS_DIR_INDEX_KEY); in replay_one_dir_item()
2287 di = btrfs_item_ptr(wc->log_leaf, wc->log_slot, struct btrfs_dir_item); in replay_one_dir_item()
2288 ret = replay_one_name(wc, di); in replay_one_dir_item()
2293 * If this entry refers to a non-directory (directories can not have a in replay_one_dir_item()
2307 * xfs_io -c "fsync" testdir/bar in replay_one_dir_item()
2318 if (ret == 1 && btrfs_dir_ftype(wc->log_leaf, di) != BTRFS_FT_DIR) { in replay_one_dir_item()
2321 btrfs_dir_item_key_to_cpu(wc->log_leaf, di, &di_key); in replay_one_dir_item()
2322 ret = link_to_fixup_dir(wc, di_key.objectid); in replay_one_dir_item()
2350 if (*start_ret == (u64)-1) in find_dir_range()
2361 if (path->slots[0] == 0) in find_dir_range()
2363 path->slots[0]--; in find_dir_range()
2366 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); in find_dir_range()
2372 item = btrfs_item_ptr(path->nodes[0], path->slots[0], in find_dir_range()
2374 found_end = btrfs_dir_log_end(path->nodes[0], item); in find_dir_range()
2385 nritems = btrfs_header_nritems(path->nodes[0]); in find_dir_range()
2386 path->slots[0]++; in find_dir_range()
2387 if (path->slots[0] >= nritems) { in find_dir_range()
2393 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); in find_dir_range()
2399 item = btrfs_item_ptr(path->nodes[0], path->slots[0], in find_dir_range()
2401 found_end = btrfs_dir_log_end(path->nodes[0], item); in find_dir_range()
2415 static noinline int check_item_in_log(struct walk_control *wc, in check_item_in_log() argument
2421 struct btrfs_trans_handle *trans = wc->trans; in check_item_in_log()
2422 struct btrfs_root *root = dir->root; in check_item_in_log()
2437 ASSERT(dir_key->type == BTRFS_DIR_INDEX_KEY); in check_item_in_log()
2439 eb = wc->subvol_path->nodes[0]; in check_item_in_log()
2440 slot = wc->subvol_path->slots[0]; in check_item_in_log()
2444 btrfs_abort_log_replay(wc, ret, in check_item_in_log()
2446 btrfs_ino(dir), dir_key->offset, in check_item_in_log()
2454 log_di = btrfs_lookup_dir_index_item(trans, wc->log, log_path, in check_item_in_log()
2455 dir_key->objectid, in check_item_in_log()
2456 dir_key->offset, &name, 0); in check_item_in_log()
2459 btrfs_abort_log_replay(wc, ret, in check_item_in_log()
2461 btrfs_ino(dir), dir_key->offset, in check_item_in_log()
2473 btrfs_release_path(wc->subvol_path); in check_item_in_log()
2479 btrfs_abort_log_replay(wc, ret, in check_item_in_log()
2485 ret = link_to_fixup_dir(wc, location.objectid); in check_item_in_log()
2489 inc_nlink(&inode->vfs_inode); in check_item_in_log()
2490 ret = unlink_inode_for_log_replay(wc, dir, inode, &name); in check_item_in_log()
2493 * them, as there are no key collisions since each key has a unique offset in check_item_in_log()
2497 btrfs_release_path(wc->subvol_path); in check_item_in_log()
2501 iput(&inode->vfs_inode); in check_item_in_log()
2505 static int replay_xattr_deletes(struct walk_control *wc) in replay_xattr_deletes() argument
2507 struct btrfs_trans_handle *trans = wc->trans; in replay_xattr_deletes()
2508 struct btrfs_root *root = wc->root; in replay_xattr_deletes()
2509 struct btrfs_root *log = wc->log; in replay_xattr_deletes()
2512 const u64 ino = wc->log_key.objectid; in replay_xattr_deletes()
2518 btrfs_abort_log_replay(wc, -ENOMEM, "failed to allocate path"); in replay_xattr_deletes()
2519 return -ENOMEM; in replay_xattr_deletes()
2526 ret = btrfs_search_slot(NULL, root, &search_key, wc->subvol_path, 0, 0); in replay_xattr_deletes()
2528 btrfs_abort_log_replay(wc, ret, in replay_xattr_deletes()
2534 nritems = btrfs_header_nritems(wc->subvol_path->nodes[0]); in replay_xattr_deletes()
2535 for (int i = wc->subvol_path->slots[0]; i < nritems; i++) { in replay_xattr_deletes()
2542 btrfs_item_key_to_cpu(wc->subvol_path->nodes[0], &key, i); in replay_xattr_deletes()
2548 di = btrfs_item_ptr(wc->subvol_path->nodes[0], i, struct btrfs_dir_item); in replay_xattr_deletes()
2549 total_size = btrfs_item_size(wc->subvol_path->nodes[0], i); in replay_xattr_deletes()
2552 u16 name_len = btrfs_dir_name_len(wc->subvol_path->nodes[0], di); in replay_xattr_deletes()
2553 u16 data_len = btrfs_dir_data_len(wc->subvol_path->nodes[0], di); in replay_xattr_deletes()
2559 ret = -ENOMEM; in replay_xattr_deletes()
2560 btrfs_abort_log_replay(wc, ret, in replay_xattr_deletes()
2561 "failed to allocate memory for name of length %u", in replay_xattr_deletes()
2565 read_extent_buffer(wc->subvol_path->nodes[0], name, in replay_xattr_deletes()
2573 btrfs_release_path(wc->subvol_path); in replay_xattr_deletes()
2574 di = btrfs_lookup_xattr(trans, root, wc->subvol_path, ino, in replay_xattr_deletes()
2575 name, name_len, -1); in replay_xattr_deletes()
2578 btrfs_abort_log_replay(wc, ret, in replay_xattr_deletes()
2587 wc->subvol_path, di); in replay_xattr_deletes()
2589 btrfs_abort_log_replay(wc, ret, in replay_xattr_deletes()
2596 btrfs_release_path(wc->subvol_path); in replay_xattr_deletes()
2603 btrfs_abort_log_replay(wc, ret, in replay_xattr_deletes()
2615 ret = btrfs_next_leaf(root, wc->subvol_path); in replay_xattr_deletes()
2621 btrfs_abort_log_replay(wc, ret, in replay_xattr_deletes()
2625 btrfs_release_path(wc->subvol_path); in replay_xattr_deletes()
2640 static noinline int replay_dir_deletes(struct walk_control *wc, in replay_dir_deletes() argument
2643 struct btrfs_root *root = wc->root; in replay_dir_deletes()
2644 struct btrfs_root *log = (del_all ? NULL : wc->log); in replay_dir_deletes()
2657 btrfs_abort_log_replay(wc, -ENOMEM, "failed to allocate path"); in replay_dir_deletes()
2658 return -ENOMEM; in replay_dir_deletes()
2669 if (ret == -ENOENT) in replay_dir_deletes()
2672 btrfs_abort_log_replay(wc, ret, in replay_dir_deletes()
2682 range_end = (u64)-1; in replay_dir_deletes()
2684 ret = find_dir_range(log, wc->subvol_path, dirid, in replay_dir_deletes()
2687 btrfs_abort_log_replay(wc, ret, in replay_dir_deletes()
2700 wc->subvol_path, 0, 0); in replay_dir_deletes()
2702 btrfs_abort_log_replay(wc, ret, in replay_dir_deletes()
2710 nritems = btrfs_header_nritems(wc->subvol_path->nodes[0]); in replay_dir_deletes()
2711 if (wc->subvol_path->slots[0] >= nritems) { in replay_dir_deletes()
2712 ret = btrfs_next_leaf(root, wc->subvol_path); in replay_dir_deletes()
2716 btrfs_abort_log_replay(wc, ret, in replay_dir_deletes()
2722 btrfs_item_key_to_cpu(wc->subvol_path->nodes[0], &found_key, in replay_dir_deletes()
2723 wc->subvol_path->slots[0]); in replay_dir_deletes()
2733 ret = check_item_in_log(wc, log_path, dir, &found_key, del_all); in replay_dir_deletes()
2736 if (found_key.offset == (u64)-1) in replay_dir_deletes()
2740 btrfs_release_path(wc->subvol_path); in replay_dir_deletes()
2741 if (range_end == (u64)-1) in replay_dir_deletes()
2747 btrfs_release_path(wc->subvol_path); in replay_dir_deletes()
2749 iput(&dir->vfs_inode); in replay_dir_deletes()
2765 struct walk_control *wc, u64 gen, int level) in replay_one_buffer() argument
2772 struct btrfs_root *root = wc->root; in replay_one_buffer()
2773 struct btrfs_trans_handle *trans = wc->trans; in replay_one_buffer()
2781 * on error, we have no valid log tree leaf to dump. in replay_one_buffer()
2783 wc->log_leaf = NULL; in replay_one_buffer()
2786 btrfs_abort_log_replay(wc, ret, in replay_one_buffer()
2788 eb->start, btrfs_root_id(root)); in replay_one_buffer()
2792 ASSERT(wc->subvol_path == NULL); in replay_one_buffer()
2793 wc->subvol_path = btrfs_alloc_path(); in replay_one_buffer()
2794 if (!wc->subvol_path) { in replay_one_buffer()
2795 btrfs_abort_log_replay(wc, -ENOMEM, "failed to allocate path"); in replay_one_buffer()
2796 return -ENOMEM; in replay_one_buffer()
2799 wc->log_leaf = eb; in replay_one_buffer()
2802 for (wc->log_slot = 0; wc->log_slot < nritems; wc->log_slot++) { in replay_one_buffer()
2805 btrfs_item_key_to_cpu(eb, &wc->log_key, wc->log_slot); in replay_one_buffer()
2807 if (wc->log_key.type == BTRFS_INODE_ITEM_KEY) { in replay_one_buffer()
2808 inode_item = btrfs_item_ptr(eb, wc->log_slot, in replay_one_buffer()
2811 * An inode with no links is either: in replay_one_buffer()
2820 * 2) A non-tmpfile which got its last link deleted in replay_one_buffer()
2823 * parent inodes when inode->last_unlink_trans is in replay_one_buffer()
2830 wc->ignore_cur_inode = true; in replay_one_buffer()
2833 wc->ignore_cur_inode = false; in replay_one_buffer()
2838 if (wc->log_key.type == BTRFS_INODE_ITEM_KEY && in replay_one_buffer()
2839 wc->stage == LOG_WALK_REPLAY_INODES) { in replay_one_buffer()
2842 ret = replay_xattr_deletes(wc); in replay_one_buffer()
2847 ret = replay_dir_deletes(wc, wc->log_key.objectid, false); in replay_one_buffer()
2851 ret = overwrite_item(wc); in replay_one_buffer()
2868 inode = btrfs_iget_logging(wc->log_key.objectid, root); in replay_one_buffer()
2871 btrfs_abort_log_replay(wc, ret, in replay_one_buffer()
2873 wc->log_key.objectid, in replay_one_buffer()
2877 from = ALIGN(i_size_read(&inode->vfs_inode), in replay_one_buffer()
2878 root->fs_info->sectorsize); in replay_one_buffer()
2880 drop_args.end = (u64)-1; in replay_one_buffer()
2882 drop_args.path = wc->subvol_path; in replay_one_buffer()
2885 btrfs_abort_log_replay(wc, ret, in replay_one_buffer()
2891 inode_sub_bytes(&inode->vfs_inode, in replay_one_buffer()
2896 btrfs_abort_log_replay(wc, ret, in replay_one_buffer()
2901 iput(&inode->vfs_inode); in replay_one_buffer()
2906 ret = link_to_fixup_dir(wc, wc->log_key.objectid); in replay_one_buffer()
2911 if (wc->ignore_cur_inode) in replay_one_buffer()
2914 if (wc->log_key.type == BTRFS_DIR_INDEX_KEY && in replay_one_buffer()
2915 wc->stage == LOG_WALK_REPLAY_DIR_INDEX) { in replay_one_buffer()
2916 ret = replay_one_dir_item(wc); in replay_one_buffer()
2921 if (wc->stage < LOG_WALK_REPLAY_ALL) in replay_one_buffer()
2925 if (wc->log_key.type == BTRFS_XATTR_ITEM_KEY) { in replay_one_buffer()
2926 ret = overwrite_item(wc); in replay_one_buffer()
2929 } else if (wc->log_key.type == BTRFS_INODE_REF_KEY || in replay_one_buffer()
2930 wc->log_key.type == BTRFS_INODE_EXTREF_KEY) { in replay_one_buffer()
2931 ret = add_inode_ref(wc); in replay_one_buffer()
2934 } else if (wc->log_key.type == BTRFS_EXTENT_DATA_KEY) { in replay_one_buffer()
2935 ret = replay_one_extent(wc); in replay_one_buffer()
2946 btrfs_free_path(wc->subvol_path); in replay_one_buffer()
2947 wc->subvol_path = NULL; in replay_one_buffer()
2954 struct btrfs_fs_info *fs_info = eb->fs_info; in clean_log_buffer()
2971 bg = btrfs_lookup_block_group(fs_info, eb->start); in clean_log_buffer()
2973 btrfs_err(fs_info, "unable to find block group for %llu", eb->start); in clean_log_buffer()
2974 btrfs_handle_fs_error(fs_info, -ENOENT, NULL); in clean_log_buffer()
2975 return -ENOENT; in clean_log_buffer()
2978 spin_lock(&bg->space_info->lock); in clean_log_buffer()
2979 spin_lock(&bg->lock); in clean_log_buffer()
2980 bg->reserved -= fs_info->nodesize; in clean_log_buffer()
2981 bg->space_info->bytes_reserved -= fs_info->nodesize; in clean_log_buffer()
2982 spin_unlock(&bg->lock); in clean_log_buffer()
2983 spin_unlock(&bg->space_info->lock); in clean_log_buffer()
2991 struct walk_control *wc) in walk_down_log_tree() argument
2993 struct btrfs_trans_handle *trans = wc->trans; in walk_down_log_tree()
2994 struct btrfs_fs_info *fs_info = wc->log->fs_info; in walk_down_log_tree()
3004 cur = path->nodes[*level]; in walk_down_log_tree()
3008 if (path->slots[*level] >= in walk_down_log_tree()
3012 bytenr = btrfs_node_blockptr(cur, path->slots[*level]); in walk_down_log_tree()
3013 ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]); in walk_down_log_tree()
3015 check.level = *level - 1; in walk_down_log_tree()
3017 btrfs_node_key_to_cpu(cur, &check.first_key, path->slots[*level]); in walk_down_log_tree()
3021 *level - 1); in walk_down_log_tree()
3032 ret = wc->process_func(next, wc, ptr_gen, *level - 1); in walk_down_log_tree()
3038 path->slots[*level]++; in walk_down_log_tree()
3039 if (wc->free) { in walk_down_log_tree()
3069 if (path->nodes[*level-1]) in walk_down_log_tree()
3070 free_extent_buffer(path->nodes[*level-1]); in walk_down_log_tree()
3071 path->nodes[*level-1] = next; in walk_down_log_tree()
3073 path->slots[*level] = 0; in walk_down_log_tree()
3076 path->slots[*level] = btrfs_header_nritems(path->nodes[*level]); in walk_down_log_tree()
3083 struct walk_control *wc) in walk_up_log_tree() argument
3089 for (i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) { in walk_up_log_tree()
3090 slot = path->slots[i]; in walk_up_log_tree()
3091 if (slot + 1 < btrfs_header_nritems(path->nodes[i])) { in walk_up_log_tree()
3092 path->slots[i]++; in walk_up_log_tree()
3097 ret = wc->process_func(path->nodes[*level], wc, in walk_up_log_tree()
3098 btrfs_header_generation(path->nodes[*level]), in walk_up_log_tree()
3103 if (wc->free) { in walk_up_log_tree()
3104 ret = clean_log_buffer(wc->trans, path->nodes[*level]); in walk_up_log_tree()
3108 free_extent_buffer(path->nodes[*level]); in walk_up_log_tree()
3109 path->nodes[*level] = NULL; in walk_up_log_tree()
3121 static int walk_log_tree(struct walk_control *wc) in walk_log_tree() argument
3123 struct btrfs_root *log = wc->log; in walk_log_tree()
3132 return -ENOMEM; in walk_log_tree()
3134 level = btrfs_header_level(log->node); in walk_log_tree()
3136 path->nodes[level] = log->node; in walk_log_tree()
3137 refcount_inc(&log->node->refs); in walk_log_tree()
3138 path->slots[level] = 0; in walk_log_tree()
3141 wret = walk_down_log_tree(path, &level, wc); in walk_log_tree()
3147 wret = walk_up_log_tree(path, &level, wc); in walk_log_tree()
3155 if (path->nodes[orig_level]) { in walk_log_tree()
3156 ret = wc->process_func(path->nodes[orig_level], wc, in walk_log_tree()
3157 btrfs_header_generation(path->nodes[orig_level]), in walk_log_tree()
3161 if (wc->free) in walk_log_tree()
3162 ret = clean_log_buffer(wc->trans, path->nodes[orig_level]); in walk_log_tree()
3176 struct btrfs_fs_info *fs_info = log->fs_info; in update_log_root()
3179 if (log->log_transid == 1) { in update_log_root()
3181 ret = btrfs_insert_root(trans, fs_info->log_root_tree, in update_log_root()
3182 &log->root_key, root_item); in update_log_root()
3184 ret = btrfs_update_root(trans, fs_info->log_root_tree, in update_log_root()
3185 &log->root_key, root_item); in update_log_root()
3201 prepare_to_wait(&root->log_commit_wait[index], in wait_log_commit()
3204 if (!(root->log_transid_committed < transid && in wait_log_commit()
3205 atomic_read(&root->log_commit[index]))) in wait_log_commit()
3208 mutex_unlock(&root->log_mutex); in wait_log_commit()
3210 mutex_lock(&root->log_mutex); in wait_log_commit()
3212 finish_wait(&root->log_commit_wait[index], &wait); in wait_log_commit()
3220 prepare_to_wait(&root->log_writer_wait, &wait, in wait_for_writer()
3222 if (!atomic_read(&root->log_writers)) in wait_for_writer()
3225 mutex_unlock(&root->log_mutex); in wait_for_writer()
3227 mutex_lock(&root->log_mutex); in wait_for_writer()
3229 finish_wait(&root->log_writer_wait, &wait); in wait_for_writer()
3234 ctx->log_ret = 0; in btrfs_init_log_ctx()
3235 ctx->log_transid = 0; in btrfs_init_log_ctx()
3236 ctx->log_new_dentries = false; in btrfs_init_log_ctx()
3237 ctx->logging_new_name = false; in btrfs_init_log_ctx()
3238 ctx->logging_new_delayed_dentries = false; in btrfs_init_log_ctx()
3239 ctx->logged_before = false; in btrfs_init_log_ctx()
3240 ctx->inode = inode; in btrfs_init_log_ctx()
3241 INIT_LIST_HEAD(&ctx->list); in btrfs_init_log_ctx()
3242 INIT_LIST_HEAD(&ctx->ordered_extents); in btrfs_init_log_ctx()
3243 INIT_LIST_HEAD(&ctx->conflict_inodes); in btrfs_init_log_ctx()
3244 ctx->num_conflict_inodes = 0; in btrfs_init_log_ctx()
3245 ctx->logging_conflict_inodes = false; in btrfs_init_log_ctx()
3246 ctx->scratch_eb = NULL; in btrfs_init_log_ctx()
3251 struct btrfs_inode *inode = ctx->inode; in btrfs_init_log_ctx_scratch_eb()
3253 if (!test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &inode->runtime_flags) && in btrfs_init_log_ctx_scratch_eb()
3254 !test_bit(BTRFS_INODE_COPY_EVERYTHING, &inode->runtime_flags)) in btrfs_init_log_ctx_scratch_eb()
3261 ctx->scratch_eb = alloc_dummy_extent_buffer(inode->root->fs_info, 0); in btrfs_init_log_ctx_scratch_eb()
3269 btrfs_assert_inode_locked(ctx->inode); in btrfs_release_log_ctx_extents()
3271 list_for_each_entry_safe(ordered, tmp, &ctx->ordered_extents, log_list) { in btrfs_release_log_ctx_extents()
3272 list_del_init(&ordered->log_list); in btrfs_release_log_ctx_extents()
3281 mutex_lock(&root->log_mutex); in btrfs_remove_log_ctx()
3282 list_del_init(&ctx->list); in btrfs_remove_log_ctx()
3283 mutex_unlock(&root->log_mutex); in btrfs_remove_log_ctx()
3287 * Invoked in log mutex context, or be sure there is no other task which
3296 list_for_each_entry_safe(ctx, safe, &root->log_ctxs[index], list) { in btrfs_remove_all_log_ctxs()
3297 list_del_init(&ctx->list); in btrfs_remove_all_log_ctxs()
3298 ctx->log_ret = error; in btrfs_remove_all_log_ctxs()
3310 * fsync is to commit the whole FS. When btrfs_sync_log returns -EAGAIN,
3320 struct btrfs_fs_info *fs_info = root->fs_info; in btrfs_sync_log()
3321 struct btrfs_root *log = root->log_root; in btrfs_sync_log()
3322 struct btrfs_root *log_root_tree = fs_info->log_root_tree; in btrfs_sync_log()
3330 mutex_lock(&root->log_mutex); in btrfs_sync_log()
3331 log_transid = ctx->log_transid; in btrfs_sync_log()
3332 if (root->log_transid_committed >= log_transid) { in btrfs_sync_log()
3333 mutex_unlock(&root->log_mutex); in btrfs_sync_log()
3334 return ctx->log_ret; in btrfs_sync_log()
3338 if (atomic_read(&root->log_commit[index1])) { in btrfs_sync_log()
3340 mutex_unlock(&root->log_mutex); in btrfs_sync_log()
3341 return ctx->log_ret; in btrfs_sync_log()
3343 ASSERT(log_transid == root->log_transid); in btrfs_sync_log()
3344 atomic_set(&root->log_commit[index1], 1); in btrfs_sync_log()
3347 if (atomic_read(&root->log_commit[(index1 + 1) % 2])) in btrfs_sync_log()
3348 wait_log_commit(root, log_transid - 1); in btrfs_sync_log()
3351 int batch = atomic_read(&root->log_batch); in btrfs_sync_log()
3354 test_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state)) { in btrfs_sync_log()
3355 mutex_unlock(&root->log_mutex); in btrfs_sync_log()
3357 mutex_lock(&root->log_mutex); in btrfs_sync_log()
3360 if (batch == atomic_read(&root->log_batch)) in btrfs_sync_log()
3367 mutex_unlock(&root->log_mutex); in btrfs_sync_log()
3380 ret = btrfs_write_marked_extents(fs_info, &log->dirty_log_pages, mark); in btrfs_sync_log()
3382 * -EAGAIN happens when someone, e.g., a concurrent transaction in btrfs_sync_log()
3383 * commit, writes a dirty extent in this tree-log commit. This in btrfs_sync_log()
3390 if (ret == -EAGAIN && btrfs_is_zoned(fs_info)) in btrfs_sync_log()
3395 mutex_unlock(&root->log_mutex); in btrfs_sync_log()
3400 * We _must_ update under the root->log_mutex in order to make sure we in btrfs_sync_log()
3405 * log_root_tree->log_mutex yet. This is important because when we in btrfs_sync_log()
3412 btrfs_set_root_node(&log->root_item, log->node); in btrfs_sync_log()
3413 memcpy(&new_root_item, &log->root_item, sizeof(new_root_item)); in btrfs_sync_log()
3415 btrfs_set_root_log_transid(root, root->log_transid + 1); in btrfs_sync_log()
3416 log->log_transid = root->log_transid; in btrfs_sync_log()
3417 root->log_start_pid = 0; in btrfs_sync_log()
3423 mutex_unlock(&root->log_mutex); in btrfs_sync_log()
3426 mutex_lock(&fs_info->tree_root->log_mutex); in btrfs_sync_log()
3427 if (!log_root_tree->node) { in btrfs_sync_log()
3430 mutex_unlock(&fs_info->tree_root->log_mutex); in btrfs_sync_log()
3435 mutex_unlock(&fs_info->tree_root->log_mutex); in btrfs_sync_log()
3440 mutex_lock(&log_root_tree->log_mutex); in btrfs_sync_log()
3442 index2 = log_root_tree->log_transid % 2; in btrfs_sync_log()
3443 list_add_tail(&root_log_ctx.list, &log_root_tree->log_ctxs[index2]); in btrfs_sync_log()
3444 root_log_ctx.log_transid = log_root_tree->log_transid; in btrfs_sync_log()
3456 if (ret != -ENOSPC) in btrfs_sync_log()
3461 mutex_unlock(&log_root_tree->log_mutex); in btrfs_sync_log()
3465 if (log_root_tree->log_transid_committed >= root_log_ctx.log_transid) { in btrfs_sync_log()
3468 mutex_unlock(&log_root_tree->log_mutex); in btrfs_sync_log()
3473 if (atomic_read(&log_root_tree->log_commit[index2])) { in btrfs_sync_log()
3478 mutex_unlock(&log_root_tree->log_mutex); in btrfs_sync_log()
3483 ASSERT(root_log_ctx.log_transid == log_root_tree->log_transid); in btrfs_sync_log()
3484 atomic_set(&log_root_tree->log_commit[index2], 1); in btrfs_sync_log()
3486 if (atomic_read(&log_root_tree->log_commit[(index2 + 1) % 2])) { in btrfs_sync_log()
3488 root_log_ctx.log_transid - 1); in btrfs_sync_log()
3498 mutex_unlock(&log_root_tree->log_mutex); in btrfs_sync_log()
3504 &log_root_tree->dirty_log_pages, in btrfs_sync_log()
3508 * As described above, -EAGAIN indicates a hole in the extents. We in btrfs_sync_log()
3512 if (ret == -EAGAIN && btrfs_is_zoned(fs_info)) { in btrfs_sync_log()
3515 mutex_unlock(&log_root_tree->log_mutex); in btrfs_sync_log()
3519 mutex_unlock(&log_root_tree->log_mutex); in btrfs_sync_log()
3528 mutex_unlock(&log_root_tree->log_mutex); in btrfs_sync_log()
3532 log_root_start = log_root_tree->node->start; in btrfs_sync_log()
3533 log_root_level = btrfs_header_level(log_root_tree->node); in btrfs_sync_log()
3534 log_root_tree->log_transid++; in btrfs_sync_log()
3535 mutex_unlock(&log_root_tree->log_mutex); in btrfs_sync_log()
3543 * 1) We are holding a handle on the current transaction, so no body in btrfs_sync_log()
3552 mutex_lock(&fs_info->tree_log_mutex); in btrfs_sync_log()
3562 ret = -EIO; in btrfs_sync_log()
3565 mutex_unlock(&fs_info->tree_log_mutex); in btrfs_sync_log()
3569 btrfs_set_super_log_root(fs_info->super_for_commit, log_root_start); in btrfs_sync_log()
3570 btrfs_set_super_log_root_level(fs_info->super_for_commit, log_root_level); in btrfs_sync_log()
3572 mutex_unlock(&fs_info->tree_log_mutex); in btrfs_sync_log()
3581 * root->log_commit[index1] to 0 and any task attempting to sync the in btrfs_sync_log()
3591 mutex_lock(&log_root_tree->log_mutex); in btrfs_sync_log()
3594 log_root_tree->log_transid_committed++; in btrfs_sync_log()
3595 atomic_set(&log_root_tree->log_commit[index2], 0); in btrfs_sync_log()
3596 mutex_unlock(&log_root_tree->log_mutex); in btrfs_sync_log()
3603 cond_wake_up(&log_root_tree->log_commit_wait[index2]); in btrfs_sync_log()
3605 mutex_lock(&root->log_mutex); in btrfs_sync_log()
3607 root->log_transid_committed++; in btrfs_sync_log()
3608 atomic_set(&root->log_commit[index1], 0); in btrfs_sync_log()
3609 mutex_unlock(&root->log_mutex); in btrfs_sync_log()
3616 cond_wake_up(&root->log_commit_wait[index1]); in btrfs_sync_log()
3624 struct walk_control wc = { in free_log_tree() local
3631 if (log->node) { in free_log_tree()
3632 ret = walk_log_tree(&wc); in free_log_tree()
3636 * typical scenario is getting an -EIO when reading an in free_log_tree()
3641 &log->fs_info->fs_state); in free_log_tree()
3651 btrfs_write_marked_extents(log->fs_info, in free_log_tree()
3652 &log->dirty_log_pages, in free_log_tree()
3660 btrfs_handle_fs_error(log->fs_info, ret, NULL); in free_log_tree()
3664 btrfs_extent_io_tree_release(&log->dirty_log_pages); in free_log_tree()
3665 btrfs_extent_io_tree_release(&log->log_csum_range); in free_log_tree()
3676 if (root->log_root) { in btrfs_free_log()
3677 free_log_tree(trans, root->log_root); in btrfs_free_log()
3678 root->log_root = NULL; in btrfs_free_log()
3679 clear_bit(BTRFS_ROOT_HAS_LOG_TREE, &root->state); in btrfs_free_log()
3687 if (fs_info->log_root_tree) { in btrfs_free_log_root_tree()
3688 free_log_tree(trans, fs_info->log_root_tree); in btrfs_free_log_root_tree()
3689 fs_info->log_root_tree = NULL; in btrfs_free_log_root_tree()
3690 clear_bit(BTRFS_ROOT_HAS_LOG_TREE, &fs_info->tree_root->state); in btrfs_free_log_root_tree()
3701 * Do this only if ->logged_trans is still 0 to prevent races with in mark_inode_as_not_logged()
3704 * not find it in the log tree and we end up setting ->logged_trans to a in mark_inode_as_not_logged()
3705 * value less than trans->transid after the concurrent logging task has in mark_inode_as_not_logged()
3706 * set it to trans->transid. As a consequence, subsequent rename, unlink in mark_inode_as_not_logged()
3710 spin_lock(&inode->lock); in mark_inode_as_not_logged()
3711 if (inode->logged_trans == 0) in mark_inode_as_not_logged()
3712 inode->logged_trans = trans->transid - 1; in mark_inode_as_not_logged()
3713 else if (inode->logged_trans == trans->transid) in mark_inode_as_not_logged()
3715 spin_unlock(&inode->lock); in mark_inode_as_not_logged()
3724 * memory only field (not persisted).
3738 * Quick lockless call, since once ->logged_trans is set to the current in inode_logged()
3741 if (data_race(inode->logged_trans) == trans->transid) in inode_logged()
3745 * If logged_trans is not 0 and not trans->transid, then we know the in inode_logged()
3749 * in this function further below - an update to trans->transid can be in inode_logged()
3751 * see a positive value that is not trans->transid and assume the inode in inode_logged()
3754 spin_lock(&inode->lock); in inode_logged()
3755 if (inode->logged_trans == trans->transid) { in inode_logged()
3756 spin_unlock(&inode->lock); in inode_logged()
3758 } else if (inode->logged_trans > 0) { in inode_logged()
3759 spin_unlock(&inode->lock); in inode_logged()
3762 spin_unlock(&inode->lock); in inode_logged()
3765 * If no log tree was created for this root in this transaction, then in inode_logged()
3771 if (!test_bit(BTRFS_ROOT_HAS_LOG_TREE, &inode->root->state)) in inode_logged()
3805 return -ENOMEM; in inode_logged()
3808 ret = btrfs_search_slot(NULL, inode->root->log_root, &key, path, 0, 0); in inode_logged()
3834 spin_lock(&inode->lock); in inode_logged()
3835 inode->logged_trans = trans->transid; in inode_logged()
3836 spin_unlock(&inode->lock); in inode_logged()
3862 index, name, -1); in del_logged_dentry()
3924 mutex_lock(&dir->log_mutex); in btrfs_del_dir_entries_in_log()
3926 ret = del_logged_dentry(trans, root->log_root, path, btrfs_ino(dir), in btrfs_del_dir_entries_in_log()
3928 mutex_unlock(&dir->log_mutex); in btrfs_del_dir_entries_in_log()
3955 log = root->log_root; in btrfs_del_inode_ref_in_log()
3956 mutex_lock(&inode->log_mutex); in btrfs_del_inode_ref_in_log()
3959 mutex_unlock(&inode->log_mutex); in btrfs_del_inode_ref_in_log()
3960 if (ret < 0 && ret != -ENOENT) in btrfs_del_inode_ref_in_log()
3985 * -EEXIST is fine and can happen sporadically when we are logging a in insert_dir_log_key()
3991 if (ret && ret != -EEXIST) in insert_dir_log_key()
3994 item = btrfs_item_ptr(path->nodes[0], path->slots[0], in insert_dir_log_key()
3996 if (ret == -EEXIST) { in insert_dir_log_key()
3997 const u64 curr_end = btrfs_dir_log_end(path->nodes[0], item); in insert_dir_log_key()
4007 btrfs_set_dir_log_end(path->nodes[0], item, last_offset); in insert_dir_log_key()
4019 struct btrfs_root *log = inode->root->log_root; in flush_dir_items_batch()
4046 return -ENOMEM; in flush_dir_items_batch()
4067 dst = dst_path->nodes[0]; in flush_dir_items_batch()
4078 dst_offset = btrfs_item_ptr_offset(dst, dst_path->slots[0] + count - 1); in flush_dir_items_batch()
4079 src_offset = btrfs_item_ptr_offset(src, start_slot + count - 1); in flush_dir_items_batch()
4083 last_index = batch.keys[count - 1].offset; in flush_dir_items_batch()
4084 ASSERT(last_index > inode->last_dir_index_offset); in flush_dir_items_batch()
4090 if (WARN_ON(last_index <= inode->last_dir_index_offset)) in flush_dir_items_batch()
4093 inode->last_dir_index_offset = last_index; in flush_dir_items_batch()
4105 const int slot = path->slots[0]; in clone_leaf()
4107 if (ctx->scratch_eb) { in clone_leaf()
4108 copy_extent_buffer_full(ctx->scratch_eb, path->nodes[0]); in clone_leaf()
4110 ctx->scratch_eb = btrfs_clone_extent_buffer(path->nodes[0]); in clone_leaf()
4111 if (!ctx->scratch_eb) in clone_leaf()
4112 return -ENOMEM; in clone_leaf()
4116 path->nodes[0] = ctx->scratch_eb; in clone_leaf()
4117 path->slots[0] = slot; in clone_leaf()
4122 refcount_inc(&ctx->scratch_eb->refs); in clone_leaf()
4134 struct btrfs_root *log = inode->root->log_root; in process_dir_items_leaf()
4136 const int nritems = btrfs_header_nritems(path->nodes[0]); in process_dir_items_leaf()
4152 src = path->nodes[0]; in process_dir_items_leaf()
4154 for (int i = path->slots[0]; i < nritems; i++) { in process_dir_items_leaf()
4174 if (btrfs_dir_transid(src, di) < trans->transid) { in process_dir_items_leaf()
4178 key.offset - 1); in process_dir_items_leaf()
4188 if (key.offset <= inode->last_dir_index_offset) in process_dir_items_leaf()
4200 * xfs_io -c "fsync" mydir in process_dir_items_leaf()
4211 * resulting in -ENOTEMPTY errors. in process_dir_items_leaf()
4213 if (!ctx->log_new_dentries) { in process_dir_items_leaf()
4218 ctx->log_new_dentries = true; in process_dir_items_leaf()
4251 struct btrfs_root *root = inode->root; in log_dir_items()
4252 struct btrfs_root *log = root->log_root; in log_dir_items()
4254 u64 last_old_dentry_offset = min_offset - 1; in log_dir_items()
4255 u64 last_offset = (u64)-1; in log_dir_items()
4262 ret = btrfs_search_forward(root, &min_key, path, trans->transid); in log_dir_items()
4272 min_key.offset = (u64)-1; in log_dir_items()
4283 * otherwise, there are no items in this directory after in log_dir_items()
4289 btrfs_item_key_to_cpu(path->nodes[0], &tmp, in log_dir_items()
4290 path->slots[0]); in log_dir_items()
4305 btrfs_item_key_to_cpu(path->nodes[0], &tmp, path->slots[0]); in log_dir_items()
4332 * and we can end up logging a dir index range that ends at (u64)-1 in log_dir_items()
4341 /* There are no more keys in the inode's root. */ in log_dir_items()
4361 path->slots[0] = btrfs_header_nritems(path->nodes[0]); in log_dir_items()
4370 last_offset = (u64)-1; in log_dir_items()
4375 btrfs_item_key_to_cpu(path->nodes[0], &min_key, path->slots[0]); in log_dir_items()
4377 last_offset = (u64)-1; in log_dir_items()
4380 if (btrfs_header_generation(path->nodes[0]) != trans->transid) { in log_dir_items()
4390 last_offset = min_key.offset - 1; in log_dir_items()
4408 * in the leaf is a dir item and there's no gap between that last in log_dir_items()
4439 lockdep_assert_held(&inode->log_mutex); in update_last_dir_index_offset()
4441 if (inode->last_dir_index_offset != 0) in update_last_dir_index_offset()
4444 if (!ctx->logged_before) { in update_last_dir_index_offset()
4445 inode->last_dir_index_offset = BTRFS_DIR_START_INDEX - 1; in update_last_dir_index_offset()
4451 key.offset = (u64)-1; in update_last_dir_index_offset()
4453 ret = btrfs_search_slot(NULL, inode->root->log_root, &key, path, 0, 0); in update_last_dir_index_offset()
4456 * value of (u64)-1. Bail out, we're done. in update_last_dir_index_offset()
4462 inode->last_dir_index_offset = BTRFS_DIR_START_INDEX - 1; in update_last_dir_index_offset()
4465 * No dir index items, bail out and leave last_dir_index_offset with in update_last_dir_index_offset()
4468 if (path->slots[0] == 0) in update_last_dir_index_offset()
4478 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0] - 1); in update_last_dir_index_offset()
4480 inode->last_dir_index_offset = key.offset; in update_last_dir_index_offset()
4522 if (max_key == (u64)-1) in log_directory_changes()
4549 key.offset = (u64)-1; in drop_inode_items()
4552 ret = btrfs_search_slot(trans, log, &key, path, -1, 1); in drop_inode_items()
4556 if (path->slots[0] == 0) in drop_inode_items()
4558 path->slots[0]--; in drop_inode_items()
4561 btrfs_item_key_to_cpu(path->nodes[0], &found_key, in drop_inode_items()
4562 path->slots[0]); in drop_inode_items()
4569 ret = btrfs_bin_search(path->nodes[0], 0, &found_key, &start_slot); in drop_inode_items()
4574 path->slots[0] - start_slot + 1); in drop_inode_items()
4576 * If start slot isn't 0 then we don't need to re-search, we've in drop_inode_items()
4621 btrfs_set_inode_generation(leaf, item, BTRFS_I(inode)->generation); in fill_inode_item()
4622 btrfs_set_inode_size(leaf, item, inode->i_size); in fill_inode_item()
4627 btrfs_set_inode_mode(leaf, item, inode->i_mode); in fill_inode_item()
4628 btrfs_set_inode_nlink(leaf, item, inode->i_nlink); in fill_inode_item()
4630 btrfs_set_timespec_sec(leaf, &item->atime, inode_get_atime_sec(inode)); in fill_inode_item()
4631 btrfs_set_timespec_nsec(leaf, &item->atime, inode_get_atime_nsec(inode)); in fill_inode_item()
4633 btrfs_set_timespec_sec(leaf, &item->mtime, inode_get_mtime_sec(inode)); in fill_inode_item()
4634 btrfs_set_timespec_nsec(leaf, &item->mtime, inode_get_mtime_nsec(inode)); in fill_inode_item()
4636 btrfs_set_timespec_sec(leaf, &item->ctime, inode_get_ctime_sec(inode)); in fill_inode_item()
4637 btrfs_set_timespec_nsec(leaf, &item->ctime, inode_get_ctime_nsec(inode)); in fill_inode_item()
4639 btrfs_set_timespec_sec(leaf, &item->otime, BTRFS_I(inode)->i_otime_sec); in fill_inode_item()
4640 btrfs_set_timespec_nsec(leaf, &item->otime, BTRFS_I(inode)->i_otime_nsec); in fill_inode_item()
4652 btrfs_set_inode_transid(leaf, item, trans->transid); in fill_inode_item()
4653 btrfs_set_inode_rdev(leaf, item, inode->i_rdev); in fill_inode_item()
4654 flags = btrfs_inode_combine_flags(BTRFS_I(inode)->flags, in fill_inode_item()
4655 BTRFS_I(inode)->ro_flags); in fill_inode_item()
4679 if (!inode_item_dropped && inode->logged_trans == trans->transid) { in log_inode_item()
4683 ret = -ENOENT; in log_inode_item()
4688 * We can never get -EEXIST because we are only called for a fast in log_inode_item()
4692 * flags and set ->logged_trans to 0. in log_inode_item()
4696 ASSERT(ret != -EEXIST); in log_inode_item()
4700 inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0], in log_inode_item()
4702 fill_inode_item(trans, path->nodes[0], inode_item, &inode->vfs_inode, in log_inode_item()
4713 const u64 lock_end = sums->logical + sums->len - 1; in log_csums()
4719 * transaction with new extents, then do the fast path, no need to in log_csums()
4722 if (inode->last_reflink_trans < trans->transid) in log_csums()
4731 ret = btrfs_lock_extent(&log_root->log_csum_range, sums->logical, lock_end, in log_csums()
4744 ret = btrfs_del_csums(trans, log_root, sums->logical, sums->len); in log_csums()
4748 btrfs_unlock_extent(&log_root->log_csum_range, sums->logical, lock_end, in log_csums()
4761 struct btrfs_root *log = inode->root->log_root; in copy_items()
4770 const bool skip_csum = (inode->flags & BTRFS_INODE_NODATASUM); in copy_items()
4771 const u64 i_size = i_size_read(&inode->vfs_inode); in copy_items()
4792 * buffers of a subvolume tree - all this while holding a write lock in copy_items()
4805 src = src_path->nodes[0]; in copy_items()
4809 return -ENOMEM; in copy_items()
4840 trans->transid); in copy_items()
4848 * generations, so we can skip them - as long as the inode has in copy_items()
4857 inode->last_reflink_trans < trans->transid) in copy_items()
4870 * no need to log them. in copy_items()
4876 /* If it's an explicit hole, there are no checksums. */ in copy_items()
4890 csum_root = btrfs_csum_root(trans->fs_info, disk_bytenr); in copy_items()
4893 disk_bytenr + extent_num_bytes - 1, in copy_items()
4902 list_del(&sums->list); in copy_items()
4929 const int dst_slot = dst_path->slots[0] + dst_index; in copy_items()
4950 if (btrfs_file_extent_generation(src, extent) < trans->transid && in copy_items()
4952 inode->last_reflink_trans < trans->transid) in copy_items()
4956 dst_offset = btrfs_item_ptr_offset(dst_path->nodes[0], dst_slot); in copy_items()
4962 inode_item = btrfs_item_ptr(dst_path->nodes[0], dst_slot, in copy_items()
4964 fill_inode_item(trans, dst_path->nodes[0], inode_item, in copy_items()
4965 &inode->vfs_inode, in copy_items()
4969 copy_extent_buffer(dst_path->nodes[0], src, dst_offset, in copy_items()
4991 if (em1->start < em2->start) in extent_cmp()
4992 return -1; in extent_cmp()
4993 else if (em1->start > em2->start) in extent_cmp()
5009 u64 mod_start = em->start; in log_extent_csums()
5010 u64 mod_len = em->len; in log_extent_csums()
5014 if (inode->flags & BTRFS_INODE_NODATASUM || in log_extent_csums()
5015 (em->flags & EXTENT_FLAG_PREALLOC) || in log_extent_csums()
5016 em->disk_bytenr == EXTENT_MAP_HOLE) in log_extent_csums()
5019 list_for_each_entry(ordered, &ctx->ordered_extents, log_list) { in log_extent_csums()
5020 const u64 ordered_end = ordered->file_offset + ordered->num_bytes; in log_extent_csums()
5029 if (mod_end <= ordered->file_offset) in log_extent_csums()
5037 if (ordered->file_offset > mod_start) { in log_extent_csums()
5039 mod_len = ordered->file_offset - mod_start; in log_extent_csums()
5043 * |--------- logged extent ---------| in log_extent_csums()
5044 * |----- ordered extent ----| in log_extent_csums()
5052 mod_len = mod_end - ordered_end; in log_extent_csums()
5063 if (test_and_set_bit(BTRFS_ORDERED_LOGGED_CSUM, &ordered->flags)) in log_extent_csums()
5066 list_for_each_entry(sums, &ordered->list, list) { in log_extent_csums()
5080 csum_len = em->disk_num_bytes; in log_extent_csums()
5082 csum_offset = mod_start - em->start; in log_extent_csums()
5088 csum_root = btrfs_csum_root(trans->fs_info, block_start); in log_extent_csums()
5090 block_start + csum_offset + csum_len - 1, in log_extent_csums()
5102 list_del(&sums->list); in log_extent_csums()
5116 struct btrfs_root *log = inode->root->log_root; in log_one_extent()
5121 u64 extent_offset = em->offset; in log_one_extent()
5126 btrfs_set_stack_file_extent_generation(&fi, trans->transid); in log_one_extent()
5127 if (em->flags & EXTENT_FLAG_PREALLOC) in log_one_extent()
5132 block_len = em->disk_num_bytes; in log_one_extent()
5137 } else if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) { in log_one_extent()
5138 btrfs_set_stack_file_extent_disk_bytenr(&fi, block_start - extent_offset); in log_one_extent()
5143 btrfs_set_stack_file_extent_num_bytes(&fi, em->len); in log_one_extent()
5144 btrfs_set_stack_file_extent_ram_bytes(&fi, em->ram_bytes); in log_one_extent()
5160 if (ctx->logged_before) { in log_one_extent()
5162 drop_args.start = em->start; in log_one_extent()
5163 drop_args.end = em->start + em->len; in log_one_extent()
5174 key.offset = em->start; in log_one_extent()
5181 leaf = path->nodes[0]; in log_one_extent()
5183 btrfs_item_ptr_offset(leaf, path->slots[0]), in log_one_extent()
5204 struct btrfs_root *root = inode->root; in btrfs_log_prealloc_extents()
5206 const u64 i_size = i_size_read(&inode->vfs_inode); in btrfs_log_prealloc_extents()
5217 if (!(inode->flags & BTRFS_INODE_PREALLOC)) in btrfs_log_prealloc_extents()
5242 leaf = path->nodes[0]; in btrfs_log_prealloc_extents()
5243 slot = path->slots[0]; in btrfs_log_prealloc_extents()
5262 leaf = path->nodes[0]; in btrfs_log_prealloc_extents()
5263 slot = path->slots[0]; in btrfs_log_prealloc_extents()
5289 path->slots[0]++; in btrfs_log_prealloc_extents()
5301 ret = truncate_inode_items(trans, root->log_root, inode, in btrfs_log_prealloc_extents()
5312 path->slots[0]++; in btrfs_log_prealloc_extents()
5316 ret = -ENOMEM; in btrfs_log_prealloc_extents()
5338 struct extent_map_tree *tree = &inode->extent_tree; in btrfs_log_changed_extents()
5342 write_lock(&tree->lock); in btrfs_log_changed_extents()
5344 list_for_each_entry_safe(em, n, &tree->modified_extents, list) { in btrfs_log_changed_extents()
5345 list_del_init(&em->list); in btrfs_log_changed_extents()
5353 list_del_init(&tree->modified_extents); in btrfs_log_changed_extents()
5354 ret = -EFBIG; in btrfs_log_changed_extents()
5358 if (em->generation < trans->transid) in btrfs_log_changed_extents()
5362 if ((em->flags & EXTENT_FLAG_PREALLOC) && in btrfs_log_changed_extents()
5363 em->start >= i_size_read(&inode->vfs_inode)) in btrfs_log_changed_extents()
5367 refcount_inc(&em->refs); in btrfs_log_changed_extents()
5368 em->flags |= EXTENT_FLAG_LOGGING; in btrfs_log_changed_extents()
5369 list_add_tail(&em->list, &extents); in btrfs_log_changed_extents()
5378 list_del_init(&em->list); in btrfs_log_changed_extents()
5390 write_unlock(&tree->lock); in btrfs_log_changed_extents()
5393 write_lock(&tree->lock); in btrfs_log_changed_extents()
5398 write_unlock(&tree->lock); in btrfs_log_changed_extents()
5412 list_for_each_entry_safe(ordered, tmp, &ctx->ordered_extents, log_list) { in btrfs_log_changed_extents()
5413 list_del_init(&ordered->log_list); in btrfs_log_changed_extents()
5414 set_bit(BTRFS_ORDERED_LOGGED, &ordered->flags); in btrfs_log_changed_extents()
5416 if (!test_bit(BTRFS_ORDERED_COMPLETE, &ordered->flags)) { in btrfs_log_changed_extents()
5417 spin_lock_irq(&inode->ordered_tree_lock); in btrfs_log_changed_extents()
5418 if (!test_bit(BTRFS_ORDERED_COMPLETE, &ordered->flags)) { in btrfs_log_changed_extents()
5419 set_bit(BTRFS_ORDERED_PENDING, &ordered->flags); in btrfs_log_changed_extents()
5420 atomic_inc(&trans->transaction->pending_ordered); in btrfs_log_changed_extents()
5422 spin_unlock_irq(&inode->ordered_tree_lock); in btrfs_log_changed_extents()
5448 item = btrfs_item_ptr(path->nodes[0], path->slots[0], in logged_inode_size()
5450 *size_ret = btrfs_inode_size(path->nodes[0], item); in logged_inode_size()
5452 * If the in-memory inode's i_size is smaller then the inode in logged_inode_size()
5462 if (*size_ret > inode->vfs_inode.i_size) in logged_inode_size()
5463 *size_ret = inode->vfs_inode.i_size; in logged_inode_size()
5485 struct btrfs_root *root = inode->root; in btrfs_log_all_xattrs()
5493 if (test_bit(BTRFS_INODE_NO_XATTRS, &inode->runtime_flags)) in btrfs_log_all_xattrs()
5505 int slot = path->slots[0]; in btrfs_log_all_xattrs()
5506 struct extent_buffer *leaf = path->nodes[0]; in btrfs_log_all_xattrs()
5532 path->slots[0]++; in btrfs_log_all_xattrs()
5544 set_bit(BTRFS_INODE_NO_XATTRS, &inode->runtime_flags); in btrfs_log_all_xattrs()
5553 * any extents, because there are no leafs with a generation matching the
5562 struct btrfs_root *root = inode->root; in btrfs_log_holes()
5563 struct btrfs_fs_info *fs_info = root->fs_info; in btrfs_log_holes()
5566 const u64 i_size = i_size_read(&inode->vfs_inode); in btrfs_log_holes()
5582 struct extent_buffer *leaf = path->nodes[0]; in btrfs_log_holes()
5584 if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) { in btrfs_log_holes()
5592 leaf = path->nodes[0]; in btrfs_log_holes()
5595 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); in btrfs_log_holes()
5601 const u64 hole_len = key.offset - prev_extent_end; in btrfs_log_holes()
5609 ret = btrfs_insert_hole_extent(trans, root->log_root, in btrfs_log_holes()
5626 return -ENOENT; in btrfs_log_holes()
5627 leaf = path->nodes[0]; in btrfs_log_holes()
5631 path->slots[0]++; in btrfs_log_holes()
5639 hole_len = ALIGN(i_size - prev_extent_end, fs_info->sectorsize); in btrfs_log_holes()
5640 ret = btrfs_insert_hole_extent(trans, root->log_root, ino, in btrfs_log_holes()
5660 * xfs_io -c fsync /mnt/x
5672 * xfs_io -c fsync /mnt/foo
5707 return -ENOMEM; in btrfs_check_ref_name_override()
5708 search_path->search_commit_root = 1; in btrfs_check_ref_name_override()
5709 search_path->skip_locking = 1; in btrfs_check_ref_name_override()
5719 if (key->type == BTRFS_INODE_REF_KEY) { in btrfs_check_ref_name_override()
5723 parent = key->offset; in btrfs_check_ref_name_override()
5734 name_ptr = (unsigned long)&extref->name; in btrfs_check_ref_name_override()
5743 ret = -ENOMEM; in btrfs_check_ref_name_override()
5754 di = btrfs_lookup_dir_item(NULL, inode->root, search_path, in btrfs_check_ref_name_override()
5759 btrfs_dir_item_key_to_cpu(search_path->nodes[0], in btrfs_check_ref_name_override()
5762 if (di_key.objectid != key->objectid) { in btrfs_check_ref_name_override()
5770 ret = -EAGAIN; in btrfs_check_ref_name_override()
5792 * while here we do not care if the log transaction was already committed - our
5793 * caller will commit the log later - and we want to avoid logging an inode
5800 * If a directory was not modified, no dentries added or removed, we can in need_log_inode()
5803 if (S_ISDIR(inode->vfs_inode.i_mode) && inode->last_trans < trans->transid) in need_log_inode()
5816 !test_bit(BTRFS_INODE_COPY_EVERYTHING, &inode->runtime_flags)) in need_log_inode()
5830 * This is a recursive operation - if an existing dentry corresponds to a
5837 * ---- ----
5838 * lock(&type->i_mutex_dir_key#3/2);
5840 * lock(&type->i_mutex_dir_key#3/2);
5841 * lock(&sb->s_type->i_mutex_key#14);
5859 * names - this is ok, not a problem, because at log replay time we set the
5867 struct btrfs_root *root = start_inode->root; in log_new_dir_dentries()
5880 if (ctx->logging_new_name) in log_new_dir_dentries()
5885 return -ENOMEM; in log_new_dir_dentries()
5888 ihold(&curr_inode->vfs_inode); in log_new_dir_dentries()
5902 btrfs_for_each_slot(root->log_root, &key, &found_key, path, iter_ret) { in log_new_dir_dentries()
5903 struct extent_buffer *leaf = path->nodes[0]; in log_new_dir_dentries()
5918 di = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item); in log_new_dir_dentries()
5920 if (btrfs_dir_transid(leaf, di) < trans->transid) in log_new_dir_dentries()
5938 ctx->log_new_dentries = false; in log_new_dir_dentries()
5945 if (ctx->log_new_dentries) { in log_new_dir_dentries()
5948 ret = -ENOMEM; in log_new_dir_dentries()
5951 dir_elem->ino = di_key.objectid; in log_new_dir_dentries()
5952 list_add_tail(&dir_elem->list, &dir_list); in log_new_dir_dentries()
5968 if (continue_curr_inode && key.offset < (u64)-1) { in log_new_dir_dentries()
5979 ino = dir_elem->ino; in log_new_dir_dentries()
5980 list_del(&dir_elem->list); in log_new_dir_dentries()
6018 list_for_each_entry_safe(curr, next, &ctx->conflict_inodes, list) { in free_conflicting_inodes()
6019 list_del(&curr->list); in free_conflicting_inodes()
6034 path->search_commit_root = 1; in conflicting_inode_is_dir()
6035 path->skip_locking = 1; in conflicting_inode_is_dir()
6044 ret = -ENOENT; in conflicting_inode_is_dir()
6048 item = btrfs_item_ptr(path->nodes[0], path->slots[0], in conflicting_inode_is_dir()
6050 if (S_ISDIR(btrfs_inode_mode(path->nodes[0], item))) in conflicting_inode_is_dir()
6055 path->search_commit_root = 0; in conflicting_inode_is_dir()
6056 path->skip_locking = 0; in conflicting_inode_is_dir()
6077 if (ctx->num_conflict_inodes >= MAX_CONFLICT_INODES) in add_conflicting_inode()
6098 * case it has a last_unlink_trans == trans->transid, due to moving in add_conflicting_inode()
6104 if (ret != -ENOENT) in add_conflicting_inode()
6115 return -ENOMEM; in add_conflicting_inode()
6116 ino_elem->ino = ino; in add_conflicting_inode()
6117 ino_elem->parent = parent; in add_conflicting_inode()
6118 list_add_tail(&ino_elem->list, &ctx->conflict_inodes); in add_conflicting_inode()
6119 ctx->num_conflict_inodes++; in add_conflicting_inode()
6125 * If the inode was already logged skip it - otherwise we can hit an in add_conflicting_inode()
6145 * - we detect inode 258 as a conflicting inode, with inode 261 in add_conflicting_inode()
6148 * - we detect inode 259 as a conflicting inode, with inode 258 in add_conflicting_inode()
6151 * - we detect inode 258 as a conflicting inode, with inode 259 in add_conflicting_inode()
6152 * on reference "zz_link", and log it - again! After this we in add_conflicting_inode()
6168 return -ENOMEM; in add_conflicting_inode()
6169 ino_elem->ino = ino; in add_conflicting_inode()
6170 ino_elem->parent = parent; in add_conflicting_inode()
6171 list_add_tail(&ino_elem->list, &ctx->conflict_inodes); in add_conflicting_inode()
6172 ctx->num_conflict_inodes++; in add_conflicting_inode()
6188 if (ctx->logging_conflict_inodes) in log_conflicting_inodes()
6191 ctx->logging_conflict_inodes = true; in log_conflicting_inodes()
6198 while (!list_empty(&ctx->conflict_inodes)) { in log_conflicting_inodes()
6204 curr = list_first_entry(&ctx->conflict_inodes, in log_conflicting_inodes()
6206 ino = curr->ino; in log_conflicting_inodes()
6207 parent = curr->parent; in log_conflicting_inodes()
6208 list_del(&curr->list); in log_conflicting_inodes()
6219 if (ret != -ENOENT) in log_conflicting_inodes()
6271 ctx->logging_conflict_inodes = false; in log_conflicting_inodes()
6289 const u64 i_size = i_size_read(&inode->vfs_inode); in copy_inode_items_to_log()
6290 struct btrfs_root *root = inode->root; in copy_inode_items_to_log()
6296 ret = btrfs_search_forward(root, min_key, path, trans->transid); in copy_inode_items_to_log()
6305 if (min_key->objectid != max_key->objectid) in copy_inode_items_to_log()
6307 if (min_key->type > max_key->type) in copy_inode_items_to_log()
6310 if (min_key->type == BTRFS_INODE_ITEM_KEY) { in copy_inode_items_to_log()
6312 } else if (min_key->type == BTRFS_EXTENT_DATA_KEY && in copy_inode_items_to_log()
6313 min_key->offset >= i_size) { in copy_inode_items_to_log()
6318 * and no keys greater than that, so bail out. in copy_inode_items_to_log()
6321 } else if ((min_key->type == BTRFS_INODE_REF_KEY || in copy_inode_items_to_log()
6322 min_key->type == BTRFS_INODE_EXTREF_KEY) && in copy_inode_items_to_log()
6323 (inode->generation == trans->transid || in copy_inode_items_to_log()
6324 ctx->logging_conflict_inodes)) { in copy_inode_items_to_log()
6328 ret = btrfs_check_ref_name_override(path->nodes[0], in copy_inode_items_to_log()
6329 path->slots[0], min_key, inode, in copy_inode_items_to_log()
6334 other_ino != btrfs_ino(ctx->inode)) { in copy_inode_items_to_log()
6339 ins_start_slot = path->slots[0]; in copy_inode_items_to_log()
6356 } else if (min_key->type == BTRFS_XATTR_ITEM_KEY) { in copy_inode_items_to_log()
6369 if (ins_nr && ins_start_slot + ins_nr == path->slots[0]) { in copy_inode_items_to_log()
6373 ins_start_slot = path->slots[0]; in copy_inode_items_to_log()
6383 ins_start_slot = path->slots[0]; in copy_inode_items_to_log()
6385 path->slots[0]++; in copy_inode_items_to_log()
6386 if (path->slots[0] < btrfs_header_nritems(path->nodes[0])) { in copy_inode_items_to_log()
6387 btrfs_item_key_to_cpu(path->nodes[0], min_key, in copy_inode_items_to_log()
6388 path->slots[0]); in copy_inode_items_to_log()
6401 if (min_key->offset < (u64)-1) { in copy_inode_items_to_log()
6402 min_key->offset++; in copy_inode_items_to_log()
6403 } else if (min_key->type < max_key->type) { in copy_inode_items_to_log()
6404 min_key->type++; in copy_inode_items_to_log()
6405 min_key->offset = 0; in copy_inode_items_to_log()
6424 if (inode_only == LOG_INODE_ALL && S_ISREG(inode->vfs_inode.i_mode)) { in copy_inode_items_to_log()
6449 for (int i = 0; i < batch->nr; i++) { in insert_delayed_items_batch()
6452 data_ptr = btrfs_item_ptr(path->nodes[0], path->slots[0], char); in insert_delayed_items_batch()
6453 write_extent_buffer(path->nodes[0], &curr->data, in insert_delayed_items_batch()
6454 (unsigned long)data_ptr, curr->data_len); in insert_delayed_items_batch()
6456 path->slots[0]++; in insert_delayed_items_batch()
6472 const int leaf_data_size = BTRFS_LEAF_DATA_SIZE(trans->fs_info); in log_delayed_insertion_items()
6474 struct btrfs_root *log = inode->root->log_root; in log_delayed_insertion_items()
6489 lockdep_assert_held(&inode->log_mutex); in log_delayed_insertion_items()
6500 if (curr->index > inode->last_dir_index_offset) { in log_delayed_insertion_items()
6512 return -ENOMEM; in log_delayed_insertion_items()
6520 const u32 curr_size = curr->data_len + sizeof(struct btrfs_item); in log_delayed_insertion_items()
6535 ins_sizes[batch_idx] = curr->data_len; in log_delayed_insertion_items()
6538 ins_keys[batch_idx].offset = curr->index; in log_delayed_insertion_items()
6540 batch.total_data_size += curr->data_len; in log_delayed_insertion_items()
6551 inode->last_dir_index_offset = curr->index; in log_delayed_insertion_items()
6571 u64 first_dir_index = curr->index; in log_delayed_deletions_full()
6583 if (next->index != curr->index + 1) in log_delayed_deletions_full()
6589 last_dir_index = curr->index; in log_delayed_deletions_full()
6592 ret = insert_dir_log_key(trans, inode->root->log_root, path, in log_delayed_deletions_full()
6610 struct extent_buffer *leaf = path->nodes[0]; in batch_delete_dir_index_items()
6611 const int last_slot = btrfs_header_nritems(leaf) - 1; in batch_delete_dir_index_items()
6612 int slot = path->slots[0] + 1; in batch_delete_dir_index_items()
6624 key.offset != next->index) in batch_delete_dir_index_items()
6632 return btrfs_del_items(trans, inode->root->log_root, path, in batch_delete_dir_index_items()
6633 path->slots[0], slot - path->slots[0]); in batch_delete_dir_index_items()
6642 struct btrfs_root *log = inode->root->log_root; in log_delayed_deletions_incremental()
6655 u64 first_dir_index = curr->index; in log_delayed_deletions_incremental()
6660 key.offset = curr->index; in log_delayed_deletions_incremental()
6661 ret = btrfs_search_slot(trans, log, &key, path, -1, 1); in log_delayed_deletions_incremental()
6677 * item logging their range, so no need to add one or update an in log_delayed_deletions_incremental()
6683 last_dir_index = last->index; in log_delayed_deletions_incremental()
6718 lockdep_assert_held(&inode->log_mutex); in log_delayed_deletion_items()
6723 if (ctx->logged_before) in log_delayed_deletion_items()
6740 const bool orig_log_new_dentries = ctx->log_new_dentries; in log_new_delayed_dentries()
6745 * No need for the log mutex, plus to avoid potential deadlocks or in log_new_delayed_dentries()
6749 lockdep_assert_not_held(&inode->log_mutex); in log_new_delayed_dentries()
6751 ASSERT(!ctx->logging_new_delayed_dentries); in log_new_delayed_dentries()
6752 ctx->logging_new_delayed_dentries = true; in log_new_delayed_dentries()
6760 dir_item = (struct btrfs_dir_item *)item->data; in log_new_delayed_dentries()
6761 btrfs_disk_key_to_cpu(&key, &dir_item->location); in log_new_delayed_dentries()
6766 di_inode = btrfs_iget_logging(key.objectid, inode->root); in log_new_delayed_dentries()
6780 ctx->log_new_dentries = false; in log_new_delayed_dentries()
6783 if (!ret && ctx->log_new_dentries) in log_new_delayed_dentries()
6792 ctx->log_new_dentries = orig_log_new_dentries; in log_new_delayed_dentries()
6793 ctx->logging_new_delayed_dentries = false; in log_new_delayed_dentries()
6821 struct btrfs_root *log = inode->root->log_root; in btrfs_log_inode()
6825 struct extent_map_tree *em_tree = &inode->extent_tree; in btrfs_log_inode()
6836 return -ENOMEM; in btrfs_log_inode()
6840 return -ENOMEM; in btrfs_log_inode()
6851 if (S_ISDIR(inode->vfs_inode.i_mode) || in btrfs_log_inode()
6853 &inode->runtime_flags) && in btrfs_log_inode()
6857 max_key.type = (u8)-1; in btrfs_log_inode()
6858 max_key.offset = (u64)-1; in btrfs_log_inode()
6860 if (S_ISDIR(inode->vfs_inode.i_mode) && inode_only == LOG_INODE_ALL) in btrfs_log_inode()
6870 * $ mkdir -p a/b/c/d/e/f/g/h/... in btrfs_log_inode()
6871 * $ xfs_io -c "fsync" a in btrfs_log_inode()
6889 * memory, and once they are hit, the items are flushed asynchronously. in btrfs_log_inode()
6893 if (full_dir_logging && ctx->logging_new_delayed_dentries) { in btrfs_log_inode()
6899 mutex_lock(&inode->log_mutex); in btrfs_log_inode()
6904 * log replay, which is invalid on linux (symlink(2) returns -ENOENT if in btrfs_log_inode()
6910 if (S_ISLNK(inode->vfs_inode.i_mode)) in btrfs_log_inode()
6921 ctx->logged_before = (ret == 1); in btrfs_log_inode()
6927 * directory A to a directory B, then fsync directory A, we have no way in btrfs_log_inode()
6931 if (full_dir_logging && inode->last_unlink_trans >= trans->transid) { in btrfs_log_inode()
6940 if (S_ISDIR(inode->vfs_inode.i_mode)) { in btrfs_log_inode()
6941 clear_bit(BTRFS_INODE_COPY_EVERYTHING, &inode->runtime_flags); in btrfs_log_inode()
6942 if (ctx->logged_before) in btrfs_log_inode()
6946 if (inode_only == LOG_INODE_EXISTS && ctx->logged_before) { in btrfs_log_inode()
6952 * truncate - for e.g. create file, write 4K into offset in btrfs_log_inode()
6954 * fsync some other file (to sync log), power fail - if in btrfs_log_inode()
6965 &inode->runtime_flags)) { in btrfs_log_inode()
6968 if (ctx->logged_before) in btrfs_log_inode()
6973 &inode->runtime_flags); in btrfs_log_inode()
6975 &inode->runtime_flags); in btrfs_log_inode()
6976 if (ctx->logged_before) in btrfs_log_inode()
6981 &inode->runtime_flags) || in btrfs_log_inode()
6986 if (ctx->logged_before) in btrfs_log_inode()
7006 if (full_dir_logging && !ctx->logging_new_delayed_dentries) in btrfs_log_inode()
7017 if (inode->vfs_inode.i_nlink == 0) { in btrfs_log_inode()
7058 if (!xattrs_logged && inode->logged_trans < trans->transid) { in btrfs_log_inode()
7072 write_lock(&em_tree->lock); in btrfs_log_inode()
7073 list_for_each_entry_safe(em, n, &em_tree->modified_extents, list) in btrfs_log_inode()
7074 list_del_init(&em->list); in btrfs_log_inode()
7075 write_unlock(&em_tree->lock); in btrfs_log_inode()
7092 spin_lock(&inode->lock); in btrfs_log_inode()
7093 inode->logged_trans = trans->transid; in btrfs_log_inode()
7119 * its last_log_commit - otherwise if an explicit fsync is made in btrfs_log_inode()
7126 inode->last_log_commit = inode->last_sub_trans; in btrfs_log_inode()
7127 spin_unlock(&inode->lock); in btrfs_log_inode()
7134 inode->last_reflink_trans = 0; in btrfs_log_inode()
7137 mutex_unlock(&inode->log_mutex); in btrfs_log_inode()
7145 ret = log_conflicting_inodes(trans, inode->root, ctx); in btrfs_log_inode()
7147 if (full_dir_logging && !ctx->logging_new_delayed_dentries) { in btrfs_log_inode()
7166 struct btrfs_root *root = inode->root; in btrfs_log_all_parents()
7171 return -ENOMEM; in btrfs_log_all_parents()
7172 path->skip_locking = 1; in btrfs_log_all_parents()
7173 path->search_commit_root = 1; in btrfs_log_all_parents()
7183 struct extent_buffer *leaf = path->nodes[0]; in btrfs_log_all_parents()
7184 int slot = path->slots[0]; in btrfs_log_all_parents()
7242 * mv -T /mnt/A /mnt/B in btrfs_log_all_parents()
7259 ctx->log_new_dentries = false; in btrfs_log_all_parents()
7261 if (!ret && ctx->log_new_dentries) in btrfs_log_all_parents()
7267 path->slots[0]++; in btrfs_log_all_parents()
7279 btrfs_item_key_to_cpu(path->nodes[0], &found_key, path->slots[0]); in log_new_ancestors()
7300 if (inode->generation >= trans->transid && in log_new_ancestors()
7315 leaf = path->nodes[0]; in log_new_ancestors()
7316 slot = path->slots[0]; in log_new_ancestors()
7322 return -ENOENT; in log_new_ancestors()
7323 leaf = path->nodes[0]; in log_new_ancestors()
7324 slot = path->slots[0]; in log_new_ancestors()
7330 return -ENOENT; in log_new_ancestors()
7340 struct btrfs_root *root = inode->root; in log_new_ancestors_fast()
7342 struct super_block *sb = inode->vfs_inode.i_sb; in log_new_ancestors_fast()
7347 sb != parent->d_sb) in log_new_ancestors_fast()
7351 if (root != inode->root) in log_new_ancestors_fast()
7354 if (inode->generation >= trans->transid && in log_new_ancestors_fast()
7378 struct btrfs_root *root = inode->root; in log_all_new_ancestors()
7388 if (inode->vfs_inode.i_nlink < 2) in log_all_new_ancestors()
7393 return -ENOMEM; in log_all_new_ancestors()
7403 path->slots[0]++; in log_all_new_ancestors()
7406 struct extent_buffer *leaf = path->nodes[0]; in log_all_new_ancestors()
7407 int slot = path->slots[0]; in log_all_new_ancestors()
7432 return -EMLINK; in log_all_new_ancestors()
7463 struct btrfs_root *root = inode->root; in btrfs_log_inode_parent()
7464 struct btrfs_fs_info *fs_info = root->fs_info; in btrfs_log_inode_parent()
7471 if (btrfs_root_refs(&root->root_item) == 0) in btrfs_log_inode_parent()
7478 if (btrfs_root_generation(&root->root_item) == trans->transid) in btrfs_log_inode_parent()
7482 if (btrfs_inode_in_log(inode, trans->transid) && in btrfs_log_inode_parent()
7483 list_empty(&ctx->ordered_extents)) in btrfs_log_inode_parent()
7500 if (S_ISREG(inode->vfs_inode.i_mode) && in btrfs_log_inode_parent()
7501 inode->generation < trans->transid && in btrfs_log_inode_parent()
7502 inode->last_unlink_trans < trans->transid) { in btrfs_log_inode_parent()
7508 * Track if we need to log dentries because ctx->log_new_dentries can in btrfs_log_inode_parent()
7511 log_dentries = ctx->log_new_dentries; in btrfs_log_inode_parent()
7519 * error -ENOTEMPTY). in btrfs_log_inode_parent()
7528 * xfs_io -c fsync testdir/foo in btrfs_log_inode_parent()
7545 * xfs_io -c fsync foo in btrfs_log_inode_parent()
7554 if (inode->last_unlink_trans >= trans->transid) { in btrfs_log_inode_parent()
7609 struct btrfs_fs_info *fs_info = log_root_tree->fs_info; in btrfs_recover_log_trees()
7610 struct walk_control wc = { in btrfs_recover_log_trees() local
7617 return -ENOMEM; in btrfs_recover_log_trees()
7619 set_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags); in btrfs_recover_log_trees()
7621 trans = btrfs_start_transaction(fs_info->tree_root, 0); in btrfs_recover_log_trees()
7627 wc.trans = trans; in btrfs_recover_log_trees()
7628 wc.pin = true; in btrfs_recover_log_trees()
7629 wc.log = log_root_tree; in btrfs_recover_log_trees()
7631 ret = walk_log_tree(&wc); in btrfs_recover_log_trees()
7632 wc.log = NULL; in btrfs_recover_log_trees()
7641 key.offset = (u64)-1; in btrfs_recover_log_trees()
7653 if (path->slots[0] == 0) in btrfs_recover_log_trees()
7655 path->slots[0]--; in btrfs_recover_log_trees()
7657 btrfs_item_key_to_cpu(path->nodes[0], &found_key, in btrfs_recover_log_trees()
7658 path->slots[0]); in btrfs_recover_log_trees()
7663 wc.log = btrfs_read_tree_root(log_root_tree, &found_key); in btrfs_recover_log_trees()
7664 if (IS_ERR(wc.log)) { in btrfs_recover_log_trees()
7665 ret = PTR_ERR(wc.log); in btrfs_recover_log_trees()
7666 wc.log = NULL; in btrfs_recover_log_trees()
7671 wc.root = btrfs_get_fs_root(fs_info, found_key.offset, true); in btrfs_recover_log_trees()
7672 if (IS_ERR(wc.root)) { in btrfs_recover_log_trees()
7673 ret = PTR_ERR(wc.root); in btrfs_recover_log_trees()
7674 wc.root = NULL; in btrfs_recover_log_trees()
7675 if (unlikely(ret != -ENOENT)) { in btrfs_recover_log_trees()
7691 ret = btrfs_pin_extent_for_log_replay(trans, wc.log->node); in btrfs_recover_log_trees()
7699 wc.root->log_root = wc.log; in btrfs_recover_log_trees()
7700 ret = btrfs_record_root_in_trans(trans, wc.root); in btrfs_recover_log_trees()
7706 ret = walk_log_tree(&wc); in btrfs_recover_log_trees()
7712 if (wc.stage == LOG_WALK_REPLAY_ALL) { in btrfs_recover_log_trees()
7713 struct btrfs_root *root = wc.root; in btrfs_recover_log_trees()
7715 wc.subvol_path = path; in btrfs_recover_log_trees()
7716 ret = fixup_inode_link_counts(&wc); in btrfs_recover_log_trees()
7717 wc.subvol_path = NULL; in btrfs_recover_log_trees()
7727 * root->objectid_mutex is not acquired as log replay in btrfs_recover_log_trees()
7737 if (wc.root) { in btrfs_recover_log_trees()
7738 wc.root->log_root = NULL; in btrfs_recover_log_trees()
7739 btrfs_put_root(wc.root); in btrfs_recover_log_trees()
7741 btrfs_put_root(wc.log); in btrfs_recover_log_trees()
7742 wc.log = NULL; in btrfs_recover_log_trees()
7748 key.offset = found_key.offset - 1; in btrfs_recover_log_trees()
7753 if (wc.pin) { in btrfs_recover_log_trees()
7754 wc.pin = false; in btrfs_recover_log_trees()
7755 wc.process_func = replay_one_buffer; in btrfs_recover_log_trees()
7756 wc.stage = LOG_WALK_REPLAY_INODES; in btrfs_recover_log_trees()
7760 if (wc.stage < LOG_WALK_REPLAY_ALL) { in btrfs_recover_log_trees()
7761 wc.stage++; in btrfs_recover_log_trees()
7772 clear_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags); in btrfs_recover_log_trees()
7776 if (wc.trans) in btrfs_recover_log_trees()
7777 btrfs_end_transaction(wc.trans); in btrfs_recover_log_trees()
7778 btrfs_put_root(wc.log); in btrfs_recover_log_trees()
7779 clear_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags); in btrfs_recover_log_trees()
7809 mutex_lock(&inode->log_mutex); in btrfs_record_unlink_dir()
7810 inode->last_unlink_trans = trans->transid; in btrfs_record_unlink_dir()
7811 mutex_unlock(&inode->log_mutex); in btrfs_record_unlink_dir()
7837 * no way to find the destination directory later and fsync it in btrfs_record_unlink_dir()
7841 mutex_lock(&dir->log_mutex); in btrfs_record_unlink_dir()
7842 dir->last_unlink_trans = trans->transid; in btrfs_record_unlink_dir()
7843 mutex_unlock(&dir->log_mutex); in btrfs_record_unlink_dir()
7861 mutex_lock(&dir->log_mutex); in btrfs_record_snapshot_destroy()
7862 dir->last_unlink_trans = trans->transid; in btrfs_record_snapshot_destroy()
7863 mutex_unlock(&dir->log_mutex); in btrfs_record_snapshot_destroy()
7881 mutex_lock(&dir->log_mutex); in btrfs_record_new_subvolume()
7882 dir->last_unlink_trans = trans->transid; in btrfs_record_new_subvolume()
7883 mutex_unlock(&dir->log_mutex); in btrfs_record_new_subvolume()
7908 struct btrfs_root *root = inode->root; in btrfs_log_new_name()
7920 if (!S_ISDIR(inode->vfs_inode.i_mode)) in btrfs_log_new_name()
7921 inode->last_unlink_trans = trans->transid; in btrfs_log_new_name()
7935 * NULL), check if old_dir was logged - if it was not we can return and in btrfs_log_new_name()
7960 if (old_dir && old_dir->logged_trans == trans->transid) { in btrfs_log_new_name()
7961 struct btrfs_root *log = old_dir->root->log_root; in btrfs_log_new_name()
7967 ret = fscrypt_setup_filename(&old_dir->vfs_inode, in btrfs_log_new_name()
7968 &old_dentry->d_name, 0, &fname); in btrfs_log_new_name()
7974 ret = -ENOMEM; in btrfs_log_new_name()
8009 mutex_lock(&old_dir->log_mutex); in btrfs_log_new_name()
8022 mutex_unlock(&old_dir->log_mutex); in btrfs_log_new_name()