Lines Matching refs:sctx

276 static int is_waiting_for_move(struct send_ctx *sctx, u64 ino);
279 get_waiting_dir_move(struct send_ctx *sctx, u64 ino);
281 static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino);
283 static int need_send_hole(struct send_ctx *sctx) in need_send_hole() argument
285 return (sctx->parent_root && !sctx->cur_inode_new && in need_send_hole()
286 !sctx->cur_inode_new_gen && !sctx->cur_inode_deleted && in need_send_hole()
287 S_ISREG(sctx->cur_inode_mode)); in need_send_hole()
542 static int tlv_put(struct send_ctx *sctx, u16 attr, const void *data, int len) in tlv_put() argument
546 int left = sctx->send_max_size - sctx->send_size; in tlv_put()
551 hdr = (struct btrfs_tlv_header *) (sctx->send_buf + sctx->send_size); in tlv_put()
555 sctx->send_size += total_len; in tlv_put()
561 static int tlv_put_u##bits(struct send_ctx *sctx, \
565 return tlv_put(sctx, attr, &__tmp, sizeof(__tmp)); \
570 static int tlv_put_string(struct send_ctx *sctx, u16 attr, in tlv_put_string() argument
575 return tlv_put(sctx, attr, str, len); in tlv_put_string()
578 static int tlv_put_uuid(struct send_ctx *sctx, u16 attr, in tlv_put_uuid() argument
581 return tlv_put(sctx, attr, uuid, BTRFS_UUID_SIZE); in tlv_put_uuid()
584 static int tlv_put_btrfs_timespec(struct send_ctx *sctx, u16 attr, in tlv_put_btrfs_timespec() argument
590 return tlv_put(sctx, attr, &bts, sizeof(bts)); in tlv_put_btrfs_timespec()
594 #define TLV_PUT(sctx, attrtype, attrlen, data) \ argument
596 ret = tlv_put(sctx, attrtype, attrlen, data); \
601 #define TLV_PUT_INT(sctx, attrtype, bits, value) \ argument
603 ret = tlv_put_u##bits(sctx, attrtype, value); \
608 #define TLV_PUT_U8(sctx, attrtype, data) TLV_PUT_INT(sctx, attrtype, 8, data) argument
609 #define TLV_PUT_U16(sctx, attrtype, data) TLV_PUT_INT(sctx, attrtype, 16, data) argument
610 #define TLV_PUT_U32(sctx, attrtype, data) TLV_PUT_INT(sctx, attrtype, 32, data) argument
611 #define TLV_PUT_U64(sctx, attrtype, data) TLV_PUT_INT(sctx, attrtype, 64, data) argument
612 #define TLV_PUT_STRING(sctx, attrtype, str, len) \ argument
614 ret = tlv_put_string(sctx, attrtype, str, len); \
618 #define TLV_PUT_PATH(sctx, attrtype, p) \ argument
620 ret = tlv_put_string(sctx, attrtype, p->start, \
625 #define TLV_PUT_UUID(sctx, attrtype, uuid) \ argument
627 ret = tlv_put_uuid(sctx, attrtype, uuid); \
631 #define TLV_PUT_BTRFS_TIMESPEC(sctx, attrtype, eb, ts) \ argument
633 ret = tlv_put_btrfs_timespec(sctx, attrtype, eb, ts); \
638 static int send_header(struct send_ctx *sctx) in send_header() argument
645 return write_buf(sctx->send_filp, &hdr, sizeof(hdr), in send_header()
646 &sctx->send_off); in send_header()
652 static int begin_cmd(struct send_ctx *sctx, int cmd) in begin_cmd() argument
656 if (WARN_ON(!sctx->send_buf)) in begin_cmd()
659 BUG_ON(sctx->send_size); in begin_cmd()
661 sctx->send_size += sizeof(*hdr); in begin_cmd()
662 hdr = (struct btrfs_cmd_header *)sctx->send_buf; in begin_cmd()
668 static int send_cmd(struct send_ctx *sctx) in send_cmd() argument
674 hdr = (struct btrfs_cmd_header *)sctx->send_buf; in send_cmd()
675 hdr->len = cpu_to_le32(sctx->send_size - sizeof(*hdr)); in send_cmd()
678 crc = btrfs_crc32c(0, (unsigned char *)sctx->send_buf, sctx->send_size); in send_cmd()
681 ret = write_buf(sctx->send_filp, sctx->send_buf, sctx->send_size, in send_cmd()
682 &sctx->send_off); in send_cmd()
684 sctx->total_send_size += sctx->send_size; in send_cmd()
685 sctx->cmd_send_size[le16_to_cpu(hdr->cmd)] += sctx->send_size; in send_cmd()
686 sctx->send_size = 0; in send_cmd()
694 static int send_rename(struct send_ctx *sctx, in send_rename() argument
701 ret = begin_cmd(sctx, BTRFS_SEND_C_RENAME); in send_rename()
705 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, from); in send_rename()
706 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_TO, to); in send_rename()
708 ret = send_cmd(sctx); in send_rename()
718 static int send_link(struct send_ctx *sctx, in send_link() argument
725 ret = begin_cmd(sctx, BTRFS_SEND_C_LINK); in send_link()
729 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path); in send_link()
730 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_LINK, lnk); in send_link()
732 ret = send_cmd(sctx); in send_link()
742 static int send_unlink(struct send_ctx *sctx, struct fs_path *path) in send_unlink() argument
748 ret = begin_cmd(sctx, BTRFS_SEND_C_UNLINK); in send_unlink()
752 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path); in send_unlink()
754 ret = send_cmd(sctx); in send_unlink()
764 static int send_rmdir(struct send_ctx *sctx, struct fs_path *path) in send_rmdir() argument
770 ret = begin_cmd(sctx, BTRFS_SEND_C_RMDIR); in send_rmdir()
774 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path); in send_rmdir()
776 ret = send_cmd(sctx); in send_rmdir()
1146 struct send_ctx *sctx; member
1205 found = bsearch((void *)(uintptr_t)root, bctx->sctx->clone_roots, in __iterate_backrefs()
1206 bctx->sctx->clone_roots_cnt, in __iterate_backrefs()
1212 if (found->root == bctx->sctx->send_root && in __iterate_backrefs()
1235 if (found->root == bctx->sctx->send_root) { in __iterate_backrefs()
1277 static int find_extent_clone(struct send_ctx *sctx, in find_extent_clone() argument
1341 down_read(&sctx->send_root->fs_info->commit_root_sem); in find_extent_clone()
1342 ret = extent_from_logical(sctx->send_root->fs_info, disk_byte, tmp_path, in find_extent_clone()
1344 up_read(&sctx->send_root->fs_info->commit_root_sem); in find_extent_clone()
1357 for (i = 0; i < sctx->clone_roots_cnt; i++) { in find_extent_clone()
1358 cur_clone_root = sctx->clone_roots + i; in find_extent_clone()
1364 backref_ctx->sctx = sctx; in find_extent_clone()
1399 ret = iterate_extent_inodes(sctx->send_root->fs_info, in find_extent_clone()
1409 btrfs_err(sctx->send_root->fs_info, "did not find backref in " in find_extent_clone()
1425 for (i = 0; i < sctx->clone_roots_cnt; i++) { in find_extent_clone()
1426 if (sctx->clone_roots[i].found_refs) { in find_extent_clone()
1428 cur_clone_root = sctx->clone_roots + i; in find_extent_clone()
1429 else if (sctx->clone_roots[i].root == sctx->send_root) in find_extent_clone()
1431 cur_clone_root = sctx->clone_roots + i; in find_extent_clone()
1509 static int gen_unique_name(struct send_ctx *sctx, in gen_unique_name() argument
1529 di = btrfs_lookup_dir_item(NULL, sctx->send_root, in gen_unique_name()
1543 if (!sctx->parent_root) { in gen_unique_name()
1549 di = btrfs_lookup_dir_item(NULL, sctx->parent_root, in gen_unique_name()
1581 static int get_cur_inode_state(struct send_ctx *sctx, u64 ino, u64 gen) in get_cur_inode_state() argument
1589 ret = get_inode_info(sctx->send_root, ino, NULL, &left_gen, NULL, NULL, in get_cur_inode_state()
1595 if (!sctx->parent_root) { in get_cur_inode_state()
1598 ret = get_inode_info(sctx->parent_root, ino, NULL, &right_gen, in get_cur_inode_state()
1609 if (ino < sctx->send_progress) in get_cur_inode_state()
1614 if (ino < sctx->send_progress) in get_cur_inode_state()
1623 if (ino < sctx->send_progress) in get_cur_inode_state()
1632 if (ino < sctx->send_progress) in get_cur_inode_state()
1647 static int is_inode_existent(struct send_ctx *sctx, u64 ino, u64 gen) in is_inode_existent() argument
1651 ret = get_cur_inode_state(sctx, ino, gen); in is_inode_existent()
1815 static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen, in will_overwrite_ref() argument
1824 if (!sctx->parent_root) in will_overwrite_ref()
1827 ret = is_inode_existent(sctx, dir, dir_gen); in will_overwrite_ref()
1836 if (sctx->parent_root) { in will_overwrite_ref()
1837 ret = get_inode_info(sctx->parent_root, dir, NULL, &gen, NULL, in will_overwrite_ref()
1849 ret = lookup_dir_item_inode(sctx->parent_root, dir, name, name_len, in will_overwrite_ref()
1863 if (other_inode > sctx->send_progress) { in will_overwrite_ref()
1864 ret = get_inode_info(sctx->parent_root, other_inode, NULL, in will_overwrite_ref()
1886 static int did_overwrite_ref(struct send_ctx *sctx, in did_overwrite_ref() argument
1896 if (!sctx->parent_root) in did_overwrite_ref()
1899 ret = is_inode_existent(sctx, dir, dir_gen); in did_overwrite_ref()
1904 ret = lookup_dir_item_inode(sctx->send_root, dir, name, name_len, in did_overwrite_ref()
1914 ret = get_inode_info(sctx->send_root, ow_inode, NULL, &gen, NULL, NULL, in did_overwrite_ref()
1930 if ((ow_inode < sctx->send_progress) || in did_overwrite_ref()
1931 (ino != sctx->cur_ino && ow_inode == sctx->cur_ino && in did_overwrite_ref()
1932 gen == sctx->cur_inode_gen)) in did_overwrite_ref()
1946 static int did_overwrite_first_ref(struct send_ctx *sctx, u64 ino, u64 gen) in did_overwrite_first_ref() argument
1953 if (!sctx->parent_root) in did_overwrite_first_ref()
1960 ret = get_first_ref(sctx->parent_root, ino, &dir, &dir_gen, name); in did_overwrite_first_ref()
1964 ret = did_overwrite_ref(sctx, dir, dir_gen, ino, gen, in did_overwrite_first_ref()
1978 static int name_cache_insert(struct send_ctx *sctx, in name_cache_insert() argument
1984 nce_head = radix_tree_lookup(&sctx->name_cache, in name_cache_insert()
1994 ret = radix_tree_insert(&sctx->name_cache, nce->ino, nce_head); in name_cache_insert()
2002 list_add_tail(&nce->list, &sctx->name_cache_list); in name_cache_insert()
2003 sctx->name_cache_size++; in name_cache_insert()
2008 static void name_cache_delete(struct send_ctx *sctx, in name_cache_delete() argument
2013 nce_head = radix_tree_lookup(&sctx->name_cache, in name_cache_delete()
2016 btrfs_err(sctx->send_root->fs_info, in name_cache_delete()
2018 nce->ino, sctx->name_cache_size); in name_cache_delete()
2023 sctx->name_cache_size--; in name_cache_delete()
2029 radix_tree_delete(&sctx->name_cache, (unsigned long)nce->ino); in name_cache_delete()
2034 static struct name_cache_entry *name_cache_search(struct send_ctx *sctx, in name_cache_search() argument
2040 nce_head = radix_tree_lookup(&sctx->name_cache, (unsigned long)ino); in name_cache_search()
2055 static void name_cache_used(struct send_ctx *sctx, struct name_cache_entry *nce) in name_cache_used() argument
2058 list_add_tail(&nce->list, &sctx->name_cache_list); in name_cache_used()
2064 static void name_cache_clean_unused(struct send_ctx *sctx) in name_cache_clean_unused() argument
2068 if (sctx->name_cache_size < SEND_CTX_NAME_CACHE_CLEAN_SIZE) in name_cache_clean_unused()
2071 while (sctx->name_cache_size > SEND_CTX_MAX_NAME_CACHE_SIZE) { in name_cache_clean_unused()
2072 nce = list_entry(sctx->name_cache_list.next, in name_cache_clean_unused()
2074 name_cache_delete(sctx, nce); in name_cache_clean_unused()
2079 static void name_cache_free(struct send_ctx *sctx) in name_cache_free() argument
2083 while (!list_empty(&sctx->name_cache_list)) { in name_cache_free()
2084 nce = list_entry(sctx->name_cache_list.next, in name_cache_free()
2086 name_cache_delete(sctx, nce); in name_cache_free()
2099 static int __get_cur_name_and_parent(struct send_ctx *sctx, in __get_cur_name_and_parent() argument
2114 nce = name_cache_search(sctx, ino, gen); in __get_cur_name_and_parent()
2116 if (ino < sctx->send_progress && nce->need_later_update) { in __get_cur_name_and_parent()
2117 name_cache_delete(sctx, nce); in __get_cur_name_and_parent()
2121 name_cache_used(sctx, nce); in __get_cur_name_and_parent()
2137 ret = is_inode_existent(sctx, ino, gen); in __get_cur_name_and_parent()
2142 ret = gen_unique_name(sctx, ino, gen, dest); in __get_cur_name_and_parent()
2153 if (ino < sctx->send_progress) in __get_cur_name_and_parent()
2154 ret = get_first_ref(sctx->send_root, ino, in __get_cur_name_and_parent()
2157 ret = get_first_ref(sctx->parent_root, ino, in __get_cur_name_and_parent()
2166 ret = did_overwrite_ref(sctx, *parent_ino, *parent_gen, ino, gen, in __get_cur_name_and_parent()
2172 ret = gen_unique_name(sctx, ino, gen, dest); in __get_cur_name_and_parent()
2196 if (ino < sctx->send_progress) in __get_cur_name_and_parent()
2201 nce_ret = name_cache_insert(sctx, nce); in __get_cur_name_and_parent()
2204 name_cache_clean_unused(sctx); in __get_cur_name_and_parent()
2235 static int get_cur_path(struct send_ctx *sctx, u64 ino, u64 gen, in get_cur_path() argument
2258 if (is_waiting_for_rm(sctx, ino)) { in get_cur_path()
2259 ret = gen_unique_name(sctx, ino, gen, name); in get_cur_path()
2266 wdm = get_waiting_dir_move(sctx, ino); in get_cur_path()
2268 ret = gen_unique_name(sctx, ino, gen, name); in get_cur_path()
2271 ret = get_first_ref(sctx->parent_root, ino, in get_cur_path()
2274 ret = __get_cur_name_and_parent(sctx, ino, gen, in get_cur_path()
2302 static int send_subvol_begin(struct send_ctx *sctx) in send_subvol_begin() argument
2305 struct btrfs_root *send_root = sctx->send_root; in send_subvol_begin()
2306 struct btrfs_root *parent_root = sctx->parent_root; in send_subvol_begin()
2350 ret = begin_cmd(sctx, BTRFS_SEND_C_SNAPSHOT); in send_subvol_begin()
2354 ret = begin_cmd(sctx, BTRFS_SEND_C_SUBVOL); in send_subvol_begin()
2359 TLV_PUT_STRING(sctx, BTRFS_SEND_A_PATH, name, namelen); in send_subvol_begin()
2361 if (!btrfs_is_empty_uuid(sctx->send_root->root_item.received_uuid)) in send_subvol_begin()
2362 TLV_PUT_UUID(sctx, BTRFS_SEND_A_UUID, in send_subvol_begin()
2363 sctx->send_root->root_item.received_uuid); in send_subvol_begin()
2365 TLV_PUT_UUID(sctx, BTRFS_SEND_A_UUID, in send_subvol_begin()
2366 sctx->send_root->root_item.uuid); in send_subvol_begin()
2368 TLV_PUT_U64(sctx, BTRFS_SEND_A_CTRANSID, in send_subvol_begin()
2369 le64_to_cpu(sctx->send_root->root_item.ctransid)); in send_subvol_begin()
2372 TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID, in send_subvol_begin()
2375 TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID, in send_subvol_begin()
2377 TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_CTRANSID, in send_subvol_begin()
2378 le64_to_cpu(sctx->parent_root->root_item.ctransid)); in send_subvol_begin()
2381 ret = send_cmd(sctx); in send_subvol_begin()
2390 static int send_truncate(struct send_ctx *sctx, u64 ino, u64 gen, u64 size) in send_truncate() argument
2401 ret = begin_cmd(sctx, BTRFS_SEND_C_TRUNCATE); in send_truncate()
2405 ret = get_cur_path(sctx, ino, gen, p); in send_truncate()
2408 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_truncate()
2409 TLV_PUT_U64(sctx, BTRFS_SEND_A_SIZE, size); in send_truncate()
2411 ret = send_cmd(sctx); in send_truncate()
2419 static int send_chmod(struct send_ctx *sctx, u64 ino, u64 gen, u64 mode) in send_chmod() argument
2430 ret = begin_cmd(sctx, BTRFS_SEND_C_CHMOD); in send_chmod()
2434 ret = get_cur_path(sctx, ino, gen, p); in send_chmod()
2437 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_chmod()
2438 TLV_PUT_U64(sctx, BTRFS_SEND_A_MODE, mode & 07777); in send_chmod()
2440 ret = send_cmd(sctx); in send_chmod()
2448 static int send_chown(struct send_ctx *sctx, u64 ino, u64 gen, u64 uid, u64 gid) in send_chown() argument
2459 ret = begin_cmd(sctx, BTRFS_SEND_C_CHOWN); in send_chown()
2463 ret = get_cur_path(sctx, ino, gen, p); in send_chown()
2466 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_chown()
2467 TLV_PUT_U64(sctx, BTRFS_SEND_A_UID, uid); in send_chown()
2468 TLV_PUT_U64(sctx, BTRFS_SEND_A_GID, gid); in send_chown()
2470 ret = send_cmd(sctx); in send_chown()
2478 static int send_utimes(struct send_ctx *sctx, u64 ino, u64 gen) in send_utimes() argument
2503 ret = btrfs_search_slot(NULL, sctx->send_root, &key, path, 0, 0); in send_utimes()
2511 ret = begin_cmd(sctx, BTRFS_SEND_C_UTIMES); in send_utimes()
2515 ret = get_cur_path(sctx, ino, gen, p); in send_utimes()
2518 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_utimes()
2519 TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_ATIME, eb, &ii->atime); in send_utimes()
2520 TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_MTIME, eb, &ii->mtime); in send_utimes()
2521 TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_CTIME, eb, &ii->ctime); in send_utimes()
2524 ret = send_cmd(sctx); in send_utimes()
2538 static int send_create_inode(struct send_ctx *sctx, u64 ino) in send_create_inode() argument
2553 if (ino != sctx->cur_ino) { in send_create_inode()
2554 ret = get_inode_info(sctx->send_root, ino, NULL, &gen, &mode, in send_create_inode()
2559 gen = sctx->cur_inode_gen; in send_create_inode()
2560 mode = sctx->cur_inode_mode; in send_create_inode()
2561 rdev = sctx->cur_inode_rdev; in send_create_inode()
2577 btrfs_warn(sctx->send_root->fs_info, "unexpected inode type %o", in send_create_inode()
2583 ret = begin_cmd(sctx, cmd); in send_create_inode()
2587 ret = gen_unique_name(sctx, ino, gen, p); in send_create_inode()
2591 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_create_inode()
2592 TLV_PUT_U64(sctx, BTRFS_SEND_A_INO, ino); in send_create_inode()
2596 ret = read_symlink(sctx->send_root, ino, p); in send_create_inode()
2599 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_LINK, p); in send_create_inode()
2602 TLV_PUT_U64(sctx, BTRFS_SEND_A_RDEV, new_encode_dev(rdev)); in send_create_inode()
2603 TLV_PUT_U64(sctx, BTRFS_SEND_A_MODE, mode); in send_create_inode()
2606 ret = send_cmd(sctx); in send_create_inode()
2622 static int did_create_dir(struct send_ctx *sctx, u64 dir) in did_create_dir() argument
2642 ret = btrfs_search_slot(NULL, sctx->send_root, &key, path, 0, 0); in did_create_dir()
2650 ret = btrfs_next_leaf(sctx->send_root, path); in did_create_dir()
2671 di_key.objectid < sctx->send_progress) { in did_create_dir()
2690 static int send_create_inode_if_needed(struct send_ctx *sctx) in send_create_inode_if_needed() argument
2694 if (S_ISDIR(sctx->cur_inode_mode)) { in send_create_inode_if_needed()
2695 ret = did_create_dir(sctx, sctx->cur_ino); in send_create_inode_if_needed()
2704 ret = send_create_inode(sctx, sctx->cur_ino); in send_create_inode_if_needed()
2782 static void free_recorded_refs(struct send_ctx *sctx) in free_recorded_refs() argument
2784 __free_recorded_refs(&sctx->new_refs); in free_recorded_refs()
2785 __free_recorded_refs(&sctx->deleted_refs); in free_recorded_refs()
2793 static int orphanize_inode(struct send_ctx *sctx, u64 ino, u64 gen, in orphanize_inode() argument
2803 ret = gen_unique_name(sctx, ino, gen, orphan); in orphanize_inode()
2807 ret = send_rename(sctx, path, orphan); in orphanize_inode()
2815 add_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino) in add_orphan_dir_info() argument
2817 struct rb_node **p = &sctx->orphan_dirs.rb_node; in add_orphan_dir_info()
2841 rb_insert_color(&odi->node, &sctx->orphan_dirs); in add_orphan_dir_info()
2846 get_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino) in get_orphan_dir_info() argument
2848 struct rb_node *n = sctx->orphan_dirs.rb_node; in get_orphan_dir_info()
2863 static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino) in is_waiting_for_rm() argument
2865 struct orphan_dir_info *odi = get_orphan_dir_info(sctx, dir_ino); in is_waiting_for_rm()
2870 static void free_orphan_dir_info(struct send_ctx *sctx, in free_orphan_dir_info() argument
2875 rb_erase(&odi->node, &sctx->orphan_dirs); in free_orphan_dir_info()
2884 static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 dir_gen, in can_rmdir() argument
2888 struct btrfs_root *root = sctx->parent_root; in can_rmdir()
2933 dm = get_waiting_dir_move(sctx, loc.objectid); in can_rmdir()
2937 odi = add_orphan_dir_info(sctx, dir); in can_rmdir()
2963 static int is_waiting_for_move(struct send_ctx *sctx, u64 ino) in is_waiting_for_move() argument
2965 struct waiting_dir_move *entry = get_waiting_dir_move(sctx, ino); in is_waiting_for_move()
2970 static int add_waiting_dir_move(struct send_ctx *sctx, u64 ino, bool orphanized) in add_waiting_dir_move() argument
2972 struct rb_node **p = &sctx->waiting_dir_moves.rb_node; in add_waiting_dir_move()
2997 rb_insert_color(&dm->node, &sctx->waiting_dir_moves); in add_waiting_dir_move()
3002 get_waiting_dir_move(struct send_ctx *sctx, u64 ino) in get_waiting_dir_move() argument
3004 struct rb_node *n = sctx->waiting_dir_moves.rb_node; in get_waiting_dir_move()
3019 static void free_waiting_dir_move(struct send_ctx *sctx, in free_waiting_dir_move() argument
3024 rb_erase(&dm->node, &sctx->waiting_dir_moves); in free_waiting_dir_move()
3028 static int add_pending_dir_move(struct send_ctx *sctx, in add_pending_dir_move() argument
3036 struct rb_node **p = &sctx->pending_dir_moves.rb_node; in add_pending_dir_move()
3078 ret = add_waiting_dir_move(sctx, pm->ino, is_orphan); in add_pending_dir_move()
3086 rb_insert_color(&pm->node, &sctx->pending_dir_moves); in add_pending_dir_move()
3097 static struct pending_dir_move *get_pending_dir_moves(struct send_ctx *sctx, in get_pending_dir_moves() argument
3100 struct rb_node *n = sctx->pending_dir_moves.rb_node; in get_pending_dir_moves()
3115 static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) in apply_dir_move() argument
3120 u64 orig_progress = sctx->send_progress; in apply_dir_move()
3134 dm = get_waiting_dir_move(sctx, pm->ino); in apply_dir_move()
3137 free_waiting_dir_move(sctx, dm); in apply_dir_move()
3140 ret = gen_unique_name(sctx, pm->ino, in apply_dir_move()
3143 ret = get_first_ref(sctx->parent_root, pm->ino, in apply_dir_move()
3147 ret = get_cur_path(sctx, parent_ino, parent_gen, in apply_dir_move()
3156 sctx->send_progress = sctx->cur_ino + 1; in apply_dir_move()
3160 ret = get_cur_path(sctx, pm->ino, pm->gen, to_path); in apply_dir_move()
3164 ret = send_rename(sctx, from_path, to_path); in apply_dir_move()
3171 odi = get_orphan_dir_info(sctx, rmdir_ino); in apply_dir_move()
3176 ret = can_rmdir(sctx, rmdir_ino, odi->gen, sctx->cur_ino + 1); in apply_dir_move()
3187 ret = get_cur_path(sctx, rmdir_ino, odi->gen, name); in apply_dir_move()
3190 ret = send_rmdir(sctx, name); in apply_dir_move()
3193 free_orphan_dir_info(sctx, odi); in apply_dir_move()
3197 ret = send_utimes(sctx, pm->ino, pm->gen); in apply_dir_move()
3208 ret = send_utimes(sctx, cur->dir, cur->dir_gen); in apply_dir_move()
3217 sctx->send_progress = orig_progress; in apply_dir_move()
3222 static void free_pending_move(struct send_ctx *sctx, struct pending_dir_move *m) in free_pending_move() argument
3227 rb_erase(&m->node, &sctx->pending_dir_moves); in free_pending_move()
3245 static int apply_children_dir_moves(struct send_ctx *sctx) in apply_children_dir_moves() argument
3249 u64 parent_ino = sctx->cur_ino; in apply_children_dir_moves()
3252 pm = get_pending_dir_moves(sctx, parent_ino); in apply_children_dir_moves()
3262 ret = apply_dir_move(sctx, pm); in apply_children_dir_moves()
3263 free_pending_move(sctx, pm); in apply_children_dir_moves()
3266 pm = get_pending_dir_moves(sctx, parent_ino); in apply_children_dir_moves()
3275 free_pending_move(sctx, pm); in apply_children_dir_moves()
3316 static int wait_for_dest_dir_move(struct send_ctx *sctx, in wait_for_dest_dir_move() argument
3328 if (RB_EMPTY_ROOT(&sctx->waiting_dir_moves)) in wait_for_dest_dir_move()
3339 ret = btrfs_search_slot(NULL, sctx->parent_root, &key, path, 0, 0); in wait_for_dest_dir_move()
3347 di = btrfs_match_dir_item_name(sctx->parent_root, path, in wait_for_dest_dir_move()
3367 ret = get_inode_info(sctx->parent_root, di_key.objectid, NULL, in wait_for_dest_dir_move()
3371 ret = get_inode_info(sctx->send_root, di_key.objectid, NULL, in wait_for_dest_dir_move()
3385 if (is_waiting_for_move(sctx, di_key.objectid)) { in wait_for_dest_dir_move()
3386 ret = add_pending_dir_move(sctx, in wait_for_dest_dir_move()
3387 sctx->cur_ino, in wait_for_dest_dir_move()
3388 sctx->cur_inode_gen, in wait_for_dest_dir_move()
3390 &sctx->new_refs, in wait_for_dest_dir_move()
3391 &sctx->deleted_refs, in wait_for_dest_dir_move()
3432 static int wait_for_parent_move(struct send_ctx *sctx, in wait_for_parent_move() argument
3458 if (is_waiting_for_move(sctx, ino)) { in wait_for_parent_move()
3469 ret = is_ancestor(sctx->parent_root, in wait_for_parent_move()
3470 sctx->cur_ino, sctx->cur_inode_gen, in wait_for_parent_move()
3478 ret = get_first_ref(sctx->send_root, ino, &parent_ino_after, in wait_for_parent_move()
3482 ret = get_first_ref(sctx->parent_root, ino, &parent_ino_before, in wait_for_parent_move()
3493 if (ino > sctx->cur_ino && in wait_for_parent_move()
3507 ret = add_pending_dir_move(sctx, in wait_for_parent_move()
3508 sctx->cur_ino, in wait_for_parent_move()
3509 sctx->cur_inode_gen, in wait_for_parent_move()
3511 &sctx->new_refs, in wait_for_parent_move()
3512 &sctx->deleted_refs, in wait_for_parent_move()
3524 static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) in process_recorded_refs() argument
3538 verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); in process_recorded_refs()
3544 BUG_ON(sctx->cur_ino <= BTRFS_FIRST_FREE_OBJECTID); in process_recorded_refs()
3564 if (!sctx->cur_inode_new) { in process_recorded_refs()
3565 ret = did_overwrite_first_ref(sctx, sctx->cur_ino, in process_recorded_refs()
3566 sctx->cur_inode_gen); in process_recorded_refs()
3572 if (sctx->cur_inode_new || did_overwrite) { in process_recorded_refs()
3573 ret = gen_unique_name(sctx, sctx->cur_ino, in process_recorded_refs()
3574 sctx->cur_inode_gen, valid_path); in process_recorded_refs()
3579 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, in process_recorded_refs()
3585 list_for_each_entry(cur, &sctx->new_refs, list) { in process_recorded_refs()
3593 ret = get_cur_inode_state(sctx, cur->dir, cur->dir_gen); in process_recorded_refs()
3602 list_for_each_entry(cur2, &sctx->new_refs, list) { in process_recorded_refs()
3616 ret = did_create_dir(sctx, cur->dir); in process_recorded_refs()
3620 ret = send_create_inode(sctx, cur->dir); in process_recorded_refs()
3632 ret = will_overwrite_ref(sctx, cur->dir, cur->dir_gen, in process_recorded_refs()
3638 ret = is_first_ref(sctx->parent_root, in process_recorded_refs()
3646 ret = orphanize_inode(sctx, ow_inode, ow_gen, in process_recorded_refs()
3660 nce = name_cache_search(sctx, ow_inode, ow_gen); in process_recorded_refs()
3662 name_cache_delete(sctx, nce); in process_recorded_refs()
3666 ret = send_unlink(sctx, cur->full_path); in process_recorded_refs()
3672 if (S_ISDIR(sctx->cur_inode_mode) && sctx->parent_root) { in process_recorded_refs()
3673 ret = wait_for_dest_dir_move(sctx, cur, is_orphan); in process_recorded_refs()
3682 if (S_ISDIR(sctx->cur_inode_mode) && sctx->parent_root && in process_recorded_refs()
3684 ret = wait_for_parent_move(sctx, cur, is_orphan); in process_recorded_refs()
3699 ret = send_rename(sctx, valid_path, cur->full_path); in process_recorded_refs()
3707 if (S_ISDIR(sctx->cur_inode_mode)) { in process_recorded_refs()
3713 ret = send_rename(sctx, valid_path, in process_recorded_refs()
3721 ret = send_link(sctx, cur->full_path, in process_recorded_refs()
3732 if (S_ISDIR(sctx->cur_inode_mode) && sctx->cur_inode_deleted) { in process_recorded_refs()
3739 ret = can_rmdir(sctx, sctx->cur_ino, sctx->cur_inode_gen, in process_recorded_refs()
3740 sctx->cur_ino); in process_recorded_refs()
3744 ret = send_rmdir(sctx, valid_path); in process_recorded_refs()
3748 ret = orphanize_inode(sctx, sctx->cur_ino, in process_recorded_refs()
3749 sctx->cur_inode_gen, valid_path); in process_recorded_refs()
3755 list_for_each_entry(cur, &sctx->deleted_refs, list) { in process_recorded_refs()
3760 } else if (S_ISDIR(sctx->cur_inode_mode) && in process_recorded_refs()
3761 !list_empty(&sctx->deleted_refs)) { in process_recorded_refs()
3765 cur = list_entry(sctx->deleted_refs.next, struct recorded_ref, in process_recorded_refs()
3770 } else if (!S_ISDIR(sctx->cur_inode_mode)) { in process_recorded_refs()
3776 list_for_each_entry(cur, &sctx->deleted_refs, list) { in process_recorded_refs()
3777 ret = did_overwrite_ref(sctx, cur->dir, cur->dir_gen, in process_recorded_refs()
3778 sctx->cur_ino, sctx->cur_inode_gen, in process_recorded_refs()
3783 ret = send_unlink(sctx, cur->full_path); in process_recorded_refs()
3800 ret = send_unlink(sctx, valid_path); in process_recorded_refs()
3818 if (cur->dir > sctx->cur_ino) in process_recorded_refs()
3821 ret = get_cur_inode_state(sctx, cur->dir, cur->dir_gen); in process_recorded_refs()
3828 ret = send_utimes(sctx, cur->dir, cur->dir_gen); in process_recorded_refs()
3833 ret = can_rmdir(sctx, cur->dir, cur->dir_gen, in process_recorded_refs()
3834 sctx->cur_ino); in process_recorded_refs()
3838 ret = get_cur_path(sctx, cur->dir, in process_recorded_refs()
3842 ret = send_rmdir(sctx, valid_path); in process_recorded_refs()
3854 free_recorded_refs(sctx); in process_recorded_refs()
3863 struct send_ctx *sctx = ctx; in record_ref() local
3876 ret = get_cur_path(sctx, dir, gen, p); in record_ref()
3895 struct send_ctx *sctx = ctx; in __record_new_ref() local
3896 return record_ref(sctx->send_root, num, dir, index, name, in __record_new_ref()
3897 ctx, &sctx->new_refs); in __record_new_ref()
3905 struct send_ctx *sctx = ctx; in __record_deleted_ref() local
3906 return record_ref(sctx->parent_root, num, dir, index, name, in __record_deleted_ref()
3907 ctx, &sctx->deleted_refs); in __record_deleted_ref()
3910 static int record_new_ref(struct send_ctx *sctx) in record_new_ref() argument
3914 ret = iterate_inode_ref(sctx->send_root, sctx->left_path, in record_new_ref()
3915 sctx->cmp_key, 0, __record_new_ref, sctx); in record_new_ref()
3924 static int record_deleted_ref(struct send_ctx *sctx) in record_deleted_ref() argument
3928 ret = iterate_inode_ref(sctx->parent_root, sctx->right_path, in record_deleted_ref()
3929 sctx->cmp_key, 0, __record_deleted_ref, sctx); in record_deleted_ref()
4002 struct send_ctx *sctx = ctx; in __record_changed_new_ref() local
4004 ret = get_inode_info(sctx->send_root, dir, NULL, &dir_gen, NULL, in __record_changed_new_ref()
4009 ret = find_iref(sctx->parent_root, sctx->right_path, in __record_changed_new_ref()
4010 sctx->cmp_key, dir, dir_gen, name); in __record_changed_new_ref()
4012 ret = __record_new_ref(num, dir, index, name, sctx); in __record_changed_new_ref()
4025 struct send_ctx *sctx = ctx; in __record_changed_deleted_ref() local
4027 ret = get_inode_info(sctx->parent_root, dir, NULL, &dir_gen, NULL, in __record_changed_deleted_ref()
4032 ret = find_iref(sctx->send_root, sctx->left_path, sctx->cmp_key, in __record_changed_deleted_ref()
4035 ret = __record_deleted_ref(num, dir, index, name, sctx); in __record_changed_deleted_ref()
4042 static int record_changed_ref(struct send_ctx *sctx) in record_changed_ref() argument
4046 ret = iterate_inode_ref(sctx->send_root, sctx->left_path, in record_changed_ref()
4047 sctx->cmp_key, 0, __record_changed_new_ref, sctx); in record_changed_ref()
4050 ret = iterate_inode_ref(sctx->parent_root, sctx->right_path, in record_changed_ref()
4051 sctx->cmp_key, 0, __record_changed_deleted_ref, sctx); in record_changed_ref()
4064 static int process_all_refs(struct send_ctx *sctx, in process_all_refs() argument
4082 root = sctx->send_root; in process_all_refs()
4085 root = sctx->parent_root; in process_all_refs()
4088 btrfs_err(sctx->send_root->fs_info, in process_all_refs()
4094 key.objectid = sctx->cmp_key->objectid; in process_all_refs()
4120 ret = iterate_inode_ref(root, path, &found_key, 0, cb, sctx); in process_all_refs()
4128 ret = process_recorded_refs(sctx, &pending_move); in process_all_refs()
4137 static int send_set_xattr(struct send_ctx *sctx, in send_set_xattr() argument
4144 ret = begin_cmd(sctx, BTRFS_SEND_C_SET_XATTR); in send_set_xattr()
4148 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path); in send_set_xattr()
4149 TLV_PUT_STRING(sctx, BTRFS_SEND_A_XATTR_NAME, name, name_len); in send_set_xattr()
4150 TLV_PUT(sctx, BTRFS_SEND_A_XATTR_DATA, data, data_len); in send_set_xattr()
4152 ret = send_cmd(sctx); in send_set_xattr()
4159 static int send_remove_xattr(struct send_ctx *sctx, in send_remove_xattr() argument
4165 ret = begin_cmd(sctx, BTRFS_SEND_C_REMOVE_XATTR); in send_remove_xattr()
4169 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path); in send_remove_xattr()
4170 TLV_PUT_STRING(sctx, BTRFS_SEND_A_XATTR_NAME, name, name_len); in send_remove_xattr()
4172 ret = send_cmd(sctx); in send_remove_xattr()
4185 struct send_ctx *sctx = ctx; in __process_new_xattr() local
4209 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in __process_new_xattr()
4213 ret = send_set_xattr(sctx, p, name, name_len, data, data_len); in __process_new_xattr()
4226 struct send_ctx *sctx = ctx; in __process_deleted_xattr() local
4233 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in __process_deleted_xattr()
4237 ret = send_remove_xattr(sctx, p, name, name_len); in __process_deleted_xattr()
4244 static int process_new_xattr(struct send_ctx *sctx) in process_new_xattr() argument
4248 ret = iterate_dir_item(sctx->send_root, sctx->left_path, in process_new_xattr()
4249 sctx->cmp_key, __process_new_xattr, sctx); in process_new_xattr()
4254 static int process_deleted_xattr(struct send_ctx *sctx) in process_deleted_xattr() argument
4258 ret = iterate_dir_item(sctx->parent_root, sctx->right_path, in process_deleted_xattr()
4259 sctx->cmp_key, __process_deleted_xattr, sctx); in process_deleted_xattr()
4328 struct send_ctx *sctx = ctx; in __process_changed_new_xattr() local
4332 ret = find_xattr(sctx->parent_root, sctx->right_path, in __process_changed_new_xattr()
4333 sctx->cmp_key, name, name_len, &found_data, in __process_changed_new_xattr()
4358 struct send_ctx *sctx = ctx; in __process_changed_deleted_xattr() local
4360 ret = find_xattr(sctx->send_root, sctx->left_path, sctx->cmp_key, in __process_changed_deleted_xattr()
4371 static int process_changed_xattr(struct send_ctx *sctx) in process_changed_xattr() argument
4375 ret = iterate_dir_item(sctx->send_root, sctx->left_path, in process_changed_xattr()
4376 sctx->cmp_key, __process_changed_new_xattr, sctx); in process_changed_xattr()
4379 ret = iterate_dir_item(sctx->parent_root, sctx->right_path, in process_changed_xattr()
4380 sctx->cmp_key, __process_changed_deleted_xattr, sctx); in process_changed_xattr()
4386 static int process_all_new_xattrs(struct send_ctx *sctx) in process_all_new_xattrs() argument
4400 root = sctx->send_root; in process_all_new_xattrs()
4402 key.objectid = sctx->cmp_key->objectid; in process_all_new_xattrs()
4431 __process_new_xattr, sctx); in process_all_new_xattrs()
4443 static ssize_t fill_read_buf(struct send_ctx *sctx, u64 offset, u32 len) in fill_read_buf() argument
4445 struct btrfs_root *root = sctx->send_root; in fill_read_buf()
4456 key.objectid = sctx->cur_ino; in fill_read_buf()
4476 memset(&sctx->ra, 0, sizeof(struct file_ra_state)); in fill_read_buf()
4477 file_ra_state_init(&sctx->ra, inode->i_mapping); in fill_read_buf()
4478 btrfs_force_ra(inode->i_mapping, &sctx->ra, NULL, index, in fill_read_buf()
4502 memcpy(sctx->read_buf + ret, addr + pg_offset, cur_len); in fill_read_buf()
4520 static int send_write(struct send_ctx *sctx, u64 offset, u32 len) in send_write() argument
4532 num_read = fill_read_buf(sctx, offset, len); in send_write()
4539 ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE); in send_write()
4543 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in send_write()
4547 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_write()
4548 TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset); in send_write()
4549 TLV_PUT(sctx, BTRFS_SEND_A_DATA, sctx->read_buf, num_read); in send_write()
4551 ret = send_cmd(sctx); in send_write()
4564 static int send_clone(struct send_ctx *sctx, in send_clone() argument
4581 ret = begin_cmd(sctx, BTRFS_SEND_C_CLONE); in send_clone()
4585 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in send_clone()
4589 TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset); in send_clone()
4590 TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_LEN, len); in send_clone()
4591 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_clone()
4593 if (clone_root->root == sctx->send_root) { in send_clone()
4594 ret = get_inode_info(sctx->send_root, clone_root->ino, NULL, in send_clone()
4598 ret = get_cur_path(sctx, clone_root->ino, gen, p); in send_clone()
4615 TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID, in send_clone()
4618 TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID, in send_clone()
4620 TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_CTRANSID, in send_clone()
4622 TLV_PUT_PATH(sctx, BTRFS_SEND_A_CLONE_PATH, p); in send_clone()
4623 TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_OFFSET, in send_clone()
4626 ret = send_cmd(sctx); in send_clone()
4637 static int send_update_extent(struct send_ctx *sctx, in send_update_extent() argument
4647 ret = begin_cmd(sctx, BTRFS_SEND_C_UPDATE_EXTENT); in send_update_extent()
4651 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in send_update_extent()
4655 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_update_extent()
4656 TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset); in send_update_extent()
4657 TLV_PUT_U64(sctx, BTRFS_SEND_A_SIZE, len); in send_update_extent()
4659 ret = send_cmd(sctx); in send_update_extent()
4667 static int send_hole(struct send_ctx *sctx, u64 end) in send_hole() argument
4670 u64 offset = sctx->cur_inode_last_extent; in send_hole()
4677 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in send_hole()
4680 memset(sctx->read_buf, 0, BTRFS_SEND_READ_SIZE); in send_hole()
4684 ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE); in send_hole()
4687 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_hole()
4688 TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset); in send_hole()
4689 TLV_PUT(sctx, BTRFS_SEND_A_DATA, sctx->read_buf, len); in send_hole()
4690 ret = send_cmd(sctx); in send_hole()
4700 static int send_extent_data(struct send_ctx *sctx, in send_extent_data() argument
4706 if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA) in send_extent_data()
4707 return send_update_extent(sctx, offset, len); in send_extent_data()
4715 ret = send_write(sctx, offset + sent, size); in send_extent_data()
4725 static int clone_range(struct send_ctx *sctx, in clone_range() argument
4820 ret = send_extent_data(sctx, offset, hole_len); in clone_range()
4839 ret = send_clone(sctx, offset, clone_len, clone_root); in clone_range()
4841 ret = send_extent_data(sctx, offset, clone_len); in clone_range()
4857 ret = send_extent_data(sctx, offset, len); in clone_range()
4865 static int send_write_or_clone(struct send_ctx *sctx, in send_write_or_clone() argument
4875 u64 bs = sctx->send_root->fs_info->sb->s_blocksize; in send_write_or_clone()
4893 if (offset + len > sctx->cur_inode_size) in send_write_or_clone()
4894 len = sctx->cur_inode_size - offset; in send_write_or_clone()
4906 ret = clone_range(sctx, clone_root, disk_byte, data_offset, in send_write_or_clone()
4909 ret = send_extent_data(sctx, offset, len); in send_write_or_clone()
4915 static int is_extent_unchanged(struct send_ctx *sctx, in is_extent_unchanged() argument
4980 ret = btrfs_search_slot_for_read(sctx->parent_root, &key, path, 0, 0); in is_extent_unchanged()
5050 ret = btrfs_next_item(sctx->parent_root, path); in is_extent_unchanged()
5085 static int get_last_extent(struct send_ctx *sctx, u64 offset) in get_last_extent() argument
5088 struct btrfs_root *root = sctx->send_root; in get_last_extent()
5099 sctx->cur_inode_last_extent = 0; in get_last_extent()
5101 key.objectid = sctx->cur_ino; in get_last_extent()
5109 if (key.objectid != sctx->cur_ino || key.type != BTRFS_EXTENT_DATA_KEY) in get_last_extent()
5119 sctx->send_root->sectorsize); in get_last_extent()
5124 sctx->cur_inode_last_extent = extent_end; in get_last_extent()
5130 static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path, in maybe_send_hole() argument
5138 if (sctx->cur_ino != key->objectid || !need_send_hole(sctx)) in maybe_send_hole()
5141 if (sctx->cur_inode_last_extent == (u64)-1) { in maybe_send_hole()
5142 ret = get_last_extent(sctx, key->offset - 1); in maybe_send_hole()
5154 sctx->send_root->sectorsize); in maybe_send_hole()
5161 sctx->cur_inode_last_extent < key->offset) { in maybe_send_hole()
5169 ret = get_last_extent(sctx, key->offset - 1); in maybe_send_hole()
5174 if (sctx->cur_inode_last_extent < key->offset) in maybe_send_hole()
5175 ret = send_hole(sctx, key->offset); in maybe_send_hole()
5176 sctx->cur_inode_last_extent = extent_end; in maybe_send_hole()
5180 static int process_extent(struct send_ctx *sctx, in process_extent() argument
5187 if (S_ISLNK(sctx->cur_inode_mode)) in process_extent()
5190 if (sctx->parent_root && !sctx->cur_inode_new) { in process_extent()
5191 ret = is_extent_unchanged(sctx, path, key); in process_extent()
5226 ret = find_extent_clone(sctx, path, key->objectid, key->offset, in process_extent()
5227 sctx->cur_inode_size, &found_clone); in process_extent()
5231 ret = send_write_or_clone(sctx, path, key, found_clone); in process_extent()
5235 ret = maybe_send_hole(sctx, path, key); in process_extent()
5240 static int process_all_extents(struct send_ctx *sctx) in process_all_extents() argument
5250 root = sctx->send_root; in process_all_extents()
5255 key.objectid = sctx->cmp_key->objectid; in process_all_extents()
5285 ret = process_extent(sctx, path, &found_key); in process_all_extents()
5297 static int process_recorded_refs_if_needed(struct send_ctx *sctx, int at_end, in process_recorded_refs_if_needed() argument
5303 if (sctx->cur_ino == 0) in process_recorded_refs_if_needed()
5305 if (!at_end && sctx->cur_ino == sctx->cmp_key->objectid && in process_recorded_refs_if_needed()
5306 sctx->cmp_key->type <= BTRFS_INODE_EXTREF_KEY) in process_recorded_refs_if_needed()
5308 if (list_empty(&sctx->new_refs) && list_empty(&sctx->deleted_refs)) in process_recorded_refs_if_needed()
5311 ret = process_recorded_refs(sctx, pending_move); in process_recorded_refs_if_needed()
5320 static int finish_inode_if_needed(struct send_ctx *sctx, int at_end) in finish_inode_if_needed() argument
5334 ret = process_recorded_refs_if_needed(sctx, at_end, &pending_move, in finish_inode_if_needed()
5352 sctx->send_progress = sctx->cur_ino + 1; in finish_inode_if_needed()
5354 if (sctx->cur_ino == 0 || sctx->cur_inode_deleted) in finish_inode_if_needed()
5356 if (!at_end && sctx->cmp_key->objectid == sctx->cur_ino) in finish_inode_if_needed()
5359 ret = get_inode_info(sctx->send_root, sctx->cur_ino, NULL, NULL, in finish_inode_if_needed()
5364 if (!sctx->parent_root || sctx->cur_inode_new) { in finish_inode_if_needed()
5366 if (!S_ISLNK(sctx->cur_inode_mode)) in finish_inode_if_needed()
5369 ret = get_inode_info(sctx->parent_root, sctx->cur_ino, in finish_inode_if_needed()
5377 if (!S_ISLNK(sctx->cur_inode_mode) && left_mode != right_mode) in finish_inode_if_needed()
5381 if (S_ISREG(sctx->cur_inode_mode)) { in finish_inode_if_needed()
5382 if (need_send_hole(sctx)) { in finish_inode_if_needed()
5383 if (sctx->cur_inode_last_extent == (u64)-1 || in finish_inode_if_needed()
5384 sctx->cur_inode_last_extent < in finish_inode_if_needed()
5385 sctx->cur_inode_size) { in finish_inode_if_needed()
5386 ret = get_last_extent(sctx, (u64)-1); in finish_inode_if_needed()
5390 if (sctx->cur_inode_last_extent < in finish_inode_if_needed()
5391 sctx->cur_inode_size) { in finish_inode_if_needed()
5392 ret = send_hole(sctx, sctx->cur_inode_size); in finish_inode_if_needed()
5397 ret = send_truncate(sctx, sctx->cur_ino, sctx->cur_inode_gen, in finish_inode_if_needed()
5398 sctx->cur_inode_size); in finish_inode_if_needed()
5404 ret = send_chown(sctx, sctx->cur_ino, sctx->cur_inode_gen, in finish_inode_if_needed()
5410 ret = send_chmod(sctx, sctx->cur_ino, sctx->cur_inode_gen, in finish_inode_if_needed()
5420 if (!is_waiting_for_move(sctx, sctx->cur_ino)) { in finish_inode_if_needed()
5421 ret = apply_children_dir_moves(sctx); in finish_inode_if_needed()
5431 sctx->send_progress = sctx->cur_ino + 1; in finish_inode_if_needed()
5432 ret = send_utimes(sctx, sctx->cur_ino, sctx->cur_inode_gen); in finish_inode_if_needed()
5441 static int changed_inode(struct send_ctx *sctx, in changed_inode() argument
5445 struct btrfs_key *key = sctx->cmp_key; in changed_inode()
5451 sctx->cur_ino = key->objectid; in changed_inode()
5452 sctx->cur_inode_new_gen = 0; in changed_inode()
5453 sctx->cur_inode_last_extent = (u64)-1; in changed_inode()
5460 sctx->send_progress = sctx->cur_ino; in changed_inode()
5464 left_ii = btrfs_item_ptr(sctx->left_path->nodes[0], in changed_inode()
5465 sctx->left_path->slots[0], in changed_inode()
5467 left_gen = btrfs_inode_generation(sctx->left_path->nodes[0], in changed_inode()
5470 right_ii = btrfs_item_ptr(sctx->right_path->nodes[0], in changed_inode()
5471 sctx->right_path->slots[0], in changed_inode()
5473 right_gen = btrfs_inode_generation(sctx->right_path->nodes[0], in changed_inode()
5477 right_ii = btrfs_item_ptr(sctx->right_path->nodes[0], in changed_inode()
5478 sctx->right_path->slots[0], in changed_inode()
5481 right_gen = btrfs_inode_generation(sctx->right_path->nodes[0], in changed_inode()
5490 sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID) in changed_inode()
5491 sctx->cur_inode_new_gen = 1; in changed_inode()
5495 sctx->cur_inode_gen = left_gen; in changed_inode()
5496 sctx->cur_inode_new = 1; in changed_inode()
5497 sctx->cur_inode_deleted = 0; in changed_inode()
5498 sctx->cur_inode_size = btrfs_inode_size( in changed_inode()
5499 sctx->left_path->nodes[0], left_ii); in changed_inode()
5500 sctx->cur_inode_mode = btrfs_inode_mode( in changed_inode()
5501 sctx->left_path->nodes[0], left_ii); in changed_inode()
5502 sctx->cur_inode_rdev = btrfs_inode_rdev( in changed_inode()
5503 sctx->left_path->nodes[0], left_ii); in changed_inode()
5504 if (sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID) in changed_inode()
5505 ret = send_create_inode_if_needed(sctx); in changed_inode()
5507 sctx->cur_inode_gen = right_gen; in changed_inode()
5508 sctx->cur_inode_new = 0; in changed_inode()
5509 sctx->cur_inode_deleted = 1; in changed_inode()
5510 sctx->cur_inode_size = btrfs_inode_size( in changed_inode()
5511 sctx->right_path->nodes[0], right_ii); in changed_inode()
5512 sctx->cur_inode_mode = btrfs_inode_mode( in changed_inode()
5513 sctx->right_path->nodes[0], right_ii); in changed_inode()
5522 if (sctx->cur_inode_new_gen) { in changed_inode()
5526 sctx->cur_inode_gen = right_gen; in changed_inode()
5527 sctx->cur_inode_new = 0; in changed_inode()
5528 sctx->cur_inode_deleted = 1; in changed_inode()
5529 sctx->cur_inode_size = btrfs_inode_size( in changed_inode()
5530 sctx->right_path->nodes[0], right_ii); in changed_inode()
5531 sctx->cur_inode_mode = btrfs_inode_mode( in changed_inode()
5532 sctx->right_path->nodes[0], right_ii); in changed_inode()
5533 ret = process_all_refs(sctx, in changed_inode()
5541 sctx->cur_inode_gen = left_gen; in changed_inode()
5542 sctx->cur_inode_new = 1; in changed_inode()
5543 sctx->cur_inode_deleted = 0; in changed_inode()
5544 sctx->cur_inode_size = btrfs_inode_size( in changed_inode()
5545 sctx->left_path->nodes[0], left_ii); in changed_inode()
5546 sctx->cur_inode_mode = btrfs_inode_mode( in changed_inode()
5547 sctx->left_path->nodes[0], left_ii); in changed_inode()
5548 sctx->cur_inode_rdev = btrfs_inode_rdev( in changed_inode()
5549 sctx->left_path->nodes[0], left_ii); in changed_inode()
5550 ret = send_create_inode_if_needed(sctx); in changed_inode()
5554 ret = process_all_refs(sctx, BTRFS_COMPARE_TREE_NEW); in changed_inode()
5561 sctx->send_progress = sctx->cur_ino + 1; in changed_inode()
5567 ret = process_all_extents(sctx); in changed_inode()
5570 ret = process_all_new_xattrs(sctx); in changed_inode()
5574 sctx->cur_inode_gen = left_gen; in changed_inode()
5575 sctx->cur_inode_new = 0; in changed_inode()
5576 sctx->cur_inode_new_gen = 0; in changed_inode()
5577 sctx->cur_inode_deleted = 0; in changed_inode()
5578 sctx->cur_inode_size = btrfs_inode_size( in changed_inode()
5579 sctx->left_path->nodes[0], left_ii); in changed_inode()
5580 sctx->cur_inode_mode = btrfs_inode_mode( in changed_inode()
5581 sctx->left_path->nodes[0], left_ii); in changed_inode()
5599 static int changed_ref(struct send_ctx *sctx, in changed_ref() argument
5604 BUG_ON(sctx->cur_ino != sctx->cmp_key->objectid); in changed_ref()
5606 if (!sctx->cur_inode_new_gen && in changed_ref()
5607 sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID) { in changed_ref()
5609 ret = record_new_ref(sctx); in changed_ref()
5611 ret = record_deleted_ref(sctx); in changed_ref()
5613 ret = record_changed_ref(sctx); in changed_ref()
5624 static int changed_xattr(struct send_ctx *sctx, in changed_xattr() argument
5629 BUG_ON(sctx->cur_ino != sctx->cmp_key->objectid); in changed_xattr()
5631 if (!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted) { in changed_xattr()
5633 ret = process_new_xattr(sctx); in changed_xattr()
5635 ret = process_deleted_xattr(sctx); in changed_xattr()
5637 ret = process_changed_xattr(sctx); in changed_xattr()
5648 static int changed_extent(struct send_ctx *sctx, in changed_extent() argument
5653 BUG_ON(sctx->cur_ino != sctx->cmp_key->objectid); in changed_extent()
5655 if (!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted) { in changed_extent()
5657 ret = process_extent(sctx, sctx->left_path, in changed_extent()
5658 sctx->cmp_key); in changed_extent()
5664 static int dir_changed(struct send_ctx *sctx, u64 dir) in dir_changed() argument
5669 ret = get_inode_info(sctx->send_root, dir, NULL, &new_gen, NULL, NULL, in dir_changed()
5674 ret = get_inode_info(sctx->parent_root, dir, NULL, &orig_gen, NULL, in dir_changed()
5682 static int compare_refs(struct send_ctx *sctx, struct btrfs_path *path, in compare_refs() argument
5698 ret = dir_changed(sctx, dirid); in compare_refs()
5713 ret = dir_changed(sctx, dirid); in compare_refs()
5735 struct send_ctx *sctx = ctx; in changed_cb() local
5740 ret = compare_refs(sctx, left_path, key); in changed_cb()
5746 return maybe_send_hole(sctx, left_path, key); in changed_cb()
5754 sctx->left_path = left_path; in changed_cb()
5755 sctx->right_path = right_path; in changed_cb()
5756 sctx->cmp_key = key; in changed_cb()
5758 ret = finish_inode_if_needed(sctx, 0); in changed_cb()
5768 ret = changed_inode(sctx, result); in changed_cb()
5771 ret = changed_ref(sctx, result); in changed_cb()
5773 ret = changed_xattr(sctx, result); in changed_cb()
5775 ret = changed_extent(sctx, result); in changed_cb()
5781 static int full_send_tree(struct send_ctx *sctx) in full_send_tree() argument
5784 struct btrfs_root *send_root = sctx->send_root; in full_send_tree()
5811 &found_key, BTRFS_COMPARE_TREE_NEW, sctx); in full_send_tree()
5829 ret = finish_inode_if_needed(sctx, 1); in full_send_tree()
5836 static int send_subvol(struct send_ctx *sctx) in send_subvol() argument
5840 if (!(sctx->flags & BTRFS_SEND_FLAG_OMIT_STREAM_HEADER)) { in send_subvol()
5841 ret = send_header(sctx); in send_subvol()
5846 ret = send_subvol_begin(sctx); in send_subvol()
5850 if (sctx->parent_root) { in send_subvol()
5851 ret = btrfs_compare_trees(sctx->send_root, sctx->parent_root, in send_subvol()
5852 changed_cb, sctx); in send_subvol()
5855 ret = finish_inode_if_needed(sctx, 1); in send_subvol()
5859 ret = full_send_tree(sctx); in send_subvol()
5865 free_recorded_refs(sctx); in send_subvol()
5882 static int ensure_commit_roots_uptodate(struct send_ctx *sctx) in ensure_commit_roots_uptodate() argument
5888 if (sctx->parent_root && in ensure_commit_roots_uptodate()
5889 sctx->parent_root->node != sctx->parent_root->commit_root) in ensure_commit_roots_uptodate()
5892 for (i = 0; i < sctx->clone_roots_cnt; i++) in ensure_commit_roots_uptodate()
5893 if (sctx->clone_roots[i].root->node != in ensure_commit_roots_uptodate()
5894 sctx->clone_roots[i].root->commit_root) in ensure_commit_roots_uptodate()
5898 return btrfs_end_transaction(trans, sctx->send_root); in ensure_commit_roots_uptodate()
5905 trans = btrfs_join_transaction(sctx->send_root); in ensure_commit_roots_uptodate()
5911 return btrfs_commit_transaction(trans, sctx->send_root); in ensure_commit_roots_uptodate()
5937 struct send_ctx *sctx = NULL; in btrfs_ioctl_send() local
5992 sctx = kzalloc(sizeof(struct send_ctx), GFP_NOFS); in btrfs_ioctl_send()
5993 if (!sctx) { in btrfs_ioctl_send()
5998 INIT_LIST_HEAD(&sctx->new_refs); in btrfs_ioctl_send()
5999 INIT_LIST_HEAD(&sctx->deleted_refs); in btrfs_ioctl_send()
6000 INIT_RADIX_TREE(&sctx->name_cache, GFP_NOFS); in btrfs_ioctl_send()
6001 INIT_LIST_HEAD(&sctx->name_cache_list); in btrfs_ioctl_send()
6003 sctx->flags = arg->flags; in btrfs_ioctl_send()
6005 sctx->send_filp = fget(arg->send_fd); in btrfs_ioctl_send()
6006 if (!sctx->send_filp) { in btrfs_ioctl_send()
6011 sctx->send_root = send_root; in btrfs_ioctl_send()
6016 if (btrfs_root_dead(sctx->send_root)) { in btrfs_ioctl_send()
6021 sctx->clone_roots_cnt = arg->clone_sources_count; in btrfs_ioctl_send()
6023 sctx->send_max_size = BTRFS_SEND_BUF_SIZE; in btrfs_ioctl_send()
6024 sctx->send_buf = vmalloc(sctx->send_max_size); in btrfs_ioctl_send()
6025 if (!sctx->send_buf) { in btrfs_ioctl_send()
6030 sctx->read_buf = vmalloc(BTRFS_SEND_READ_SIZE); in btrfs_ioctl_send()
6031 if (!sctx->read_buf) { in btrfs_ioctl_send()
6036 sctx->pending_dir_moves = RB_ROOT; in btrfs_ioctl_send()
6037 sctx->waiting_dir_moves = RB_ROOT; in btrfs_ioctl_send()
6038 sctx->orphan_dirs = RB_ROOT; in btrfs_ioctl_send()
6040 sctx->clone_roots = vzalloc(sizeof(struct clone_root) * in btrfs_ioctl_send()
6042 if (!sctx->clone_roots) { in btrfs_ioctl_send()
6088 sctx->clone_roots[i].root = clone_root; in btrfs_ioctl_send()
6102 sctx->parent_root = btrfs_read_fs_root_no_name(fs_info, &key); in btrfs_ioctl_send()
6103 if (IS_ERR(sctx->parent_root)) { in btrfs_ioctl_send()
6105 ret = PTR_ERR(sctx->parent_root); in btrfs_ioctl_send()
6109 spin_lock(&sctx->parent_root->root_item_lock); in btrfs_ioctl_send()
6110 sctx->parent_root->send_in_progress++; in btrfs_ioctl_send()
6111 if (!btrfs_root_readonly(sctx->parent_root) || in btrfs_ioctl_send()
6112 btrfs_root_dead(sctx->parent_root)) { in btrfs_ioctl_send()
6113 spin_unlock(&sctx->parent_root->root_item_lock); in btrfs_ioctl_send()
6118 spin_unlock(&sctx->parent_root->root_item_lock); in btrfs_ioctl_send()
6128 sctx->clone_roots[sctx->clone_roots_cnt++].root = sctx->send_root; in btrfs_ioctl_send()
6131 sort(sctx->clone_roots, sctx->clone_roots_cnt, in btrfs_ioctl_send()
6132 sizeof(*sctx->clone_roots), __clone_root_cmp_sort, in btrfs_ioctl_send()
6136 ret = ensure_commit_roots_uptodate(sctx); in btrfs_ioctl_send()
6141 ret = send_subvol(sctx); in btrfs_ioctl_send()
6146 if (!(sctx->flags & BTRFS_SEND_FLAG_OMIT_END_CMD)) { in btrfs_ioctl_send()
6147 ret = begin_cmd(sctx, BTRFS_SEND_C_END); in btrfs_ioctl_send()
6150 ret = send_cmd(sctx); in btrfs_ioctl_send()
6156 WARN_ON(sctx && !ret && !RB_EMPTY_ROOT(&sctx->pending_dir_moves)); in btrfs_ioctl_send()
6157 while (sctx && !RB_EMPTY_ROOT(&sctx->pending_dir_moves)) { in btrfs_ioctl_send()
6161 n = rb_first(&sctx->pending_dir_moves); in btrfs_ioctl_send()
6168 free_pending_move(sctx, pm2); in btrfs_ioctl_send()
6170 free_pending_move(sctx, pm); in btrfs_ioctl_send()
6173 WARN_ON(sctx && !ret && !RB_EMPTY_ROOT(&sctx->waiting_dir_moves)); in btrfs_ioctl_send()
6174 while (sctx && !RB_EMPTY_ROOT(&sctx->waiting_dir_moves)) { in btrfs_ioctl_send()
6178 n = rb_first(&sctx->waiting_dir_moves); in btrfs_ioctl_send()
6180 rb_erase(&dm->node, &sctx->waiting_dir_moves); in btrfs_ioctl_send()
6184 WARN_ON(sctx && !ret && !RB_EMPTY_ROOT(&sctx->orphan_dirs)); in btrfs_ioctl_send()
6185 while (sctx && !RB_EMPTY_ROOT(&sctx->orphan_dirs)) { in btrfs_ioctl_send()
6189 n = rb_first(&sctx->orphan_dirs); in btrfs_ioctl_send()
6191 free_orphan_dir_info(sctx, odi); in btrfs_ioctl_send()
6195 for (i = 0; i < sctx->clone_roots_cnt; i++) in btrfs_ioctl_send()
6197 sctx->clone_roots[i].root); in btrfs_ioctl_send()
6199 for (i = 0; sctx && i < clone_sources_to_rollback; i++) in btrfs_ioctl_send()
6201 sctx->clone_roots[i].root); in btrfs_ioctl_send()
6205 if (sctx && !IS_ERR_OR_NULL(sctx->parent_root)) in btrfs_ioctl_send()
6206 btrfs_root_dec_send_in_progress(sctx->parent_root); in btrfs_ioctl_send()
6211 if (sctx) { in btrfs_ioctl_send()
6212 if (sctx->send_filp) in btrfs_ioctl_send()
6213 fput(sctx->send_filp); in btrfs_ioctl_send()
6215 vfree(sctx->clone_roots); in btrfs_ioctl_send()
6216 vfree(sctx->send_buf); in btrfs_ioctl_send()
6217 vfree(sctx->read_buf); in btrfs_ioctl_send()
6219 name_cache_free(sctx); in btrfs_ioctl_send()
6221 kfree(sctx); in btrfs_ioctl_send()