Lines Matching refs:sctx
281 static void inconsistent_snapshot_error(struct send_ctx *sctx, in inconsistent_snapshot_error() argument
306 btrfs_err(sctx->send_root->fs_info, in inconsistent_snapshot_error()
308 result_string, what, sctx->cmp_key->objectid, in inconsistent_snapshot_error()
309 sctx->send_root->root_key.objectid, in inconsistent_snapshot_error()
310 (sctx->parent_root ? in inconsistent_snapshot_error()
311 sctx->parent_root->root_key.objectid : 0)); in inconsistent_snapshot_error()
314 static int is_waiting_for_move(struct send_ctx *sctx, u64 ino);
317 get_waiting_dir_move(struct send_ctx *sctx, u64 ino);
319 static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino);
321 static int need_send_hole(struct send_ctx *sctx) in need_send_hole() argument
323 return (sctx->parent_root && !sctx->cur_inode_new && in need_send_hole()
324 !sctx->cur_inode_new_gen && !sctx->cur_inode_deleted && in need_send_hole()
325 S_ISREG(sctx->cur_inode_mode)); in need_send_hole()
570 static int tlv_put(struct send_ctx *sctx, u16 attr, const void *data, int len) in tlv_put() argument
574 int left = sctx->send_max_size - sctx->send_size; in tlv_put()
579 hdr = (struct btrfs_tlv_header *) (sctx->send_buf + sctx->send_size); in tlv_put()
583 sctx->send_size += total_len; in tlv_put()
589 static int tlv_put_u##bits(struct send_ctx *sctx, \
593 return tlv_put(sctx, attr, &__tmp, sizeof(__tmp)); \
598 static int tlv_put_string(struct send_ctx *sctx, u16 attr, in tlv_put_string() argument
603 return tlv_put(sctx, attr, str, len); in tlv_put_string()
606 static int tlv_put_uuid(struct send_ctx *sctx, u16 attr, in tlv_put_uuid() argument
609 return tlv_put(sctx, attr, uuid, BTRFS_UUID_SIZE); in tlv_put_uuid()
612 static int tlv_put_btrfs_timespec(struct send_ctx *sctx, u16 attr, in tlv_put_btrfs_timespec() argument
618 return tlv_put(sctx, attr, &bts, sizeof(bts)); in tlv_put_btrfs_timespec()
622 #define TLV_PUT(sctx, attrtype, data, attrlen) \ argument
624 ret = tlv_put(sctx, attrtype, data, attrlen); \
629 #define TLV_PUT_INT(sctx, attrtype, bits, value) \ argument
631 ret = tlv_put_u##bits(sctx, attrtype, value); \
636 #define TLV_PUT_U8(sctx, attrtype, data) TLV_PUT_INT(sctx, attrtype, 8, data) argument
637 #define TLV_PUT_U16(sctx, attrtype, data) TLV_PUT_INT(sctx, attrtype, 16, data) argument
638 #define TLV_PUT_U32(sctx, attrtype, data) TLV_PUT_INT(sctx, attrtype, 32, data) argument
639 #define TLV_PUT_U64(sctx, attrtype, data) TLV_PUT_INT(sctx, attrtype, 64, data) argument
640 #define TLV_PUT_STRING(sctx, attrtype, str, len) \ argument
642 ret = tlv_put_string(sctx, attrtype, str, len); \
646 #define TLV_PUT_PATH(sctx, attrtype, p) \ argument
648 ret = tlv_put_string(sctx, attrtype, p->start, \
653 #define TLV_PUT_UUID(sctx, attrtype, uuid) \ argument
655 ret = tlv_put_uuid(sctx, attrtype, uuid); \
659 #define TLV_PUT_BTRFS_TIMESPEC(sctx, attrtype, eb, ts) \ argument
661 ret = tlv_put_btrfs_timespec(sctx, attrtype, eb, ts); \
666 static int send_header(struct send_ctx *sctx) in send_header() argument
673 return write_buf(sctx->send_filp, &hdr, sizeof(hdr), in send_header()
674 &sctx->send_off); in send_header()
680 static int begin_cmd(struct send_ctx *sctx, int cmd) in begin_cmd() argument
684 if (WARN_ON(!sctx->send_buf)) in begin_cmd()
687 BUG_ON(sctx->send_size); in begin_cmd()
689 sctx->send_size += sizeof(*hdr); in begin_cmd()
690 hdr = (struct btrfs_cmd_header *)sctx->send_buf; in begin_cmd()
696 static int send_cmd(struct send_ctx *sctx) in send_cmd() argument
702 hdr = (struct btrfs_cmd_header *)sctx->send_buf; in send_cmd()
703 put_unaligned_le32(sctx->send_size - sizeof(*hdr), &hdr->len); in send_cmd()
706 crc = btrfs_crc32c(0, (unsigned char *)sctx->send_buf, sctx->send_size); in send_cmd()
709 ret = write_buf(sctx->send_filp, sctx->send_buf, sctx->send_size, in send_cmd()
710 &sctx->send_off); in send_cmd()
712 sctx->total_send_size += sctx->send_size; in send_cmd()
713 sctx->cmd_send_size[get_unaligned_le16(&hdr->cmd)] += sctx->send_size; in send_cmd()
714 sctx->send_size = 0; in send_cmd()
722 static int send_rename(struct send_ctx *sctx, in send_rename() argument
725 struct btrfs_fs_info *fs_info = sctx->send_root->fs_info; in send_rename()
730 ret = begin_cmd(sctx, BTRFS_SEND_C_RENAME); in send_rename()
734 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, from); in send_rename()
735 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_TO, to); in send_rename()
737 ret = send_cmd(sctx); in send_rename()
747 static int send_link(struct send_ctx *sctx, in send_link() argument
750 struct btrfs_fs_info *fs_info = sctx->send_root->fs_info; in send_link()
755 ret = begin_cmd(sctx, BTRFS_SEND_C_LINK); in send_link()
759 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path); in send_link()
760 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_LINK, lnk); in send_link()
762 ret = send_cmd(sctx); in send_link()
772 static int send_unlink(struct send_ctx *sctx, struct fs_path *path) in send_unlink() argument
774 struct btrfs_fs_info *fs_info = sctx->send_root->fs_info; in send_unlink()
779 ret = begin_cmd(sctx, BTRFS_SEND_C_UNLINK); in send_unlink()
783 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path); in send_unlink()
785 ret = send_cmd(sctx); in send_unlink()
795 static int send_rmdir(struct send_ctx *sctx, struct fs_path *path) in send_rmdir() argument
797 struct btrfs_fs_info *fs_info = sctx->send_root->fs_info; in send_rmdir()
802 ret = begin_cmd(sctx, BTRFS_SEND_C_RMDIR); in send_rmdir()
806 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path); in send_rmdir()
808 ret = send_cmd(sctx); in send_rmdir()
1178 struct send_ctx *sctx; member
1234 found = bsearch((void *)(uintptr_t)root, bctx->sctx->clone_roots, in __iterate_backrefs()
1235 bctx->sctx->clone_roots_cnt, in __iterate_backrefs()
1241 if (found->root == bctx->sctx->send_root && in __iterate_backrefs()
1251 if (found->root == bctx->sctx->send_root) { in __iterate_backrefs()
1267 bctx->sctx->cur_inode_next_write_offset) in __iterate_backrefs()
1296 static int find_extent_clone(struct send_ctx *sctx, in find_extent_clone() argument
1302 struct btrfs_fs_info *fs_info = sctx->send_root->fs_info; in find_extent_clone()
1390 for (i = 0; i < sctx->clone_roots_cnt; i++) { in find_extent_clone()
1391 cur_clone_root = sctx->clone_roots + i; in find_extent_clone()
1397 backref_ctx->sctx = sctx; in find_extent_clone()
1456 for (i = 0; i < sctx->clone_roots_cnt; i++) { in find_extent_clone()
1457 if (sctx->clone_roots[i].found_refs) { in find_extent_clone()
1459 cur_clone_root = sctx->clone_roots + i; in find_extent_clone()
1460 else if (sctx->clone_roots[i].root == sctx->send_root) in find_extent_clone()
1462 cur_clone_root = sctx->clone_roots + i; in find_extent_clone()
1540 static int gen_unique_name(struct send_ctx *sctx, in gen_unique_name() argument
1560 di = btrfs_lookup_dir_item(NULL, sctx->send_root, in gen_unique_name()
1574 if (!sctx->parent_root) { in gen_unique_name()
1580 di = btrfs_lookup_dir_item(NULL, sctx->parent_root, in gen_unique_name()
1612 static int get_cur_inode_state(struct send_ctx *sctx, u64 ino, u64 gen) in get_cur_inode_state() argument
1620 ret = get_inode_info(sctx->send_root, ino, NULL, &left_gen, NULL, NULL, in get_cur_inode_state()
1626 if (!sctx->parent_root) { in get_cur_inode_state()
1629 ret = get_inode_info(sctx->parent_root, ino, NULL, &right_gen, in get_cur_inode_state()
1640 if (ino < sctx->send_progress) in get_cur_inode_state()
1645 if (ino < sctx->send_progress) in get_cur_inode_state()
1654 if (ino < sctx->send_progress) in get_cur_inode_state()
1663 if (ino < sctx->send_progress) in get_cur_inode_state()
1678 static int is_inode_existent(struct send_ctx *sctx, u64 ino, u64 gen) in is_inode_existent() argument
1685 ret = get_cur_inode_state(sctx, ino, gen); in is_inode_existent()
1845 static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen, in will_overwrite_ref() argument
1854 if (!sctx->parent_root) in will_overwrite_ref()
1857 ret = is_inode_existent(sctx, dir, dir_gen); in will_overwrite_ref()
1866 if (sctx->parent_root && dir != BTRFS_FIRST_FREE_OBJECTID) { in will_overwrite_ref()
1867 ret = get_inode_info(sctx->parent_root, dir, NULL, &gen, NULL, in will_overwrite_ref()
1879 ret = lookup_dir_item_inode(sctx->parent_root, dir, name, name_len, in will_overwrite_ref()
1893 if (other_inode > sctx->send_progress || in will_overwrite_ref()
1894 is_waiting_for_move(sctx, other_inode)) { in will_overwrite_ref()
1895 ret = get_inode_info(sctx->parent_root, other_inode, NULL, in will_overwrite_ref()
1917 static int did_overwrite_ref(struct send_ctx *sctx, in did_overwrite_ref() argument
1927 if (!sctx->parent_root) in did_overwrite_ref()
1930 ret = is_inode_existent(sctx, dir, dir_gen); in did_overwrite_ref()
1935 ret = get_inode_info(sctx->send_root, dir, NULL, &gen, NULL, in did_overwrite_ref()
1948 ret = lookup_dir_item_inode(sctx->send_root, dir, name, name_len, in did_overwrite_ref()
1958 ret = get_inode_info(sctx->send_root, ow_inode, NULL, &gen, NULL, NULL, in did_overwrite_ref()
1974 if ((ow_inode < sctx->send_progress) || in did_overwrite_ref()
1975 (ino != sctx->cur_ino && ow_inode == sctx->cur_ino && in did_overwrite_ref()
1976 gen == sctx->cur_inode_gen)) in did_overwrite_ref()
1990 static int did_overwrite_first_ref(struct send_ctx *sctx, u64 ino, u64 gen) in did_overwrite_first_ref() argument
1997 if (!sctx->parent_root) in did_overwrite_first_ref()
2004 ret = get_first_ref(sctx->parent_root, ino, &dir, &dir_gen, name); in did_overwrite_first_ref()
2008 ret = did_overwrite_ref(sctx, dir, dir_gen, ino, gen, in did_overwrite_first_ref()
2022 static int name_cache_insert(struct send_ctx *sctx, in name_cache_insert() argument
2028 nce_head = radix_tree_lookup(&sctx->name_cache, in name_cache_insert()
2038 ret = radix_tree_insert(&sctx->name_cache, nce->ino, nce_head); in name_cache_insert()
2046 list_add_tail(&nce->list, &sctx->name_cache_list); in name_cache_insert()
2047 sctx->name_cache_size++; in name_cache_insert()
2052 static void name_cache_delete(struct send_ctx *sctx, in name_cache_delete() argument
2057 nce_head = radix_tree_lookup(&sctx->name_cache, in name_cache_delete()
2060 btrfs_err(sctx->send_root->fs_info, in name_cache_delete()
2062 nce->ino, sctx->name_cache_size); in name_cache_delete()
2067 sctx->name_cache_size--; in name_cache_delete()
2073 radix_tree_delete(&sctx->name_cache, (unsigned long)nce->ino); in name_cache_delete()
2078 static struct name_cache_entry *name_cache_search(struct send_ctx *sctx, in name_cache_search() argument
2084 nce_head = radix_tree_lookup(&sctx->name_cache, (unsigned long)ino); in name_cache_search()
2099 static void name_cache_used(struct send_ctx *sctx, struct name_cache_entry *nce) in name_cache_used() argument
2102 list_add_tail(&nce->list, &sctx->name_cache_list); in name_cache_used()
2108 static void name_cache_clean_unused(struct send_ctx *sctx) in name_cache_clean_unused() argument
2112 if (sctx->name_cache_size < SEND_CTX_NAME_CACHE_CLEAN_SIZE) in name_cache_clean_unused()
2115 while (sctx->name_cache_size > SEND_CTX_MAX_NAME_CACHE_SIZE) { in name_cache_clean_unused()
2116 nce = list_entry(sctx->name_cache_list.next, in name_cache_clean_unused()
2118 name_cache_delete(sctx, nce); in name_cache_clean_unused()
2123 static void name_cache_free(struct send_ctx *sctx) in name_cache_free() argument
2127 while (!list_empty(&sctx->name_cache_list)) { in name_cache_free()
2128 nce = list_entry(sctx->name_cache_list.next, in name_cache_free()
2130 name_cache_delete(sctx, nce); in name_cache_free()
2143 static int __get_cur_name_and_parent(struct send_ctx *sctx, in __get_cur_name_and_parent() argument
2158 nce = name_cache_search(sctx, ino, gen); in __get_cur_name_and_parent()
2160 if (ino < sctx->send_progress && nce->need_later_update) { in __get_cur_name_and_parent()
2161 name_cache_delete(sctx, nce); in __get_cur_name_and_parent()
2165 name_cache_used(sctx, nce); in __get_cur_name_and_parent()
2181 ret = is_inode_existent(sctx, ino, gen); in __get_cur_name_and_parent()
2186 ret = gen_unique_name(sctx, ino, gen, dest); in __get_cur_name_and_parent()
2197 if (ino < sctx->send_progress) in __get_cur_name_and_parent()
2198 ret = get_first_ref(sctx->send_root, ino, in __get_cur_name_and_parent()
2201 ret = get_first_ref(sctx->parent_root, ino, in __get_cur_name_and_parent()
2210 ret = did_overwrite_ref(sctx, *parent_ino, *parent_gen, ino, gen, in __get_cur_name_and_parent()
2216 ret = gen_unique_name(sctx, ino, gen, dest); in __get_cur_name_and_parent()
2240 if (ino < sctx->send_progress) in __get_cur_name_and_parent()
2245 nce_ret = name_cache_insert(sctx, nce); in __get_cur_name_and_parent()
2248 name_cache_clean_unused(sctx); in __get_cur_name_and_parent()
2279 static int get_cur_path(struct send_ctx *sctx, u64 ino, u64 gen, in get_cur_path() argument
2302 if (is_waiting_for_rm(sctx, ino)) { in get_cur_path()
2303 ret = gen_unique_name(sctx, ino, gen, name); in get_cur_path()
2310 wdm = get_waiting_dir_move(sctx, ino); in get_cur_path()
2312 ret = gen_unique_name(sctx, ino, gen, name); in get_cur_path()
2315 ret = get_first_ref(sctx->parent_root, ino, in get_cur_path()
2318 ret = __get_cur_name_and_parent(sctx, ino, gen, in get_cur_path()
2346 static int send_subvol_begin(struct send_ctx *sctx) in send_subvol_begin() argument
2349 struct btrfs_root *send_root = sctx->send_root; in send_subvol_begin()
2350 struct btrfs_root *parent_root = sctx->parent_root; in send_subvol_begin()
2394 ret = begin_cmd(sctx, BTRFS_SEND_C_SNAPSHOT); in send_subvol_begin()
2398 ret = begin_cmd(sctx, BTRFS_SEND_C_SUBVOL); in send_subvol_begin()
2403 TLV_PUT_STRING(sctx, BTRFS_SEND_A_PATH, name, namelen); in send_subvol_begin()
2405 if (!btrfs_is_empty_uuid(sctx->send_root->root_item.received_uuid)) in send_subvol_begin()
2406 TLV_PUT_UUID(sctx, BTRFS_SEND_A_UUID, in send_subvol_begin()
2407 sctx->send_root->root_item.received_uuid); in send_subvol_begin()
2409 TLV_PUT_UUID(sctx, BTRFS_SEND_A_UUID, in send_subvol_begin()
2410 sctx->send_root->root_item.uuid); in send_subvol_begin()
2412 TLV_PUT_U64(sctx, BTRFS_SEND_A_CTRANSID, in send_subvol_begin()
2413 le64_to_cpu(sctx->send_root->root_item.ctransid)); in send_subvol_begin()
2416 TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID, in send_subvol_begin()
2419 TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID, in send_subvol_begin()
2421 TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_CTRANSID, in send_subvol_begin()
2422 le64_to_cpu(sctx->parent_root->root_item.ctransid)); in send_subvol_begin()
2425 ret = send_cmd(sctx); in send_subvol_begin()
2434 static int send_truncate(struct send_ctx *sctx, u64 ino, u64 gen, u64 size) in send_truncate() argument
2436 struct btrfs_fs_info *fs_info = sctx->send_root->fs_info; in send_truncate()
2446 ret = begin_cmd(sctx, BTRFS_SEND_C_TRUNCATE); in send_truncate()
2450 ret = get_cur_path(sctx, ino, gen, p); in send_truncate()
2453 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_truncate()
2454 TLV_PUT_U64(sctx, BTRFS_SEND_A_SIZE, size); in send_truncate()
2456 ret = send_cmd(sctx); in send_truncate()
2464 static int send_chmod(struct send_ctx *sctx, u64 ino, u64 gen, u64 mode) in send_chmod() argument
2466 struct btrfs_fs_info *fs_info = sctx->send_root->fs_info; in send_chmod()
2476 ret = begin_cmd(sctx, BTRFS_SEND_C_CHMOD); in send_chmod()
2480 ret = get_cur_path(sctx, ino, gen, p); in send_chmod()
2483 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_chmod()
2484 TLV_PUT_U64(sctx, BTRFS_SEND_A_MODE, mode & 07777); in send_chmod()
2486 ret = send_cmd(sctx); in send_chmod()
2494 static int send_chown(struct send_ctx *sctx, u64 ino, u64 gen, u64 uid, u64 gid) in send_chown() argument
2496 struct btrfs_fs_info *fs_info = sctx->send_root->fs_info; in send_chown()
2507 ret = begin_cmd(sctx, BTRFS_SEND_C_CHOWN); in send_chown()
2511 ret = get_cur_path(sctx, ino, gen, p); in send_chown()
2514 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_chown()
2515 TLV_PUT_U64(sctx, BTRFS_SEND_A_UID, uid); in send_chown()
2516 TLV_PUT_U64(sctx, BTRFS_SEND_A_GID, gid); in send_chown()
2518 ret = send_cmd(sctx); in send_chown()
2526 static int send_utimes(struct send_ctx *sctx, u64 ino, u64 gen) in send_utimes() argument
2528 struct btrfs_fs_info *fs_info = sctx->send_root->fs_info; in send_utimes()
2552 ret = btrfs_search_slot(NULL, sctx->send_root, &key, path, 0, 0); in send_utimes()
2562 ret = begin_cmd(sctx, BTRFS_SEND_C_UTIMES); in send_utimes()
2566 ret = get_cur_path(sctx, ino, gen, p); in send_utimes()
2569 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_utimes()
2570 TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_ATIME, eb, &ii->atime); in send_utimes()
2571 TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_MTIME, eb, &ii->mtime); in send_utimes()
2572 TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_CTIME, eb, &ii->ctime); in send_utimes()
2575 ret = send_cmd(sctx); in send_utimes()
2589 static int send_create_inode(struct send_ctx *sctx, u64 ino) in send_create_inode() argument
2591 struct btrfs_fs_info *fs_info = sctx->send_root->fs_info; in send_create_inode()
2605 if (ino != sctx->cur_ino) { in send_create_inode()
2606 ret = get_inode_info(sctx->send_root, ino, NULL, &gen, &mode, in send_create_inode()
2611 gen = sctx->cur_inode_gen; in send_create_inode()
2612 mode = sctx->cur_inode_mode; in send_create_inode()
2613 rdev = sctx->cur_inode_rdev; in send_create_inode()
2629 btrfs_warn(sctx->send_root->fs_info, "unexpected inode type %o", in send_create_inode()
2635 ret = begin_cmd(sctx, cmd); in send_create_inode()
2639 ret = gen_unique_name(sctx, ino, gen, p); in send_create_inode()
2643 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_create_inode()
2644 TLV_PUT_U64(sctx, BTRFS_SEND_A_INO, ino); in send_create_inode()
2648 ret = read_symlink(sctx->send_root, ino, p); in send_create_inode()
2651 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_LINK, p); in send_create_inode()
2654 TLV_PUT_U64(sctx, BTRFS_SEND_A_RDEV, new_encode_dev(rdev)); in send_create_inode()
2655 TLV_PUT_U64(sctx, BTRFS_SEND_A_MODE, mode); in send_create_inode()
2658 ret = send_cmd(sctx); in send_create_inode()
2674 static int did_create_dir(struct send_ctx *sctx, u64 dir) in did_create_dir() argument
2694 ret = btrfs_search_slot(NULL, sctx->send_root, &key, path, 0, 0); in did_create_dir()
2702 ret = btrfs_next_leaf(sctx->send_root, path); in did_create_dir()
2723 di_key.objectid < sctx->send_progress) { in did_create_dir()
2742 static int send_create_inode_if_needed(struct send_ctx *sctx) in send_create_inode_if_needed() argument
2746 if (S_ISDIR(sctx->cur_inode_mode)) { in send_create_inode_if_needed()
2747 ret = did_create_dir(sctx, sctx->cur_ino); in send_create_inode_if_needed()
2756 ret = send_create_inode(sctx, sctx->cur_ino); in send_create_inode_if_needed()
2829 static void free_recorded_refs(struct send_ctx *sctx) in free_recorded_refs() argument
2831 __free_recorded_refs(&sctx->new_refs); in free_recorded_refs()
2832 __free_recorded_refs(&sctx->deleted_refs); in free_recorded_refs()
2840 static int orphanize_inode(struct send_ctx *sctx, u64 ino, u64 gen, in orphanize_inode() argument
2850 ret = gen_unique_name(sctx, ino, gen, orphan); in orphanize_inode()
2854 ret = send_rename(sctx, path, orphan); in orphanize_inode()
2862 add_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino) in add_orphan_dir_info() argument
2864 struct rb_node **p = &sctx->orphan_dirs.rb_node; in add_orphan_dir_info()
2888 rb_insert_color(&odi->node, &sctx->orphan_dirs); in add_orphan_dir_info()
2893 get_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino) in get_orphan_dir_info() argument
2895 struct rb_node *n = sctx->orphan_dirs.rb_node; in get_orphan_dir_info()
2910 static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino) in is_waiting_for_rm() argument
2912 struct orphan_dir_info *odi = get_orphan_dir_info(sctx, dir_ino); in is_waiting_for_rm()
2917 static void free_orphan_dir_info(struct send_ctx *sctx, in free_orphan_dir_info() argument
2922 rb_erase(&odi->node, &sctx->orphan_dirs); in free_orphan_dir_info()
2931 static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 dir_gen, in can_rmdir() argument
2935 struct btrfs_root *root = sctx->parent_root; in can_rmdir()
2957 odi = get_orphan_dir_info(sctx, dir); in can_rmdir()
2986 dm = get_waiting_dir_move(sctx, loc.objectid); in can_rmdir()
2988 odi = add_orphan_dir_info(sctx, dir); in can_rmdir()
3001 odi = add_orphan_dir_info(sctx, dir); in can_rmdir()
3014 free_orphan_dir_info(sctx, odi); in can_rmdir()
3023 static int is_waiting_for_move(struct send_ctx *sctx, u64 ino) in is_waiting_for_move() argument
3025 struct waiting_dir_move *entry = get_waiting_dir_move(sctx, ino); in is_waiting_for_move()
3030 static int add_waiting_dir_move(struct send_ctx *sctx, u64 ino, bool orphanized) in add_waiting_dir_move() argument
3032 struct rb_node **p = &sctx->waiting_dir_moves.rb_node; in add_waiting_dir_move()
3057 rb_insert_color(&dm->node, &sctx->waiting_dir_moves); in add_waiting_dir_move()
3062 get_waiting_dir_move(struct send_ctx *sctx, u64 ino) in get_waiting_dir_move() argument
3064 struct rb_node *n = sctx->waiting_dir_moves.rb_node; in get_waiting_dir_move()
3079 static void free_waiting_dir_move(struct send_ctx *sctx, in free_waiting_dir_move() argument
3084 rb_erase(&dm->node, &sctx->waiting_dir_moves); in free_waiting_dir_move()
3088 static int add_pending_dir_move(struct send_ctx *sctx, in add_pending_dir_move() argument
3096 struct rb_node **p = &sctx->pending_dir_moves.rb_node; in add_pending_dir_move()
3137 ret = add_waiting_dir_move(sctx, pm->ino, is_orphan); in add_pending_dir_move()
3145 rb_insert_color(&pm->node, &sctx->pending_dir_moves); in add_pending_dir_move()
3156 static struct pending_dir_move *get_pending_dir_moves(struct send_ctx *sctx, in get_pending_dir_moves() argument
3159 struct rb_node *n = sctx->pending_dir_moves.rb_node; in get_pending_dir_moves()
3174 static int path_loop(struct send_ctx *sctx, struct fs_path *name, in path_loop() argument
3186 if (is_waiting_for_rm(sctx, ino)) in path_loop()
3188 if (is_waiting_for_move(sctx, ino)) { in path_loop()
3191 ret = get_first_ref(sctx->parent_root, ino, in path_loop()
3194 ret = __get_cur_name_and_parent(sctx, ino, gen, in path_loop()
3216 static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) in apply_dir_move() argument
3221 u64 orig_progress = sctx->send_progress; in apply_dir_move()
3237 dm = get_waiting_dir_move(sctx, pm->ino); in apply_dir_move()
3241 free_waiting_dir_move(sctx, dm); in apply_dir_move()
3244 ret = gen_unique_name(sctx, pm->ino, in apply_dir_move()
3247 ret = get_first_ref(sctx->parent_root, pm->ino, in apply_dir_move()
3251 ret = get_cur_path(sctx, parent_ino, parent_gen, in apply_dir_move()
3260 sctx->send_progress = sctx->cur_ino + 1; in apply_dir_move()
3261 ret = path_loop(sctx, name, pm->ino, pm->gen, &ancestor); in apply_dir_move()
3267 ret = add_pending_dir_move(sctx, pm->ino, pm->gen, ancestor, in apply_dir_move()
3273 dm = get_waiting_dir_move(sctx, pm->ino); in apply_dir_move()
3282 ret = get_cur_path(sctx, pm->ino, pm->gen, to_path); in apply_dir_move()
3286 ret = send_rename(sctx, from_path, to_path); in apply_dir_move()
3294 odi = get_orphan_dir_info(sctx, rmdir_ino); in apply_dir_move()
3301 ret = can_rmdir(sctx, rmdir_ino, gen, sctx->cur_ino); in apply_dir_move()
3312 ret = get_cur_path(sctx, rmdir_ino, gen, name); in apply_dir_move()
3315 ret = send_rmdir(sctx, name); in apply_dir_move()
3321 ret = send_utimes(sctx, pm->ino, pm->gen); in apply_dir_move()
3333 ret = get_inode_info(sctx->send_root, cur->dir, NULL, in apply_dir_move()
3342 ret = send_utimes(sctx, cur->dir, cur->dir_gen); in apply_dir_move()
3351 sctx->send_progress = orig_progress; in apply_dir_move()
3356 static void free_pending_move(struct send_ctx *sctx, struct pending_dir_move *m) in free_pending_move() argument
3361 rb_erase(&m->node, &sctx->pending_dir_moves); in free_pending_move()
3366 static void tail_append_pending_moves(struct send_ctx *sctx, in tail_append_pending_moves() argument
3379 rb_erase(&moves->node, &sctx->pending_dir_moves); in tail_append_pending_moves()
3384 static int apply_children_dir_moves(struct send_ctx *sctx) in apply_children_dir_moves() argument
3388 u64 parent_ino = sctx->cur_ino; in apply_children_dir_moves()
3391 pm = get_pending_dir_moves(sctx, parent_ino); in apply_children_dir_moves()
3396 tail_append_pending_moves(sctx, pm, &stack); in apply_children_dir_moves()
3401 ret = apply_dir_move(sctx, pm); in apply_children_dir_moves()
3402 free_pending_move(sctx, pm); in apply_children_dir_moves()
3405 pm = get_pending_dir_moves(sctx, parent_ino); in apply_children_dir_moves()
3407 tail_append_pending_moves(sctx, pm, &stack); in apply_children_dir_moves()
3414 free_pending_move(sctx, pm); in apply_children_dir_moves()
3455 static int wait_for_dest_dir_move(struct send_ctx *sctx, in wait_for_dest_dir_move() argument
3459 struct btrfs_fs_info *fs_info = sctx->parent_root->fs_info; in wait_for_dest_dir_move()
3469 if (RB_EMPTY_ROOT(&sctx->waiting_dir_moves)) in wait_for_dest_dir_move()
3480 ret = btrfs_search_slot(NULL, sctx->parent_root, &key, path, 0, 0); in wait_for_dest_dir_move()
3508 ret = get_inode_info(sctx->parent_root, di_key.objectid, NULL, in wait_for_dest_dir_move()
3512 ret = get_inode_info(sctx->send_root, di_key.objectid, NULL, in wait_for_dest_dir_move()
3526 wdm = get_waiting_dir_move(sctx, di_key.objectid); in wait_for_dest_dir_move()
3528 ret = add_pending_dir_move(sctx, in wait_for_dest_dir_move()
3529 sctx->cur_ino, in wait_for_dest_dir_move()
3530 sctx->cur_inode_gen, in wait_for_dest_dir_move()
3532 &sctx->new_refs, in wait_for_dest_dir_move()
3533 &sctx->deleted_refs, in wait_for_dest_dir_move()
3675 static int wait_for_parent_move(struct send_ctx *sctx, in wait_for_parent_move() argument
3704 if (is_waiting_for_move(sctx, ino)) { in wait_for_parent_move()
3715 ret = is_ancestor(sctx->parent_root, in wait_for_parent_move()
3716 sctx->cur_ino, sctx->cur_inode_gen, in wait_for_parent_move()
3725 ret = get_first_ref(sctx->send_root, ino, &parent_ino_after, in wait_for_parent_move()
3729 ret = get_first_ref(sctx->parent_root, ino, &parent_ino_before, in wait_for_parent_move()
3740 if (ino > sctx->cur_ino && in wait_for_parent_move()
3745 ret = get_inode_info(sctx->parent_root, ino, NULL, in wait_for_parent_move()
3764 ret = add_pending_dir_move(sctx, in wait_for_parent_move()
3765 sctx->cur_ino, in wait_for_parent_move()
3766 sctx->cur_inode_gen, in wait_for_parent_move()
3768 &sctx->new_refs, in wait_for_parent_move()
3769 &sctx->deleted_refs, in wait_for_parent_move()
3778 static int update_ref_path(struct send_ctx *sctx, struct recorded_ref *ref) in update_ref_path() argument
3791 ret = get_cur_path(sctx, ref->dir, ref->dir_gen, new_path); in update_ref_path()
3849 static int refresh_ref_path(struct send_ctx *sctx, struct recorded_ref *ref) in refresh_ref_path() argument
3859 ret = get_cur_path(sctx, ref->dir, ref->dir_gen, ref->full_path); in refresh_ref_path()
3877 static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) in process_recorded_refs() argument
3879 struct btrfs_fs_info *fs_info = sctx->send_root->fs_info; in process_recorded_refs()
3895 btrfs_debug(fs_info, "process_recorded_refs %llu", sctx->cur_ino); in process_recorded_refs()
3901 BUG_ON(sctx->cur_ino <= BTRFS_FIRST_FREE_OBJECTID); in process_recorded_refs()
3921 if (!sctx->cur_inode_new) { in process_recorded_refs()
3922 ret = did_overwrite_first_ref(sctx, sctx->cur_ino, in process_recorded_refs()
3923 sctx->cur_inode_gen); in process_recorded_refs()
3929 if (sctx->cur_inode_new || did_overwrite) { in process_recorded_refs()
3930 ret = gen_unique_name(sctx, sctx->cur_ino, in process_recorded_refs()
3931 sctx->cur_inode_gen, valid_path); in process_recorded_refs()
3936 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, in process_recorded_refs()
3980 list_for_each_entry(cur, &sctx->new_refs, list) { in process_recorded_refs()
3981 ret = get_cur_inode_state(sctx, cur->dir, cur->dir_gen); in process_recorded_refs()
3993 ret = will_overwrite_ref(sctx, cur->dir, cur->dir_gen, in process_recorded_refs()
3999 ret = is_first_ref(sctx->parent_root, in process_recorded_refs()
4009 ret = refresh_ref_path(sctx, cur); in process_recorded_refs()
4014 ret = orphanize_inode(sctx, ow_inode, ow_gen, in process_recorded_refs()
4027 if (is_waiting_for_move(sctx, ow_inode)) { in process_recorded_refs()
4028 wdm = get_waiting_dir_move(sctx, in process_recorded_refs()
4044 nce = name_cache_search(sctx, ow_inode, ow_gen); in process_recorded_refs()
4046 name_cache_delete(sctx, nce); in process_recorded_refs()
4057 ret = is_ancestor(sctx->parent_root, in process_recorded_refs()
4059 sctx->cur_ino, NULL); in process_recorded_refs()
4063 ret = get_cur_path(sctx, sctx->cur_ino, in process_recorded_refs()
4064 sctx->cur_inode_gen, in process_recorded_refs()
4070 ret = send_unlink(sctx, cur->full_path); in process_recorded_refs()
4078 list_for_each_entry(cur, &sctx->new_refs, list) { in process_recorded_refs()
4086 ret = get_cur_inode_state(sctx, cur->dir, cur->dir_gen); in process_recorded_refs()
4095 list_for_each_entry(cur2, &sctx->new_refs, list) { in process_recorded_refs()
4109 ret = did_create_dir(sctx, cur->dir); in process_recorded_refs()
4113 ret = send_create_inode(sctx, cur->dir); in process_recorded_refs()
4119 if (S_ISDIR(sctx->cur_inode_mode) && sctx->parent_root) { in process_recorded_refs()
4120 ret = wait_for_dest_dir_move(sctx, cur, is_orphan); in process_recorded_refs()
4129 if (S_ISDIR(sctx->cur_inode_mode) && sctx->parent_root && in process_recorded_refs()
4131 ret = wait_for_parent_move(sctx, cur, is_orphan); in process_recorded_refs()
4146 ret = send_rename(sctx, valid_path, cur->full_path); in process_recorded_refs()
4154 if (S_ISDIR(sctx->cur_inode_mode)) { in process_recorded_refs()
4160 ret = send_rename(sctx, valid_path, in process_recorded_refs()
4176 ret = update_ref_path(sctx, cur); in process_recorded_refs()
4180 ret = send_link(sctx, cur->full_path, in process_recorded_refs()
4191 if (S_ISDIR(sctx->cur_inode_mode) && sctx->cur_inode_deleted) { in process_recorded_refs()
4198 ret = can_rmdir(sctx, sctx->cur_ino, sctx->cur_inode_gen, in process_recorded_refs()
4199 sctx->cur_ino); in process_recorded_refs()
4203 ret = send_rmdir(sctx, valid_path); in process_recorded_refs()
4207 ret = orphanize_inode(sctx, sctx->cur_ino, in process_recorded_refs()
4208 sctx->cur_inode_gen, valid_path); in process_recorded_refs()
4214 list_for_each_entry(cur, &sctx->deleted_refs, list) { in process_recorded_refs()
4219 } else if (S_ISDIR(sctx->cur_inode_mode) && in process_recorded_refs()
4220 !list_empty(&sctx->deleted_refs)) { in process_recorded_refs()
4224 cur = list_entry(sctx->deleted_refs.next, struct recorded_ref, in process_recorded_refs()
4229 } else if (!S_ISDIR(sctx->cur_inode_mode)) { in process_recorded_refs()
4235 list_for_each_entry(cur, &sctx->deleted_refs, list) { in process_recorded_refs()
4236 ret = did_overwrite_ref(sctx, cur->dir, cur->dir_gen, in process_recorded_refs()
4237 sctx->cur_ino, sctx->cur_inode_gen, in process_recorded_refs()
4250 ret = update_ref_path(sctx, cur); in process_recorded_refs()
4254 ret = send_unlink(sctx, cur->full_path); in process_recorded_refs()
4271 ret = send_unlink(sctx, valid_path); in process_recorded_refs()
4289 if (cur->dir > sctx->cur_ino) in process_recorded_refs()
4292 ret = get_cur_inode_state(sctx, cur->dir, cur->dir_gen); in process_recorded_refs()
4299 ret = send_utimes(sctx, cur->dir, cur->dir_gen); in process_recorded_refs()
4304 ret = can_rmdir(sctx, cur->dir, cur->dir_gen, in process_recorded_refs()
4305 sctx->cur_ino); in process_recorded_refs()
4309 ret = get_cur_path(sctx, cur->dir, in process_recorded_refs()
4313 ret = send_rmdir(sctx, valid_path); in process_recorded_refs()
4325 free_recorded_refs(sctx); in process_recorded_refs()
4334 struct send_ctx *sctx = ctx; in record_ref() local
4347 ret = get_cur_path(sctx, dir, gen, p); in record_ref()
4366 struct send_ctx *sctx = ctx; in __record_new_ref() local
4367 return record_ref(sctx->send_root, dir, name, ctx, &sctx->new_refs); in __record_new_ref()
4375 struct send_ctx *sctx = ctx; in __record_deleted_ref() local
4376 return record_ref(sctx->parent_root, dir, name, ctx, in __record_deleted_ref()
4377 &sctx->deleted_refs); in __record_deleted_ref()
4380 static int record_new_ref(struct send_ctx *sctx) in record_new_ref() argument
4384 ret = iterate_inode_ref(sctx->send_root, sctx->left_path, in record_new_ref()
4385 sctx->cmp_key, 0, __record_new_ref, sctx); in record_new_ref()
4394 static int record_deleted_ref(struct send_ctx *sctx) in record_deleted_ref() argument
4398 ret = iterate_inode_ref(sctx->parent_root, sctx->right_path, in record_deleted_ref()
4399 sctx->cmp_key, 0, __record_deleted_ref, sctx); in record_deleted_ref()
4472 struct send_ctx *sctx = ctx; in __record_changed_new_ref() local
4474 ret = get_inode_info(sctx->send_root, dir, NULL, &dir_gen, NULL, in __record_changed_new_ref()
4479 ret = find_iref(sctx->parent_root, sctx->right_path, in __record_changed_new_ref()
4480 sctx->cmp_key, dir, dir_gen, name); in __record_changed_new_ref()
4482 ret = __record_new_ref(num, dir, index, name, sctx); in __record_changed_new_ref()
4495 struct send_ctx *sctx = ctx; in __record_changed_deleted_ref() local
4497 ret = get_inode_info(sctx->parent_root, dir, NULL, &dir_gen, NULL, in __record_changed_deleted_ref()
4502 ret = find_iref(sctx->send_root, sctx->left_path, sctx->cmp_key, in __record_changed_deleted_ref()
4505 ret = __record_deleted_ref(num, dir, index, name, sctx); in __record_changed_deleted_ref()
4512 static int record_changed_ref(struct send_ctx *sctx) in record_changed_ref() argument
4516 ret = iterate_inode_ref(sctx->send_root, sctx->left_path, in record_changed_ref()
4517 sctx->cmp_key, 0, __record_changed_new_ref, sctx); in record_changed_ref()
4520 ret = iterate_inode_ref(sctx->parent_root, sctx->right_path, in record_changed_ref()
4521 sctx->cmp_key, 0, __record_changed_deleted_ref, sctx); in record_changed_ref()
4534 static int process_all_refs(struct send_ctx *sctx, in process_all_refs() argument
4552 root = sctx->send_root; in process_all_refs()
4555 root = sctx->parent_root; in process_all_refs()
4558 btrfs_err(sctx->send_root->fs_info, in process_all_refs()
4564 key.objectid = sctx->cmp_key->objectid; in process_all_refs()
4590 ret = iterate_inode_ref(root, path, &found_key, 0, cb, sctx); in process_all_refs()
4603 ret = process_recorded_refs(sctx, &pending_move); in process_all_refs()
4609 static int send_set_xattr(struct send_ctx *sctx, in send_set_xattr() argument
4616 ret = begin_cmd(sctx, BTRFS_SEND_C_SET_XATTR); in send_set_xattr()
4620 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path); in send_set_xattr()
4621 TLV_PUT_STRING(sctx, BTRFS_SEND_A_XATTR_NAME, name, name_len); in send_set_xattr()
4622 TLV_PUT(sctx, BTRFS_SEND_A_XATTR_DATA, data, data_len); in send_set_xattr()
4624 ret = send_cmd(sctx); in send_set_xattr()
4631 static int send_remove_xattr(struct send_ctx *sctx, in send_remove_xattr() argument
4637 ret = begin_cmd(sctx, BTRFS_SEND_C_REMOVE_XATTR); in send_remove_xattr()
4641 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path); in send_remove_xattr()
4642 TLV_PUT_STRING(sctx, BTRFS_SEND_A_XATTR_NAME, name, name_len); in send_remove_xattr()
4644 ret = send_cmd(sctx); in send_remove_xattr()
4657 struct send_ctx *sctx = ctx; in __process_new_xattr() local
4685 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in __process_new_xattr()
4689 ret = send_set_xattr(sctx, p, name, name_len, data, data_len); in __process_new_xattr()
4702 struct send_ctx *sctx = ctx; in __process_deleted_xattr() local
4709 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in __process_deleted_xattr()
4713 ret = send_remove_xattr(sctx, p, name, name_len); in __process_deleted_xattr()
4720 static int process_new_xattr(struct send_ctx *sctx) in process_new_xattr() argument
4724 ret = iterate_dir_item(sctx->send_root, sctx->left_path, in process_new_xattr()
4725 __process_new_xattr, sctx); in process_new_xattr()
4730 static int process_deleted_xattr(struct send_ctx *sctx) in process_deleted_xattr() argument
4732 return iterate_dir_item(sctx->parent_root, sctx->right_path, in process_deleted_xattr()
4733 __process_deleted_xattr, sctx); in process_deleted_xattr()
4800 struct send_ctx *sctx = ctx; in __process_changed_new_xattr() local
4804 ret = find_xattr(sctx->parent_root, sctx->right_path, in __process_changed_new_xattr()
4805 sctx->cmp_key, name, name_len, &found_data, in __process_changed_new_xattr()
4830 struct send_ctx *sctx = ctx; in __process_changed_deleted_xattr() local
4832 ret = find_xattr(sctx->send_root, sctx->left_path, sctx->cmp_key, in __process_changed_deleted_xattr()
4843 static int process_changed_xattr(struct send_ctx *sctx) in process_changed_xattr() argument
4847 ret = iterate_dir_item(sctx->send_root, sctx->left_path, in process_changed_xattr()
4848 __process_changed_new_xattr, sctx); in process_changed_xattr()
4851 ret = iterate_dir_item(sctx->parent_root, sctx->right_path, in process_changed_xattr()
4852 __process_changed_deleted_xattr, sctx); in process_changed_xattr()
4858 static int process_all_new_xattrs(struct send_ctx *sctx) in process_all_new_xattrs() argument
4872 root = sctx->send_root; in process_all_new_xattrs()
4874 key.objectid = sctx->cmp_key->objectid; in process_all_new_xattrs()
4902 ret = iterate_dir_item(root, path, __process_new_xattr, sctx); in process_all_new_xattrs()
4914 static inline u64 max_send_read_size(const struct send_ctx *sctx) in max_send_read_size() argument
4916 return sctx->send_max_size - SZ_16K; in max_send_read_size()
4919 static int put_data_header(struct send_ctx *sctx, u32 len) in put_data_header() argument
4923 if (sctx->send_max_size - sctx->send_size < sizeof(*hdr) + len) in put_data_header()
4925 hdr = (struct btrfs_tlv_header *)(sctx->send_buf + sctx->send_size); in put_data_header()
4928 sctx->send_size += sizeof(*hdr); in put_data_header()
4932 static int put_file_data(struct send_ctx *sctx, u64 offset, u32 len) in put_file_data() argument
4934 struct btrfs_root *root = sctx->send_root; in put_file_data()
4944 ret = put_data_header(sctx, len); in put_file_data()
4948 inode = btrfs_iget(fs_info->sb, sctx->cur_ino, root); in put_file_data()
4955 memset(&sctx->ra, 0, sizeof(struct file_ra_state)); in put_file_data()
4956 file_ra_state_init(&sctx->ra, inode->i_mapping); in put_file_data()
4964 page_cache_sync_readahead(inode->i_mapping, &sctx->ra, in put_file_data()
4976 page_cache_async_readahead(inode->i_mapping, &sctx->ra, in put_file_data()
4992 memcpy(sctx->send_buf + sctx->send_size, addr + pg_offset, in put_file_data()
5000 sctx->send_size += cur_len; in put_file_data()
5010 static int send_write(struct send_ctx *sctx, u64 offset, u32 len) in send_write() argument
5012 struct btrfs_fs_info *fs_info = sctx->send_root->fs_info; in send_write()
5022 ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE); in send_write()
5026 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in send_write()
5030 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_write()
5031 TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset); in send_write()
5032 ret = put_file_data(sctx, offset, len); in send_write()
5036 ret = send_cmd(sctx); in send_write()
5047 static int send_clone(struct send_ctx *sctx, in send_clone() argument
5055 btrfs_debug(sctx->send_root->fs_info, in send_clone()
5064 ret = begin_cmd(sctx, BTRFS_SEND_C_CLONE); in send_clone()
5068 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in send_clone()
5072 TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset); in send_clone()
5073 TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_LEN, len); in send_clone()
5074 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_clone()
5076 if (clone_root->root == sctx->send_root) { in send_clone()
5077 ret = get_inode_info(sctx->send_root, clone_root->ino, NULL, in send_clone()
5081 ret = get_cur_path(sctx, clone_root->ino, gen, p); in send_clone()
5098 TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID, in send_clone()
5101 TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID, in send_clone()
5103 TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_CTRANSID, in send_clone()
5105 TLV_PUT_PATH(sctx, BTRFS_SEND_A_CLONE_PATH, p); in send_clone()
5106 TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_OFFSET, in send_clone()
5109 ret = send_cmd(sctx); in send_clone()
5120 static int send_update_extent(struct send_ctx *sctx, in send_update_extent() argument
5130 ret = begin_cmd(sctx, BTRFS_SEND_C_UPDATE_EXTENT); in send_update_extent()
5134 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in send_update_extent()
5138 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_update_extent()
5139 TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset); in send_update_extent()
5140 TLV_PUT_U64(sctx, BTRFS_SEND_A_SIZE, len); in send_update_extent()
5142 ret = send_cmd(sctx); in send_update_extent()
5150 static int send_hole(struct send_ctx *sctx, u64 end) in send_hole() argument
5153 u64 read_size = max_send_read_size(sctx); in send_hole()
5154 u64 offset = sctx->cur_inode_last_extent; in send_hole()
5163 if (offset >= sctx->cur_inode_size) in send_hole()
5170 end = min_t(u64, end, sctx->cur_inode_size); in send_hole()
5172 if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA) in send_hole()
5173 return send_update_extent(sctx, offset, end - offset); in send_hole()
5178 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in send_hole()
5184 ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE); in send_hole()
5187 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_hole()
5188 TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset); in send_hole()
5189 ret = put_data_header(sctx, len); in send_hole()
5192 memset(sctx->send_buf + sctx->send_size, 0, len); in send_hole()
5193 sctx->send_size += len; in send_hole()
5194 ret = send_cmd(sctx); in send_hole()
5199 sctx->cur_inode_next_write_offset = offset; in send_hole()
5205 static int send_extent_data(struct send_ctx *sctx, in send_extent_data() argument
5209 u64 read_size = max_send_read_size(sctx); in send_extent_data()
5212 if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA) in send_extent_data()
5213 return send_update_extent(sctx, offset, len); in send_extent_data()
5219 ret = send_write(sctx, offset + sent, size); in send_extent_data()
5234 static int send_capabilities(struct send_ctx *sctx) in send_capabilities() argument
5249 di = btrfs_lookup_xattr(NULL, sctx->send_root, path, sctx->cur_ino, in send_capabilities()
5269 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath); in send_capabilities()
5276 ret = send_set_xattr(sctx, fspath, XATTR_NAME_CAPS, in send_capabilities()
5285 static int clone_range(struct send_ctx *sctx, in clone_range() argument
5313 len == sctx->send_root->fs_info->sectorsize) in clone_range()
5314 return send_extent_data(sctx, offset, len); in clone_range()
5411 ret = send_extent_data(sctx, offset, hole_len); in clone_range()
5473 offset + clone_len < sctx->cur_inode_size) { in clone_range()
5479 ret = send_clone(sctx, offset, slen, in clone_range()
5484 ret = send_extent_data(sctx, offset + slen, in clone_range()
5487 ret = send_clone(sctx, offset, clone_len, in clone_range()
5491 ret = send_extent_data(sctx, offset, clone_len); in clone_range()
5508 ret = send_extent_data(sctx, offset, len); in clone_range()
5516 static int send_write_or_clone(struct send_ctx *sctx, in send_write_or_clone() argument
5524 u64 bs = sctx->send_root->fs_info->sb->s_blocksize; in send_write_or_clone()
5526 end = min_t(u64, btrfs_file_extent_end(path), sctx->cur_inode_size); in send_write_or_clone()
5539 ret = clone_range(sctx, clone_root, disk_byte, data_offset, in send_write_or_clone()
5542 ret = send_extent_data(sctx, offset, end - offset); in send_write_or_clone()
5544 sctx->cur_inode_next_write_offset = end; in send_write_or_clone()
5548 static int is_extent_unchanged(struct send_ctx *sctx, in is_extent_unchanged() argument
5613 ret = btrfs_search_slot_for_read(sctx->parent_root, &key, path, 0, 0); in is_extent_unchanged()
5703 ret = btrfs_next_item(sctx->parent_root, path); in is_extent_unchanged()
5738 static int get_last_extent(struct send_ctx *sctx, u64 offset) in get_last_extent() argument
5741 struct btrfs_root *root = sctx->send_root; in get_last_extent()
5749 sctx->cur_inode_last_extent = 0; in get_last_extent()
5751 key.objectid = sctx->cur_ino; in get_last_extent()
5759 if (key.objectid != sctx->cur_ino || key.type != BTRFS_EXTENT_DATA_KEY) in get_last_extent()
5762 sctx->cur_inode_last_extent = btrfs_file_extent_end(path); in get_last_extent()
5768 static int range_is_hole_in_parent(struct send_ctx *sctx, in range_is_hole_in_parent() argument
5774 struct btrfs_root *root = sctx->parent_root; in range_is_hole_in_parent()
5782 key.objectid = sctx->cur_ino; in range_is_hole_in_parent()
5807 if (key.objectid < sctx->cur_ino || in range_is_hole_in_parent()
5810 if (key.objectid > sctx->cur_ino || in range_is_hole_in_parent()
5834 static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path, in maybe_send_hole() argument
5839 if (sctx->cur_ino != key->objectid || !need_send_hole(sctx)) in maybe_send_hole()
5842 if (sctx->cur_inode_last_extent == (u64)-1) { in maybe_send_hole()
5843 ret = get_last_extent(sctx, key->offset - 1); in maybe_send_hole()
5849 sctx->cur_inode_last_extent < key->offset) { in maybe_send_hole()
5857 ret = get_last_extent(sctx, key->offset - 1); in maybe_send_hole()
5862 if (sctx->cur_inode_last_extent < key->offset) { in maybe_send_hole()
5863 ret = range_is_hole_in_parent(sctx, in maybe_send_hole()
5864 sctx->cur_inode_last_extent, in maybe_send_hole()
5869 ret = send_hole(sctx, key->offset); in maybe_send_hole()
5873 sctx->cur_inode_last_extent = btrfs_file_extent_end(path); in maybe_send_hole()
5877 static int process_extent(struct send_ctx *sctx, in process_extent() argument
5884 if (S_ISLNK(sctx->cur_inode_mode)) in process_extent()
5887 if (sctx->parent_root && !sctx->cur_inode_new) { in process_extent()
5888 ret = is_extent_unchanged(sctx, path, key); in process_extent()
5923 ret = find_extent_clone(sctx, path, key->objectid, key->offset, in process_extent()
5924 sctx->cur_inode_size, &found_clone); in process_extent()
5928 ret = send_write_or_clone(sctx, path, key, found_clone); in process_extent()
5932 ret = maybe_send_hole(sctx, path, key); in process_extent()
5937 static int process_all_extents(struct send_ctx *sctx) in process_all_extents() argument
5947 root = sctx->send_root; in process_all_extents()
5952 key.objectid = sctx->cmp_key->objectid; in process_all_extents()
5982 ret = process_extent(sctx, path, &found_key); in process_all_extents()
5994 static int process_recorded_refs_if_needed(struct send_ctx *sctx, int at_end, in process_recorded_refs_if_needed() argument
6000 if (sctx->cur_ino == 0) in process_recorded_refs_if_needed()
6002 if (!at_end && sctx->cur_ino == sctx->cmp_key->objectid && in process_recorded_refs_if_needed()
6003 sctx->cmp_key->type <= BTRFS_INODE_EXTREF_KEY) in process_recorded_refs_if_needed()
6005 if (list_empty(&sctx->new_refs) && list_empty(&sctx->deleted_refs)) in process_recorded_refs_if_needed()
6008 ret = process_recorded_refs(sctx, pending_move); in process_recorded_refs_if_needed()
6017 static int finish_inode_if_needed(struct send_ctx *sctx, int at_end) in finish_inode_if_needed() argument
6032 if (sctx->ignore_cur_inode) in finish_inode_if_needed()
6035 ret = process_recorded_refs_if_needed(sctx, at_end, &pending_move, in finish_inode_if_needed()
6053 sctx->send_progress = sctx->cur_ino + 1; in finish_inode_if_needed()
6055 if (sctx->cur_ino == 0 || sctx->cur_inode_deleted) in finish_inode_if_needed()
6057 if (!at_end && sctx->cmp_key->objectid == sctx->cur_ino) in finish_inode_if_needed()
6060 ret = get_inode_info(sctx->send_root, sctx->cur_ino, NULL, NULL, in finish_inode_if_needed()
6065 if (!sctx->parent_root || sctx->cur_inode_new) { in finish_inode_if_needed()
6067 if (!S_ISLNK(sctx->cur_inode_mode)) in finish_inode_if_needed()
6069 if (sctx->cur_inode_next_write_offset == sctx->cur_inode_size) in finish_inode_if_needed()
6074 ret = get_inode_info(sctx->parent_root, sctx->cur_ino, in finish_inode_if_needed()
6082 if (!S_ISLNK(sctx->cur_inode_mode) && left_mode != right_mode) in finish_inode_if_needed()
6084 if ((old_size == sctx->cur_inode_size) || in finish_inode_if_needed()
6085 (sctx->cur_inode_size > old_size && in finish_inode_if_needed()
6086 sctx->cur_inode_next_write_offset == sctx->cur_inode_size)) in finish_inode_if_needed()
6090 if (S_ISREG(sctx->cur_inode_mode)) { in finish_inode_if_needed()
6091 if (need_send_hole(sctx)) { in finish_inode_if_needed()
6092 if (sctx->cur_inode_last_extent == (u64)-1 || in finish_inode_if_needed()
6093 sctx->cur_inode_last_extent < in finish_inode_if_needed()
6094 sctx->cur_inode_size) { in finish_inode_if_needed()
6095 ret = get_last_extent(sctx, (u64)-1); in finish_inode_if_needed()
6099 if (sctx->cur_inode_last_extent < in finish_inode_if_needed()
6100 sctx->cur_inode_size) { in finish_inode_if_needed()
6101 ret = send_hole(sctx, sctx->cur_inode_size); in finish_inode_if_needed()
6107 ret = send_truncate(sctx, sctx->cur_ino, in finish_inode_if_needed()
6108 sctx->cur_inode_gen, in finish_inode_if_needed()
6109 sctx->cur_inode_size); in finish_inode_if_needed()
6116 ret = send_chown(sctx, sctx->cur_ino, sctx->cur_inode_gen, in finish_inode_if_needed()
6122 ret = send_chmod(sctx, sctx->cur_ino, sctx->cur_inode_gen, in finish_inode_if_needed()
6128 ret = send_capabilities(sctx); in finish_inode_if_needed()
6136 if (!is_waiting_for_move(sctx, sctx->cur_ino)) { in finish_inode_if_needed()
6137 ret = apply_children_dir_moves(sctx); in finish_inode_if_needed()
6147 sctx->send_progress = sctx->cur_ino + 1; in finish_inode_if_needed()
6148 ret = send_utimes(sctx, sctx->cur_ino, sctx->cur_inode_gen); in finish_inode_if_needed()
6159 struct send_ctx *sctx; member
6167 return record_ref(ppctx->sctx->parent_root, dir, name, ppctx->sctx, in record_parent_ref()
6175 static int btrfs_unlink_all_paths(struct send_ctx *sctx) in btrfs_unlink_all_paths() argument
6187 key.objectid = sctx->cur_ino; in btrfs_unlink_all_paths()
6190 ret = btrfs_search_slot(NULL, sctx->parent_root, &key, path, 0, 0); in btrfs_unlink_all_paths()
6195 ctx.sctx = sctx; in btrfs_unlink_all_paths()
6202 ret = btrfs_next_leaf(sctx->parent_root, path); in btrfs_unlink_all_paths()
6211 if (key.objectid != sctx->cur_ino) in btrfs_unlink_all_paths()
6217 ret = iterate_inode_ref(sctx->parent_root, path, &key, 1, in btrfs_unlink_all_paths()
6229 ret = send_unlink(sctx, ref->full_path); in btrfs_unlink_all_paths()
6244 static int changed_inode(struct send_ctx *sctx, in changed_inode() argument
6248 struct btrfs_key *key = sctx->cmp_key; in changed_inode()
6254 sctx->cur_ino = key->objectid; in changed_inode()
6255 sctx->cur_inode_new_gen = 0; in changed_inode()
6256 sctx->cur_inode_last_extent = (u64)-1; in changed_inode()
6257 sctx->cur_inode_next_write_offset = 0; in changed_inode()
6258 sctx->ignore_cur_inode = false; in changed_inode()
6265 sctx->send_progress = sctx->cur_ino; in changed_inode()
6269 left_ii = btrfs_item_ptr(sctx->left_path->nodes[0], in changed_inode()
6270 sctx->left_path->slots[0], in changed_inode()
6272 left_gen = btrfs_inode_generation(sctx->left_path->nodes[0], in changed_inode()
6275 right_ii = btrfs_item_ptr(sctx->right_path->nodes[0], in changed_inode()
6276 sctx->right_path->slots[0], in changed_inode()
6278 right_gen = btrfs_inode_generation(sctx->right_path->nodes[0], in changed_inode()
6282 right_ii = btrfs_item_ptr(sctx->right_path->nodes[0], in changed_inode()
6283 sctx->right_path->slots[0], in changed_inode()
6286 right_gen = btrfs_inode_generation(sctx->right_path->nodes[0], in changed_inode()
6295 sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID) in changed_inode()
6296 sctx->cur_inode_new_gen = 1; in changed_inode()
6317 nlinks = btrfs_inode_nlink(sctx->left_path->nodes[0], left_ii); in changed_inode()
6319 sctx->ignore_cur_inode = true; in changed_inode()
6321 ret = btrfs_unlink_all_paths(sctx); in changed_inode()
6327 sctx->cur_inode_gen = left_gen; in changed_inode()
6328 sctx->cur_inode_new = 1; in changed_inode()
6329 sctx->cur_inode_deleted = 0; in changed_inode()
6330 sctx->cur_inode_size = btrfs_inode_size( in changed_inode()
6331 sctx->left_path->nodes[0], left_ii); in changed_inode()
6332 sctx->cur_inode_mode = btrfs_inode_mode( in changed_inode()
6333 sctx->left_path->nodes[0], left_ii); in changed_inode()
6334 sctx->cur_inode_rdev = btrfs_inode_rdev( in changed_inode()
6335 sctx->left_path->nodes[0], left_ii); in changed_inode()
6336 if (sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID) in changed_inode()
6337 ret = send_create_inode_if_needed(sctx); in changed_inode()
6339 sctx->cur_inode_gen = right_gen; in changed_inode()
6340 sctx->cur_inode_new = 0; in changed_inode()
6341 sctx->cur_inode_deleted = 1; in changed_inode()
6342 sctx->cur_inode_size = btrfs_inode_size( in changed_inode()
6343 sctx->right_path->nodes[0], right_ii); in changed_inode()
6344 sctx->cur_inode_mode = btrfs_inode_mode( in changed_inode()
6345 sctx->right_path->nodes[0], right_ii); in changed_inode()
6354 if (sctx->cur_inode_new_gen) { in changed_inode()
6358 sctx->cur_inode_gen = right_gen; in changed_inode()
6359 sctx->cur_inode_new = 0; in changed_inode()
6360 sctx->cur_inode_deleted = 1; in changed_inode()
6361 sctx->cur_inode_size = btrfs_inode_size( in changed_inode()
6362 sctx->right_path->nodes[0], right_ii); in changed_inode()
6363 sctx->cur_inode_mode = btrfs_inode_mode( in changed_inode()
6364 sctx->right_path->nodes[0], right_ii); in changed_inode()
6365 ret = process_all_refs(sctx, in changed_inode()
6373 sctx->cur_inode_gen = left_gen; in changed_inode()
6374 sctx->cur_inode_new = 1; in changed_inode()
6375 sctx->cur_inode_deleted = 0; in changed_inode()
6376 sctx->cur_inode_size = btrfs_inode_size( in changed_inode()
6377 sctx->left_path->nodes[0], left_ii); in changed_inode()
6378 sctx->cur_inode_mode = btrfs_inode_mode( in changed_inode()
6379 sctx->left_path->nodes[0], left_ii); in changed_inode()
6380 sctx->cur_inode_rdev = btrfs_inode_rdev( in changed_inode()
6381 sctx->left_path->nodes[0], left_ii); in changed_inode()
6382 ret = send_create_inode_if_needed(sctx); in changed_inode()
6386 ret = process_all_refs(sctx, BTRFS_COMPARE_TREE_NEW); in changed_inode()
6393 sctx->send_progress = sctx->cur_ino + 1; in changed_inode()
6399 ret = process_all_extents(sctx); in changed_inode()
6402 ret = process_all_new_xattrs(sctx); in changed_inode()
6406 sctx->cur_inode_gen = left_gen; in changed_inode()
6407 sctx->cur_inode_new = 0; in changed_inode()
6408 sctx->cur_inode_new_gen = 0; in changed_inode()
6409 sctx->cur_inode_deleted = 0; in changed_inode()
6410 sctx->cur_inode_size = btrfs_inode_size( in changed_inode()
6411 sctx->left_path->nodes[0], left_ii); in changed_inode()
6412 sctx->cur_inode_mode = btrfs_inode_mode( in changed_inode()
6413 sctx->left_path->nodes[0], left_ii); in changed_inode()
6431 static int changed_ref(struct send_ctx *sctx, in changed_ref() argument
6436 if (sctx->cur_ino != sctx->cmp_key->objectid) { in changed_ref()
6437 inconsistent_snapshot_error(sctx, result, "reference"); in changed_ref()
6441 if (!sctx->cur_inode_new_gen && in changed_ref()
6442 sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID) { in changed_ref()
6444 ret = record_new_ref(sctx); in changed_ref()
6446 ret = record_deleted_ref(sctx); in changed_ref()
6448 ret = record_changed_ref(sctx); in changed_ref()
6459 static int changed_xattr(struct send_ctx *sctx, in changed_xattr() argument
6464 if (sctx->cur_ino != sctx->cmp_key->objectid) { in changed_xattr()
6465 inconsistent_snapshot_error(sctx, result, "xattr"); in changed_xattr()
6469 if (!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted) { in changed_xattr()
6471 ret = process_new_xattr(sctx); in changed_xattr()
6473 ret = process_deleted_xattr(sctx); in changed_xattr()
6475 ret = process_changed_xattr(sctx); in changed_xattr()
6486 static int changed_extent(struct send_ctx *sctx, in changed_extent() argument
6504 if (sctx->cur_ino != sctx->cmp_key->objectid) in changed_extent()
6507 if (!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted) { in changed_extent()
6509 ret = process_extent(sctx, sctx->left_path, in changed_extent()
6510 sctx->cmp_key); in changed_extent()
6516 static int dir_changed(struct send_ctx *sctx, u64 dir) in dir_changed() argument
6521 ret = get_inode_info(sctx->send_root, dir, NULL, &new_gen, NULL, NULL, in dir_changed()
6526 ret = get_inode_info(sctx->parent_root, dir, NULL, &orig_gen, NULL, in dir_changed()
6534 static int compare_refs(struct send_ctx *sctx, struct btrfs_path *path, in compare_refs() argument
6550 ret = dir_changed(sctx, dirid); in compare_refs()
6565 ret = dir_changed(sctx, dirid); in compare_refs()
6585 struct send_ctx *sctx = ctx; in changed_cb() local
6590 ret = compare_refs(sctx, left_path, key); in changed_cb()
6596 return maybe_send_hole(sctx, left_path, key); in changed_cb()
6604 sctx->left_path = left_path; in changed_cb()
6605 sctx->right_path = right_path; in changed_cb()
6606 sctx->cmp_key = key; in changed_cb()
6608 ret = finish_inode_if_needed(sctx, 0); in changed_cb()
6618 ret = changed_inode(sctx, result); in changed_cb()
6619 } else if (!sctx->ignore_cur_inode) { in changed_cb()
6622 ret = changed_ref(sctx, result); in changed_cb()
6624 ret = changed_xattr(sctx, result); in changed_cb()
6626 ret = changed_extent(sctx, result); in changed_cb()
6633 static int full_send_tree(struct send_ctx *sctx) in full_send_tree() argument
6636 struct btrfs_root *send_root = sctx->send_root; in full_send_tree()
6662 BTRFS_COMPARE_TREE_NEW, sctx); in full_send_tree()
6676 ret = finish_inode_if_needed(sctx, 1); in full_send_tree()
7042 static int send_subvol(struct send_ctx *sctx) in send_subvol() argument
7046 if (!(sctx->flags & BTRFS_SEND_FLAG_OMIT_STREAM_HEADER)) { in send_subvol()
7047 ret = send_header(sctx); in send_subvol()
7052 ret = send_subvol_begin(sctx); in send_subvol()
7056 if (sctx->parent_root) { in send_subvol()
7057 ret = btrfs_compare_trees(sctx->send_root, sctx->parent_root, sctx); in send_subvol()
7060 ret = finish_inode_if_needed(sctx, 1); in send_subvol()
7064 ret = full_send_tree(sctx); in send_subvol()
7070 free_recorded_refs(sctx); in send_subvol()
7087 static int ensure_commit_roots_uptodate(struct send_ctx *sctx) in ensure_commit_roots_uptodate() argument
7093 if (sctx->parent_root && in ensure_commit_roots_uptodate()
7094 sctx->parent_root->node != sctx->parent_root->commit_root) in ensure_commit_roots_uptodate()
7097 for (i = 0; i < sctx->clone_roots_cnt; i++) in ensure_commit_roots_uptodate()
7098 if (sctx->clone_roots[i].root->node != in ensure_commit_roots_uptodate()
7099 sctx->clone_roots[i].root->commit_root) in ensure_commit_roots_uptodate()
7110 trans = btrfs_join_transaction(sctx->send_root); in ensure_commit_roots_uptodate()
7127 static int flush_delalloc_roots(struct send_ctx *sctx) in flush_delalloc_roots() argument
7129 struct btrfs_root *root = sctx->parent_root; in flush_delalloc_roots()
7140 for (i = 0; i < sctx->clone_roots_cnt; i++) { in flush_delalloc_roots()
7141 root = sctx->clone_roots[i].root; in flush_delalloc_roots()
7179 struct send_ctx *sctx = NULL; in btrfs_ioctl_send() local
7227 sctx = kzalloc(sizeof(struct send_ctx), GFP_KERNEL); in btrfs_ioctl_send()
7228 if (!sctx) { in btrfs_ioctl_send()
7233 INIT_LIST_HEAD(&sctx->new_refs); in btrfs_ioctl_send()
7234 INIT_LIST_HEAD(&sctx->deleted_refs); in btrfs_ioctl_send()
7235 INIT_RADIX_TREE(&sctx->name_cache, GFP_KERNEL); in btrfs_ioctl_send()
7236 INIT_LIST_HEAD(&sctx->name_cache_list); in btrfs_ioctl_send()
7238 sctx->flags = arg->flags; in btrfs_ioctl_send()
7240 sctx->send_filp = fget(arg->send_fd); in btrfs_ioctl_send()
7241 if (!sctx->send_filp) { in btrfs_ioctl_send()
7246 sctx->send_root = send_root; in btrfs_ioctl_send()
7251 if (btrfs_root_dead(sctx->send_root)) { in btrfs_ioctl_send()
7256 sctx->clone_roots_cnt = arg->clone_sources_count; in btrfs_ioctl_send()
7258 sctx->send_max_size = BTRFS_SEND_BUF_SIZE; in btrfs_ioctl_send()
7259 sctx->send_buf = kvmalloc(sctx->send_max_size, GFP_KERNEL); in btrfs_ioctl_send()
7260 if (!sctx->send_buf) { in btrfs_ioctl_send()
7265 sctx->pending_dir_moves = RB_ROOT; in btrfs_ioctl_send()
7266 sctx->waiting_dir_moves = RB_ROOT; in btrfs_ioctl_send()
7267 sctx->orphan_dirs = RB_ROOT; in btrfs_ioctl_send()
7269 sctx->clone_roots = kvcalloc(sizeof(*sctx->clone_roots), in btrfs_ioctl_send()
7272 if (!sctx->clone_roots) { in btrfs_ioctl_send()
7319 sctx->clone_roots[i].root = clone_root; in btrfs_ioctl_send()
7327 sctx->parent_root = btrfs_get_fs_root(fs_info, arg->parent_root, in btrfs_ioctl_send()
7329 if (IS_ERR(sctx->parent_root)) { in btrfs_ioctl_send()
7330 ret = PTR_ERR(sctx->parent_root); in btrfs_ioctl_send()
7334 spin_lock(&sctx->parent_root->root_item_lock); in btrfs_ioctl_send()
7335 sctx->parent_root->send_in_progress++; in btrfs_ioctl_send()
7336 if (!btrfs_root_readonly(sctx->parent_root) || in btrfs_ioctl_send()
7337 btrfs_root_dead(sctx->parent_root)) { in btrfs_ioctl_send()
7338 spin_unlock(&sctx->parent_root->root_item_lock); in btrfs_ioctl_send()
7342 if (sctx->parent_root->dedupe_in_progress) { in btrfs_ioctl_send()
7343 dedupe_in_progress_warn(sctx->parent_root); in btrfs_ioctl_send()
7344 spin_unlock(&sctx->parent_root->root_item_lock); in btrfs_ioctl_send()
7348 spin_unlock(&sctx->parent_root->root_item_lock); in btrfs_ioctl_send()
7356 sctx->clone_roots[sctx->clone_roots_cnt++].root = in btrfs_ioctl_send()
7357 btrfs_grab_root(sctx->send_root); in btrfs_ioctl_send()
7360 sort(sctx->clone_roots, sctx->clone_roots_cnt, in btrfs_ioctl_send()
7361 sizeof(*sctx->clone_roots), __clone_root_cmp_sort, in btrfs_ioctl_send()
7365 ret = flush_delalloc_roots(sctx); in btrfs_ioctl_send()
7369 ret = ensure_commit_roots_uptodate(sctx); in btrfs_ioctl_send()
7385 ret = send_subvol(sctx); in btrfs_ioctl_send()
7393 if (!(sctx->flags & BTRFS_SEND_FLAG_OMIT_END_CMD)) { in btrfs_ioctl_send()
7394 ret = begin_cmd(sctx, BTRFS_SEND_C_END); in btrfs_ioctl_send()
7397 ret = send_cmd(sctx); in btrfs_ioctl_send()
7403 WARN_ON(sctx && !ret && !RB_EMPTY_ROOT(&sctx->pending_dir_moves)); in btrfs_ioctl_send()
7404 while (sctx && !RB_EMPTY_ROOT(&sctx->pending_dir_moves)) { in btrfs_ioctl_send()
7408 n = rb_first(&sctx->pending_dir_moves); in btrfs_ioctl_send()
7415 free_pending_move(sctx, pm2); in btrfs_ioctl_send()
7417 free_pending_move(sctx, pm); in btrfs_ioctl_send()
7420 WARN_ON(sctx && !ret && !RB_EMPTY_ROOT(&sctx->waiting_dir_moves)); in btrfs_ioctl_send()
7421 while (sctx && !RB_EMPTY_ROOT(&sctx->waiting_dir_moves)) { in btrfs_ioctl_send()
7425 n = rb_first(&sctx->waiting_dir_moves); in btrfs_ioctl_send()
7427 rb_erase(&dm->node, &sctx->waiting_dir_moves); in btrfs_ioctl_send()
7431 WARN_ON(sctx && !ret && !RB_EMPTY_ROOT(&sctx->orphan_dirs)); in btrfs_ioctl_send()
7432 while (sctx && !RB_EMPTY_ROOT(&sctx->orphan_dirs)) { in btrfs_ioctl_send()
7436 n = rb_first(&sctx->orphan_dirs); in btrfs_ioctl_send()
7438 free_orphan_dir_info(sctx, odi); in btrfs_ioctl_send()
7442 for (i = 0; i < sctx->clone_roots_cnt; i++) { in btrfs_ioctl_send()
7444 sctx->clone_roots[i].root); in btrfs_ioctl_send()
7445 btrfs_put_root(sctx->clone_roots[i].root); in btrfs_ioctl_send()
7448 for (i = 0; sctx && i < clone_sources_to_rollback; i++) { in btrfs_ioctl_send()
7450 sctx->clone_roots[i].root); in btrfs_ioctl_send()
7451 btrfs_put_root(sctx->clone_roots[i].root); in btrfs_ioctl_send()
7456 if (sctx && !IS_ERR_OR_NULL(sctx->parent_root)) { in btrfs_ioctl_send()
7457 btrfs_root_dec_send_in_progress(sctx->parent_root); in btrfs_ioctl_send()
7458 btrfs_put_root(sctx->parent_root); in btrfs_ioctl_send()
7463 if (sctx) { in btrfs_ioctl_send()
7464 if (sctx->send_filp) in btrfs_ioctl_send()
7465 fput(sctx->send_filp); in btrfs_ioctl_send()
7467 kvfree(sctx->clone_roots); in btrfs_ioctl_send()
7468 kvfree(sctx->send_buf); in btrfs_ioctl_send()
7470 name_cache_free(sctx); in btrfs_ioctl_send()
7472 kfree(sctx); in btrfs_ioctl_send()