Lines Matching refs:sctx

275 static int is_waiting_for_move(struct send_ctx *sctx, u64 ino);
278 get_waiting_dir_move(struct send_ctx *sctx, u64 ino);
280 static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino);
282 static int need_send_hole(struct send_ctx *sctx) in need_send_hole() argument
284 return (sctx->parent_root && !sctx->cur_inode_new && in need_send_hole()
285 !sctx->cur_inode_new_gen && !sctx->cur_inode_deleted && in need_send_hole()
286 S_ISREG(sctx->cur_inode_mode)); in need_send_hole()
541 static int tlv_put(struct send_ctx *sctx, u16 attr, const void *data, int len) in tlv_put() argument
545 int left = sctx->send_max_size - sctx->send_size; in tlv_put()
550 hdr = (struct btrfs_tlv_header *) (sctx->send_buf + sctx->send_size); in tlv_put()
554 sctx->send_size += total_len; in tlv_put()
560 static int tlv_put_u##bits(struct send_ctx *sctx, \
564 return tlv_put(sctx, attr, &__tmp, sizeof(__tmp)); \
569 static int tlv_put_string(struct send_ctx *sctx, u16 attr, in tlv_put_string() argument
574 return tlv_put(sctx, attr, str, len); in tlv_put_string()
577 static int tlv_put_uuid(struct send_ctx *sctx, u16 attr, in tlv_put_uuid() argument
580 return tlv_put(sctx, attr, uuid, BTRFS_UUID_SIZE); in tlv_put_uuid()
583 static int tlv_put_btrfs_timespec(struct send_ctx *sctx, u16 attr, in tlv_put_btrfs_timespec() argument
589 return tlv_put(sctx, attr, &bts, sizeof(bts)); in tlv_put_btrfs_timespec()
593 #define TLV_PUT(sctx, attrtype, attrlen, data) \ argument
595 ret = tlv_put(sctx, attrtype, attrlen, data); \
600 #define TLV_PUT_INT(sctx, attrtype, bits, value) \ argument
602 ret = tlv_put_u##bits(sctx, attrtype, value); \
607 #define TLV_PUT_U8(sctx, attrtype, data) TLV_PUT_INT(sctx, attrtype, 8, data) argument
608 #define TLV_PUT_U16(sctx, attrtype, data) TLV_PUT_INT(sctx, attrtype, 16, data) argument
609 #define TLV_PUT_U32(sctx, attrtype, data) TLV_PUT_INT(sctx, attrtype, 32, data) argument
610 #define TLV_PUT_U64(sctx, attrtype, data) TLV_PUT_INT(sctx, attrtype, 64, data) argument
611 #define TLV_PUT_STRING(sctx, attrtype, str, len) \ argument
613 ret = tlv_put_string(sctx, attrtype, str, len); \
617 #define TLV_PUT_PATH(sctx, attrtype, p) \ argument
619 ret = tlv_put_string(sctx, attrtype, p->start, \
624 #define TLV_PUT_UUID(sctx, attrtype, uuid) \ argument
626 ret = tlv_put_uuid(sctx, attrtype, uuid); \
630 #define TLV_PUT_BTRFS_TIMESPEC(sctx, attrtype, eb, ts) \ argument
632 ret = tlv_put_btrfs_timespec(sctx, attrtype, eb, ts); \
637 static int send_header(struct send_ctx *sctx) in send_header() argument
644 return write_buf(sctx->send_filp, &hdr, sizeof(hdr), in send_header()
645 &sctx->send_off); in send_header()
651 static int begin_cmd(struct send_ctx *sctx, int cmd) in begin_cmd() argument
655 if (WARN_ON(!sctx->send_buf)) in begin_cmd()
658 BUG_ON(sctx->send_size); in begin_cmd()
660 sctx->send_size += sizeof(*hdr); in begin_cmd()
661 hdr = (struct btrfs_cmd_header *)sctx->send_buf; in begin_cmd()
667 static int send_cmd(struct send_ctx *sctx) in send_cmd() argument
673 hdr = (struct btrfs_cmd_header *)sctx->send_buf; in send_cmd()
674 hdr->len = cpu_to_le32(sctx->send_size - sizeof(*hdr)); in send_cmd()
677 crc = btrfs_crc32c(0, (unsigned char *)sctx->send_buf, sctx->send_size); in send_cmd()
680 ret = write_buf(sctx->send_filp, sctx->send_buf, sctx->send_size, in send_cmd()
681 &sctx->send_off); in send_cmd()
683 sctx->total_send_size += sctx->send_size; in send_cmd()
684 sctx->cmd_send_size[le16_to_cpu(hdr->cmd)] += sctx->send_size; in send_cmd()
685 sctx->send_size = 0; in send_cmd()
693 static int send_rename(struct send_ctx *sctx, in send_rename() argument
700 ret = begin_cmd(sctx, BTRFS_SEND_C_RENAME); in send_rename()
704 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, from); in send_rename()
705 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_TO, to); in send_rename()
707 ret = send_cmd(sctx); in send_rename()
717 static int send_link(struct send_ctx *sctx, in send_link() argument
724 ret = begin_cmd(sctx, BTRFS_SEND_C_LINK); in send_link()
728 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path); in send_link()
729 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_LINK, lnk); in send_link()
731 ret = send_cmd(sctx); in send_link()
741 static int send_unlink(struct send_ctx *sctx, struct fs_path *path) in send_unlink() argument
747 ret = begin_cmd(sctx, BTRFS_SEND_C_UNLINK); in send_unlink()
751 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path); in send_unlink()
753 ret = send_cmd(sctx); in send_unlink()
763 static int send_rmdir(struct send_ctx *sctx, struct fs_path *path) in send_rmdir() argument
769 ret = begin_cmd(sctx, BTRFS_SEND_C_RMDIR); in send_rmdir()
773 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path); in send_rmdir()
775 ret = send_cmd(sctx); in send_rmdir()
1145 struct send_ctx *sctx; member
1201 found = bsearch((void *)(uintptr_t)root, bctx->sctx->clone_roots, in __iterate_backrefs()
1202 bctx->sctx->clone_roots_cnt, in __iterate_backrefs()
1208 if (found->root == bctx->sctx->send_root && in __iterate_backrefs()
1231 if (found->root == bctx->sctx->send_root) { in __iterate_backrefs()
1273 static int find_extent_clone(struct send_ctx *sctx, in find_extent_clone() argument
1337 down_read(&sctx->send_root->fs_info->commit_root_sem); in find_extent_clone()
1338 ret = extent_from_logical(sctx->send_root->fs_info, disk_byte, tmp_path, in find_extent_clone()
1340 up_read(&sctx->send_root->fs_info->commit_root_sem); in find_extent_clone()
1353 for (i = 0; i < sctx->clone_roots_cnt; i++) { in find_extent_clone()
1354 cur_clone_root = sctx->clone_roots + i; in find_extent_clone()
1360 backref_ctx->sctx = sctx; in find_extent_clone()
1382 ret = iterate_extent_inodes(sctx->send_root->fs_info, in find_extent_clone()
1392 btrfs_err(sctx->send_root->fs_info, "did not find backref in " in find_extent_clone()
1408 for (i = 0; i < sctx->clone_roots_cnt; i++) { in find_extent_clone()
1409 if (sctx->clone_roots[i].found_refs) { in find_extent_clone()
1411 cur_clone_root = sctx->clone_roots + i; in find_extent_clone()
1412 else if (sctx->clone_roots[i].root == sctx->send_root) in find_extent_clone()
1414 cur_clone_root = sctx->clone_roots + i; in find_extent_clone()
1502 static int gen_unique_name(struct send_ctx *sctx, in gen_unique_name() argument
1522 di = btrfs_lookup_dir_item(NULL, sctx->send_root, in gen_unique_name()
1536 if (!sctx->parent_root) { in gen_unique_name()
1542 di = btrfs_lookup_dir_item(NULL, sctx->parent_root, in gen_unique_name()
1574 static int get_cur_inode_state(struct send_ctx *sctx, u64 ino, u64 gen) in get_cur_inode_state() argument
1582 ret = get_inode_info(sctx->send_root, ino, NULL, &left_gen, NULL, NULL, in get_cur_inode_state()
1588 if (!sctx->parent_root) { in get_cur_inode_state()
1591 ret = get_inode_info(sctx->parent_root, ino, NULL, &right_gen, in get_cur_inode_state()
1602 if (ino < sctx->send_progress) in get_cur_inode_state()
1607 if (ino < sctx->send_progress) in get_cur_inode_state()
1616 if (ino < sctx->send_progress) in get_cur_inode_state()
1625 if (ino < sctx->send_progress) in get_cur_inode_state()
1640 static int is_inode_existent(struct send_ctx *sctx, u64 ino, u64 gen) in is_inode_existent() argument
1644 ret = get_cur_inode_state(sctx, ino, gen); in is_inode_existent()
1808 static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen, in will_overwrite_ref() argument
1817 if (!sctx->parent_root) in will_overwrite_ref()
1820 ret = is_inode_existent(sctx, dir, dir_gen); in will_overwrite_ref()
1829 if (sctx->parent_root) { in will_overwrite_ref()
1830 ret = get_inode_info(sctx->parent_root, dir, NULL, &gen, NULL, in will_overwrite_ref()
1842 ret = lookup_dir_item_inode(sctx->parent_root, dir, name, name_len, in will_overwrite_ref()
1856 if (other_inode > sctx->send_progress) { in will_overwrite_ref()
1857 ret = get_inode_info(sctx->parent_root, other_inode, NULL, in will_overwrite_ref()
1879 static int did_overwrite_ref(struct send_ctx *sctx, in did_overwrite_ref() argument
1889 if (!sctx->parent_root) in did_overwrite_ref()
1892 ret = is_inode_existent(sctx, dir, dir_gen); in did_overwrite_ref()
1897 ret = lookup_dir_item_inode(sctx->send_root, dir, name, name_len, in did_overwrite_ref()
1907 ret = get_inode_info(sctx->send_root, ow_inode, NULL, &gen, NULL, NULL, in did_overwrite_ref()
1918 if (ow_inode < sctx->send_progress) in did_overwrite_ref()
1932 static int did_overwrite_first_ref(struct send_ctx *sctx, u64 ino, u64 gen) in did_overwrite_first_ref() argument
1939 if (!sctx->parent_root) in did_overwrite_first_ref()
1946 ret = get_first_ref(sctx->parent_root, ino, &dir, &dir_gen, name); in did_overwrite_first_ref()
1950 ret = did_overwrite_ref(sctx, dir, dir_gen, ino, gen, in did_overwrite_first_ref()
1964 static int name_cache_insert(struct send_ctx *sctx, in name_cache_insert() argument
1970 nce_head = radix_tree_lookup(&sctx->name_cache, in name_cache_insert()
1980 ret = radix_tree_insert(&sctx->name_cache, nce->ino, nce_head); in name_cache_insert()
1988 list_add_tail(&nce->list, &sctx->name_cache_list); in name_cache_insert()
1989 sctx->name_cache_size++; in name_cache_insert()
1994 static void name_cache_delete(struct send_ctx *sctx, in name_cache_delete() argument
1999 nce_head = radix_tree_lookup(&sctx->name_cache, in name_cache_delete()
2002 btrfs_err(sctx->send_root->fs_info, in name_cache_delete()
2004 nce->ino, sctx->name_cache_size); in name_cache_delete()
2009 sctx->name_cache_size--; in name_cache_delete()
2015 radix_tree_delete(&sctx->name_cache, (unsigned long)nce->ino); in name_cache_delete()
2020 static struct name_cache_entry *name_cache_search(struct send_ctx *sctx, in name_cache_search() argument
2026 nce_head = radix_tree_lookup(&sctx->name_cache, (unsigned long)ino); in name_cache_search()
2041 static void name_cache_used(struct send_ctx *sctx, struct name_cache_entry *nce) in name_cache_used() argument
2044 list_add_tail(&nce->list, &sctx->name_cache_list); in name_cache_used()
2050 static void name_cache_clean_unused(struct send_ctx *sctx) in name_cache_clean_unused() argument
2054 if (sctx->name_cache_size < SEND_CTX_NAME_CACHE_CLEAN_SIZE) in name_cache_clean_unused()
2057 while (sctx->name_cache_size > SEND_CTX_MAX_NAME_CACHE_SIZE) { in name_cache_clean_unused()
2058 nce = list_entry(sctx->name_cache_list.next, in name_cache_clean_unused()
2060 name_cache_delete(sctx, nce); in name_cache_clean_unused()
2065 static void name_cache_free(struct send_ctx *sctx) in name_cache_free() argument
2069 while (!list_empty(&sctx->name_cache_list)) { in name_cache_free()
2070 nce = list_entry(sctx->name_cache_list.next, in name_cache_free()
2072 name_cache_delete(sctx, nce); in name_cache_free()
2085 static int __get_cur_name_and_parent(struct send_ctx *sctx, in __get_cur_name_and_parent() argument
2100 nce = name_cache_search(sctx, ino, gen); in __get_cur_name_and_parent()
2102 if (ino < sctx->send_progress && nce->need_later_update) { in __get_cur_name_and_parent()
2103 name_cache_delete(sctx, nce); in __get_cur_name_and_parent()
2107 name_cache_used(sctx, nce); in __get_cur_name_and_parent()
2123 ret = is_inode_existent(sctx, ino, gen); in __get_cur_name_and_parent()
2128 ret = gen_unique_name(sctx, ino, gen, dest); in __get_cur_name_and_parent()
2139 if (ino < sctx->send_progress) in __get_cur_name_and_parent()
2140 ret = get_first_ref(sctx->send_root, ino, in __get_cur_name_and_parent()
2143 ret = get_first_ref(sctx->parent_root, ino, in __get_cur_name_and_parent()
2152 ret = did_overwrite_ref(sctx, *parent_ino, *parent_gen, ino, gen, in __get_cur_name_and_parent()
2158 ret = gen_unique_name(sctx, ino, gen, dest); in __get_cur_name_and_parent()
2182 if (ino < sctx->send_progress) in __get_cur_name_and_parent()
2187 nce_ret = name_cache_insert(sctx, nce); in __get_cur_name_and_parent()
2190 name_cache_clean_unused(sctx); in __get_cur_name_and_parent()
2221 static int get_cur_path(struct send_ctx *sctx, u64 ino, u64 gen, in get_cur_path() argument
2242 if (is_waiting_for_rm(sctx, ino)) { in get_cur_path()
2243 ret = gen_unique_name(sctx, ino, gen, name); in get_cur_path()
2250 if (is_waiting_for_move(sctx, ino)) { in get_cur_path()
2251 ret = get_first_ref(sctx->parent_root, ino, in get_cur_path()
2254 ret = __get_cur_name_and_parent(sctx, ino, gen, in get_cur_path()
2282 static int send_subvol_begin(struct send_ctx *sctx) in send_subvol_begin() argument
2285 struct btrfs_root *send_root = sctx->send_root; in send_subvol_begin()
2286 struct btrfs_root *parent_root = sctx->parent_root; in send_subvol_begin()
2330 ret = begin_cmd(sctx, BTRFS_SEND_C_SNAPSHOT); in send_subvol_begin()
2334 ret = begin_cmd(sctx, BTRFS_SEND_C_SUBVOL); in send_subvol_begin()
2339 TLV_PUT_STRING(sctx, BTRFS_SEND_A_PATH, name, namelen); in send_subvol_begin()
2340 TLV_PUT_UUID(sctx, BTRFS_SEND_A_UUID, in send_subvol_begin()
2341 sctx->send_root->root_item.uuid); in send_subvol_begin()
2342 TLV_PUT_U64(sctx, BTRFS_SEND_A_CTRANSID, in send_subvol_begin()
2343 le64_to_cpu(sctx->send_root->root_item.ctransid)); in send_subvol_begin()
2345 TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID, in send_subvol_begin()
2346 sctx->parent_root->root_item.uuid); in send_subvol_begin()
2347 TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_CTRANSID, in send_subvol_begin()
2348 le64_to_cpu(sctx->parent_root->root_item.ctransid)); in send_subvol_begin()
2351 ret = send_cmd(sctx); in send_subvol_begin()
2360 static int send_truncate(struct send_ctx *sctx, u64 ino, u64 gen, u64 size) in send_truncate() argument
2371 ret = begin_cmd(sctx, BTRFS_SEND_C_TRUNCATE); in send_truncate()
2375 ret = get_cur_path(sctx, ino, gen, p); in send_truncate()
2378 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_truncate()
2379 TLV_PUT_U64(sctx, BTRFS_SEND_A_SIZE, size); in send_truncate()
2381 ret = send_cmd(sctx); in send_truncate()
2389 static int send_chmod(struct send_ctx *sctx, u64 ino, u64 gen, u64 mode) in send_chmod() argument
2400 ret = begin_cmd(sctx, BTRFS_SEND_C_CHMOD); in send_chmod()
2404 ret = get_cur_path(sctx, ino, gen, p); in send_chmod()
2407 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_chmod()
2408 TLV_PUT_U64(sctx, BTRFS_SEND_A_MODE, mode & 07777); in send_chmod()
2410 ret = send_cmd(sctx); in send_chmod()
2418 static int send_chown(struct send_ctx *sctx, u64 ino, u64 gen, u64 uid, u64 gid) in send_chown() argument
2429 ret = begin_cmd(sctx, BTRFS_SEND_C_CHOWN); in send_chown()
2433 ret = get_cur_path(sctx, ino, gen, p); in send_chown()
2436 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_chown()
2437 TLV_PUT_U64(sctx, BTRFS_SEND_A_UID, uid); in send_chown()
2438 TLV_PUT_U64(sctx, BTRFS_SEND_A_GID, gid); in send_chown()
2440 ret = send_cmd(sctx); in send_chown()
2448 static int send_utimes(struct send_ctx *sctx, u64 ino, u64 gen) in send_utimes() argument
2473 ret = btrfs_search_slot(NULL, sctx->send_root, &key, path, 0, 0); in send_utimes()
2481 ret = begin_cmd(sctx, BTRFS_SEND_C_UTIMES); in send_utimes()
2485 ret = get_cur_path(sctx, ino, gen, p); in send_utimes()
2488 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_utimes()
2489 TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_ATIME, eb, &ii->atime); in send_utimes()
2490 TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_MTIME, eb, &ii->mtime); in send_utimes()
2491 TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_CTIME, eb, &ii->ctime); in send_utimes()
2494 ret = send_cmd(sctx); in send_utimes()
2508 static int send_create_inode(struct send_ctx *sctx, u64 ino) in send_create_inode() argument
2523 if (ino != sctx->cur_ino) { in send_create_inode()
2524 ret = get_inode_info(sctx->send_root, ino, NULL, &gen, &mode, in send_create_inode()
2529 gen = sctx->cur_inode_gen; in send_create_inode()
2530 mode = sctx->cur_inode_mode; in send_create_inode()
2531 rdev = sctx->cur_inode_rdev; in send_create_inode()
2553 ret = begin_cmd(sctx, cmd); in send_create_inode()
2557 ret = gen_unique_name(sctx, ino, gen, p); in send_create_inode()
2561 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_create_inode()
2562 TLV_PUT_U64(sctx, BTRFS_SEND_A_INO, ino); in send_create_inode()
2566 ret = read_symlink(sctx->send_root, ino, p); in send_create_inode()
2569 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_LINK, p); in send_create_inode()
2572 TLV_PUT_U64(sctx, BTRFS_SEND_A_RDEV, new_encode_dev(rdev)); in send_create_inode()
2573 TLV_PUT_U64(sctx, BTRFS_SEND_A_MODE, mode); in send_create_inode()
2576 ret = send_cmd(sctx); in send_create_inode()
2592 static int did_create_dir(struct send_ctx *sctx, u64 dir) in did_create_dir() argument
2612 ret = btrfs_search_slot(NULL, sctx->send_root, &key, path, 0, 0); in did_create_dir()
2620 ret = btrfs_next_leaf(sctx->send_root, path); in did_create_dir()
2641 di_key.objectid < sctx->send_progress) { in did_create_dir()
2660 static int send_create_inode_if_needed(struct send_ctx *sctx) in send_create_inode_if_needed() argument
2664 if (S_ISDIR(sctx->cur_inode_mode)) { in send_create_inode_if_needed()
2665 ret = did_create_dir(sctx, sctx->cur_ino); in send_create_inode_if_needed()
2674 ret = send_create_inode(sctx, sctx->cur_ino); in send_create_inode_if_needed()
2752 static void free_recorded_refs(struct send_ctx *sctx) in free_recorded_refs() argument
2754 __free_recorded_refs(&sctx->new_refs); in free_recorded_refs()
2755 __free_recorded_refs(&sctx->deleted_refs); in free_recorded_refs()
2763 static int orphanize_inode(struct send_ctx *sctx, u64 ino, u64 gen, in orphanize_inode() argument
2773 ret = gen_unique_name(sctx, ino, gen, orphan); in orphanize_inode()
2777 ret = send_rename(sctx, path, orphan); in orphanize_inode()
2785 add_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino) in add_orphan_dir_info() argument
2787 struct rb_node **p = &sctx->orphan_dirs.rb_node; in add_orphan_dir_info()
2811 rb_insert_color(&odi->node, &sctx->orphan_dirs); in add_orphan_dir_info()
2816 get_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino) in get_orphan_dir_info() argument
2818 struct rb_node *n = sctx->orphan_dirs.rb_node; in get_orphan_dir_info()
2833 static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino) in is_waiting_for_rm() argument
2835 struct orphan_dir_info *odi = get_orphan_dir_info(sctx, dir_ino); in is_waiting_for_rm()
2840 static void free_orphan_dir_info(struct send_ctx *sctx, in free_orphan_dir_info() argument
2845 rb_erase(&odi->node, &sctx->orphan_dirs); in free_orphan_dir_info()
2854 static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 dir_gen, in can_rmdir() argument
2858 struct btrfs_root *root = sctx->parent_root; in can_rmdir()
2903 dm = get_waiting_dir_move(sctx, loc.objectid); in can_rmdir()
2907 odi = add_orphan_dir_info(sctx, dir); in can_rmdir()
2933 static int is_waiting_for_move(struct send_ctx *sctx, u64 ino) in is_waiting_for_move() argument
2935 struct waiting_dir_move *entry = get_waiting_dir_move(sctx, ino); in is_waiting_for_move()
2940 static int add_waiting_dir_move(struct send_ctx *sctx, u64 ino) in add_waiting_dir_move() argument
2942 struct rb_node **p = &sctx->waiting_dir_moves.rb_node; in add_waiting_dir_move()
2966 rb_insert_color(&dm->node, &sctx->waiting_dir_moves); in add_waiting_dir_move()
2971 get_waiting_dir_move(struct send_ctx *sctx, u64 ino) in get_waiting_dir_move() argument
2973 struct rb_node *n = sctx->waiting_dir_moves.rb_node; in get_waiting_dir_move()
2988 static void free_waiting_dir_move(struct send_ctx *sctx, in free_waiting_dir_move() argument
2993 rb_erase(&dm->node, &sctx->waiting_dir_moves); in free_waiting_dir_move()
2997 static int add_pending_dir_move(struct send_ctx *sctx, in add_pending_dir_move() argument
3005 struct rb_node **p = &sctx->pending_dir_moves.rb_node; in add_pending_dir_move()
3047 ret = add_waiting_dir_move(sctx, pm->ino); in add_pending_dir_move()
3055 rb_insert_color(&pm->node, &sctx->pending_dir_moves); in add_pending_dir_move()
3066 static struct pending_dir_move *get_pending_dir_moves(struct send_ctx *sctx, in get_pending_dir_moves() argument
3069 struct rb_node *n = sctx->pending_dir_moves.rb_node; in get_pending_dir_moves()
3084 static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) in apply_dir_move() argument
3089 u64 orig_progress = sctx->send_progress; in apply_dir_move()
3103 dm = get_waiting_dir_move(sctx, pm->ino); in apply_dir_move()
3106 free_waiting_dir_move(sctx, dm); in apply_dir_move()
3109 ret = gen_unique_name(sctx, pm->ino, in apply_dir_move()
3112 ret = get_first_ref(sctx->parent_root, pm->ino, in apply_dir_move()
3116 ret = get_cur_path(sctx, parent_ino, parent_gen, in apply_dir_move()
3125 sctx->send_progress = sctx->cur_ino + 1; in apply_dir_move()
3129 ret = get_cur_path(sctx, pm->ino, pm->gen, to_path); in apply_dir_move()
3133 ret = send_rename(sctx, from_path, to_path); in apply_dir_move()
3140 odi = get_orphan_dir_info(sctx, rmdir_ino); in apply_dir_move()
3145 ret = can_rmdir(sctx, rmdir_ino, odi->gen, sctx->cur_ino + 1); in apply_dir_move()
3156 ret = get_cur_path(sctx, rmdir_ino, odi->gen, name); in apply_dir_move()
3159 ret = send_rmdir(sctx, name); in apply_dir_move()
3162 free_orphan_dir_info(sctx, odi); in apply_dir_move()
3166 ret = send_utimes(sctx, pm->ino, pm->gen); in apply_dir_move()
3177 ret = send_utimes(sctx, cur->dir, cur->dir_gen); in apply_dir_move()
3186 sctx->send_progress = orig_progress; in apply_dir_move()
3191 static void free_pending_move(struct send_ctx *sctx, struct pending_dir_move *m) in free_pending_move() argument
3196 rb_erase(&m->node, &sctx->pending_dir_moves); in free_pending_move()
3214 static int apply_children_dir_moves(struct send_ctx *sctx) in apply_children_dir_moves() argument
3218 u64 parent_ino = sctx->cur_ino; in apply_children_dir_moves()
3221 pm = get_pending_dir_moves(sctx, parent_ino); in apply_children_dir_moves()
3231 ret = apply_dir_move(sctx, pm); in apply_children_dir_moves()
3232 free_pending_move(sctx, pm); in apply_children_dir_moves()
3235 pm = get_pending_dir_moves(sctx, parent_ino); in apply_children_dir_moves()
3244 free_pending_move(sctx, pm); in apply_children_dir_moves()
3285 static int wait_for_dest_dir_move(struct send_ctx *sctx, in wait_for_dest_dir_move() argument
3297 if (RB_EMPTY_ROOT(&sctx->waiting_dir_moves)) in wait_for_dest_dir_move()
3308 ret = btrfs_search_slot(NULL, sctx->parent_root, &key, path, 0, 0); in wait_for_dest_dir_move()
3316 di = btrfs_match_dir_item_name(sctx->parent_root, path, in wait_for_dest_dir_move()
3336 ret = get_inode_info(sctx->parent_root, di_key.objectid, NULL, in wait_for_dest_dir_move()
3340 ret = get_inode_info(sctx->send_root, di_key.objectid, NULL, in wait_for_dest_dir_move()
3354 if (is_waiting_for_move(sctx, di_key.objectid)) { in wait_for_dest_dir_move()
3355 ret = add_pending_dir_move(sctx, in wait_for_dest_dir_move()
3356 sctx->cur_ino, in wait_for_dest_dir_move()
3357 sctx->cur_inode_gen, in wait_for_dest_dir_move()
3359 &sctx->new_refs, in wait_for_dest_dir_move()
3360 &sctx->deleted_refs, in wait_for_dest_dir_move()
3370 static int wait_for_parent_move(struct send_ctx *sctx, in wait_for_parent_move() argument
3394 if (is_waiting_for_move(sctx, ino)) { in wait_for_parent_move()
3402 ret = get_first_ref(sctx->send_root, ino, &parent_ino_after, in wait_for_parent_move()
3406 ret = get_first_ref(sctx->parent_root, ino, &parent_ino_before, in wait_for_parent_move()
3417 if (ino > sctx->cur_ino && in wait_for_parent_move()
3431 ret = add_pending_dir_move(sctx, in wait_for_parent_move()
3432 sctx->cur_ino, in wait_for_parent_move()
3433 sctx->cur_inode_gen, in wait_for_parent_move()
3435 &sctx->new_refs, in wait_for_parent_move()
3436 &sctx->deleted_refs, in wait_for_parent_move()
3448 static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) in process_recorded_refs() argument
3462 verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); in process_recorded_refs()
3468 BUG_ON(sctx->cur_ino <= BTRFS_FIRST_FREE_OBJECTID); in process_recorded_refs()
3488 if (!sctx->cur_inode_new) { in process_recorded_refs()
3489 ret = did_overwrite_first_ref(sctx, sctx->cur_ino, in process_recorded_refs()
3490 sctx->cur_inode_gen); in process_recorded_refs()
3496 if (sctx->cur_inode_new || did_overwrite) { in process_recorded_refs()
3497 ret = gen_unique_name(sctx, sctx->cur_ino, in process_recorded_refs()
3498 sctx->cur_inode_gen, valid_path); in process_recorded_refs()
3503 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, in process_recorded_refs()
3509 list_for_each_entry(cur, &sctx->new_refs, list) { in process_recorded_refs()
3517 ret = get_cur_inode_state(sctx, cur->dir, cur->dir_gen); in process_recorded_refs()
3526 list_for_each_entry(cur2, &sctx->new_refs, list) { in process_recorded_refs()
3540 ret = did_create_dir(sctx, cur->dir); in process_recorded_refs()
3544 ret = send_create_inode(sctx, cur->dir); in process_recorded_refs()
3556 ret = will_overwrite_ref(sctx, cur->dir, cur->dir_gen, in process_recorded_refs()
3562 ret = is_first_ref(sctx->parent_root, in process_recorded_refs()
3570 ret = orphanize_inode(sctx, ow_inode, ow_gen, in process_recorded_refs()
3584 nce = name_cache_search(sctx, ow_inode, ow_gen); in process_recorded_refs()
3586 name_cache_delete(sctx, nce); in process_recorded_refs()
3590 ret = send_unlink(sctx, cur->full_path); in process_recorded_refs()
3596 if (S_ISDIR(sctx->cur_inode_mode) && sctx->parent_root) { in process_recorded_refs()
3597 ret = wait_for_dest_dir_move(sctx, cur, is_orphan); in process_recorded_refs()
3612 ret = send_rename(sctx, valid_path, cur->full_path); in process_recorded_refs()
3620 if (S_ISDIR(sctx->cur_inode_mode)) { in process_recorded_refs()
3626 ret = wait_for_parent_move(sctx, cur); in process_recorded_refs()
3632 ret = send_rename(sctx, valid_path, in process_recorded_refs()
3641 ret = send_link(sctx, cur->full_path, in process_recorded_refs()
3652 if (S_ISDIR(sctx->cur_inode_mode) && sctx->cur_inode_deleted) { in process_recorded_refs()
3659 ret = can_rmdir(sctx, sctx->cur_ino, sctx->cur_inode_gen, in process_recorded_refs()
3660 sctx->cur_ino); in process_recorded_refs()
3664 ret = send_rmdir(sctx, valid_path); in process_recorded_refs()
3668 ret = orphanize_inode(sctx, sctx->cur_ino, in process_recorded_refs()
3669 sctx->cur_inode_gen, valid_path); in process_recorded_refs()
3675 list_for_each_entry(cur, &sctx->deleted_refs, list) { in process_recorded_refs()
3680 } else if (S_ISDIR(sctx->cur_inode_mode) && in process_recorded_refs()
3681 !list_empty(&sctx->deleted_refs)) { in process_recorded_refs()
3685 cur = list_entry(sctx->deleted_refs.next, struct recorded_ref, in process_recorded_refs()
3690 } else if (!S_ISDIR(sctx->cur_inode_mode)) { in process_recorded_refs()
3696 list_for_each_entry(cur, &sctx->deleted_refs, list) { in process_recorded_refs()
3697 ret = did_overwrite_ref(sctx, cur->dir, cur->dir_gen, in process_recorded_refs()
3698 sctx->cur_ino, sctx->cur_inode_gen, in process_recorded_refs()
3703 ret = send_unlink(sctx, cur->full_path); in process_recorded_refs()
3720 ret = send_unlink(sctx, valid_path); in process_recorded_refs()
3738 if (cur->dir > sctx->cur_ino) in process_recorded_refs()
3741 ret = get_cur_inode_state(sctx, cur->dir, cur->dir_gen); in process_recorded_refs()
3748 ret = send_utimes(sctx, cur->dir, cur->dir_gen); in process_recorded_refs()
3753 ret = can_rmdir(sctx, cur->dir, cur->dir_gen, in process_recorded_refs()
3754 sctx->cur_ino); in process_recorded_refs()
3758 ret = get_cur_path(sctx, cur->dir, in process_recorded_refs()
3762 ret = send_rmdir(sctx, valid_path); in process_recorded_refs()
3774 free_recorded_refs(sctx); in process_recorded_refs()
3783 struct send_ctx *sctx = ctx; in record_ref() local
3796 ret = get_cur_path(sctx, dir, gen, p); in record_ref()
3815 struct send_ctx *sctx = ctx; in __record_new_ref() local
3816 return record_ref(sctx->send_root, num, dir, index, name, in __record_new_ref()
3817 ctx, &sctx->new_refs); in __record_new_ref()
3825 struct send_ctx *sctx = ctx; in __record_deleted_ref() local
3826 return record_ref(sctx->parent_root, num, dir, index, name, in __record_deleted_ref()
3827 ctx, &sctx->deleted_refs); in __record_deleted_ref()
3830 static int record_new_ref(struct send_ctx *sctx) in record_new_ref() argument
3834 ret = iterate_inode_ref(sctx->send_root, sctx->left_path, in record_new_ref()
3835 sctx->cmp_key, 0, __record_new_ref, sctx); in record_new_ref()
3844 static int record_deleted_ref(struct send_ctx *sctx) in record_deleted_ref() argument
3848 ret = iterate_inode_ref(sctx->parent_root, sctx->right_path, in record_deleted_ref()
3849 sctx->cmp_key, 0, __record_deleted_ref, sctx); in record_deleted_ref()
3922 struct send_ctx *sctx = ctx; in __record_changed_new_ref() local
3924 ret = get_inode_info(sctx->send_root, dir, NULL, &dir_gen, NULL, in __record_changed_new_ref()
3929 ret = find_iref(sctx->parent_root, sctx->right_path, in __record_changed_new_ref()
3930 sctx->cmp_key, dir, dir_gen, name); in __record_changed_new_ref()
3932 ret = __record_new_ref(num, dir, index, name, sctx); in __record_changed_new_ref()
3945 struct send_ctx *sctx = ctx; in __record_changed_deleted_ref() local
3947 ret = get_inode_info(sctx->parent_root, dir, NULL, &dir_gen, NULL, in __record_changed_deleted_ref()
3952 ret = find_iref(sctx->send_root, sctx->left_path, sctx->cmp_key, in __record_changed_deleted_ref()
3955 ret = __record_deleted_ref(num, dir, index, name, sctx); in __record_changed_deleted_ref()
3962 static int record_changed_ref(struct send_ctx *sctx) in record_changed_ref() argument
3966 ret = iterate_inode_ref(sctx->send_root, sctx->left_path, in record_changed_ref()
3967 sctx->cmp_key, 0, __record_changed_new_ref, sctx); in record_changed_ref()
3970 ret = iterate_inode_ref(sctx->parent_root, sctx->right_path, in record_changed_ref()
3971 sctx->cmp_key, 0, __record_changed_deleted_ref, sctx); in record_changed_ref()
3984 static int process_all_refs(struct send_ctx *sctx, in process_all_refs() argument
4002 root = sctx->send_root; in process_all_refs()
4005 root = sctx->parent_root; in process_all_refs()
4008 btrfs_err(sctx->send_root->fs_info, in process_all_refs()
4014 key.objectid = sctx->cmp_key->objectid; in process_all_refs()
4040 ret = iterate_inode_ref(root, path, &found_key, 0, cb, sctx); in process_all_refs()
4048 ret = process_recorded_refs(sctx, &pending_move); in process_all_refs()
4057 static int send_set_xattr(struct send_ctx *sctx, in send_set_xattr() argument
4064 ret = begin_cmd(sctx, BTRFS_SEND_C_SET_XATTR); in send_set_xattr()
4068 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path); in send_set_xattr()
4069 TLV_PUT_STRING(sctx, BTRFS_SEND_A_XATTR_NAME, name, name_len); in send_set_xattr()
4070 TLV_PUT(sctx, BTRFS_SEND_A_XATTR_DATA, data, data_len); in send_set_xattr()
4072 ret = send_cmd(sctx); in send_set_xattr()
4079 static int send_remove_xattr(struct send_ctx *sctx, in send_remove_xattr() argument
4085 ret = begin_cmd(sctx, BTRFS_SEND_C_REMOVE_XATTR); in send_remove_xattr()
4089 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path); in send_remove_xattr()
4090 TLV_PUT_STRING(sctx, BTRFS_SEND_A_XATTR_NAME, name, name_len); in send_remove_xattr()
4092 ret = send_cmd(sctx); in send_remove_xattr()
4105 struct send_ctx *sctx = ctx; in __process_new_xattr() local
4129 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in __process_new_xattr()
4133 ret = send_set_xattr(sctx, p, name, name_len, data, data_len); in __process_new_xattr()
4146 struct send_ctx *sctx = ctx; in __process_deleted_xattr() local
4153 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in __process_deleted_xattr()
4157 ret = send_remove_xattr(sctx, p, name, name_len); in __process_deleted_xattr()
4164 static int process_new_xattr(struct send_ctx *sctx) in process_new_xattr() argument
4168 ret = iterate_dir_item(sctx->send_root, sctx->left_path, in process_new_xattr()
4169 sctx->cmp_key, __process_new_xattr, sctx); in process_new_xattr()
4174 static int process_deleted_xattr(struct send_ctx *sctx) in process_deleted_xattr() argument
4178 ret = iterate_dir_item(sctx->parent_root, sctx->right_path, in process_deleted_xattr()
4179 sctx->cmp_key, __process_deleted_xattr, sctx); in process_deleted_xattr()
4248 struct send_ctx *sctx = ctx; in __process_changed_new_xattr() local
4252 ret = find_xattr(sctx->parent_root, sctx->right_path, in __process_changed_new_xattr()
4253 sctx->cmp_key, name, name_len, &found_data, in __process_changed_new_xattr()
4278 struct send_ctx *sctx = ctx; in __process_changed_deleted_xattr() local
4280 ret = find_xattr(sctx->send_root, sctx->left_path, sctx->cmp_key, in __process_changed_deleted_xattr()
4291 static int process_changed_xattr(struct send_ctx *sctx) in process_changed_xattr() argument
4295 ret = iterate_dir_item(sctx->send_root, sctx->left_path, in process_changed_xattr()
4296 sctx->cmp_key, __process_changed_new_xattr, sctx); in process_changed_xattr()
4299 ret = iterate_dir_item(sctx->parent_root, sctx->right_path, in process_changed_xattr()
4300 sctx->cmp_key, __process_changed_deleted_xattr, sctx); in process_changed_xattr()
4306 static int process_all_new_xattrs(struct send_ctx *sctx) in process_all_new_xattrs() argument
4320 root = sctx->send_root; in process_all_new_xattrs()
4322 key.objectid = sctx->cmp_key->objectid; in process_all_new_xattrs()
4351 __process_new_xattr, sctx); in process_all_new_xattrs()
4363 static ssize_t fill_read_buf(struct send_ctx *sctx, u64 offset, u32 len) in fill_read_buf() argument
4365 struct btrfs_root *root = sctx->send_root; in fill_read_buf()
4376 key.objectid = sctx->cur_ino; in fill_read_buf()
4396 memset(&sctx->ra, 0, sizeof(struct file_ra_state)); in fill_read_buf()
4397 file_ra_state_init(&sctx->ra, inode->i_mapping); in fill_read_buf()
4398 btrfs_force_ra(inode->i_mapping, &sctx->ra, NULL, index, in fill_read_buf()
4422 memcpy(sctx->read_buf + ret, addr + pg_offset, cur_len); in fill_read_buf()
4440 static int send_write(struct send_ctx *sctx, u64 offset, u32 len) in send_write() argument
4452 num_read = fill_read_buf(sctx, offset, len); in send_write()
4459 ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE); in send_write()
4463 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in send_write()
4467 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_write()
4468 TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset); in send_write()
4469 TLV_PUT(sctx, BTRFS_SEND_A_DATA, sctx->read_buf, num_read); in send_write()
4471 ret = send_cmd(sctx); in send_write()
4484 static int send_clone(struct send_ctx *sctx, in send_clone() argument
4501 ret = begin_cmd(sctx, BTRFS_SEND_C_CLONE); in send_clone()
4505 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in send_clone()
4509 TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset); in send_clone()
4510 TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_LEN, len); in send_clone()
4511 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_clone()
4513 if (clone_root->root == sctx->send_root) { in send_clone()
4514 ret = get_inode_info(sctx->send_root, clone_root->ino, NULL, in send_clone()
4518 ret = get_cur_path(sctx, clone_root->ino, gen, p); in send_clone()
4525 TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID, in send_clone()
4527 TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_CTRANSID, in send_clone()
4529 TLV_PUT_PATH(sctx, BTRFS_SEND_A_CLONE_PATH, p); in send_clone()
4530 TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_OFFSET, in send_clone()
4533 ret = send_cmd(sctx); in send_clone()
4544 static int send_update_extent(struct send_ctx *sctx, in send_update_extent() argument
4554 ret = begin_cmd(sctx, BTRFS_SEND_C_UPDATE_EXTENT); in send_update_extent()
4558 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in send_update_extent()
4562 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_update_extent()
4563 TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset); in send_update_extent()
4564 TLV_PUT_U64(sctx, BTRFS_SEND_A_SIZE, len); in send_update_extent()
4566 ret = send_cmd(sctx); in send_update_extent()
4574 static int send_hole(struct send_ctx *sctx, u64 end) in send_hole() argument
4577 u64 offset = sctx->cur_inode_last_extent; in send_hole()
4584 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p); in send_hole()
4587 memset(sctx->read_buf, 0, BTRFS_SEND_READ_SIZE); in send_hole()
4591 ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE); in send_hole()
4594 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p); in send_hole()
4595 TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset); in send_hole()
4596 TLV_PUT(sctx, BTRFS_SEND_A_DATA, sctx->read_buf, len); in send_hole()
4597 ret = send_cmd(sctx); in send_hole()
4607 static int send_write_or_clone(struct send_ctx *sctx, in send_write_or_clone() argument
4619 u64 bs = sctx->send_root->fs_info->sb->s_blocksize; in send_write_or_clone()
4637 if (offset + len > sctx->cur_inode_size) in send_write_or_clone()
4638 len = sctx->cur_inode_size - offset; in send_write_or_clone()
4645 ret = send_clone(sctx, offset, len, clone_root); in send_write_or_clone()
4646 } else if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA) { in send_write_or_clone()
4647 ret = send_update_extent(sctx, offset, len); in send_write_or_clone()
4653 ret = send_write(sctx, pos + offset, l); in send_write_or_clone()
4666 static int is_extent_unchanged(struct send_ctx *sctx, in is_extent_unchanged() argument
4731 ret = btrfs_search_slot_for_read(sctx->parent_root, &key, path, 0, 0); in is_extent_unchanged()
4801 ret = btrfs_next_item(sctx->parent_root, path); in is_extent_unchanged()
4836 static int get_last_extent(struct send_ctx *sctx, u64 offset) in get_last_extent() argument
4839 struct btrfs_root *root = sctx->send_root; in get_last_extent()
4850 sctx->cur_inode_last_extent = 0; in get_last_extent()
4852 key.objectid = sctx->cur_ino; in get_last_extent()
4860 if (key.objectid != sctx->cur_ino || key.type != BTRFS_EXTENT_DATA_KEY) in get_last_extent()
4870 sctx->send_root->sectorsize); in get_last_extent()
4875 sctx->cur_inode_last_extent = extent_end; in get_last_extent()
4881 static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path, in maybe_send_hole() argument
4889 if (sctx->cur_ino != key->objectid || !need_send_hole(sctx)) in maybe_send_hole()
4892 if (sctx->cur_inode_last_extent == (u64)-1) { in maybe_send_hole()
4893 ret = get_last_extent(sctx, key->offset - 1); in maybe_send_hole()
4905 sctx->send_root->sectorsize); in maybe_send_hole()
4912 sctx->cur_inode_last_extent < key->offset) { in maybe_send_hole()
4920 ret = get_last_extent(sctx, key->offset - 1); in maybe_send_hole()
4925 if (sctx->cur_inode_last_extent < key->offset) in maybe_send_hole()
4926 ret = send_hole(sctx, key->offset); in maybe_send_hole()
4927 sctx->cur_inode_last_extent = extent_end; in maybe_send_hole()
4931 static int process_extent(struct send_ctx *sctx, in process_extent() argument
4938 if (S_ISLNK(sctx->cur_inode_mode)) in process_extent()
4941 if (sctx->parent_root && !sctx->cur_inode_new) { in process_extent()
4942 ret = is_extent_unchanged(sctx, path, key); in process_extent()
4977 ret = find_extent_clone(sctx, path, key->objectid, key->offset, in process_extent()
4978 sctx->cur_inode_size, &found_clone); in process_extent()
4982 ret = send_write_or_clone(sctx, path, key, found_clone); in process_extent()
4986 ret = maybe_send_hole(sctx, path, key); in process_extent()
4991 static int process_all_extents(struct send_ctx *sctx) in process_all_extents() argument
5001 root = sctx->send_root; in process_all_extents()
5006 key.objectid = sctx->cmp_key->objectid; in process_all_extents()
5036 ret = process_extent(sctx, path, &found_key); in process_all_extents()
5048 static int process_recorded_refs_if_needed(struct send_ctx *sctx, int at_end, in process_recorded_refs_if_needed() argument
5054 if (sctx->cur_ino == 0) in process_recorded_refs_if_needed()
5056 if (!at_end && sctx->cur_ino == sctx->cmp_key->objectid && in process_recorded_refs_if_needed()
5057 sctx->cmp_key->type <= BTRFS_INODE_EXTREF_KEY) in process_recorded_refs_if_needed()
5059 if (list_empty(&sctx->new_refs) && list_empty(&sctx->deleted_refs)) in process_recorded_refs_if_needed()
5062 ret = process_recorded_refs(sctx, pending_move); in process_recorded_refs_if_needed()
5071 static int finish_inode_if_needed(struct send_ctx *sctx, int at_end) in finish_inode_if_needed() argument
5085 ret = process_recorded_refs_if_needed(sctx, at_end, &pending_move, in finish_inode_if_needed()
5103 sctx->send_progress = sctx->cur_ino + 1; in finish_inode_if_needed()
5105 if (sctx->cur_ino == 0 || sctx->cur_inode_deleted) in finish_inode_if_needed()
5107 if (!at_end && sctx->cmp_key->objectid == sctx->cur_ino) in finish_inode_if_needed()
5110 ret = get_inode_info(sctx->send_root, sctx->cur_ino, NULL, NULL, in finish_inode_if_needed()
5115 if (!sctx->parent_root || sctx->cur_inode_new) { in finish_inode_if_needed()
5117 if (!S_ISLNK(sctx->cur_inode_mode)) in finish_inode_if_needed()
5120 ret = get_inode_info(sctx->parent_root, sctx->cur_ino, in finish_inode_if_needed()
5128 if (!S_ISLNK(sctx->cur_inode_mode) && left_mode != right_mode) in finish_inode_if_needed()
5132 if (S_ISREG(sctx->cur_inode_mode)) { in finish_inode_if_needed()
5133 if (need_send_hole(sctx)) { in finish_inode_if_needed()
5134 if (sctx->cur_inode_last_extent == (u64)-1 || in finish_inode_if_needed()
5135 sctx->cur_inode_last_extent < in finish_inode_if_needed()
5136 sctx->cur_inode_size) { in finish_inode_if_needed()
5137 ret = get_last_extent(sctx, (u64)-1); in finish_inode_if_needed()
5141 if (sctx->cur_inode_last_extent < in finish_inode_if_needed()
5142 sctx->cur_inode_size) { in finish_inode_if_needed()
5143 ret = send_hole(sctx, sctx->cur_inode_size); in finish_inode_if_needed()
5148 ret = send_truncate(sctx, sctx->cur_ino, sctx->cur_inode_gen, in finish_inode_if_needed()
5149 sctx->cur_inode_size); in finish_inode_if_needed()
5155 ret = send_chown(sctx, sctx->cur_ino, sctx->cur_inode_gen, in finish_inode_if_needed()
5161 ret = send_chmod(sctx, sctx->cur_ino, sctx->cur_inode_gen, in finish_inode_if_needed()
5171 if (!is_waiting_for_move(sctx, sctx->cur_ino)) { in finish_inode_if_needed()
5172 ret = apply_children_dir_moves(sctx); in finish_inode_if_needed()
5182 sctx->send_progress = sctx->cur_ino + 1; in finish_inode_if_needed()
5183 ret = send_utimes(sctx, sctx->cur_ino, sctx->cur_inode_gen); in finish_inode_if_needed()
5192 static int changed_inode(struct send_ctx *sctx, in changed_inode() argument
5196 struct btrfs_key *key = sctx->cmp_key; in changed_inode()
5202 sctx->cur_ino = key->objectid; in changed_inode()
5203 sctx->cur_inode_new_gen = 0; in changed_inode()
5204 sctx->cur_inode_last_extent = (u64)-1; in changed_inode()
5211 sctx->send_progress = sctx->cur_ino; in changed_inode()
5215 left_ii = btrfs_item_ptr(sctx->left_path->nodes[0], in changed_inode()
5216 sctx->left_path->slots[0], in changed_inode()
5218 left_gen = btrfs_inode_generation(sctx->left_path->nodes[0], in changed_inode()
5221 right_ii = btrfs_item_ptr(sctx->right_path->nodes[0], in changed_inode()
5222 sctx->right_path->slots[0], in changed_inode()
5224 right_gen = btrfs_inode_generation(sctx->right_path->nodes[0], in changed_inode()
5228 right_ii = btrfs_item_ptr(sctx->right_path->nodes[0], in changed_inode()
5229 sctx->right_path->slots[0], in changed_inode()
5232 right_gen = btrfs_inode_generation(sctx->right_path->nodes[0], in changed_inode()
5241 sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID) in changed_inode()
5242 sctx->cur_inode_new_gen = 1; in changed_inode()
5246 sctx->cur_inode_gen = left_gen; in changed_inode()
5247 sctx->cur_inode_new = 1; in changed_inode()
5248 sctx->cur_inode_deleted = 0; in changed_inode()
5249 sctx->cur_inode_size = btrfs_inode_size( in changed_inode()
5250 sctx->left_path->nodes[0], left_ii); in changed_inode()
5251 sctx->cur_inode_mode = btrfs_inode_mode( in changed_inode()
5252 sctx->left_path->nodes[0], left_ii); in changed_inode()
5253 sctx->cur_inode_rdev = btrfs_inode_rdev( in changed_inode()
5254 sctx->left_path->nodes[0], left_ii); in changed_inode()
5255 if (sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID) in changed_inode()
5256 ret = send_create_inode_if_needed(sctx); in changed_inode()
5258 sctx->cur_inode_gen = right_gen; in changed_inode()
5259 sctx->cur_inode_new = 0; in changed_inode()
5260 sctx->cur_inode_deleted = 1; in changed_inode()
5261 sctx->cur_inode_size = btrfs_inode_size( in changed_inode()
5262 sctx->right_path->nodes[0], right_ii); in changed_inode()
5263 sctx->cur_inode_mode = btrfs_inode_mode( in changed_inode()
5264 sctx->right_path->nodes[0], right_ii); in changed_inode()
5273 if (sctx->cur_inode_new_gen) { in changed_inode()
5277 sctx->cur_inode_gen = right_gen; in changed_inode()
5278 sctx->cur_inode_new = 0; in changed_inode()
5279 sctx->cur_inode_deleted = 1; in changed_inode()
5280 sctx->cur_inode_size = btrfs_inode_size( in changed_inode()
5281 sctx->right_path->nodes[0], right_ii); in changed_inode()
5282 sctx->cur_inode_mode = btrfs_inode_mode( in changed_inode()
5283 sctx->right_path->nodes[0], right_ii); in changed_inode()
5284 ret = process_all_refs(sctx, in changed_inode()
5292 sctx->cur_inode_gen = left_gen; in changed_inode()
5293 sctx->cur_inode_new = 1; in changed_inode()
5294 sctx->cur_inode_deleted = 0; in changed_inode()
5295 sctx->cur_inode_size = btrfs_inode_size( in changed_inode()
5296 sctx->left_path->nodes[0], left_ii); in changed_inode()
5297 sctx->cur_inode_mode = btrfs_inode_mode( in changed_inode()
5298 sctx->left_path->nodes[0], left_ii); in changed_inode()
5299 sctx->cur_inode_rdev = btrfs_inode_rdev( in changed_inode()
5300 sctx->left_path->nodes[0], left_ii); in changed_inode()
5301 ret = send_create_inode_if_needed(sctx); in changed_inode()
5305 ret = process_all_refs(sctx, BTRFS_COMPARE_TREE_NEW); in changed_inode()
5312 sctx->send_progress = sctx->cur_ino + 1; in changed_inode()
5318 ret = process_all_extents(sctx); in changed_inode()
5321 ret = process_all_new_xattrs(sctx); in changed_inode()
5325 sctx->cur_inode_gen = left_gen; in changed_inode()
5326 sctx->cur_inode_new = 0; in changed_inode()
5327 sctx->cur_inode_new_gen = 0; in changed_inode()
5328 sctx->cur_inode_deleted = 0; in changed_inode()
5329 sctx->cur_inode_size = btrfs_inode_size( in changed_inode()
5330 sctx->left_path->nodes[0], left_ii); in changed_inode()
5331 sctx->cur_inode_mode = btrfs_inode_mode( in changed_inode()
5332 sctx->left_path->nodes[0], left_ii); in changed_inode()
5350 static int changed_ref(struct send_ctx *sctx, in changed_ref() argument
5355 BUG_ON(sctx->cur_ino != sctx->cmp_key->objectid); in changed_ref()
5357 if (!sctx->cur_inode_new_gen && in changed_ref()
5358 sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID) { in changed_ref()
5360 ret = record_new_ref(sctx); in changed_ref()
5362 ret = record_deleted_ref(sctx); in changed_ref()
5364 ret = record_changed_ref(sctx); in changed_ref()
5375 static int changed_xattr(struct send_ctx *sctx, in changed_xattr() argument
5380 BUG_ON(sctx->cur_ino != sctx->cmp_key->objectid); in changed_xattr()
5382 if (!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted) { in changed_xattr()
5384 ret = process_new_xattr(sctx); in changed_xattr()
5386 ret = process_deleted_xattr(sctx); in changed_xattr()
5388 ret = process_changed_xattr(sctx); in changed_xattr()
5399 static int changed_extent(struct send_ctx *sctx, in changed_extent() argument
5404 BUG_ON(sctx->cur_ino != sctx->cmp_key->objectid); in changed_extent()
5406 if (!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted) { in changed_extent()
5408 ret = process_extent(sctx, sctx->left_path, in changed_extent()
5409 sctx->cmp_key); in changed_extent()
5415 static int dir_changed(struct send_ctx *sctx, u64 dir) in dir_changed() argument
5420 ret = get_inode_info(sctx->send_root, dir, NULL, &new_gen, NULL, NULL, in dir_changed()
5425 ret = get_inode_info(sctx->parent_root, dir, NULL, &orig_gen, NULL, in dir_changed()
5433 static int compare_refs(struct send_ctx *sctx, struct btrfs_path *path, in compare_refs() argument
5449 ret = dir_changed(sctx, dirid); in compare_refs()
5464 ret = dir_changed(sctx, dirid); in compare_refs()
5486 struct send_ctx *sctx = ctx; in changed_cb() local
5491 ret = compare_refs(sctx, left_path, key); in changed_cb()
5497 return maybe_send_hole(sctx, left_path, key); in changed_cb()
5505 sctx->left_path = left_path; in changed_cb()
5506 sctx->right_path = right_path; in changed_cb()
5507 sctx->cmp_key = key; in changed_cb()
5509 ret = finish_inode_if_needed(sctx, 0); in changed_cb()
5519 ret = changed_inode(sctx, result); in changed_cb()
5522 ret = changed_ref(sctx, result); in changed_cb()
5524 ret = changed_xattr(sctx, result); in changed_cb()
5526 ret = changed_extent(sctx, result); in changed_cb()
5532 static int full_send_tree(struct send_ctx *sctx) in full_send_tree() argument
5535 struct btrfs_root *send_root = sctx->send_root; in full_send_tree()
5562 &found_key, BTRFS_COMPARE_TREE_NEW, sctx); in full_send_tree()
5580 ret = finish_inode_if_needed(sctx, 1); in full_send_tree()
5587 static int send_subvol(struct send_ctx *sctx) in send_subvol() argument
5591 if (!(sctx->flags & BTRFS_SEND_FLAG_OMIT_STREAM_HEADER)) { in send_subvol()
5592 ret = send_header(sctx); in send_subvol()
5597 ret = send_subvol_begin(sctx); in send_subvol()
5601 if (sctx->parent_root) { in send_subvol()
5602 ret = btrfs_compare_trees(sctx->send_root, sctx->parent_root, in send_subvol()
5603 changed_cb, sctx); in send_subvol()
5606 ret = finish_inode_if_needed(sctx, 1); in send_subvol()
5610 ret = full_send_tree(sctx); in send_subvol()
5616 free_recorded_refs(sctx); in send_subvol()
5633 static int ensure_commit_roots_uptodate(struct send_ctx *sctx) in ensure_commit_roots_uptodate() argument
5639 if (sctx->parent_root && in ensure_commit_roots_uptodate()
5640 sctx->parent_root->node != sctx->parent_root->commit_root) in ensure_commit_roots_uptodate()
5643 for (i = 0; i < sctx->clone_roots_cnt; i++) in ensure_commit_roots_uptodate()
5644 if (sctx->clone_roots[i].root->node != in ensure_commit_roots_uptodate()
5645 sctx->clone_roots[i].root->commit_root) in ensure_commit_roots_uptodate()
5649 return btrfs_end_transaction(trans, sctx->send_root); in ensure_commit_roots_uptodate()
5656 trans = btrfs_join_transaction(sctx->send_root); in ensure_commit_roots_uptodate()
5662 return btrfs_commit_transaction(trans, sctx->send_root); in ensure_commit_roots_uptodate()
5688 struct send_ctx *sctx = NULL; in btrfs_ioctl_send() local
5743 sctx = kzalloc(sizeof(struct send_ctx), GFP_NOFS); in btrfs_ioctl_send()
5744 if (!sctx) { in btrfs_ioctl_send()
5749 INIT_LIST_HEAD(&sctx->new_refs); in btrfs_ioctl_send()
5750 INIT_LIST_HEAD(&sctx->deleted_refs); in btrfs_ioctl_send()
5751 INIT_RADIX_TREE(&sctx->name_cache, GFP_NOFS); in btrfs_ioctl_send()
5752 INIT_LIST_HEAD(&sctx->name_cache_list); in btrfs_ioctl_send()
5754 sctx->flags = arg->flags; in btrfs_ioctl_send()
5756 sctx->send_filp = fget(arg->send_fd); in btrfs_ioctl_send()
5757 if (!sctx->send_filp) { in btrfs_ioctl_send()
5762 sctx->send_root = send_root; in btrfs_ioctl_send()
5767 if (btrfs_root_dead(sctx->send_root)) { in btrfs_ioctl_send()
5772 sctx->clone_roots_cnt = arg->clone_sources_count; in btrfs_ioctl_send()
5774 sctx->send_max_size = BTRFS_SEND_BUF_SIZE; in btrfs_ioctl_send()
5775 sctx->send_buf = vmalloc(sctx->send_max_size); in btrfs_ioctl_send()
5776 if (!sctx->send_buf) { in btrfs_ioctl_send()
5781 sctx->read_buf = vmalloc(BTRFS_SEND_READ_SIZE); in btrfs_ioctl_send()
5782 if (!sctx->read_buf) { in btrfs_ioctl_send()
5787 sctx->pending_dir_moves = RB_ROOT; in btrfs_ioctl_send()
5788 sctx->waiting_dir_moves = RB_ROOT; in btrfs_ioctl_send()
5789 sctx->orphan_dirs = RB_ROOT; in btrfs_ioctl_send()
5791 sctx->clone_roots = vzalloc(sizeof(struct clone_root) * in btrfs_ioctl_send()
5793 if (!sctx->clone_roots) { in btrfs_ioctl_send()
5839 sctx->clone_roots[i].root = clone_root; in btrfs_ioctl_send()
5853 sctx->parent_root = btrfs_read_fs_root_no_name(fs_info, &key); in btrfs_ioctl_send()
5854 if (IS_ERR(sctx->parent_root)) { in btrfs_ioctl_send()
5856 ret = PTR_ERR(sctx->parent_root); in btrfs_ioctl_send()
5860 spin_lock(&sctx->parent_root->root_item_lock); in btrfs_ioctl_send()
5861 sctx->parent_root->send_in_progress++; in btrfs_ioctl_send()
5862 if (!btrfs_root_readonly(sctx->parent_root) || in btrfs_ioctl_send()
5863 btrfs_root_dead(sctx->parent_root)) { in btrfs_ioctl_send()
5864 spin_unlock(&sctx->parent_root->root_item_lock); in btrfs_ioctl_send()
5869 spin_unlock(&sctx->parent_root->root_item_lock); in btrfs_ioctl_send()
5879 sctx->clone_roots[sctx->clone_roots_cnt++].root = sctx->send_root; in btrfs_ioctl_send()
5882 sort(sctx->clone_roots, sctx->clone_roots_cnt, in btrfs_ioctl_send()
5883 sizeof(*sctx->clone_roots), __clone_root_cmp_sort, in btrfs_ioctl_send()
5887 ret = ensure_commit_roots_uptodate(sctx); in btrfs_ioctl_send()
5892 ret = send_subvol(sctx); in btrfs_ioctl_send()
5897 if (!(sctx->flags & BTRFS_SEND_FLAG_OMIT_END_CMD)) { in btrfs_ioctl_send()
5898 ret = begin_cmd(sctx, BTRFS_SEND_C_END); in btrfs_ioctl_send()
5901 ret = send_cmd(sctx); in btrfs_ioctl_send()
5907 WARN_ON(sctx && !ret && !RB_EMPTY_ROOT(&sctx->pending_dir_moves)); in btrfs_ioctl_send()
5908 while (sctx && !RB_EMPTY_ROOT(&sctx->pending_dir_moves)) { in btrfs_ioctl_send()
5912 n = rb_first(&sctx->pending_dir_moves); in btrfs_ioctl_send()
5919 free_pending_move(sctx, pm2); in btrfs_ioctl_send()
5921 free_pending_move(sctx, pm); in btrfs_ioctl_send()
5924 WARN_ON(sctx && !ret && !RB_EMPTY_ROOT(&sctx->waiting_dir_moves)); in btrfs_ioctl_send()
5925 while (sctx && !RB_EMPTY_ROOT(&sctx->waiting_dir_moves)) { in btrfs_ioctl_send()
5929 n = rb_first(&sctx->waiting_dir_moves); in btrfs_ioctl_send()
5931 rb_erase(&dm->node, &sctx->waiting_dir_moves); in btrfs_ioctl_send()
5935 WARN_ON(sctx && !ret && !RB_EMPTY_ROOT(&sctx->orphan_dirs)); in btrfs_ioctl_send()
5936 while (sctx && !RB_EMPTY_ROOT(&sctx->orphan_dirs)) { in btrfs_ioctl_send()
5940 n = rb_first(&sctx->orphan_dirs); in btrfs_ioctl_send()
5942 free_orphan_dir_info(sctx, odi); in btrfs_ioctl_send()
5946 for (i = 0; i < sctx->clone_roots_cnt; i++) in btrfs_ioctl_send()
5948 sctx->clone_roots[i].root); in btrfs_ioctl_send()
5950 for (i = 0; sctx && i < clone_sources_to_rollback; i++) in btrfs_ioctl_send()
5952 sctx->clone_roots[i].root); in btrfs_ioctl_send()
5956 if (sctx && !IS_ERR_OR_NULL(sctx->parent_root)) in btrfs_ioctl_send()
5957 btrfs_root_dec_send_in_progress(sctx->parent_root); in btrfs_ioctl_send()
5962 if (sctx) { in btrfs_ioctl_send()
5963 if (sctx->send_filp) in btrfs_ioctl_send()
5964 fput(sctx->send_filp); in btrfs_ioctl_send()
5966 vfree(sctx->clone_roots); in btrfs_ioctl_send()
5967 vfree(sctx->send_buf); in btrfs_ioctl_send()
5968 vfree(sctx->read_buf); in btrfs_ioctl_send()
5970 name_cache_free(sctx); in btrfs_ioctl_send()
5972 kfree(sctx); in btrfs_ioctl_send()