162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2012 Alexander Block.  All rights reserved.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/bsearch.h>
762306a36Sopenharmony_ci#include <linux/fs.h>
862306a36Sopenharmony_ci#include <linux/file.h>
962306a36Sopenharmony_ci#include <linux/sort.h>
1062306a36Sopenharmony_ci#include <linux/mount.h>
1162306a36Sopenharmony_ci#include <linux/xattr.h>
1262306a36Sopenharmony_ci#include <linux/posix_acl_xattr.h>
1362306a36Sopenharmony_ci#include <linux/radix-tree.h>
1462306a36Sopenharmony_ci#include <linux/vmalloc.h>
1562306a36Sopenharmony_ci#include <linux/string.h>
1662306a36Sopenharmony_ci#include <linux/compat.h>
1762306a36Sopenharmony_ci#include <linux/crc32c.h>
1862306a36Sopenharmony_ci#include <linux/fsverity.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#include "send.h"
2162306a36Sopenharmony_ci#include "ctree.h"
2262306a36Sopenharmony_ci#include "backref.h"
2362306a36Sopenharmony_ci#include "locking.h"
2462306a36Sopenharmony_ci#include "disk-io.h"
2562306a36Sopenharmony_ci#include "btrfs_inode.h"
2662306a36Sopenharmony_ci#include "transaction.h"
2762306a36Sopenharmony_ci#include "compression.h"
2862306a36Sopenharmony_ci#include "xattr.h"
2962306a36Sopenharmony_ci#include "print-tree.h"
3062306a36Sopenharmony_ci#include "accessors.h"
3162306a36Sopenharmony_ci#include "dir-item.h"
3262306a36Sopenharmony_ci#include "file-item.h"
3362306a36Sopenharmony_ci#include "ioctl.h"
3462306a36Sopenharmony_ci#include "verity.h"
3562306a36Sopenharmony_ci#include "lru_cache.h"
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci/*
3862306a36Sopenharmony_ci * Maximum number of references an extent can have in order for us to attempt to
3962306a36Sopenharmony_ci * issue clone operations instead of write operations. This currently exists to
4062306a36Sopenharmony_ci * avoid hitting limitations of the backreference walking code (taking a lot of
4162306a36Sopenharmony_ci * time and using too much memory for extents with large number of references).
4262306a36Sopenharmony_ci */
4362306a36Sopenharmony_ci#define SEND_MAX_EXTENT_REFS	1024
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci/*
4662306a36Sopenharmony_ci * A fs_path is a helper to dynamically build path names with unknown size.
4762306a36Sopenharmony_ci * It reallocates the internal buffer on demand.
4862306a36Sopenharmony_ci * It allows fast adding of path elements on the right side (normal path) and
4962306a36Sopenharmony_ci * fast adding to the left side (reversed path). A reversed path can also be
5062306a36Sopenharmony_ci * unreversed if needed.
5162306a36Sopenharmony_ci */
5262306a36Sopenharmony_cistruct fs_path {
5362306a36Sopenharmony_ci	union {
5462306a36Sopenharmony_ci		struct {
5562306a36Sopenharmony_ci			char *start;
5662306a36Sopenharmony_ci			char *end;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci			char *buf;
5962306a36Sopenharmony_ci			unsigned short buf_len:15;
6062306a36Sopenharmony_ci			unsigned short reversed:1;
6162306a36Sopenharmony_ci			char inline_buf[];
6262306a36Sopenharmony_ci		};
6362306a36Sopenharmony_ci		/*
6462306a36Sopenharmony_ci		 * Average path length does not exceed 200 bytes, we'll have
6562306a36Sopenharmony_ci		 * better packing in the slab and higher chance to satisfy
6662306a36Sopenharmony_ci		 * a allocation later during send.
6762306a36Sopenharmony_ci		 */
6862306a36Sopenharmony_ci		char pad[256];
6962306a36Sopenharmony_ci	};
7062306a36Sopenharmony_ci};
7162306a36Sopenharmony_ci#define FS_PATH_INLINE_SIZE \
7262306a36Sopenharmony_ci	(sizeof(struct fs_path) - offsetof(struct fs_path, inline_buf))
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci/* reused for each extent */
7662306a36Sopenharmony_cistruct clone_root {
7762306a36Sopenharmony_ci	struct btrfs_root *root;
7862306a36Sopenharmony_ci	u64 ino;
7962306a36Sopenharmony_ci	u64 offset;
8062306a36Sopenharmony_ci	u64 num_bytes;
8162306a36Sopenharmony_ci	bool found_ref;
8262306a36Sopenharmony_ci};
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci#define SEND_MAX_NAME_CACHE_SIZE			256
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci/*
8762306a36Sopenharmony_ci * Limit the root_ids array of struct backref_cache_entry to 17 elements.
8862306a36Sopenharmony_ci * This makes the size of a cache entry to be exactly 192 bytes on x86_64, which
8962306a36Sopenharmony_ci * can be satisfied from the kmalloc-192 slab, without wasting any space.
9062306a36Sopenharmony_ci * The most common case is to have a single root for cloning, which corresponds
9162306a36Sopenharmony_ci * to the send root. Having the user specify more than 16 clone roots is not
9262306a36Sopenharmony_ci * common, and in such rare cases we simply don't use caching if the number of
9362306a36Sopenharmony_ci * cloning roots that lead down to a leaf is more than 17.
9462306a36Sopenharmony_ci */
9562306a36Sopenharmony_ci#define SEND_MAX_BACKREF_CACHE_ROOTS			17
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci/*
9862306a36Sopenharmony_ci * Max number of entries in the cache.
9962306a36Sopenharmony_ci * With SEND_MAX_BACKREF_CACHE_ROOTS as 17, the size in bytes, excluding
10062306a36Sopenharmony_ci * maple tree's internal nodes, is 24K.
10162306a36Sopenharmony_ci */
10262306a36Sopenharmony_ci#define SEND_MAX_BACKREF_CACHE_SIZE 128
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci/*
10562306a36Sopenharmony_ci * A backref cache entry maps a leaf to a list of IDs of roots from which the
10662306a36Sopenharmony_ci * leaf is accessible and we can use for clone operations.
10762306a36Sopenharmony_ci * With SEND_MAX_BACKREF_CACHE_ROOTS as 12, each cache entry is 128 bytes (on
10862306a36Sopenharmony_ci * x86_64).
10962306a36Sopenharmony_ci */
11062306a36Sopenharmony_cistruct backref_cache_entry {
11162306a36Sopenharmony_ci	struct btrfs_lru_cache_entry entry;
11262306a36Sopenharmony_ci	u64 root_ids[SEND_MAX_BACKREF_CACHE_ROOTS];
11362306a36Sopenharmony_ci	/* Number of valid elements in the root_ids array. */
11462306a36Sopenharmony_ci	int num_roots;
11562306a36Sopenharmony_ci};
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci/* See the comment at lru_cache.h about struct btrfs_lru_cache_entry. */
11862306a36Sopenharmony_cistatic_assert(offsetof(struct backref_cache_entry, entry) == 0);
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci/*
12162306a36Sopenharmony_ci * Max number of entries in the cache that stores directories that were already
12262306a36Sopenharmony_ci * created. The cache uses raw struct btrfs_lru_cache_entry entries, so it uses
12362306a36Sopenharmony_ci * at most 4096 bytes - sizeof(struct btrfs_lru_cache_entry) is 48 bytes, but
12462306a36Sopenharmony_ci * the kmalloc-64 slab is used, so we get 4096 bytes (64 bytes * 64).
12562306a36Sopenharmony_ci */
12662306a36Sopenharmony_ci#define SEND_MAX_DIR_CREATED_CACHE_SIZE			64
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci/*
12962306a36Sopenharmony_ci * Max number of entries in the cache that stores directories that were already
13062306a36Sopenharmony_ci * created. The cache uses raw struct btrfs_lru_cache_entry entries, so it uses
13162306a36Sopenharmony_ci * at most 4096 bytes - sizeof(struct btrfs_lru_cache_entry) is 48 bytes, but
13262306a36Sopenharmony_ci * the kmalloc-64 slab is used, so we get 4096 bytes (64 bytes * 64).
13362306a36Sopenharmony_ci */
13462306a36Sopenharmony_ci#define SEND_MAX_DIR_UTIMES_CACHE_SIZE			64
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_cistruct send_ctx {
13762306a36Sopenharmony_ci	struct file *send_filp;
13862306a36Sopenharmony_ci	loff_t send_off;
13962306a36Sopenharmony_ci	char *send_buf;
14062306a36Sopenharmony_ci	u32 send_size;
14162306a36Sopenharmony_ci	u32 send_max_size;
14262306a36Sopenharmony_ci	/*
14362306a36Sopenharmony_ci	 * Whether BTRFS_SEND_A_DATA attribute was already added to current
14462306a36Sopenharmony_ci	 * command (since protocol v2, data must be the last attribute).
14562306a36Sopenharmony_ci	 */
14662306a36Sopenharmony_ci	bool put_data;
14762306a36Sopenharmony_ci	struct page **send_buf_pages;
14862306a36Sopenharmony_ci	u64 flags;	/* 'flags' member of btrfs_ioctl_send_args is u64 */
14962306a36Sopenharmony_ci	/* Protocol version compatibility requested */
15062306a36Sopenharmony_ci	u32 proto;
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci	struct btrfs_root *send_root;
15362306a36Sopenharmony_ci	struct btrfs_root *parent_root;
15462306a36Sopenharmony_ci	struct clone_root *clone_roots;
15562306a36Sopenharmony_ci	int clone_roots_cnt;
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	/* current state of the compare_tree call */
15862306a36Sopenharmony_ci	struct btrfs_path *left_path;
15962306a36Sopenharmony_ci	struct btrfs_path *right_path;
16062306a36Sopenharmony_ci	struct btrfs_key *cmp_key;
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci	/*
16362306a36Sopenharmony_ci	 * Keep track of the generation of the last transaction that was used
16462306a36Sopenharmony_ci	 * for relocating a block group. This is periodically checked in order
16562306a36Sopenharmony_ci	 * to detect if a relocation happened since the last check, so that we
16662306a36Sopenharmony_ci	 * don't operate on stale extent buffers for nodes (level >= 1) or on
16762306a36Sopenharmony_ci	 * stale disk_bytenr values of file extent items.
16862306a36Sopenharmony_ci	 */
16962306a36Sopenharmony_ci	u64 last_reloc_trans;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	/*
17262306a36Sopenharmony_ci	 * infos of the currently processed inode. In case of deleted inodes,
17362306a36Sopenharmony_ci	 * these are the values from the deleted inode.
17462306a36Sopenharmony_ci	 */
17562306a36Sopenharmony_ci	u64 cur_ino;
17662306a36Sopenharmony_ci	u64 cur_inode_gen;
17762306a36Sopenharmony_ci	u64 cur_inode_size;
17862306a36Sopenharmony_ci	u64 cur_inode_mode;
17962306a36Sopenharmony_ci	u64 cur_inode_rdev;
18062306a36Sopenharmony_ci	u64 cur_inode_last_extent;
18162306a36Sopenharmony_ci	u64 cur_inode_next_write_offset;
18262306a36Sopenharmony_ci	bool cur_inode_new;
18362306a36Sopenharmony_ci	bool cur_inode_new_gen;
18462306a36Sopenharmony_ci	bool cur_inode_deleted;
18562306a36Sopenharmony_ci	bool ignore_cur_inode;
18662306a36Sopenharmony_ci	bool cur_inode_needs_verity;
18762306a36Sopenharmony_ci	void *verity_descriptor;
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci	u64 send_progress;
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	struct list_head new_refs;
19262306a36Sopenharmony_ci	struct list_head deleted_refs;
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci	struct btrfs_lru_cache name_cache;
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci	/*
19762306a36Sopenharmony_ci	 * The inode we are currently processing. It's not NULL only when we
19862306a36Sopenharmony_ci	 * need to issue write commands for data extents from this inode.
19962306a36Sopenharmony_ci	 */
20062306a36Sopenharmony_ci	struct inode *cur_inode;
20162306a36Sopenharmony_ci	struct file_ra_state ra;
20262306a36Sopenharmony_ci	u64 page_cache_clear_start;
20362306a36Sopenharmony_ci	bool clean_page_cache;
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci	/*
20662306a36Sopenharmony_ci	 * We process inodes by their increasing order, so if before an
20762306a36Sopenharmony_ci	 * incremental send we reverse the parent/child relationship of
20862306a36Sopenharmony_ci	 * directories such that a directory with a lower inode number was
20962306a36Sopenharmony_ci	 * the parent of a directory with a higher inode number, and the one
21062306a36Sopenharmony_ci	 * becoming the new parent got renamed too, we can't rename/move the
21162306a36Sopenharmony_ci	 * directory with lower inode number when we finish processing it - we
21262306a36Sopenharmony_ci	 * must process the directory with higher inode number first, then
21362306a36Sopenharmony_ci	 * rename/move it and then rename/move the directory with lower inode
21462306a36Sopenharmony_ci	 * number. Example follows.
21562306a36Sopenharmony_ci	 *
21662306a36Sopenharmony_ci	 * Tree state when the first send was performed:
21762306a36Sopenharmony_ci	 *
21862306a36Sopenharmony_ci	 * .
21962306a36Sopenharmony_ci	 * |-- a                   (ino 257)
22062306a36Sopenharmony_ci	 *     |-- b               (ino 258)
22162306a36Sopenharmony_ci	 *         |
22262306a36Sopenharmony_ci	 *         |
22362306a36Sopenharmony_ci	 *         |-- c           (ino 259)
22462306a36Sopenharmony_ci	 *         |   |-- d       (ino 260)
22562306a36Sopenharmony_ci	 *         |
22662306a36Sopenharmony_ci	 *         |-- c2          (ino 261)
22762306a36Sopenharmony_ci	 *
22862306a36Sopenharmony_ci	 * Tree state when the second (incremental) send is performed:
22962306a36Sopenharmony_ci	 *
23062306a36Sopenharmony_ci	 * .
23162306a36Sopenharmony_ci	 * |-- a                   (ino 257)
23262306a36Sopenharmony_ci	 *     |-- b               (ino 258)
23362306a36Sopenharmony_ci	 *         |-- c2          (ino 261)
23462306a36Sopenharmony_ci	 *             |-- d2      (ino 260)
23562306a36Sopenharmony_ci	 *                 |-- cc  (ino 259)
23662306a36Sopenharmony_ci	 *
23762306a36Sopenharmony_ci	 * The sequence of steps that lead to the second state was:
23862306a36Sopenharmony_ci	 *
23962306a36Sopenharmony_ci	 * mv /a/b/c/d /a/b/c2/d2
24062306a36Sopenharmony_ci	 * mv /a/b/c /a/b/c2/d2/cc
24162306a36Sopenharmony_ci	 *
24262306a36Sopenharmony_ci	 * "c" has lower inode number, but we can't move it (2nd mv operation)
24362306a36Sopenharmony_ci	 * before we move "d", which has higher inode number.
24462306a36Sopenharmony_ci	 *
24562306a36Sopenharmony_ci	 * So we just memorize which move/rename operations must be performed
24662306a36Sopenharmony_ci	 * later when their respective parent is processed and moved/renamed.
24762306a36Sopenharmony_ci	 */
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci	/* Indexed by parent directory inode number. */
25062306a36Sopenharmony_ci	struct rb_root pending_dir_moves;
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	/*
25362306a36Sopenharmony_ci	 * Reverse index, indexed by the inode number of a directory that
25462306a36Sopenharmony_ci	 * is waiting for the move/rename of its immediate parent before its
25562306a36Sopenharmony_ci	 * own move/rename can be performed.
25662306a36Sopenharmony_ci	 */
25762306a36Sopenharmony_ci	struct rb_root waiting_dir_moves;
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci	/*
26062306a36Sopenharmony_ci	 * A directory that is going to be rm'ed might have a child directory
26162306a36Sopenharmony_ci	 * which is in the pending directory moves index above. In this case,
26262306a36Sopenharmony_ci	 * the directory can only be removed after the move/rename of its child
26362306a36Sopenharmony_ci	 * is performed. Example:
26462306a36Sopenharmony_ci	 *
26562306a36Sopenharmony_ci	 * Parent snapshot:
26662306a36Sopenharmony_ci	 *
26762306a36Sopenharmony_ci	 * .                        (ino 256)
26862306a36Sopenharmony_ci	 * |-- a/                   (ino 257)
26962306a36Sopenharmony_ci	 *     |-- b/               (ino 258)
27062306a36Sopenharmony_ci	 *         |-- c/           (ino 259)
27162306a36Sopenharmony_ci	 *         |   |-- x/       (ino 260)
27262306a36Sopenharmony_ci	 *         |
27362306a36Sopenharmony_ci	 *         |-- y/           (ino 261)
27462306a36Sopenharmony_ci	 *
27562306a36Sopenharmony_ci	 * Send snapshot:
27662306a36Sopenharmony_ci	 *
27762306a36Sopenharmony_ci	 * .                        (ino 256)
27862306a36Sopenharmony_ci	 * |-- a/                   (ino 257)
27962306a36Sopenharmony_ci	 *     |-- b/               (ino 258)
28062306a36Sopenharmony_ci	 *         |-- YY/          (ino 261)
28162306a36Sopenharmony_ci	 *              |-- x/      (ino 260)
28262306a36Sopenharmony_ci	 *
28362306a36Sopenharmony_ci	 * Sequence of steps that lead to the send snapshot:
28462306a36Sopenharmony_ci	 * rm -f /a/b/c/foo.txt
28562306a36Sopenharmony_ci	 * mv /a/b/y /a/b/YY
28662306a36Sopenharmony_ci	 * mv /a/b/c/x /a/b/YY
28762306a36Sopenharmony_ci	 * rmdir /a/b/c
28862306a36Sopenharmony_ci	 *
28962306a36Sopenharmony_ci	 * When the child is processed, its move/rename is delayed until its
29062306a36Sopenharmony_ci	 * parent is processed (as explained above), but all other operations
29162306a36Sopenharmony_ci	 * like update utimes, chown, chgrp, etc, are performed and the paths
29262306a36Sopenharmony_ci	 * that it uses for those operations must use the orphanized name of
29362306a36Sopenharmony_ci	 * its parent (the directory we're going to rm later), so we need to
29462306a36Sopenharmony_ci	 * memorize that name.
29562306a36Sopenharmony_ci	 *
29662306a36Sopenharmony_ci	 * Indexed by the inode number of the directory to be deleted.
29762306a36Sopenharmony_ci	 */
29862306a36Sopenharmony_ci	struct rb_root orphan_dirs;
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	struct rb_root rbtree_new_refs;
30162306a36Sopenharmony_ci	struct rb_root rbtree_deleted_refs;
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci	struct btrfs_lru_cache backref_cache;
30462306a36Sopenharmony_ci	u64 backref_cache_last_reloc_trans;
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci	struct btrfs_lru_cache dir_created_cache;
30762306a36Sopenharmony_ci	struct btrfs_lru_cache dir_utimes_cache;
30862306a36Sopenharmony_ci};
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_cistruct pending_dir_move {
31162306a36Sopenharmony_ci	struct rb_node node;
31262306a36Sopenharmony_ci	struct list_head list;
31362306a36Sopenharmony_ci	u64 parent_ino;
31462306a36Sopenharmony_ci	u64 ino;
31562306a36Sopenharmony_ci	u64 gen;
31662306a36Sopenharmony_ci	struct list_head update_refs;
31762306a36Sopenharmony_ci};
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_cistruct waiting_dir_move {
32062306a36Sopenharmony_ci	struct rb_node node;
32162306a36Sopenharmony_ci	u64 ino;
32262306a36Sopenharmony_ci	/*
32362306a36Sopenharmony_ci	 * There might be some directory that could not be removed because it
32462306a36Sopenharmony_ci	 * was waiting for this directory inode to be moved first. Therefore
32562306a36Sopenharmony_ci	 * after this directory is moved, we can try to rmdir the ino rmdir_ino.
32662306a36Sopenharmony_ci	 */
32762306a36Sopenharmony_ci	u64 rmdir_ino;
32862306a36Sopenharmony_ci	u64 rmdir_gen;
32962306a36Sopenharmony_ci	bool orphanized;
33062306a36Sopenharmony_ci};
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_cistruct orphan_dir_info {
33362306a36Sopenharmony_ci	struct rb_node node;
33462306a36Sopenharmony_ci	u64 ino;
33562306a36Sopenharmony_ci	u64 gen;
33662306a36Sopenharmony_ci	u64 last_dir_index_offset;
33762306a36Sopenharmony_ci	u64 dir_high_seq_ino;
33862306a36Sopenharmony_ci};
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_cistruct name_cache_entry {
34162306a36Sopenharmony_ci	/*
34262306a36Sopenharmony_ci	 * The key in the entry is an inode number, and the generation matches
34362306a36Sopenharmony_ci	 * the inode's generation.
34462306a36Sopenharmony_ci	 */
34562306a36Sopenharmony_ci	struct btrfs_lru_cache_entry entry;
34662306a36Sopenharmony_ci	u64 parent_ino;
34762306a36Sopenharmony_ci	u64 parent_gen;
34862306a36Sopenharmony_ci	int ret;
34962306a36Sopenharmony_ci	int need_later_update;
35062306a36Sopenharmony_ci	int name_len;
35162306a36Sopenharmony_ci	char name[];
35262306a36Sopenharmony_ci};
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci/* See the comment at lru_cache.h about struct btrfs_lru_cache_entry. */
35562306a36Sopenharmony_cistatic_assert(offsetof(struct name_cache_entry, entry) == 0);
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_ci#define ADVANCE							1
35862306a36Sopenharmony_ci#define ADVANCE_ONLY_NEXT					-1
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_cienum btrfs_compare_tree_result {
36162306a36Sopenharmony_ci	BTRFS_COMPARE_TREE_NEW,
36262306a36Sopenharmony_ci	BTRFS_COMPARE_TREE_DELETED,
36362306a36Sopenharmony_ci	BTRFS_COMPARE_TREE_CHANGED,
36462306a36Sopenharmony_ci	BTRFS_COMPARE_TREE_SAME,
36562306a36Sopenharmony_ci};
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci__cold
36862306a36Sopenharmony_cistatic void inconsistent_snapshot_error(struct send_ctx *sctx,
36962306a36Sopenharmony_ci					enum btrfs_compare_tree_result result,
37062306a36Sopenharmony_ci					const char *what)
37162306a36Sopenharmony_ci{
37262306a36Sopenharmony_ci	const char *result_string;
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci	switch (result) {
37562306a36Sopenharmony_ci	case BTRFS_COMPARE_TREE_NEW:
37662306a36Sopenharmony_ci		result_string = "new";
37762306a36Sopenharmony_ci		break;
37862306a36Sopenharmony_ci	case BTRFS_COMPARE_TREE_DELETED:
37962306a36Sopenharmony_ci		result_string = "deleted";
38062306a36Sopenharmony_ci		break;
38162306a36Sopenharmony_ci	case BTRFS_COMPARE_TREE_CHANGED:
38262306a36Sopenharmony_ci		result_string = "updated";
38362306a36Sopenharmony_ci		break;
38462306a36Sopenharmony_ci	case BTRFS_COMPARE_TREE_SAME:
38562306a36Sopenharmony_ci		ASSERT(0);
38662306a36Sopenharmony_ci		result_string = "unchanged";
38762306a36Sopenharmony_ci		break;
38862306a36Sopenharmony_ci	default:
38962306a36Sopenharmony_ci		ASSERT(0);
39062306a36Sopenharmony_ci		result_string = "unexpected";
39162306a36Sopenharmony_ci	}
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci	btrfs_err(sctx->send_root->fs_info,
39462306a36Sopenharmony_ci		  "Send: inconsistent snapshot, found %s %s for inode %llu without updated inode item, send root is %llu, parent root is %llu",
39562306a36Sopenharmony_ci		  result_string, what, sctx->cmp_key->objectid,
39662306a36Sopenharmony_ci		  sctx->send_root->root_key.objectid,
39762306a36Sopenharmony_ci		  (sctx->parent_root ?
39862306a36Sopenharmony_ci		   sctx->parent_root->root_key.objectid : 0));
39962306a36Sopenharmony_ci}
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci__maybe_unused
40262306a36Sopenharmony_cistatic bool proto_cmd_ok(const struct send_ctx *sctx, int cmd)
40362306a36Sopenharmony_ci{
40462306a36Sopenharmony_ci	switch (sctx->proto) {
40562306a36Sopenharmony_ci	case 1:	 return cmd <= BTRFS_SEND_C_MAX_V1;
40662306a36Sopenharmony_ci	case 2:	 return cmd <= BTRFS_SEND_C_MAX_V2;
40762306a36Sopenharmony_ci	case 3:	 return cmd <= BTRFS_SEND_C_MAX_V3;
40862306a36Sopenharmony_ci	default: return false;
40962306a36Sopenharmony_ci	}
41062306a36Sopenharmony_ci}
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_cistatic int is_waiting_for_move(struct send_ctx *sctx, u64 ino);
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_cistatic struct waiting_dir_move *
41562306a36Sopenharmony_ciget_waiting_dir_move(struct send_ctx *sctx, u64 ino);
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_cistatic int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino, u64 gen);
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_cistatic int need_send_hole(struct send_ctx *sctx)
42062306a36Sopenharmony_ci{
42162306a36Sopenharmony_ci	return (sctx->parent_root && !sctx->cur_inode_new &&
42262306a36Sopenharmony_ci		!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted &&
42362306a36Sopenharmony_ci		S_ISREG(sctx->cur_inode_mode));
42462306a36Sopenharmony_ci}
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_cistatic void fs_path_reset(struct fs_path *p)
42762306a36Sopenharmony_ci{
42862306a36Sopenharmony_ci	if (p->reversed) {
42962306a36Sopenharmony_ci		p->start = p->buf + p->buf_len - 1;
43062306a36Sopenharmony_ci		p->end = p->start;
43162306a36Sopenharmony_ci		*p->start = 0;
43262306a36Sopenharmony_ci	} else {
43362306a36Sopenharmony_ci		p->start = p->buf;
43462306a36Sopenharmony_ci		p->end = p->start;
43562306a36Sopenharmony_ci		*p->start = 0;
43662306a36Sopenharmony_ci	}
43762306a36Sopenharmony_ci}
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_cistatic struct fs_path *fs_path_alloc(void)
44062306a36Sopenharmony_ci{
44162306a36Sopenharmony_ci	struct fs_path *p;
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci	p = kmalloc(sizeof(*p), GFP_KERNEL);
44462306a36Sopenharmony_ci	if (!p)
44562306a36Sopenharmony_ci		return NULL;
44662306a36Sopenharmony_ci	p->reversed = 0;
44762306a36Sopenharmony_ci	p->buf = p->inline_buf;
44862306a36Sopenharmony_ci	p->buf_len = FS_PATH_INLINE_SIZE;
44962306a36Sopenharmony_ci	fs_path_reset(p);
45062306a36Sopenharmony_ci	return p;
45162306a36Sopenharmony_ci}
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_cistatic struct fs_path *fs_path_alloc_reversed(void)
45462306a36Sopenharmony_ci{
45562306a36Sopenharmony_ci	struct fs_path *p;
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci	p = fs_path_alloc();
45862306a36Sopenharmony_ci	if (!p)
45962306a36Sopenharmony_ci		return NULL;
46062306a36Sopenharmony_ci	p->reversed = 1;
46162306a36Sopenharmony_ci	fs_path_reset(p);
46262306a36Sopenharmony_ci	return p;
46362306a36Sopenharmony_ci}
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_cistatic void fs_path_free(struct fs_path *p)
46662306a36Sopenharmony_ci{
46762306a36Sopenharmony_ci	if (!p)
46862306a36Sopenharmony_ci		return;
46962306a36Sopenharmony_ci	if (p->buf != p->inline_buf)
47062306a36Sopenharmony_ci		kfree(p->buf);
47162306a36Sopenharmony_ci	kfree(p);
47262306a36Sopenharmony_ci}
47362306a36Sopenharmony_ci
47462306a36Sopenharmony_cistatic int fs_path_len(struct fs_path *p)
47562306a36Sopenharmony_ci{
47662306a36Sopenharmony_ci	return p->end - p->start;
47762306a36Sopenharmony_ci}
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_cistatic int fs_path_ensure_buf(struct fs_path *p, int len)
48062306a36Sopenharmony_ci{
48162306a36Sopenharmony_ci	char *tmp_buf;
48262306a36Sopenharmony_ci	int path_len;
48362306a36Sopenharmony_ci	int old_buf_len;
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci	len++;
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci	if (p->buf_len >= len)
48862306a36Sopenharmony_ci		return 0;
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci	if (len > PATH_MAX) {
49162306a36Sopenharmony_ci		WARN_ON(1);
49262306a36Sopenharmony_ci		return -ENOMEM;
49362306a36Sopenharmony_ci	}
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci	path_len = p->end - p->start;
49662306a36Sopenharmony_ci	old_buf_len = p->buf_len;
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci	/*
49962306a36Sopenharmony_ci	 * Allocate to the next largest kmalloc bucket size, to let
50062306a36Sopenharmony_ci	 * the fast path happen most of the time.
50162306a36Sopenharmony_ci	 */
50262306a36Sopenharmony_ci	len = kmalloc_size_roundup(len);
50362306a36Sopenharmony_ci	/*
50462306a36Sopenharmony_ci	 * First time the inline_buf does not suffice
50562306a36Sopenharmony_ci	 */
50662306a36Sopenharmony_ci	if (p->buf == p->inline_buf) {
50762306a36Sopenharmony_ci		tmp_buf = kmalloc(len, GFP_KERNEL);
50862306a36Sopenharmony_ci		if (tmp_buf)
50962306a36Sopenharmony_ci			memcpy(tmp_buf, p->buf, old_buf_len);
51062306a36Sopenharmony_ci	} else {
51162306a36Sopenharmony_ci		tmp_buf = krealloc(p->buf, len, GFP_KERNEL);
51262306a36Sopenharmony_ci	}
51362306a36Sopenharmony_ci	if (!tmp_buf)
51462306a36Sopenharmony_ci		return -ENOMEM;
51562306a36Sopenharmony_ci	p->buf = tmp_buf;
51662306a36Sopenharmony_ci	p->buf_len = len;
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ci	if (p->reversed) {
51962306a36Sopenharmony_ci		tmp_buf = p->buf + old_buf_len - path_len - 1;
52062306a36Sopenharmony_ci		p->end = p->buf + p->buf_len - 1;
52162306a36Sopenharmony_ci		p->start = p->end - path_len;
52262306a36Sopenharmony_ci		memmove(p->start, tmp_buf, path_len + 1);
52362306a36Sopenharmony_ci	} else {
52462306a36Sopenharmony_ci		p->start = p->buf;
52562306a36Sopenharmony_ci		p->end = p->start + path_len;
52662306a36Sopenharmony_ci	}
52762306a36Sopenharmony_ci	return 0;
52862306a36Sopenharmony_ci}
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_cistatic int fs_path_prepare_for_add(struct fs_path *p, int name_len,
53162306a36Sopenharmony_ci				   char **prepared)
53262306a36Sopenharmony_ci{
53362306a36Sopenharmony_ci	int ret;
53462306a36Sopenharmony_ci	int new_len;
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci	new_len = p->end - p->start + name_len;
53762306a36Sopenharmony_ci	if (p->start != p->end)
53862306a36Sopenharmony_ci		new_len++;
53962306a36Sopenharmony_ci	ret = fs_path_ensure_buf(p, new_len);
54062306a36Sopenharmony_ci	if (ret < 0)
54162306a36Sopenharmony_ci		goto out;
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_ci	if (p->reversed) {
54462306a36Sopenharmony_ci		if (p->start != p->end)
54562306a36Sopenharmony_ci			*--p->start = '/';
54662306a36Sopenharmony_ci		p->start -= name_len;
54762306a36Sopenharmony_ci		*prepared = p->start;
54862306a36Sopenharmony_ci	} else {
54962306a36Sopenharmony_ci		if (p->start != p->end)
55062306a36Sopenharmony_ci			*p->end++ = '/';
55162306a36Sopenharmony_ci		*prepared = p->end;
55262306a36Sopenharmony_ci		p->end += name_len;
55362306a36Sopenharmony_ci		*p->end = 0;
55462306a36Sopenharmony_ci	}
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ciout:
55762306a36Sopenharmony_ci	return ret;
55862306a36Sopenharmony_ci}
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_cistatic int fs_path_add(struct fs_path *p, const char *name, int name_len)
56162306a36Sopenharmony_ci{
56262306a36Sopenharmony_ci	int ret;
56362306a36Sopenharmony_ci	char *prepared;
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci	ret = fs_path_prepare_for_add(p, name_len, &prepared);
56662306a36Sopenharmony_ci	if (ret < 0)
56762306a36Sopenharmony_ci		goto out;
56862306a36Sopenharmony_ci	memcpy(prepared, name, name_len);
56962306a36Sopenharmony_ci
57062306a36Sopenharmony_ciout:
57162306a36Sopenharmony_ci	return ret;
57262306a36Sopenharmony_ci}
57362306a36Sopenharmony_ci
57462306a36Sopenharmony_cistatic int fs_path_add_path(struct fs_path *p, struct fs_path *p2)
57562306a36Sopenharmony_ci{
57662306a36Sopenharmony_ci	int ret;
57762306a36Sopenharmony_ci	char *prepared;
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	ret = fs_path_prepare_for_add(p, p2->end - p2->start, &prepared);
58062306a36Sopenharmony_ci	if (ret < 0)
58162306a36Sopenharmony_ci		goto out;
58262306a36Sopenharmony_ci	memcpy(prepared, p2->start, p2->end - p2->start);
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ciout:
58562306a36Sopenharmony_ci	return ret;
58662306a36Sopenharmony_ci}
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_cistatic int fs_path_add_from_extent_buffer(struct fs_path *p,
58962306a36Sopenharmony_ci					  struct extent_buffer *eb,
59062306a36Sopenharmony_ci					  unsigned long off, int len)
59162306a36Sopenharmony_ci{
59262306a36Sopenharmony_ci	int ret;
59362306a36Sopenharmony_ci	char *prepared;
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci	ret = fs_path_prepare_for_add(p, len, &prepared);
59662306a36Sopenharmony_ci	if (ret < 0)
59762306a36Sopenharmony_ci		goto out;
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_ci	read_extent_buffer(eb, prepared, off, len);
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ciout:
60262306a36Sopenharmony_ci	return ret;
60362306a36Sopenharmony_ci}
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_cistatic int fs_path_copy(struct fs_path *p, struct fs_path *from)
60662306a36Sopenharmony_ci{
60762306a36Sopenharmony_ci	p->reversed = from->reversed;
60862306a36Sopenharmony_ci	fs_path_reset(p);
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci	return fs_path_add_path(p, from);
61162306a36Sopenharmony_ci}
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_cistatic void fs_path_unreverse(struct fs_path *p)
61462306a36Sopenharmony_ci{
61562306a36Sopenharmony_ci	char *tmp;
61662306a36Sopenharmony_ci	int len;
61762306a36Sopenharmony_ci
61862306a36Sopenharmony_ci	if (!p->reversed)
61962306a36Sopenharmony_ci		return;
62062306a36Sopenharmony_ci
62162306a36Sopenharmony_ci	tmp = p->start;
62262306a36Sopenharmony_ci	len = p->end - p->start;
62362306a36Sopenharmony_ci	p->start = p->buf;
62462306a36Sopenharmony_ci	p->end = p->start + len;
62562306a36Sopenharmony_ci	memmove(p->start, tmp, len + 1);
62662306a36Sopenharmony_ci	p->reversed = 0;
62762306a36Sopenharmony_ci}
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_cistatic struct btrfs_path *alloc_path_for_send(void)
63062306a36Sopenharmony_ci{
63162306a36Sopenharmony_ci	struct btrfs_path *path;
63262306a36Sopenharmony_ci
63362306a36Sopenharmony_ci	path = btrfs_alloc_path();
63462306a36Sopenharmony_ci	if (!path)
63562306a36Sopenharmony_ci		return NULL;
63662306a36Sopenharmony_ci	path->search_commit_root = 1;
63762306a36Sopenharmony_ci	path->skip_locking = 1;
63862306a36Sopenharmony_ci	path->need_commit_sem = 1;
63962306a36Sopenharmony_ci	return path;
64062306a36Sopenharmony_ci}
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_cistatic int write_buf(struct file *filp, const void *buf, u32 len, loff_t *off)
64362306a36Sopenharmony_ci{
64462306a36Sopenharmony_ci	int ret;
64562306a36Sopenharmony_ci	u32 pos = 0;
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_ci	while (pos < len) {
64862306a36Sopenharmony_ci		ret = kernel_write(filp, buf + pos, len - pos, off);
64962306a36Sopenharmony_ci		if (ret < 0)
65062306a36Sopenharmony_ci			return ret;
65162306a36Sopenharmony_ci		if (ret == 0)
65262306a36Sopenharmony_ci			return -EIO;
65362306a36Sopenharmony_ci		pos += ret;
65462306a36Sopenharmony_ci	}
65562306a36Sopenharmony_ci
65662306a36Sopenharmony_ci	return 0;
65762306a36Sopenharmony_ci}
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_cistatic int tlv_put(struct send_ctx *sctx, u16 attr, const void *data, int len)
66062306a36Sopenharmony_ci{
66162306a36Sopenharmony_ci	struct btrfs_tlv_header *hdr;
66262306a36Sopenharmony_ci	int total_len = sizeof(*hdr) + len;
66362306a36Sopenharmony_ci	int left = sctx->send_max_size - sctx->send_size;
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci	if (WARN_ON_ONCE(sctx->put_data))
66662306a36Sopenharmony_ci		return -EINVAL;
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_ci	if (unlikely(left < total_len))
66962306a36Sopenharmony_ci		return -EOVERFLOW;
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_ci	hdr = (struct btrfs_tlv_header *) (sctx->send_buf + sctx->send_size);
67262306a36Sopenharmony_ci	put_unaligned_le16(attr, &hdr->tlv_type);
67362306a36Sopenharmony_ci	put_unaligned_le16(len, &hdr->tlv_len);
67462306a36Sopenharmony_ci	memcpy(hdr + 1, data, len);
67562306a36Sopenharmony_ci	sctx->send_size += total_len;
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_ci	return 0;
67862306a36Sopenharmony_ci}
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci#define TLV_PUT_DEFINE_INT(bits) \
68162306a36Sopenharmony_ci	static int tlv_put_u##bits(struct send_ctx *sctx,	 	\
68262306a36Sopenharmony_ci			u##bits attr, u##bits value)			\
68362306a36Sopenharmony_ci	{								\
68462306a36Sopenharmony_ci		__le##bits __tmp = cpu_to_le##bits(value);		\
68562306a36Sopenharmony_ci		return tlv_put(sctx, attr, &__tmp, sizeof(__tmp));	\
68662306a36Sopenharmony_ci	}
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ciTLV_PUT_DEFINE_INT(8)
68962306a36Sopenharmony_ciTLV_PUT_DEFINE_INT(32)
69062306a36Sopenharmony_ciTLV_PUT_DEFINE_INT(64)
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_cistatic int tlv_put_string(struct send_ctx *sctx, u16 attr,
69362306a36Sopenharmony_ci			  const char *str, int len)
69462306a36Sopenharmony_ci{
69562306a36Sopenharmony_ci	if (len == -1)
69662306a36Sopenharmony_ci		len = strlen(str);
69762306a36Sopenharmony_ci	return tlv_put(sctx, attr, str, len);
69862306a36Sopenharmony_ci}
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_cistatic int tlv_put_uuid(struct send_ctx *sctx, u16 attr,
70162306a36Sopenharmony_ci			const u8 *uuid)
70262306a36Sopenharmony_ci{
70362306a36Sopenharmony_ci	return tlv_put(sctx, attr, uuid, BTRFS_UUID_SIZE);
70462306a36Sopenharmony_ci}
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_cistatic int tlv_put_btrfs_timespec(struct send_ctx *sctx, u16 attr,
70762306a36Sopenharmony_ci				  struct extent_buffer *eb,
70862306a36Sopenharmony_ci				  struct btrfs_timespec *ts)
70962306a36Sopenharmony_ci{
71062306a36Sopenharmony_ci	struct btrfs_timespec bts;
71162306a36Sopenharmony_ci	read_extent_buffer(eb, &bts, (unsigned long)ts, sizeof(bts));
71262306a36Sopenharmony_ci	return tlv_put(sctx, attr, &bts, sizeof(bts));
71362306a36Sopenharmony_ci}
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci#define TLV_PUT(sctx, attrtype, data, attrlen) \
71762306a36Sopenharmony_ci	do { \
71862306a36Sopenharmony_ci		ret = tlv_put(sctx, attrtype, data, attrlen); \
71962306a36Sopenharmony_ci		if (ret < 0) \
72062306a36Sopenharmony_ci			goto tlv_put_failure; \
72162306a36Sopenharmony_ci	} while (0)
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_ci#define TLV_PUT_INT(sctx, attrtype, bits, value) \
72462306a36Sopenharmony_ci	do { \
72562306a36Sopenharmony_ci		ret = tlv_put_u##bits(sctx, attrtype, value); \
72662306a36Sopenharmony_ci		if (ret < 0) \
72762306a36Sopenharmony_ci			goto tlv_put_failure; \
72862306a36Sopenharmony_ci	} while (0)
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci#define TLV_PUT_U8(sctx, attrtype, data) TLV_PUT_INT(sctx, attrtype, 8, data)
73162306a36Sopenharmony_ci#define TLV_PUT_U16(sctx, attrtype, data) TLV_PUT_INT(sctx, attrtype, 16, data)
73262306a36Sopenharmony_ci#define TLV_PUT_U32(sctx, attrtype, data) TLV_PUT_INT(sctx, attrtype, 32, data)
73362306a36Sopenharmony_ci#define TLV_PUT_U64(sctx, attrtype, data) TLV_PUT_INT(sctx, attrtype, 64, data)
73462306a36Sopenharmony_ci#define TLV_PUT_STRING(sctx, attrtype, str, len) \
73562306a36Sopenharmony_ci	do { \
73662306a36Sopenharmony_ci		ret = tlv_put_string(sctx, attrtype, str, len); \
73762306a36Sopenharmony_ci		if (ret < 0) \
73862306a36Sopenharmony_ci			goto tlv_put_failure; \
73962306a36Sopenharmony_ci	} while (0)
74062306a36Sopenharmony_ci#define TLV_PUT_PATH(sctx, attrtype, p) \
74162306a36Sopenharmony_ci	do { \
74262306a36Sopenharmony_ci		ret = tlv_put_string(sctx, attrtype, p->start, \
74362306a36Sopenharmony_ci			p->end - p->start); \
74462306a36Sopenharmony_ci		if (ret < 0) \
74562306a36Sopenharmony_ci			goto tlv_put_failure; \
74662306a36Sopenharmony_ci	} while(0)
74762306a36Sopenharmony_ci#define TLV_PUT_UUID(sctx, attrtype, uuid) \
74862306a36Sopenharmony_ci	do { \
74962306a36Sopenharmony_ci		ret = tlv_put_uuid(sctx, attrtype, uuid); \
75062306a36Sopenharmony_ci		if (ret < 0) \
75162306a36Sopenharmony_ci			goto tlv_put_failure; \
75262306a36Sopenharmony_ci	} while (0)
75362306a36Sopenharmony_ci#define TLV_PUT_BTRFS_TIMESPEC(sctx, attrtype, eb, ts) \
75462306a36Sopenharmony_ci	do { \
75562306a36Sopenharmony_ci		ret = tlv_put_btrfs_timespec(sctx, attrtype, eb, ts); \
75662306a36Sopenharmony_ci		if (ret < 0) \
75762306a36Sopenharmony_ci			goto tlv_put_failure; \
75862306a36Sopenharmony_ci	} while (0)
75962306a36Sopenharmony_ci
76062306a36Sopenharmony_cistatic int send_header(struct send_ctx *sctx)
76162306a36Sopenharmony_ci{
76262306a36Sopenharmony_ci	struct btrfs_stream_header hdr;
76362306a36Sopenharmony_ci
76462306a36Sopenharmony_ci	strcpy(hdr.magic, BTRFS_SEND_STREAM_MAGIC);
76562306a36Sopenharmony_ci	hdr.version = cpu_to_le32(sctx->proto);
76662306a36Sopenharmony_ci	return write_buf(sctx->send_filp, &hdr, sizeof(hdr),
76762306a36Sopenharmony_ci					&sctx->send_off);
76862306a36Sopenharmony_ci}
76962306a36Sopenharmony_ci
77062306a36Sopenharmony_ci/*
77162306a36Sopenharmony_ci * For each command/item we want to send to userspace, we call this function.
77262306a36Sopenharmony_ci */
77362306a36Sopenharmony_cistatic int begin_cmd(struct send_ctx *sctx, int cmd)
77462306a36Sopenharmony_ci{
77562306a36Sopenharmony_ci	struct btrfs_cmd_header *hdr;
77662306a36Sopenharmony_ci
77762306a36Sopenharmony_ci	if (WARN_ON(!sctx->send_buf))
77862306a36Sopenharmony_ci		return -EINVAL;
77962306a36Sopenharmony_ci
78062306a36Sopenharmony_ci	BUG_ON(sctx->send_size);
78162306a36Sopenharmony_ci
78262306a36Sopenharmony_ci	sctx->send_size += sizeof(*hdr);
78362306a36Sopenharmony_ci	hdr = (struct btrfs_cmd_header *)sctx->send_buf;
78462306a36Sopenharmony_ci	put_unaligned_le16(cmd, &hdr->cmd);
78562306a36Sopenharmony_ci
78662306a36Sopenharmony_ci	return 0;
78762306a36Sopenharmony_ci}
78862306a36Sopenharmony_ci
78962306a36Sopenharmony_cistatic int send_cmd(struct send_ctx *sctx)
79062306a36Sopenharmony_ci{
79162306a36Sopenharmony_ci	int ret;
79262306a36Sopenharmony_ci	struct btrfs_cmd_header *hdr;
79362306a36Sopenharmony_ci	u32 crc;
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_ci	hdr = (struct btrfs_cmd_header *)sctx->send_buf;
79662306a36Sopenharmony_ci	put_unaligned_le32(sctx->send_size - sizeof(*hdr), &hdr->len);
79762306a36Sopenharmony_ci	put_unaligned_le32(0, &hdr->crc);
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_ci	crc = btrfs_crc32c(0, (unsigned char *)sctx->send_buf, sctx->send_size);
80062306a36Sopenharmony_ci	put_unaligned_le32(crc, &hdr->crc);
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_ci	ret = write_buf(sctx->send_filp, sctx->send_buf, sctx->send_size,
80362306a36Sopenharmony_ci					&sctx->send_off);
80462306a36Sopenharmony_ci
80562306a36Sopenharmony_ci	sctx->send_size = 0;
80662306a36Sopenharmony_ci	sctx->put_data = false;
80762306a36Sopenharmony_ci
80862306a36Sopenharmony_ci	return ret;
80962306a36Sopenharmony_ci}
81062306a36Sopenharmony_ci
81162306a36Sopenharmony_ci/*
81262306a36Sopenharmony_ci * Sends a move instruction to user space
81362306a36Sopenharmony_ci */
81462306a36Sopenharmony_cistatic int send_rename(struct send_ctx *sctx,
81562306a36Sopenharmony_ci		     struct fs_path *from, struct fs_path *to)
81662306a36Sopenharmony_ci{
81762306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
81862306a36Sopenharmony_ci	int ret;
81962306a36Sopenharmony_ci
82062306a36Sopenharmony_ci	btrfs_debug(fs_info, "send_rename %s -> %s", from->start, to->start);
82162306a36Sopenharmony_ci
82262306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_RENAME);
82362306a36Sopenharmony_ci	if (ret < 0)
82462306a36Sopenharmony_ci		goto out;
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, from);
82762306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_TO, to);
82862306a36Sopenharmony_ci
82962306a36Sopenharmony_ci	ret = send_cmd(sctx);
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_citlv_put_failure:
83262306a36Sopenharmony_ciout:
83362306a36Sopenharmony_ci	return ret;
83462306a36Sopenharmony_ci}
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ci/*
83762306a36Sopenharmony_ci * Sends a link instruction to user space
83862306a36Sopenharmony_ci */
83962306a36Sopenharmony_cistatic int send_link(struct send_ctx *sctx,
84062306a36Sopenharmony_ci		     struct fs_path *path, struct fs_path *lnk)
84162306a36Sopenharmony_ci{
84262306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
84362306a36Sopenharmony_ci	int ret;
84462306a36Sopenharmony_ci
84562306a36Sopenharmony_ci	btrfs_debug(fs_info, "send_link %s -> %s", path->start, lnk->start);
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_LINK);
84862306a36Sopenharmony_ci	if (ret < 0)
84962306a36Sopenharmony_ci		goto out;
85062306a36Sopenharmony_ci
85162306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path);
85262306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_LINK, lnk);
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_ci	ret = send_cmd(sctx);
85562306a36Sopenharmony_ci
85662306a36Sopenharmony_citlv_put_failure:
85762306a36Sopenharmony_ciout:
85862306a36Sopenharmony_ci	return ret;
85962306a36Sopenharmony_ci}
86062306a36Sopenharmony_ci
86162306a36Sopenharmony_ci/*
86262306a36Sopenharmony_ci * Sends an unlink instruction to user space
86362306a36Sopenharmony_ci */
86462306a36Sopenharmony_cistatic int send_unlink(struct send_ctx *sctx, struct fs_path *path)
86562306a36Sopenharmony_ci{
86662306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
86762306a36Sopenharmony_ci	int ret;
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_ci	btrfs_debug(fs_info, "send_unlink %s", path->start);
87062306a36Sopenharmony_ci
87162306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_UNLINK);
87262306a36Sopenharmony_ci	if (ret < 0)
87362306a36Sopenharmony_ci		goto out;
87462306a36Sopenharmony_ci
87562306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path);
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_ci	ret = send_cmd(sctx);
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_citlv_put_failure:
88062306a36Sopenharmony_ciout:
88162306a36Sopenharmony_ci	return ret;
88262306a36Sopenharmony_ci}
88362306a36Sopenharmony_ci
88462306a36Sopenharmony_ci/*
88562306a36Sopenharmony_ci * Sends a rmdir instruction to user space
88662306a36Sopenharmony_ci */
88762306a36Sopenharmony_cistatic int send_rmdir(struct send_ctx *sctx, struct fs_path *path)
88862306a36Sopenharmony_ci{
88962306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
89062306a36Sopenharmony_ci	int ret;
89162306a36Sopenharmony_ci
89262306a36Sopenharmony_ci	btrfs_debug(fs_info, "send_rmdir %s", path->start);
89362306a36Sopenharmony_ci
89462306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_RMDIR);
89562306a36Sopenharmony_ci	if (ret < 0)
89662306a36Sopenharmony_ci		goto out;
89762306a36Sopenharmony_ci
89862306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path);
89962306a36Sopenharmony_ci
90062306a36Sopenharmony_ci	ret = send_cmd(sctx);
90162306a36Sopenharmony_ci
90262306a36Sopenharmony_citlv_put_failure:
90362306a36Sopenharmony_ciout:
90462306a36Sopenharmony_ci	return ret;
90562306a36Sopenharmony_ci}
90662306a36Sopenharmony_ci
90762306a36Sopenharmony_cistruct btrfs_inode_info {
90862306a36Sopenharmony_ci	u64 size;
90962306a36Sopenharmony_ci	u64 gen;
91062306a36Sopenharmony_ci	u64 mode;
91162306a36Sopenharmony_ci	u64 uid;
91262306a36Sopenharmony_ci	u64 gid;
91362306a36Sopenharmony_ci	u64 rdev;
91462306a36Sopenharmony_ci	u64 fileattr;
91562306a36Sopenharmony_ci	u64 nlink;
91662306a36Sopenharmony_ci};
91762306a36Sopenharmony_ci
91862306a36Sopenharmony_ci/*
91962306a36Sopenharmony_ci * Helper function to retrieve some fields from an inode item.
92062306a36Sopenharmony_ci */
92162306a36Sopenharmony_cistatic int get_inode_info(struct btrfs_root *root, u64 ino,
92262306a36Sopenharmony_ci			  struct btrfs_inode_info *info)
92362306a36Sopenharmony_ci{
92462306a36Sopenharmony_ci	int ret;
92562306a36Sopenharmony_ci	struct btrfs_path *path;
92662306a36Sopenharmony_ci	struct btrfs_inode_item *ii;
92762306a36Sopenharmony_ci	struct btrfs_key key;
92862306a36Sopenharmony_ci
92962306a36Sopenharmony_ci	path = alloc_path_for_send();
93062306a36Sopenharmony_ci	if (!path)
93162306a36Sopenharmony_ci		return -ENOMEM;
93262306a36Sopenharmony_ci
93362306a36Sopenharmony_ci	key.objectid = ino;
93462306a36Sopenharmony_ci	key.type = BTRFS_INODE_ITEM_KEY;
93562306a36Sopenharmony_ci	key.offset = 0;
93662306a36Sopenharmony_ci	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
93762306a36Sopenharmony_ci	if (ret) {
93862306a36Sopenharmony_ci		if (ret > 0)
93962306a36Sopenharmony_ci			ret = -ENOENT;
94062306a36Sopenharmony_ci		goto out;
94162306a36Sopenharmony_ci	}
94262306a36Sopenharmony_ci
94362306a36Sopenharmony_ci	if (!info)
94462306a36Sopenharmony_ci		goto out;
94562306a36Sopenharmony_ci
94662306a36Sopenharmony_ci	ii = btrfs_item_ptr(path->nodes[0], path->slots[0],
94762306a36Sopenharmony_ci			struct btrfs_inode_item);
94862306a36Sopenharmony_ci	info->size = btrfs_inode_size(path->nodes[0], ii);
94962306a36Sopenharmony_ci	info->gen = btrfs_inode_generation(path->nodes[0], ii);
95062306a36Sopenharmony_ci	info->mode = btrfs_inode_mode(path->nodes[0], ii);
95162306a36Sopenharmony_ci	info->uid = btrfs_inode_uid(path->nodes[0], ii);
95262306a36Sopenharmony_ci	info->gid = btrfs_inode_gid(path->nodes[0], ii);
95362306a36Sopenharmony_ci	info->rdev = btrfs_inode_rdev(path->nodes[0], ii);
95462306a36Sopenharmony_ci	info->nlink = btrfs_inode_nlink(path->nodes[0], ii);
95562306a36Sopenharmony_ci	/*
95662306a36Sopenharmony_ci	 * Transfer the unchanged u64 value of btrfs_inode_item::flags, that's
95762306a36Sopenharmony_ci	 * otherwise logically split to 32/32 parts.
95862306a36Sopenharmony_ci	 */
95962306a36Sopenharmony_ci	info->fileattr = btrfs_inode_flags(path->nodes[0], ii);
96062306a36Sopenharmony_ci
96162306a36Sopenharmony_ciout:
96262306a36Sopenharmony_ci	btrfs_free_path(path);
96362306a36Sopenharmony_ci	return ret;
96462306a36Sopenharmony_ci}
96562306a36Sopenharmony_ci
96662306a36Sopenharmony_cistatic int get_inode_gen(struct btrfs_root *root, u64 ino, u64 *gen)
96762306a36Sopenharmony_ci{
96862306a36Sopenharmony_ci	int ret;
96962306a36Sopenharmony_ci	struct btrfs_inode_info info = { 0 };
97062306a36Sopenharmony_ci
97162306a36Sopenharmony_ci	ASSERT(gen);
97262306a36Sopenharmony_ci
97362306a36Sopenharmony_ci	ret = get_inode_info(root, ino, &info);
97462306a36Sopenharmony_ci	*gen = info.gen;
97562306a36Sopenharmony_ci	return ret;
97662306a36Sopenharmony_ci}
97762306a36Sopenharmony_ci
97862306a36Sopenharmony_citypedef int (*iterate_inode_ref_t)(int num, u64 dir, int index,
97962306a36Sopenharmony_ci				   struct fs_path *p,
98062306a36Sopenharmony_ci				   void *ctx);
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_ci/*
98362306a36Sopenharmony_ci * Helper function to iterate the entries in ONE btrfs_inode_ref or
98462306a36Sopenharmony_ci * btrfs_inode_extref.
98562306a36Sopenharmony_ci * The iterate callback may return a non zero value to stop iteration. This can
98662306a36Sopenharmony_ci * be a negative value for error codes or 1 to simply stop it.
98762306a36Sopenharmony_ci *
98862306a36Sopenharmony_ci * path must point to the INODE_REF or INODE_EXTREF when called.
98962306a36Sopenharmony_ci */
99062306a36Sopenharmony_cistatic int iterate_inode_ref(struct btrfs_root *root, struct btrfs_path *path,
99162306a36Sopenharmony_ci			     struct btrfs_key *found_key, int resolve,
99262306a36Sopenharmony_ci			     iterate_inode_ref_t iterate, void *ctx)
99362306a36Sopenharmony_ci{
99462306a36Sopenharmony_ci	struct extent_buffer *eb = path->nodes[0];
99562306a36Sopenharmony_ci	struct btrfs_inode_ref *iref;
99662306a36Sopenharmony_ci	struct btrfs_inode_extref *extref;
99762306a36Sopenharmony_ci	struct btrfs_path *tmp_path;
99862306a36Sopenharmony_ci	struct fs_path *p;
99962306a36Sopenharmony_ci	u32 cur = 0;
100062306a36Sopenharmony_ci	u32 total;
100162306a36Sopenharmony_ci	int slot = path->slots[0];
100262306a36Sopenharmony_ci	u32 name_len;
100362306a36Sopenharmony_ci	char *start;
100462306a36Sopenharmony_ci	int ret = 0;
100562306a36Sopenharmony_ci	int num = 0;
100662306a36Sopenharmony_ci	int index;
100762306a36Sopenharmony_ci	u64 dir;
100862306a36Sopenharmony_ci	unsigned long name_off;
100962306a36Sopenharmony_ci	unsigned long elem_size;
101062306a36Sopenharmony_ci	unsigned long ptr;
101162306a36Sopenharmony_ci
101262306a36Sopenharmony_ci	p = fs_path_alloc_reversed();
101362306a36Sopenharmony_ci	if (!p)
101462306a36Sopenharmony_ci		return -ENOMEM;
101562306a36Sopenharmony_ci
101662306a36Sopenharmony_ci	tmp_path = alloc_path_for_send();
101762306a36Sopenharmony_ci	if (!tmp_path) {
101862306a36Sopenharmony_ci		fs_path_free(p);
101962306a36Sopenharmony_ci		return -ENOMEM;
102062306a36Sopenharmony_ci	}
102162306a36Sopenharmony_ci
102262306a36Sopenharmony_ci
102362306a36Sopenharmony_ci	if (found_key->type == BTRFS_INODE_REF_KEY) {
102462306a36Sopenharmony_ci		ptr = (unsigned long)btrfs_item_ptr(eb, slot,
102562306a36Sopenharmony_ci						    struct btrfs_inode_ref);
102662306a36Sopenharmony_ci		total = btrfs_item_size(eb, slot);
102762306a36Sopenharmony_ci		elem_size = sizeof(*iref);
102862306a36Sopenharmony_ci	} else {
102962306a36Sopenharmony_ci		ptr = btrfs_item_ptr_offset(eb, slot);
103062306a36Sopenharmony_ci		total = btrfs_item_size(eb, slot);
103162306a36Sopenharmony_ci		elem_size = sizeof(*extref);
103262306a36Sopenharmony_ci	}
103362306a36Sopenharmony_ci
103462306a36Sopenharmony_ci	while (cur < total) {
103562306a36Sopenharmony_ci		fs_path_reset(p);
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_ci		if (found_key->type == BTRFS_INODE_REF_KEY) {
103862306a36Sopenharmony_ci			iref = (struct btrfs_inode_ref *)(ptr + cur);
103962306a36Sopenharmony_ci			name_len = btrfs_inode_ref_name_len(eb, iref);
104062306a36Sopenharmony_ci			name_off = (unsigned long)(iref + 1);
104162306a36Sopenharmony_ci			index = btrfs_inode_ref_index(eb, iref);
104262306a36Sopenharmony_ci			dir = found_key->offset;
104362306a36Sopenharmony_ci		} else {
104462306a36Sopenharmony_ci			extref = (struct btrfs_inode_extref *)(ptr + cur);
104562306a36Sopenharmony_ci			name_len = btrfs_inode_extref_name_len(eb, extref);
104662306a36Sopenharmony_ci			name_off = (unsigned long)&extref->name;
104762306a36Sopenharmony_ci			index = btrfs_inode_extref_index(eb, extref);
104862306a36Sopenharmony_ci			dir = btrfs_inode_extref_parent(eb, extref);
104962306a36Sopenharmony_ci		}
105062306a36Sopenharmony_ci
105162306a36Sopenharmony_ci		if (resolve) {
105262306a36Sopenharmony_ci			start = btrfs_ref_to_path(root, tmp_path, name_len,
105362306a36Sopenharmony_ci						  name_off, eb, dir,
105462306a36Sopenharmony_ci						  p->buf, p->buf_len);
105562306a36Sopenharmony_ci			if (IS_ERR(start)) {
105662306a36Sopenharmony_ci				ret = PTR_ERR(start);
105762306a36Sopenharmony_ci				goto out;
105862306a36Sopenharmony_ci			}
105962306a36Sopenharmony_ci			if (start < p->buf) {
106062306a36Sopenharmony_ci				/* overflow , try again with larger buffer */
106162306a36Sopenharmony_ci				ret = fs_path_ensure_buf(p,
106262306a36Sopenharmony_ci						p->buf_len + p->buf - start);
106362306a36Sopenharmony_ci				if (ret < 0)
106462306a36Sopenharmony_ci					goto out;
106562306a36Sopenharmony_ci				start = btrfs_ref_to_path(root, tmp_path,
106662306a36Sopenharmony_ci							  name_len, name_off,
106762306a36Sopenharmony_ci							  eb, dir,
106862306a36Sopenharmony_ci							  p->buf, p->buf_len);
106962306a36Sopenharmony_ci				if (IS_ERR(start)) {
107062306a36Sopenharmony_ci					ret = PTR_ERR(start);
107162306a36Sopenharmony_ci					goto out;
107262306a36Sopenharmony_ci				}
107362306a36Sopenharmony_ci				BUG_ON(start < p->buf);
107462306a36Sopenharmony_ci			}
107562306a36Sopenharmony_ci			p->start = start;
107662306a36Sopenharmony_ci		} else {
107762306a36Sopenharmony_ci			ret = fs_path_add_from_extent_buffer(p, eb, name_off,
107862306a36Sopenharmony_ci							     name_len);
107962306a36Sopenharmony_ci			if (ret < 0)
108062306a36Sopenharmony_ci				goto out;
108162306a36Sopenharmony_ci		}
108262306a36Sopenharmony_ci
108362306a36Sopenharmony_ci		cur += elem_size + name_len;
108462306a36Sopenharmony_ci		ret = iterate(num, dir, index, p, ctx);
108562306a36Sopenharmony_ci		if (ret)
108662306a36Sopenharmony_ci			goto out;
108762306a36Sopenharmony_ci		num++;
108862306a36Sopenharmony_ci	}
108962306a36Sopenharmony_ci
109062306a36Sopenharmony_ciout:
109162306a36Sopenharmony_ci	btrfs_free_path(tmp_path);
109262306a36Sopenharmony_ci	fs_path_free(p);
109362306a36Sopenharmony_ci	return ret;
109462306a36Sopenharmony_ci}
109562306a36Sopenharmony_ci
109662306a36Sopenharmony_citypedef int (*iterate_dir_item_t)(int num, struct btrfs_key *di_key,
109762306a36Sopenharmony_ci				  const char *name, int name_len,
109862306a36Sopenharmony_ci				  const char *data, int data_len,
109962306a36Sopenharmony_ci				  void *ctx);
110062306a36Sopenharmony_ci
110162306a36Sopenharmony_ci/*
110262306a36Sopenharmony_ci * Helper function to iterate the entries in ONE btrfs_dir_item.
110362306a36Sopenharmony_ci * The iterate callback may return a non zero value to stop iteration. This can
110462306a36Sopenharmony_ci * be a negative value for error codes or 1 to simply stop it.
110562306a36Sopenharmony_ci *
110662306a36Sopenharmony_ci * path must point to the dir item when called.
110762306a36Sopenharmony_ci */
110862306a36Sopenharmony_cistatic int iterate_dir_item(struct btrfs_root *root, struct btrfs_path *path,
110962306a36Sopenharmony_ci			    iterate_dir_item_t iterate, void *ctx)
111062306a36Sopenharmony_ci{
111162306a36Sopenharmony_ci	int ret = 0;
111262306a36Sopenharmony_ci	struct extent_buffer *eb;
111362306a36Sopenharmony_ci	struct btrfs_dir_item *di;
111462306a36Sopenharmony_ci	struct btrfs_key di_key;
111562306a36Sopenharmony_ci	char *buf = NULL;
111662306a36Sopenharmony_ci	int buf_len;
111762306a36Sopenharmony_ci	u32 name_len;
111862306a36Sopenharmony_ci	u32 data_len;
111962306a36Sopenharmony_ci	u32 cur;
112062306a36Sopenharmony_ci	u32 len;
112162306a36Sopenharmony_ci	u32 total;
112262306a36Sopenharmony_ci	int slot;
112362306a36Sopenharmony_ci	int num;
112462306a36Sopenharmony_ci
112562306a36Sopenharmony_ci	/*
112662306a36Sopenharmony_ci	 * Start with a small buffer (1 page). If later we end up needing more
112762306a36Sopenharmony_ci	 * space, which can happen for xattrs on a fs with a leaf size greater
112862306a36Sopenharmony_ci	 * then the page size, attempt to increase the buffer. Typically xattr
112962306a36Sopenharmony_ci	 * values are small.
113062306a36Sopenharmony_ci	 */
113162306a36Sopenharmony_ci	buf_len = PATH_MAX;
113262306a36Sopenharmony_ci	buf = kmalloc(buf_len, GFP_KERNEL);
113362306a36Sopenharmony_ci	if (!buf) {
113462306a36Sopenharmony_ci		ret = -ENOMEM;
113562306a36Sopenharmony_ci		goto out;
113662306a36Sopenharmony_ci	}
113762306a36Sopenharmony_ci
113862306a36Sopenharmony_ci	eb = path->nodes[0];
113962306a36Sopenharmony_ci	slot = path->slots[0];
114062306a36Sopenharmony_ci	di = btrfs_item_ptr(eb, slot, struct btrfs_dir_item);
114162306a36Sopenharmony_ci	cur = 0;
114262306a36Sopenharmony_ci	len = 0;
114362306a36Sopenharmony_ci	total = btrfs_item_size(eb, slot);
114462306a36Sopenharmony_ci
114562306a36Sopenharmony_ci	num = 0;
114662306a36Sopenharmony_ci	while (cur < total) {
114762306a36Sopenharmony_ci		name_len = btrfs_dir_name_len(eb, di);
114862306a36Sopenharmony_ci		data_len = btrfs_dir_data_len(eb, di);
114962306a36Sopenharmony_ci		btrfs_dir_item_key_to_cpu(eb, di, &di_key);
115062306a36Sopenharmony_ci
115162306a36Sopenharmony_ci		if (btrfs_dir_ftype(eb, di) == BTRFS_FT_XATTR) {
115262306a36Sopenharmony_ci			if (name_len > XATTR_NAME_MAX) {
115362306a36Sopenharmony_ci				ret = -ENAMETOOLONG;
115462306a36Sopenharmony_ci				goto out;
115562306a36Sopenharmony_ci			}
115662306a36Sopenharmony_ci			if (name_len + data_len >
115762306a36Sopenharmony_ci					BTRFS_MAX_XATTR_SIZE(root->fs_info)) {
115862306a36Sopenharmony_ci				ret = -E2BIG;
115962306a36Sopenharmony_ci				goto out;
116062306a36Sopenharmony_ci			}
116162306a36Sopenharmony_ci		} else {
116262306a36Sopenharmony_ci			/*
116362306a36Sopenharmony_ci			 * Path too long
116462306a36Sopenharmony_ci			 */
116562306a36Sopenharmony_ci			if (name_len + data_len > PATH_MAX) {
116662306a36Sopenharmony_ci				ret = -ENAMETOOLONG;
116762306a36Sopenharmony_ci				goto out;
116862306a36Sopenharmony_ci			}
116962306a36Sopenharmony_ci		}
117062306a36Sopenharmony_ci
117162306a36Sopenharmony_ci		if (name_len + data_len > buf_len) {
117262306a36Sopenharmony_ci			buf_len = name_len + data_len;
117362306a36Sopenharmony_ci			if (is_vmalloc_addr(buf)) {
117462306a36Sopenharmony_ci				vfree(buf);
117562306a36Sopenharmony_ci				buf = NULL;
117662306a36Sopenharmony_ci			} else {
117762306a36Sopenharmony_ci				char *tmp = krealloc(buf, buf_len,
117862306a36Sopenharmony_ci						GFP_KERNEL | __GFP_NOWARN);
117962306a36Sopenharmony_ci
118062306a36Sopenharmony_ci				if (!tmp)
118162306a36Sopenharmony_ci					kfree(buf);
118262306a36Sopenharmony_ci				buf = tmp;
118362306a36Sopenharmony_ci			}
118462306a36Sopenharmony_ci			if (!buf) {
118562306a36Sopenharmony_ci				buf = kvmalloc(buf_len, GFP_KERNEL);
118662306a36Sopenharmony_ci				if (!buf) {
118762306a36Sopenharmony_ci					ret = -ENOMEM;
118862306a36Sopenharmony_ci					goto out;
118962306a36Sopenharmony_ci				}
119062306a36Sopenharmony_ci			}
119162306a36Sopenharmony_ci		}
119262306a36Sopenharmony_ci
119362306a36Sopenharmony_ci		read_extent_buffer(eb, buf, (unsigned long)(di + 1),
119462306a36Sopenharmony_ci				name_len + data_len);
119562306a36Sopenharmony_ci
119662306a36Sopenharmony_ci		len = sizeof(*di) + name_len + data_len;
119762306a36Sopenharmony_ci		di = (struct btrfs_dir_item *)((char *)di + len);
119862306a36Sopenharmony_ci		cur += len;
119962306a36Sopenharmony_ci
120062306a36Sopenharmony_ci		ret = iterate(num, &di_key, buf, name_len, buf + name_len,
120162306a36Sopenharmony_ci			      data_len, ctx);
120262306a36Sopenharmony_ci		if (ret < 0)
120362306a36Sopenharmony_ci			goto out;
120462306a36Sopenharmony_ci		if (ret) {
120562306a36Sopenharmony_ci			ret = 0;
120662306a36Sopenharmony_ci			goto out;
120762306a36Sopenharmony_ci		}
120862306a36Sopenharmony_ci
120962306a36Sopenharmony_ci		num++;
121062306a36Sopenharmony_ci	}
121162306a36Sopenharmony_ci
121262306a36Sopenharmony_ciout:
121362306a36Sopenharmony_ci	kvfree(buf);
121462306a36Sopenharmony_ci	return ret;
121562306a36Sopenharmony_ci}
121662306a36Sopenharmony_ci
121762306a36Sopenharmony_cistatic int __copy_first_ref(int num, u64 dir, int index,
121862306a36Sopenharmony_ci			    struct fs_path *p, void *ctx)
121962306a36Sopenharmony_ci{
122062306a36Sopenharmony_ci	int ret;
122162306a36Sopenharmony_ci	struct fs_path *pt = ctx;
122262306a36Sopenharmony_ci
122362306a36Sopenharmony_ci	ret = fs_path_copy(pt, p);
122462306a36Sopenharmony_ci	if (ret < 0)
122562306a36Sopenharmony_ci		return ret;
122662306a36Sopenharmony_ci
122762306a36Sopenharmony_ci	/* we want the first only */
122862306a36Sopenharmony_ci	return 1;
122962306a36Sopenharmony_ci}
123062306a36Sopenharmony_ci
123162306a36Sopenharmony_ci/*
123262306a36Sopenharmony_ci * Retrieve the first path of an inode. If an inode has more then one
123362306a36Sopenharmony_ci * ref/hardlink, this is ignored.
123462306a36Sopenharmony_ci */
123562306a36Sopenharmony_cistatic int get_inode_path(struct btrfs_root *root,
123662306a36Sopenharmony_ci			  u64 ino, struct fs_path *path)
123762306a36Sopenharmony_ci{
123862306a36Sopenharmony_ci	int ret;
123962306a36Sopenharmony_ci	struct btrfs_key key, found_key;
124062306a36Sopenharmony_ci	struct btrfs_path *p;
124162306a36Sopenharmony_ci
124262306a36Sopenharmony_ci	p = alloc_path_for_send();
124362306a36Sopenharmony_ci	if (!p)
124462306a36Sopenharmony_ci		return -ENOMEM;
124562306a36Sopenharmony_ci
124662306a36Sopenharmony_ci	fs_path_reset(path);
124762306a36Sopenharmony_ci
124862306a36Sopenharmony_ci	key.objectid = ino;
124962306a36Sopenharmony_ci	key.type = BTRFS_INODE_REF_KEY;
125062306a36Sopenharmony_ci	key.offset = 0;
125162306a36Sopenharmony_ci
125262306a36Sopenharmony_ci	ret = btrfs_search_slot_for_read(root, &key, p, 1, 0);
125362306a36Sopenharmony_ci	if (ret < 0)
125462306a36Sopenharmony_ci		goto out;
125562306a36Sopenharmony_ci	if (ret) {
125662306a36Sopenharmony_ci		ret = 1;
125762306a36Sopenharmony_ci		goto out;
125862306a36Sopenharmony_ci	}
125962306a36Sopenharmony_ci	btrfs_item_key_to_cpu(p->nodes[0], &found_key, p->slots[0]);
126062306a36Sopenharmony_ci	if (found_key.objectid != ino ||
126162306a36Sopenharmony_ci	    (found_key.type != BTRFS_INODE_REF_KEY &&
126262306a36Sopenharmony_ci	     found_key.type != BTRFS_INODE_EXTREF_KEY)) {
126362306a36Sopenharmony_ci		ret = -ENOENT;
126462306a36Sopenharmony_ci		goto out;
126562306a36Sopenharmony_ci	}
126662306a36Sopenharmony_ci
126762306a36Sopenharmony_ci	ret = iterate_inode_ref(root, p, &found_key, 1,
126862306a36Sopenharmony_ci				__copy_first_ref, path);
126962306a36Sopenharmony_ci	if (ret < 0)
127062306a36Sopenharmony_ci		goto out;
127162306a36Sopenharmony_ci	ret = 0;
127262306a36Sopenharmony_ci
127362306a36Sopenharmony_ciout:
127462306a36Sopenharmony_ci	btrfs_free_path(p);
127562306a36Sopenharmony_ci	return ret;
127662306a36Sopenharmony_ci}
127762306a36Sopenharmony_ci
127862306a36Sopenharmony_cistruct backref_ctx {
127962306a36Sopenharmony_ci	struct send_ctx *sctx;
128062306a36Sopenharmony_ci
128162306a36Sopenharmony_ci	/* number of total found references */
128262306a36Sopenharmony_ci	u64 found;
128362306a36Sopenharmony_ci
128462306a36Sopenharmony_ci	/*
128562306a36Sopenharmony_ci	 * used for clones found in send_root. clones found behind cur_objectid
128662306a36Sopenharmony_ci	 * and cur_offset are not considered as allowed clones.
128762306a36Sopenharmony_ci	 */
128862306a36Sopenharmony_ci	u64 cur_objectid;
128962306a36Sopenharmony_ci	u64 cur_offset;
129062306a36Sopenharmony_ci
129162306a36Sopenharmony_ci	/* may be truncated in case it's the last extent in a file */
129262306a36Sopenharmony_ci	u64 extent_len;
129362306a36Sopenharmony_ci
129462306a36Sopenharmony_ci	/* The bytenr the file extent item we are processing refers to. */
129562306a36Sopenharmony_ci	u64 bytenr;
129662306a36Sopenharmony_ci	/* The owner (root id) of the data backref for the current extent. */
129762306a36Sopenharmony_ci	u64 backref_owner;
129862306a36Sopenharmony_ci	/* The offset of the data backref for the current extent. */
129962306a36Sopenharmony_ci	u64 backref_offset;
130062306a36Sopenharmony_ci};
130162306a36Sopenharmony_ci
130262306a36Sopenharmony_cistatic int __clone_root_cmp_bsearch(const void *key, const void *elt)
130362306a36Sopenharmony_ci{
130462306a36Sopenharmony_ci	u64 root = (u64)(uintptr_t)key;
130562306a36Sopenharmony_ci	const struct clone_root *cr = elt;
130662306a36Sopenharmony_ci
130762306a36Sopenharmony_ci	if (root < cr->root->root_key.objectid)
130862306a36Sopenharmony_ci		return -1;
130962306a36Sopenharmony_ci	if (root > cr->root->root_key.objectid)
131062306a36Sopenharmony_ci		return 1;
131162306a36Sopenharmony_ci	return 0;
131262306a36Sopenharmony_ci}
131362306a36Sopenharmony_ci
131462306a36Sopenharmony_cistatic int __clone_root_cmp_sort(const void *e1, const void *e2)
131562306a36Sopenharmony_ci{
131662306a36Sopenharmony_ci	const struct clone_root *cr1 = e1;
131762306a36Sopenharmony_ci	const struct clone_root *cr2 = e2;
131862306a36Sopenharmony_ci
131962306a36Sopenharmony_ci	if (cr1->root->root_key.objectid < cr2->root->root_key.objectid)
132062306a36Sopenharmony_ci		return -1;
132162306a36Sopenharmony_ci	if (cr1->root->root_key.objectid > cr2->root->root_key.objectid)
132262306a36Sopenharmony_ci		return 1;
132362306a36Sopenharmony_ci	return 0;
132462306a36Sopenharmony_ci}
132562306a36Sopenharmony_ci
132662306a36Sopenharmony_ci/*
132762306a36Sopenharmony_ci * Called for every backref that is found for the current extent.
132862306a36Sopenharmony_ci * Results are collected in sctx->clone_roots->ino/offset.
132962306a36Sopenharmony_ci */
133062306a36Sopenharmony_cistatic int iterate_backrefs(u64 ino, u64 offset, u64 num_bytes, u64 root_id,
133162306a36Sopenharmony_ci			    void *ctx_)
133262306a36Sopenharmony_ci{
133362306a36Sopenharmony_ci	struct backref_ctx *bctx = ctx_;
133462306a36Sopenharmony_ci	struct clone_root *clone_root;
133562306a36Sopenharmony_ci
133662306a36Sopenharmony_ci	/* First check if the root is in the list of accepted clone sources */
133762306a36Sopenharmony_ci	clone_root = bsearch((void *)(uintptr_t)root_id, bctx->sctx->clone_roots,
133862306a36Sopenharmony_ci			     bctx->sctx->clone_roots_cnt,
133962306a36Sopenharmony_ci			     sizeof(struct clone_root),
134062306a36Sopenharmony_ci			     __clone_root_cmp_bsearch);
134162306a36Sopenharmony_ci	if (!clone_root)
134262306a36Sopenharmony_ci		return 0;
134362306a36Sopenharmony_ci
134462306a36Sopenharmony_ci	/* This is our own reference, bail out as we can't clone from it. */
134562306a36Sopenharmony_ci	if (clone_root->root == bctx->sctx->send_root &&
134662306a36Sopenharmony_ci	    ino == bctx->cur_objectid &&
134762306a36Sopenharmony_ci	    offset == bctx->cur_offset)
134862306a36Sopenharmony_ci		return 0;
134962306a36Sopenharmony_ci
135062306a36Sopenharmony_ci	/*
135162306a36Sopenharmony_ci	 * Make sure we don't consider clones from send_root that are
135262306a36Sopenharmony_ci	 * behind the current inode/offset.
135362306a36Sopenharmony_ci	 */
135462306a36Sopenharmony_ci	if (clone_root->root == bctx->sctx->send_root) {
135562306a36Sopenharmony_ci		/*
135662306a36Sopenharmony_ci		 * If the source inode was not yet processed we can't issue a
135762306a36Sopenharmony_ci		 * clone operation, as the source extent does not exist yet at
135862306a36Sopenharmony_ci		 * the destination of the stream.
135962306a36Sopenharmony_ci		 */
136062306a36Sopenharmony_ci		if (ino > bctx->cur_objectid)
136162306a36Sopenharmony_ci			return 0;
136262306a36Sopenharmony_ci		/*
136362306a36Sopenharmony_ci		 * We clone from the inode currently being sent as long as the
136462306a36Sopenharmony_ci		 * source extent is already processed, otherwise we could try
136562306a36Sopenharmony_ci		 * to clone from an extent that does not exist yet at the
136662306a36Sopenharmony_ci		 * destination of the stream.
136762306a36Sopenharmony_ci		 */
136862306a36Sopenharmony_ci		if (ino == bctx->cur_objectid &&
136962306a36Sopenharmony_ci		    offset + bctx->extent_len >
137062306a36Sopenharmony_ci		    bctx->sctx->cur_inode_next_write_offset)
137162306a36Sopenharmony_ci			return 0;
137262306a36Sopenharmony_ci	}
137362306a36Sopenharmony_ci
137462306a36Sopenharmony_ci	bctx->found++;
137562306a36Sopenharmony_ci	clone_root->found_ref = true;
137662306a36Sopenharmony_ci
137762306a36Sopenharmony_ci	/*
137862306a36Sopenharmony_ci	 * If the given backref refers to a file extent item with a larger
137962306a36Sopenharmony_ci	 * number of bytes than what we found before, use the new one so that
138062306a36Sopenharmony_ci	 * we clone more optimally and end up doing less writes and getting
138162306a36Sopenharmony_ci	 * less exclusive, non-shared extents at the destination.
138262306a36Sopenharmony_ci	 */
138362306a36Sopenharmony_ci	if (num_bytes > clone_root->num_bytes) {
138462306a36Sopenharmony_ci		clone_root->ino = ino;
138562306a36Sopenharmony_ci		clone_root->offset = offset;
138662306a36Sopenharmony_ci		clone_root->num_bytes = num_bytes;
138762306a36Sopenharmony_ci
138862306a36Sopenharmony_ci		/*
138962306a36Sopenharmony_ci		 * Found a perfect candidate, so there's no need to continue
139062306a36Sopenharmony_ci		 * backref walking.
139162306a36Sopenharmony_ci		 */
139262306a36Sopenharmony_ci		if (num_bytes >= bctx->extent_len)
139362306a36Sopenharmony_ci			return BTRFS_ITERATE_EXTENT_INODES_STOP;
139462306a36Sopenharmony_ci	}
139562306a36Sopenharmony_ci
139662306a36Sopenharmony_ci	return 0;
139762306a36Sopenharmony_ci}
139862306a36Sopenharmony_ci
139962306a36Sopenharmony_cistatic bool lookup_backref_cache(u64 leaf_bytenr, void *ctx,
140062306a36Sopenharmony_ci				 const u64 **root_ids_ret, int *root_count_ret)
140162306a36Sopenharmony_ci{
140262306a36Sopenharmony_ci	struct backref_ctx *bctx = ctx;
140362306a36Sopenharmony_ci	struct send_ctx *sctx = bctx->sctx;
140462306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
140562306a36Sopenharmony_ci	const u64 key = leaf_bytenr >> fs_info->sectorsize_bits;
140662306a36Sopenharmony_ci	struct btrfs_lru_cache_entry *raw_entry;
140762306a36Sopenharmony_ci	struct backref_cache_entry *entry;
140862306a36Sopenharmony_ci
140962306a36Sopenharmony_ci	if (btrfs_lru_cache_size(&sctx->backref_cache) == 0)
141062306a36Sopenharmony_ci		return false;
141162306a36Sopenharmony_ci
141262306a36Sopenharmony_ci	/*
141362306a36Sopenharmony_ci	 * If relocation happened since we first filled the cache, then we must
141462306a36Sopenharmony_ci	 * empty the cache and can not use it, because even though we operate on
141562306a36Sopenharmony_ci	 * read-only roots, their leaves and nodes may have been reallocated and
141662306a36Sopenharmony_ci	 * now be used for different nodes/leaves of the same tree or some other
141762306a36Sopenharmony_ci	 * tree.
141862306a36Sopenharmony_ci	 *
141962306a36Sopenharmony_ci	 * We are called from iterate_extent_inodes() while either holding a
142062306a36Sopenharmony_ci	 * transaction handle or holding fs_info->commit_root_sem, so no need
142162306a36Sopenharmony_ci	 * to take any lock here.
142262306a36Sopenharmony_ci	 */
142362306a36Sopenharmony_ci	if (fs_info->last_reloc_trans > sctx->backref_cache_last_reloc_trans) {
142462306a36Sopenharmony_ci		btrfs_lru_cache_clear(&sctx->backref_cache);
142562306a36Sopenharmony_ci		return false;
142662306a36Sopenharmony_ci	}
142762306a36Sopenharmony_ci
142862306a36Sopenharmony_ci	raw_entry = btrfs_lru_cache_lookup(&sctx->backref_cache, key, 0);
142962306a36Sopenharmony_ci	if (!raw_entry)
143062306a36Sopenharmony_ci		return false;
143162306a36Sopenharmony_ci
143262306a36Sopenharmony_ci	entry = container_of(raw_entry, struct backref_cache_entry, entry);
143362306a36Sopenharmony_ci	*root_ids_ret = entry->root_ids;
143462306a36Sopenharmony_ci	*root_count_ret = entry->num_roots;
143562306a36Sopenharmony_ci
143662306a36Sopenharmony_ci	return true;
143762306a36Sopenharmony_ci}
143862306a36Sopenharmony_ci
143962306a36Sopenharmony_cistatic void store_backref_cache(u64 leaf_bytenr, const struct ulist *root_ids,
144062306a36Sopenharmony_ci				void *ctx)
144162306a36Sopenharmony_ci{
144262306a36Sopenharmony_ci	struct backref_ctx *bctx = ctx;
144362306a36Sopenharmony_ci	struct send_ctx *sctx = bctx->sctx;
144462306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
144562306a36Sopenharmony_ci	struct backref_cache_entry *new_entry;
144662306a36Sopenharmony_ci	struct ulist_iterator uiter;
144762306a36Sopenharmony_ci	struct ulist_node *node;
144862306a36Sopenharmony_ci	int ret;
144962306a36Sopenharmony_ci
145062306a36Sopenharmony_ci	/*
145162306a36Sopenharmony_ci	 * We're called while holding a transaction handle or while holding
145262306a36Sopenharmony_ci	 * fs_info->commit_root_sem (at iterate_extent_inodes()), so must do a
145362306a36Sopenharmony_ci	 * NOFS allocation.
145462306a36Sopenharmony_ci	 */
145562306a36Sopenharmony_ci	new_entry = kmalloc(sizeof(struct backref_cache_entry), GFP_NOFS);
145662306a36Sopenharmony_ci	/* No worries, cache is optional. */
145762306a36Sopenharmony_ci	if (!new_entry)
145862306a36Sopenharmony_ci		return;
145962306a36Sopenharmony_ci
146062306a36Sopenharmony_ci	new_entry->entry.key = leaf_bytenr >> fs_info->sectorsize_bits;
146162306a36Sopenharmony_ci	new_entry->entry.gen = 0;
146262306a36Sopenharmony_ci	new_entry->num_roots = 0;
146362306a36Sopenharmony_ci	ULIST_ITER_INIT(&uiter);
146462306a36Sopenharmony_ci	while ((node = ulist_next(root_ids, &uiter)) != NULL) {
146562306a36Sopenharmony_ci		const u64 root_id = node->val;
146662306a36Sopenharmony_ci		struct clone_root *root;
146762306a36Sopenharmony_ci
146862306a36Sopenharmony_ci		root = bsearch((void *)(uintptr_t)root_id, sctx->clone_roots,
146962306a36Sopenharmony_ci			       sctx->clone_roots_cnt, sizeof(struct clone_root),
147062306a36Sopenharmony_ci			       __clone_root_cmp_bsearch);
147162306a36Sopenharmony_ci		if (!root)
147262306a36Sopenharmony_ci			continue;
147362306a36Sopenharmony_ci
147462306a36Sopenharmony_ci		/* Too many roots, just exit, no worries as caching is optional. */
147562306a36Sopenharmony_ci		if (new_entry->num_roots >= SEND_MAX_BACKREF_CACHE_ROOTS) {
147662306a36Sopenharmony_ci			kfree(new_entry);
147762306a36Sopenharmony_ci			return;
147862306a36Sopenharmony_ci		}
147962306a36Sopenharmony_ci
148062306a36Sopenharmony_ci		new_entry->root_ids[new_entry->num_roots] = root_id;
148162306a36Sopenharmony_ci		new_entry->num_roots++;
148262306a36Sopenharmony_ci	}
148362306a36Sopenharmony_ci
148462306a36Sopenharmony_ci	/*
148562306a36Sopenharmony_ci	 * We may have not added any roots to the new cache entry, which means
148662306a36Sopenharmony_ci	 * none of the roots is part of the list of roots from which we are
148762306a36Sopenharmony_ci	 * allowed to clone. Cache the new entry as it's still useful to avoid
148862306a36Sopenharmony_ci	 * backref walking to determine which roots have a path to the leaf.
148962306a36Sopenharmony_ci	 *
149062306a36Sopenharmony_ci	 * Also use GFP_NOFS because we're called while holding a transaction
149162306a36Sopenharmony_ci	 * handle or while holding fs_info->commit_root_sem.
149262306a36Sopenharmony_ci	 */
149362306a36Sopenharmony_ci	ret = btrfs_lru_cache_store(&sctx->backref_cache, &new_entry->entry,
149462306a36Sopenharmony_ci				    GFP_NOFS);
149562306a36Sopenharmony_ci	ASSERT(ret == 0 || ret == -ENOMEM);
149662306a36Sopenharmony_ci	if (ret) {
149762306a36Sopenharmony_ci		/* Caching is optional, no worries. */
149862306a36Sopenharmony_ci		kfree(new_entry);
149962306a36Sopenharmony_ci		return;
150062306a36Sopenharmony_ci	}
150162306a36Sopenharmony_ci
150262306a36Sopenharmony_ci	/*
150362306a36Sopenharmony_ci	 * We are called from iterate_extent_inodes() while either holding a
150462306a36Sopenharmony_ci	 * transaction handle or holding fs_info->commit_root_sem, so no need
150562306a36Sopenharmony_ci	 * to take any lock here.
150662306a36Sopenharmony_ci	 */
150762306a36Sopenharmony_ci	if (btrfs_lru_cache_size(&sctx->backref_cache) == 1)
150862306a36Sopenharmony_ci		sctx->backref_cache_last_reloc_trans = fs_info->last_reloc_trans;
150962306a36Sopenharmony_ci}
151062306a36Sopenharmony_ci
151162306a36Sopenharmony_cistatic int check_extent_item(u64 bytenr, const struct btrfs_extent_item *ei,
151262306a36Sopenharmony_ci			     const struct extent_buffer *leaf, void *ctx)
151362306a36Sopenharmony_ci{
151462306a36Sopenharmony_ci	const u64 refs = btrfs_extent_refs(leaf, ei);
151562306a36Sopenharmony_ci	const struct backref_ctx *bctx = ctx;
151662306a36Sopenharmony_ci	const struct send_ctx *sctx = bctx->sctx;
151762306a36Sopenharmony_ci
151862306a36Sopenharmony_ci	if (bytenr == bctx->bytenr) {
151962306a36Sopenharmony_ci		const u64 flags = btrfs_extent_flags(leaf, ei);
152062306a36Sopenharmony_ci
152162306a36Sopenharmony_ci		if (WARN_ON(flags & BTRFS_EXTENT_FLAG_TREE_BLOCK))
152262306a36Sopenharmony_ci			return -EUCLEAN;
152362306a36Sopenharmony_ci
152462306a36Sopenharmony_ci		/*
152562306a36Sopenharmony_ci		 * If we have only one reference and only the send root as a
152662306a36Sopenharmony_ci		 * clone source - meaning no clone roots were given in the
152762306a36Sopenharmony_ci		 * struct btrfs_ioctl_send_args passed to the send ioctl - then
152862306a36Sopenharmony_ci		 * it's our reference and there's no point in doing backref
152962306a36Sopenharmony_ci		 * walking which is expensive, so exit early.
153062306a36Sopenharmony_ci		 */
153162306a36Sopenharmony_ci		if (refs == 1 && sctx->clone_roots_cnt == 1)
153262306a36Sopenharmony_ci			return -ENOENT;
153362306a36Sopenharmony_ci	}
153462306a36Sopenharmony_ci
153562306a36Sopenharmony_ci	/*
153662306a36Sopenharmony_ci	 * Backreference walking (iterate_extent_inodes() below) is currently
153762306a36Sopenharmony_ci	 * too expensive when an extent has a large number of references, both
153862306a36Sopenharmony_ci	 * in time spent and used memory. So for now just fallback to write
153962306a36Sopenharmony_ci	 * operations instead of clone operations when an extent has more than
154062306a36Sopenharmony_ci	 * a certain amount of references.
154162306a36Sopenharmony_ci	 */
154262306a36Sopenharmony_ci	if (refs > SEND_MAX_EXTENT_REFS)
154362306a36Sopenharmony_ci		return -ENOENT;
154462306a36Sopenharmony_ci
154562306a36Sopenharmony_ci	return 0;
154662306a36Sopenharmony_ci}
154762306a36Sopenharmony_ci
154862306a36Sopenharmony_cistatic bool skip_self_data_ref(u64 root, u64 ino, u64 offset, void *ctx)
154962306a36Sopenharmony_ci{
155062306a36Sopenharmony_ci	const struct backref_ctx *bctx = ctx;
155162306a36Sopenharmony_ci
155262306a36Sopenharmony_ci	if (ino == bctx->cur_objectid &&
155362306a36Sopenharmony_ci	    root == bctx->backref_owner &&
155462306a36Sopenharmony_ci	    offset == bctx->backref_offset)
155562306a36Sopenharmony_ci		return true;
155662306a36Sopenharmony_ci
155762306a36Sopenharmony_ci	return false;
155862306a36Sopenharmony_ci}
155962306a36Sopenharmony_ci
156062306a36Sopenharmony_ci/*
156162306a36Sopenharmony_ci * Given an inode, offset and extent item, it finds a good clone for a clone
156262306a36Sopenharmony_ci * instruction. Returns -ENOENT when none could be found. The function makes
156362306a36Sopenharmony_ci * sure that the returned clone is usable at the point where sending is at the
156462306a36Sopenharmony_ci * moment. This means, that no clones are accepted which lie behind the current
156562306a36Sopenharmony_ci * inode+offset.
156662306a36Sopenharmony_ci *
156762306a36Sopenharmony_ci * path must point to the extent item when called.
156862306a36Sopenharmony_ci */
156962306a36Sopenharmony_cistatic int find_extent_clone(struct send_ctx *sctx,
157062306a36Sopenharmony_ci			     struct btrfs_path *path,
157162306a36Sopenharmony_ci			     u64 ino, u64 data_offset,
157262306a36Sopenharmony_ci			     u64 ino_size,
157362306a36Sopenharmony_ci			     struct clone_root **found)
157462306a36Sopenharmony_ci{
157562306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
157662306a36Sopenharmony_ci	int ret;
157762306a36Sopenharmony_ci	int extent_type;
157862306a36Sopenharmony_ci	u64 logical;
157962306a36Sopenharmony_ci	u64 disk_byte;
158062306a36Sopenharmony_ci	u64 num_bytes;
158162306a36Sopenharmony_ci	struct btrfs_file_extent_item *fi;
158262306a36Sopenharmony_ci	struct extent_buffer *eb = path->nodes[0];
158362306a36Sopenharmony_ci	struct backref_ctx backref_ctx = { 0 };
158462306a36Sopenharmony_ci	struct btrfs_backref_walk_ctx backref_walk_ctx = { 0 };
158562306a36Sopenharmony_ci	struct clone_root *cur_clone_root;
158662306a36Sopenharmony_ci	int compressed;
158762306a36Sopenharmony_ci	u32 i;
158862306a36Sopenharmony_ci
158962306a36Sopenharmony_ci	/*
159062306a36Sopenharmony_ci	 * With fallocate we can get prealloc extents beyond the inode's i_size,
159162306a36Sopenharmony_ci	 * so we don't do anything here because clone operations can not clone
159262306a36Sopenharmony_ci	 * to a range beyond i_size without increasing the i_size of the
159362306a36Sopenharmony_ci	 * destination inode.
159462306a36Sopenharmony_ci	 */
159562306a36Sopenharmony_ci	if (data_offset >= ino_size)
159662306a36Sopenharmony_ci		return 0;
159762306a36Sopenharmony_ci
159862306a36Sopenharmony_ci	fi = btrfs_item_ptr(eb, path->slots[0], struct btrfs_file_extent_item);
159962306a36Sopenharmony_ci	extent_type = btrfs_file_extent_type(eb, fi);
160062306a36Sopenharmony_ci	if (extent_type == BTRFS_FILE_EXTENT_INLINE)
160162306a36Sopenharmony_ci		return -ENOENT;
160262306a36Sopenharmony_ci
160362306a36Sopenharmony_ci	disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
160462306a36Sopenharmony_ci	if (disk_byte == 0)
160562306a36Sopenharmony_ci		return -ENOENT;
160662306a36Sopenharmony_ci
160762306a36Sopenharmony_ci	compressed = btrfs_file_extent_compression(eb, fi);
160862306a36Sopenharmony_ci	num_bytes = btrfs_file_extent_num_bytes(eb, fi);
160962306a36Sopenharmony_ci	logical = disk_byte + btrfs_file_extent_offset(eb, fi);
161062306a36Sopenharmony_ci
161162306a36Sopenharmony_ci	/*
161262306a36Sopenharmony_ci	 * Setup the clone roots.
161362306a36Sopenharmony_ci	 */
161462306a36Sopenharmony_ci	for (i = 0; i < sctx->clone_roots_cnt; i++) {
161562306a36Sopenharmony_ci		cur_clone_root = sctx->clone_roots + i;
161662306a36Sopenharmony_ci		cur_clone_root->ino = (u64)-1;
161762306a36Sopenharmony_ci		cur_clone_root->offset = 0;
161862306a36Sopenharmony_ci		cur_clone_root->num_bytes = 0;
161962306a36Sopenharmony_ci		cur_clone_root->found_ref = false;
162062306a36Sopenharmony_ci	}
162162306a36Sopenharmony_ci
162262306a36Sopenharmony_ci	backref_ctx.sctx = sctx;
162362306a36Sopenharmony_ci	backref_ctx.cur_objectid = ino;
162462306a36Sopenharmony_ci	backref_ctx.cur_offset = data_offset;
162562306a36Sopenharmony_ci	backref_ctx.bytenr = disk_byte;
162662306a36Sopenharmony_ci	/*
162762306a36Sopenharmony_ci	 * Use the header owner and not the send root's id, because in case of a
162862306a36Sopenharmony_ci	 * snapshot we can have shared subtrees.
162962306a36Sopenharmony_ci	 */
163062306a36Sopenharmony_ci	backref_ctx.backref_owner = btrfs_header_owner(eb);
163162306a36Sopenharmony_ci	backref_ctx.backref_offset = data_offset - btrfs_file_extent_offset(eb, fi);
163262306a36Sopenharmony_ci
163362306a36Sopenharmony_ci	/*
163462306a36Sopenharmony_ci	 * The last extent of a file may be too large due to page alignment.
163562306a36Sopenharmony_ci	 * We need to adjust extent_len in this case so that the checks in
163662306a36Sopenharmony_ci	 * iterate_backrefs() work.
163762306a36Sopenharmony_ci	 */
163862306a36Sopenharmony_ci	if (data_offset + num_bytes >= ino_size)
163962306a36Sopenharmony_ci		backref_ctx.extent_len = ino_size - data_offset;
164062306a36Sopenharmony_ci	else
164162306a36Sopenharmony_ci		backref_ctx.extent_len = num_bytes;
164262306a36Sopenharmony_ci
164362306a36Sopenharmony_ci	/*
164462306a36Sopenharmony_ci	 * Now collect all backrefs.
164562306a36Sopenharmony_ci	 */
164662306a36Sopenharmony_ci	backref_walk_ctx.bytenr = disk_byte;
164762306a36Sopenharmony_ci	if (compressed == BTRFS_COMPRESS_NONE)
164862306a36Sopenharmony_ci		backref_walk_ctx.extent_item_pos = btrfs_file_extent_offset(eb, fi);
164962306a36Sopenharmony_ci	backref_walk_ctx.fs_info = fs_info;
165062306a36Sopenharmony_ci	backref_walk_ctx.cache_lookup = lookup_backref_cache;
165162306a36Sopenharmony_ci	backref_walk_ctx.cache_store = store_backref_cache;
165262306a36Sopenharmony_ci	backref_walk_ctx.indirect_ref_iterator = iterate_backrefs;
165362306a36Sopenharmony_ci	backref_walk_ctx.check_extent_item = check_extent_item;
165462306a36Sopenharmony_ci	backref_walk_ctx.user_ctx = &backref_ctx;
165562306a36Sopenharmony_ci
165662306a36Sopenharmony_ci	/*
165762306a36Sopenharmony_ci	 * If have a single clone root, then it's the send root and we can tell
165862306a36Sopenharmony_ci	 * the backref walking code to skip our own backref and not resolve it,
165962306a36Sopenharmony_ci	 * since we can not use it for cloning - the source and destination
166062306a36Sopenharmony_ci	 * ranges can't overlap and in case the leaf is shared through a subtree
166162306a36Sopenharmony_ci	 * due to snapshots, we can't use those other roots since they are not
166262306a36Sopenharmony_ci	 * in the list of clone roots.
166362306a36Sopenharmony_ci	 */
166462306a36Sopenharmony_ci	if (sctx->clone_roots_cnt == 1)
166562306a36Sopenharmony_ci		backref_walk_ctx.skip_data_ref = skip_self_data_ref;
166662306a36Sopenharmony_ci
166762306a36Sopenharmony_ci	ret = iterate_extent_inodes(&backref_walk_ctx, true, iterate_backrefs,
166862306a36Sopenharmony_ci				    &backref_ctx);
166962306a36Sopenharmony_ci	if (ret < 0)
167062306a36Sopenharmony_ci		return ret;
167162306a36Sopenharmony_ci
167262306a36Sopenharmony_ci	down_read(&fs_info->commit_root_sem);
167362306a36Sopenharmony_ci	if (fs_info->last_reloc_trans > sctx->last_reloc_trans) {
167462306a36Sopenharmony_ci		/*
167562306a36Sopenharmony_ci		 * A transaction commit for a transaction in which block group
167662306a36Sopenharmony_ci		 * relocation was done just happened.
167762306a36Sopenharmony_ci		 * The disk_bytenr of the file extent item we processed is
167862306a36Sopenharmony_ci		 * possibly stale, referring to the extent's location before
167962306a36Sopenharmony_ci		 * relocation. So act as if we haven't found any clone sources
168062306a36Sopenharmony_ci		 * and fallback to write commands, which will read the correct
168162306a36Sopenharmony_ci		 * data from the new extent location. Otherwise we will fail
168262306a36Sopenharmony_ci		 * below because we haven't found our own back reference or we
168362306a36Sopenharmony_ci		 * could be getting incorrect sources in case the old extent
168462306a36Sopenharmony_ci		 * was already reallocated after the relocation.
168562306a36Sopenharmony_ci		 */
168662306a36Sopenharmony_ci		up_read(&fs_info->commit_root_sem);
168762306a36Sopenharmony_ci		return -ENOENT;
168862306a36Sopenharmony_ci	}
168962306a36Sopenharmony_ci	up_read(&fs_info->commit_root_sem);
169062306a36Sopenharmony_ci
169162306a36Sopenharmony_ci	btrfs_debug(fs_info,
169262306a36Sopenharmony_ci		    "find_extent_clone: data_offset=%llu, ino=%llu, num_bytes=%llu, logical=%llu",
169362306a36Sopenharmony_ci		    data_offset, ino, num_bytes, logical);
169462306a36Sopenharmony_ci
169562306a36Sopenharmony_ci	if (!backref_ctx.found) {
169662306a36Sopenharmony_ci		btrfs_debug(fs_info, "no clones found");
169762306a36Sopenharmony_ci		return -ENOENT;
169862306a36Sopenharmony_ci	}
169962306a36Sopenharmony_ci
170062306a36Sopenharmony_ci	cur_clone_root = NULL;
170162306a36Sopenharmony_ci	for (i = 0; i < sctx->clone_roots_cnt; i++) {
170262306a36Sopenharmony_ci		struct clone_root *clone_root = &sctx->clone_roots[i];
170362306a36Sopenharmony_ci
170462306a36Sopenharmony_ci		if (!clone_root->found_ref)
170562306a36Sopenharmony_ci			continue;
170662306a36Sopenharmony_ci
170762306a36Sopenharmony_ci		/*
170862306a36Sopenharmony_ci		 * Choose the root from which we can clone more bytes, to
170962306a36Sopenharmony_ci		 * minimize write operations and therefore have more extent
171062306a36Sopenharmony_ci		 * sharing at the destination (the same as in the source).
171162306a36Sopenharmony_ci		 */
171262306a36Sopenharmony_ci		if (!cur_clone_root ||
171362306a36Sopenharmony_ci		    clone_root->num_bytes > cur_clone_root->num_bytes) {
171462306a36Sopenharmony_ci			cur_clone_root = clone_root;
171562306a36Sopenharmony_ci
171662306a36Sopenharmony_ci			/*
171762306a36Sopenharmony_ci			 * We found an optimal clone candidate (any inode from
171862306a36Sopenharmony_ci			 * any root is fine), so we're done.
171962306a36Sopenharmony_ci			 */
172062306a36Sopenharmony_ci			if (clone_root->num_bytes >= backref_ctx.extent_len)
172162306a36Sopenharmony_ci				break;
172262306a36Sopenharmony_ci		}
172362306a36Sopenharmony_ci	}
172462306a36Sopenharmony_ci
172562306a36Sopenharmony_ci	if (cur_clone_root) {
172662306a36Sopenharmony_ci		*found = cur_clone_root;
172762306a36Sopenharmony_ci		ret = 0;
172862306a36Sopenharmony_ci	} else {
172962306a36Sopenharmony_ci		ret = -ENOENT;
173062306a36Sopenharmony_ci	}
173162306a36Sopenharmony_ci
173262306a36Sopenharmony_ci	return ret;
173362306a36Sopenharmony_ci}
173462306a36Sopenharmony_ci
173562306a36Sopenharmony_cistatic int read_symlink(struct btrfs_root *root,
173662306a36Sopenharmony_ci			u64 ino,
173762306a36Sopenharmony_ci			struct fs_path *dest)
173862306a36Sopenharmony_ci{
173962306a36Sopenharmony_ci	int ret;
174062306a36Sopenharmony_ci	struct btrfs_path *path;
174162306a36Sopenharmony_ci	struct btrfs_key key;
174262306a36Sopenharmony_ci	struct btrfs_file_extent_item *ei;
174362306a36Sopenharmony_ci	u8 type;
174462306a36Sopenharmony_ci	u8 compression;
174562306a36Sopenharmony_ci	unsigned long off;
174662306a36Sopenharmony_ci	int len;
174762306a36Sopenharmony_ci
174862306a36Sopenharmony_ci	path = alloc_path_for_send();
174962306a36Sopenharmony_ci	if (!path)
175062306a36Sopenharmony_ci		return -ENOMEM;
175162306a36Sopenharmony_ci
175262306a36Sopenharmony_ci	key.objectid = ino;
175362306a36Sopenharmony_ci	key.type = BTRFS_EXTENT_DATA_KEY;
175462306a36Sopenharmony_ci	key.offset = 0;
175562306a36Sopenharmony_ci	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
175662306a36Sopenharmony_ci	if (ret < 0)
175762306a36Sopenharmony_ci		goto out;
175862306a36Sopenharmony_ci	if (ret) {
175962306a36Sopenharmony_ci		/*
176062306a36Sopenharmony_ci		 * An empty symlink inode. Can happen in rare error paths when
176162306a36Sopenharmony_ci		 * creating a symlink (transaction committed before the inode
176262306a36Sopenharmony_ci		 * eviction handler removed the symlink inode items and a crash
176362306a36Sopenharmony_ci		 * happened in between or the subvol was snapshoted in between).
176462306a36Sopenharmony_ci		 * Print an informative message to dmesg/syslog so that the user
176562306a36Sopenharmony_ci		 * can delete the symlink.
176662306a36Sopenharmony_ci		 */
176762306a36Sopenharmony_ci		btrfs_err(root->fs_info,
176862306a36Sopenharmony_ci			  "Found empty symlink inode %llu at root %llu",
176962306a36Sopenharmony_ci			  ino, root->root_key.objectid);
177062306a36Sopenharmony_ci		ret = -EIO;
177162306a36Sopenharmony_ci		goto out;
177262306a36Sopenharmony_ci	}
177362306a36Sopenharmony_ci
177462306a36Sopenharmony_ci	ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
177562306a36Sopenharmony_ci			struct btrfs_file_extent_item);
177662306a36Sopenharmony_ci	type = btrfs_file_extent_type(path->nodes[0], ei);
177762306a36Sopenharmony_ci	if (unlikely(type != BTRFS_FILE_EXTENT_INLINE)) {
177862306a36Sopenharmony_ci		ret = -EUCLEAN;
177962306a36Sopenharmony_ci		btrfs_crit(root->fs_info,
178062306a36Sopenharmony_ci"send: found symlink extent that is not inline, ino %llu root %llu extent type %d",
178162306a36Sopenharmony_ci			   ino, btrfs_root_id(root), type);
178262306a36Sopenharmony_ci		goto out;
178362306a36Sopenharmony_ci	}
178462306a36Sopenharmony_ci	compression = btrfs_file_extent_compression(path->nodes[0], ei);
178562306a36Sopenharmony_ci	if (unlikely(compression != BTRFS_COMPRESS_NONE)) {
178662306a36Sopenharmony_ci		ret = -EUCLEAN;
178762306a36Sopenharmony_ci		btrfs_crit(root->fs_info,
178862306a36Sopenharmony_ci"send: found symlink extent with compression, ino %llu root %llu compression type %d",
178962306a36Sopenharmony_ci			   ino, btrfs_root_id(root), compression);
179062306a36Sopenharmony_ci		goto out;
179162306a36Sopenharmony_ci	}
179262306a36Sopenharmony_ci
179362306a36Sopenharmony_ci	off = btrfs_file_extent_inline_start(ei);
179462306a36Sopenharmony_ci	len = btrfs_file_extent_ram_bytes(path->nodes[0], ei);
179562306a36Sopenharmony_ci
179662306a36Sopenharmony_ci	ret = fs_path_add_from_extent_buffer(dest, path->nodes[0], off, len);
179762306a36Sopenharmony_ci
179862306a36Sopenharmony_ciout:
179962306a36Sopenharmony_ci	btrfs_free_path(path);
180062306a36Sopenharmony_ci	return ret;
180162306a36Sopenharmony_ci}
180262306a36Sopenharmony_ci
180362306a36Sopenharmony_ci/*
180462306a36Sopenharmony_ci * Helper function to generate a file name that is unique in the root of
180562306a36Sopenharmony_ci * send_root and parent_root. This is used to generate names for orphan inodes.
180662306a36Sopenharmony_ci */
180762306a36Sopenharmony_cistatic int gen_unique_name(struct send_ctx *sctx,
180862306a36Sopenharmony_ci			   u64 ino, u64 gen,
180962306a36Sopenharmony_ci			   struct fs_path *dest)
181062306a36Sopenharmony_ci{
181162306a36Sopenharmony_ci	int ret = 0;
181262306a36Sopenharmony_ci	struct btrfs_path *path;
181362306a36Sopenharmony_ci	struct btrfs_dir_item *di;
181462306a36Sopenharmony_ci	char tmp[64];
181562306a36Sopenharmony_ci	int len;
181662306a36Sopenharmony_ci	u64 idx = 0;
181762306a36Sopenharmony_ci
181862306a36Sopenharmony_ci	path = alloc_path_for_send();
181962306a36Sopenharmony_ci	if (!path)
182062306a36Sopenharmony_ci		return -ENOMEM;
182162306a36Sopenharmony_ci
182262306a36Sopenharmony_ci	while (1) {
182362306a36Sopenharmony_ci		struct fscrypt_str tmp_name;
182462306a36Sopenharmony_ci
182562306a36Sopenharmony_ci		len = snprintf(tmp, sizeof(tmp), "o%llu-%llu-%llu",
182662306a36Sopenharmony_ci				ino, gen, idx);
182762306a36Sopenharmony_ci		ASSERT(len < sizeof(tmp));
182862306a36Sopenharmony_ci		tmp_name.name = tmp;
182962306a36Sopenharmony_ci		tmp_name.len = strlen(tmp);
183062306a36Sopenharmony_ci
183162306a36Sopenharmony_ci		di = btrfs_lookup_dir_item(NULL, sctx->send_root,
183262306a36Sopenharmony_ci				path, BTRFS_FIRST_FREE_OBJECTID,
183362306a36Sopenharmony_ci				&tmp_name, 0);
183462306a36Sopenharmony_ci		btrfs_release_path(path);
183562306a36Sopenharmony_ci		if (IS_ERR(di)) {
183662306a36Sopenharmony_ci			ret = PTR_ERR(di);
183762306a36Sopenharmony_ci			goto out;
183862306a36Sopenharmony_ci		}
183962306a36Sopenharmony_ci		if (di) {
184062306a36Sopenharmony_ci			/* not unique, try again */
184162306a36Sopenharmony_ci			idx++;
184262306a36Sopenharmony_ci			continue;
184362306a36Sopenharmony_ci		}
184462306a36Sopenharmony_ci
184562306a36Sopenharmony_ci		if (!sctx->parent_root) {
184662306a36Sopenharmony_ci			/* unique */
184762306a36Sopenharmony_ci			ret = 0;
184862306a36Sopenharmony_ci			break;
184962306a36Sopenharmony_ci		}
185062306a36Sopenharmony_ci
185162306a36Sopenharmony_ci		di = btrfs_lookup_dir_item(NULL, sctx->parent_root,
185262306a36Sopenharmony_ci				path, BTRFS_FIRST_FREE_OBJECTID,
185362306a36Sopenharmony_ci				&tmp_name, 0);
185462306a36Sopenharmony_ci		btrfs_release_path(path);
185562306a36Sopenharmony_ci		if (IS_ERR(di)) {
185662306a36Sopenharmony_ci			ret = PTR_ERR(di);
185762306a36Sopenharmony_ci			goto out;
185862306a36Sopenharmony_ci		}
185962306a36Sopenharmony_ci		if (di) {
186062306a36Sopenharmony_ci			/* not unique, try again */
186162306a36Sopenharmony_ci			idx++;
186262306a36Sopenharmony_ci			continue;
186362306a36Sopenharmony_ci		}
186462306a36Sopenharmony_ci		/* unique */
186562306a36Sopenharmony_ci		break;
186662306a36Sopenharmony_ci	}
186762306a36Sopenharmony_ci
186862306a36Sopenharmony_ci	ret = fs_path_add(dest, tmp, strlen(tmp));
186962306a36Sopenharmony_ci
187062306a36Sopenharmony_ciout:
187162306a36Sopenharmony_ci	btrfs_free_path(path);
187262306a36Sopenharmony_ci	return ret;
187362306a36Sopenharmony_ci}
187462306a36Sopenharmony_ci
187562306a36Sopenharmony_cienum inode_state {
187662306a36Sopenharmony_ci	inode_state_no_change,
187762306a36Sopenharmony_ci	inode_state_will_create,
187862306a36Sopenharmony_ci	inode_state_did_create,
187962306a36Sopenharmony_ci	inode_state_will_delete,
188062306a36Sopenharmony_ci	inode_state_did_delete,
188162306a36Sopenharmony_ci};
188262306a36Sopenharmony_ci
188362306a36Sopenharmony_cistatic int get_cur_inode_state(struct send_ctx *sctx, u64 ino, u64 gen,
188462306a36Sopenharmony_ci			       u64 *send_gen, u64 *parent_gen)
188562306a36Sopenharmony_ci{
188662306a36Sopenharmony_ci	int ret;
188762306a36Sopenharmony_ci	int left_ret;
188862306a36Sopenharmony_ci	int right_ret;
188962306a36Sopenharmony_ci	u64 left_gen;
189062306a36Sopenharmony_ci	u64 right_gen = 0;
189162306a36Sopenharmony_ci	struct btrfs_inode_info info;
189262306a36Sopenharmony_ci
189362306a36Sopenharmony_ci	ret = get_inode_info(sctx->send_root, ino, &info);
189462306a36Sopenharmony_ci	if (ret < 0 && ret != -ENOENT)
189562306a36Sopenharmony_ci		goto out;
189662306a36Sopenharmony_ci	left_ret = (info.nlink == 0) ? -ENOENT : ret;
189762306a36Sopenharmony_ci	left_gen = info.gen;
189862306a36Sopenharmony_ci	if (send_gen)
189962306a36Sopenharmony_ci		*send_gen = ((left_ret == -ENOENT) ? 0 : info.gen);
190062306a36Sopenharmony_ci
190162306a36Sopenharmony_ci	if (!sctx->parent_root) {
190262306a36Sopenharmony_ci		right_ret = -ENOENT;
190362306a36Sopenharmony_ci	} else {
190462306a36Sopenharmony_ci		ret = get_inode_info(sctx->parent_root, ino, &info);
190562306a36Sopenharmony_ci		if (ret < 0 && ret != -ENOENT)
190662306a36Sopenharmony_ci			goto out;
190762306a36Sopenharmony_ci		right_ret = (info.nlink == 0) ? -ENOENT : ret;
190862306a36Sopenharmony_ci		right_gen = info.gen;
190962306a36Sopenharmony_ci		if (parent_gen)
191062306a36Sopenharmony_ci			*parent_gen = ((right_ret == -ENOENT) ? 0 : info.gen);
191162306a36Sopenharmony_ci	}
191262306a36Sopenharmony_ci
191362306a36Sopenharmony_ci	if (!left_ret && !right_ret) {
191462306a36Sopenharmony_ci		if (left_gen == gen && right_gen == gen) {
191562306a36Sopenharmony_ci			ret = inode_state_no_change;
191662306a36Sopenharmony_ci		} else if (left_gen == gen) {
191762306a36Sopenharmony_ci			if (ino < sctx->send_progress)
191862306a36Sopenharmony_ci				ret = inode_state_did_create;
191962306a36Sopenharmony_ci			else
192062306a36Sopenharmony_ci				ret = inode_state_will_create;
192162306a36Sopenharmony_ci		} else if (right_gen == gen) {
192262306a36Sopenharmony_ci			if (ino < sctx->send_progress)
192362306a36Sopenharmony_ci				ret = inode_state_did_delete;
192462306a36Sopenharmony_ci			else
192562306a36Sopenharmony_ci				ret = inode_state_will_delete;
192662306a36Sopenharmony_ci		} else  {
192762306a36Sopenharmony_ci			ret = -ENOENT;
192862306a36Sopenharmony_ci		}
192962306a36Sopenharmony_ci	} else if (!left_ret) {
193062306a36Sopenharmony_ci		if (left_gen == gen) {
193162306a36Sopenharmony_ci			if (ino < sctx->send_progress)
193262306a36Sopenharmony_ci				ret = inode_state_did_create;
193362306a36Sopenharmony_ci			else
193462306a36Sopenharmony_ci				ret = inode_state_will_create;
193562306a36Sopenharmony_ci		} else {
193662306a36Sopenharmony_ci			ret = -ENOENT;
193762306a36Sopenharmony_ci		}
193862306a36Sopenharmony_ci	} else if (!right_ret) {
193962306a36Sopenharmony_ci		if (right_gen == gen) {
194062306a36Sopenharmony_ci			if (ino < sctx->send_progress)
194162306a36Sopenharmony_ci				ret = inode_state_did_delete;
194262306a36Sopenharmony_ci			else
194362306a36Sopenharmony_ci				ret = inode_state_will_delete;
194462306a36Sopenharmony_ci		} else {
194562306a36Sopenharmony_ci			ret = -ENOENT;
194662306a36Sopenharmony_ci		}
194762306a36Sopenharmony_ci	} else {
194862306a36Sopenharmony_ci		ret = -ENOENT;
194962306a36Sopenharmony_ci	}
195062306a36Sopenharmony_ci
195162306a36Sopenharmony_ciout:
195262306a36Sopenharmony_ci	return ret;
195362306a36Sopenharmony_ci}
195462306a36Sopenharmony_ci
195562306a36Sopenharmony_cistatic int is_inode_existent(struct send_ctx *sctx, u64 ino, u64 gen,
195662306a36Sopenharmony_ci			     u64 *send_gen, u64 *parent_gen)
195762306a36Sopenharmony_ci{
195862306a36Sopenharmony_ci	int ret;
195962306a36Sopenharmony_ci
196062306a36Sopenharmony_ci	if (ino == BTRFS_FIRST_FREE_OBJECTID)
196162306a36Sopenharmony_ci		return 1;
196262306a36Sopenharmony_ci
196362306a36Sopenharmony_ci	ret = get_cur_inode_state(sctx, ino, gen, send_gen, parent_gen);
196462306a36Sopenharmony_ci	if (ret < 0)
196562306a36Sopenharmony_ci		goto out;
196662306a36Sopenharmony_ci
196762306a36Sopenharmony_ci	if (ret == inode_state_no_change ||
196862306a36Sopenharmony_ci	    ret == inode_state_did_create ||
196962306a36Sopenharmony_ci	    ret == inode_state_will_delete)
197062306a36Sopenharmony_ci		ret = 1;
197162306a36Sopenharmony_ci	else
197262306a36Sopenharmony_ci		ret = 0;
197362306a36Sopenharmony_ci
197462306a36Sopenharmony_ciout:
197562306a36Sopenharmony_ci	return ret;
197662306a36Sopenharmony_ci}
197762306a36Sopenharmony_ci
197862306a36Sopenharmony_ci/*
197962306a36Sopenharmony_ci * Helper function to lookup a dir item in a dir.
198062306a36Sopenharmony_ci */
198162306a36Sopenharmony_cistatic int lookup_dir_item_inode(struct btrfs_root *root,
198262306a36Sopenharmony_ci				 u64 dir, const char *name, int name_len,
198362306a36Sopenharmony_ci				 u64 *found_inode)
198462306a36Sopenharmony_ci{
198562306a36Sopenharmony_ci	int ret = 0;
198662306a36Sopenharmony_ci	struct btrfs_dir_item *di;
198762306a36Sopenharmony_ci	struct btrfs_key key;
198862306a36Sopenharmony_ci	struct btrfs_path *path;
198962306a36Sopenharmony_ci	struct fscrypt_str name_str = FSTR_INIT((char *)name, name_len);
199062306a36Sopenharmony_ci
199162306a36Sopenharmony_ci	path = alloc_path_for_send();
199262306a36Sopenharmony_ci	if (!path)
199362306a36Sopenharmony_ci		return -ENOMEM;
199462306a36Sopenharmony_ci
199562306a36Sopenharmony_ci	di = btrfs_lookup_dir_item(NULL, root, path, dir, &name_str, 0);
199662306a36Sopenharmony_ci	if (IS_ERR_OR_NULL(di)) {
199762306a36Sopenharmony_ci		ret = di ? PTR_ERR(di) : -ENOENT;
199862306a36Sopenharmony_ci		goto out;
199962306a36Sopenharmony_ci	}
200062306a36Sopenharmony_ci	btrfs_dir_item_key_to_cpu(path->nodes[0], di, &key);
200162306a36Sopenharmony_ci	if (key.type == BTRFS_ROOT_ITEM_KEY) {
200262306a36Sopenharmony_ci		ret = -ENOENT;
200362306a36Sopenharmony_ci		goto out;
200462306a36Sopenharmony_ci	}
200562306a36Sopenharmony_ci	*found_inode = key.objectid;
200662306a36Sopenharmony_ci
200762306a36Sopenharmony_ciout:
200862306a36Sopenharmony_ci	btrfs_free_path(path);
200962306a36Sopenharmony_ci	return ret;
201062306a36Sopenharmony_ci}
201162306a36Sopenharmony_ci
201262306a36Sopenharmony_ci/*
201362306a36Sopenharmony_ci * Looks up the first btrfs_inode_ref of a given ino. It returns the parent dir,
201462306a36Sopenharmony_ci * generation of the parent dir and the name of the dir entry.
201562306a36Sopenharmony_ci */
201662306a36Sopenharmony_cistatic int get_first_ref(struct btrfs_root *root, u64 ino,
201762306a36Sopenharmony_ci			 u64 *dir, u64 *dir_gen, struct fs_path *name)
201862306a36Sopenharmony_ci{
201962306a36Sopenharmony_ci	int ret;
202062306a36Sopenharmony_ci	struct btrfs_key key;
202162306a36Sopenharmony_ci	struct btrfs_key found_key;
202262306a36Sopenharmony_ci	struct btrfs_path *path;
202362306a36Sopenharmony_ci	int len;
202462306a36Sopenharmony_ci	u64 parent_dir;
202562306a36Sopenharmony_ci
202662306a36Sopenharmony_ci	path = alloc_path_for_send();
202762306a36Sopenharmony_ci	if (!path)
202862306a36Sopenharmony_ci		return -ENOMEM;
202962306a36Sopenharmony_ci
203062306a36Sopenharmony_ci	key.objectid = ino;
203162306a36Sopenharmony_ci	key.type = BTRFS_INODE_REF_KEY;
203262306a36Sopenharmony_ci	key.offset = 0;
203362306a36Sopenharmony_ci
203462306a36Sopenharmony_ci	ret = btrfs_search_slot_for_read(root, &key, path, 1, 0);
203562306a36Sopenharmony_ci	if (ret < 0)
203662306a36Sopenharmony_ci		goto out;
203762306a36Sopenharmony_ci	if (!ret)
203862306a36Sopenharmony_ci		btrfs_item_key_to_cpu(path->nodes[0], &found_key,
203962306a36Sopenharmony_ci				path->slots[0]);
204062306a36Sopenharmony_ci	if (ret || found_key.objectid != ino ||
204162306a36Sopenharmony_ci	    (found_key.type != BTRFS_INODE_REF_KEY &&
204262306a36Sopenharmony_ci	     found_key.type != BTRFS_INODE_EXTREF_KEY)) {
204362306a36Sopenharmony_ci		ret = -ENOENT;
204462306a36Sopenharmony_ci		goto out;
204562306a36Sopenharmony_ci	}
204662306a36Sopenharmony_ci
204762306a36Sopenharmony_ci	if (found_key.type == BTRFS_INODE_REF_KEY) {
204862306a36Sopenharmony_ci		struct btrfs_inode_ref *iref;
204962306a36Sopenharmony_ci		iref = btrfs_item_ptr(path->nodes[0], path->slots[0],
205062306a36Sopenharmony_ci				      struct btrfs_inode_ref);
205162306a36Sopenharmony_ci		len = btrfs_inode_ref_name_len(path->nodes[0], iref);
205262306a36Sopenharmony_ci		ret = fs_path_add_from_extent_buffer(name, path->nodes[0],
205362306a36Sopenharmony_ci						     (unsigned long)(iref + 1),
205462306a36Sopenharmony_ci						     len);
205562306a36Sopenharmony_ci		parent_dir = found_key.offset;
205662306a36Sopenharmony_ci	} else {
205762306a36Sopenharmony_ci		struct btrfs_inode_extref *extref;
205862306a36Sopenharmony_ci		extref = btrfs_item_ptr(path->nodes[0], path->slots[0],
205962306a36Sopenharmony_ci					struct btrfs_inode_extref);
206062306a36Sopenharmony_ci		len = btrfs_inode_extref_name_len(path->nodes[0], extref);
206162306a36Sopenharmony_ci		ret = fs_path_add_from_extent_buffer(name, path->nodes[0],
206262306a36Sopenharmony_ci					(unsigned long)&extref->name, len);
206362306a36Sopenharmony_ci		parent_dir = btrfs_inode_extref_parent(path->nodes[0], extref);
206462306a36Sopenharmony_ci	}
206562306a36Sopenharmony_ci	if (ret < 0)
206662306a36Sopenharmony_ci		goto out;
206762306a36Sopenharmony_ci	btrfs_release_path(path);
206862306a36Sopenharmony_ci
206962306a36Sopenharmony_ci	if (dir_gen) {
207062306a36Sopenharmony_ci		ret = get_inode_gen(root, parent_dir, dir_gen);
207162306a36Sopenharmony_ci		if (ret < 0)
207262306a36Sopenharmony_ci			goto out;
207362306a36Sopenharmony_ci	}
207462306a36Sopenharmony_ci
207562306a36Sopenharmony_ci	*dir = parent_dir;
207662306a36Sopenharmony_ci
207762306a36Sopenharmony_ciout:
207862306a36Sopenharmony_ci	btrfs_free_path(path);
207962306a36Sopenharmony_ci	return ret;
208062306a36Sopenharmony_ci}
208162306a36Sopenharmony_ci
208262306a36Sopenharmony_cistatic int is_first_ref(struct btrfs_root *root,
208362306a36Sopenharmony_ci			u64 ino, u64 dir,
208462306a36Sopenharmony_ci			const char *name, int name_len)
208562306a36Sopenharmony_ci{
208662306a36Sopenharmony_ci	int ret;
208762306a36Sopenharmony_ci	struct fs_path *tmp_name;
208862306a36Sopenharmony_ci	u64 tmp_dir;
208962306a36Sopenharmony_ci
209062306a36Sopenharmony_ci	tmp_name = fs_path_alloc();
209162306a36Sopenharmony_ci	if (!tmp_name)
209262306a36Sopenharmony_ci		return -ENOMEM;
209362306a36Sopenharmony_ci
209462306a36Sopenharmony_ci	ret = get_first_ref(root, ino, &tmp_dir, NULL, tmp_name);
209562306a36Sopenharmony_ci	if (ret < 0)
209662306a36Sopenharmony_ci		goto out;
209762306a36Sopenharmony_ci
209862306a36Sopenharmony_ci	if (dir != tmp_dir || name_len != fs_path_len(tmp_name)) {
209962306a36Sopenharmony_ci		ret = 0;
210062306a36Sopenharmony_ci		goto out;
210162306a36Sopenharmony_ci	}
210262306a36Sopenharmony_ci
210362306a36Sopenharmony_ci	ret = !memcmp(tmp_name->start, name, name_len);
210462306a36Sopenharmony_ci
210562306a36Sopenharmony_ciout:
210662306a36Sopenharmony_ci	fs_path_free(tmp_name);
210762306a36Sopenharmony_ci	return ret;
210862306a36Sopenharmony_ci}
210962306a36Sopenharmony_ci
211062306a36Sopenharmony_ci/*
211162306a36Sopenharmony_ci * Used by process_recorded_refs to determine if a new ref would overwrite an
211262306a36Sopenharmony_ci * already existing ref. In case it detects an overwrite, it returns the
211362306a36Sopenharmony_ci * inode/gen in who_ino/who_gen.
211462306a36Sopenharmony_ci * When an overwrite is detected, process_recorded_refs does proper orphanizing
211562306a36Sopenharmony_ci * to make sure later references to the overwritten inode are possible.
211662306a36Sopenharmony_ci * Orphanizing is however only required for the first ref of an inode.
211762306a36Sopenharmony_ci * process_recorded_refs does an additional is_first_ref check to see if
211862306a36Sopenharmony_ci * orphanizing is really required.
211962306a36Sopenharmony_ci */
212062306a36Sopenharmony_cistatic int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen,
212162306a36Sopenharmony_ci			      const char *name, int name_len,
212262306a36Sopenharmony_ci			      u64 *who_ino, u64 *who_gen, u64 *who_mode)
212362306a36Sopenharmony_ci{
212462306a36Sopenharmony_ci	int ret;
212562306a36Sopenharmony_ci	u64 parent_root_dir_gen;
212662306a36Sopenharmony_ci	u64 other_inode = 0;
212762306a36Sopenharmony_ci	struct btrfs_inode_info info;
212862306a36Sopenharmony_ci
212962306a36Sopenharmony_ci	if (!sctx->parent_root)
213062306a36Sopenharmony_ci		return 0;
213162306a36Sopenharmony_ci
213262306a36Sopenharmony_ci	ret = is_inode_existent(sctx, dir, dir_gen, NULL, &parent_root_dir_gen);
213362306a36Sopenharmony_ci	if (ret <= 0)
213462306a36Sopenharmony_ci		return 0;
213562306a36Sopenharmony_ci
213662306a36Sopenharmony_ci	/*
213762306a36Sopenharmony_ci	 * If we have a parent root we need to verify that the parent dir was
213862306a36Sopenharmony_ci	 * not deleted and then re-created, if it was then we have no overwrite
213962306a36Sopenharmony_ci	 * and we can just unlink this entry.
214062306a36Sopenharmony_ci	 *
214162306a36Sopenharmony_ci	 * @parent_root_dir_gen was set to 0 if the inode does not exist in the
214262306a36Sopenharmony_ci	 * parent root.
214362306a36Sopenharmony_ci	 */
214462306a36Sopenharmony_ci	if (sctx->parent_root && dir != BTRFS_FIRST_FREE_OBJECTID &&
214562306a36Sopenharmony_ci	    parent_root_dir_gen != dir_gen)
214662306a36Sopenharmony_ci		return 0;
214762306a36Sopenharmony_ci
214862306a36Sopenharmony_ci	ret = lookup_dir_item_inode(sctx->parent_root, dir, name, name_len,
214962306a36Sopenharmony_ci				    &other_inode);
215062306a36Sopenharmony_ci	if (ret == -ENOENT)
215162306a36Sopenharmony_ci		return 0;
215262306a36Sopenharmony_ci	else if (ret < 0)
215362306a36Sopenharmony_ci		return ret;
215462306a36Sopenharmony_ci
215562306a36Sopenharmony_ci	/*
215662306a36Sopenharmony_ci	 * Check if the overwritten ref was already processed. If yes, the ref
215762306a36Sopenharmony_ci	 * was already unlinked/moved, so we can safely assume that we will not
215862306a36Sopenharmony_ci	 * overwrite anything at this point in time.
215962306a36Sopenharmony_ci	 */
216062306a36Sopenharmony_ci	if (other_inode > sctx->send_progress ||
216162306a36Sopenharmony_ci	    is_waiting_for_move(sctx, other_inode)) {
216262306a36Sopenharmony_ci		ret = get_inode_info(sctx->parent_root, other_inode, &info);
216362306a36Sopenharmony_ci		if (ret < 0)
216462306a36Sopenharmony_ci			return ret;
216562306a36Sopenharmony_ci
216662306a36Sopenharmony_ci		*who_ino = other_inode;
216762306a36Sopenharmony_ci		*who_gen = info.gen;
216862306a36Sopenharmony_ci		*who_mode = info.mode;
216962306a36Sopenharmony_ci		return 1;
217062306a36Sopenharmony_ci	}
217162306a36Sopenharmony_ci
217262306a36Sopenharmony_ci	return 0;
217362306a36Sopenharmony_ci}
217462306a36Sopenharmony_ci
217562306a36Sopenharmony_ci/*
217662306a36Sopenharmony_ci * Checks if the ref was overwritten by an already processed inode. This is
217762306a36Sopenharmony_ci * used by __get_cur_name_and_parent to find out if the ref was orphanized and
217862306a36Sopenharmony_ci * thus the orphan name needs be used.
217962306a36Sopenharmony_ci * process_recorded_refs also uses it to avoid unlinking of refs that were
218062306a36Sopenharmony_ci * overwritten.
218162306a36Sopenharmony_ci */
218262306a36Sopenharmony_cistatic int did_overwrite_ref(struct send_ctx *sctx,
218362306a36Sopenharmony_ci			    u64 dir, u64 dir_gen,
218462306a36Sopenharmony_ci			    u64 ino, u64 ino_gen,
218562306a36Sopenharmony_ci			    const char *name, int name_len)
218662306a36Sopenharmony_ci{
218762306a36Sopenharmony_ci	int ret;
218862306a36Sopenharmony_ci	u64 ow_inode;
218962306a36Sopenharmony_ci	u64 ow_gen = 0;
219062306a36Sopenharmony_ci	u64 send_root_dir_gen;
219162306a36Sopenharmony_ci
219262306a36Sopenharmony_ci	if (!sctx->parent_root)
219362306a36Sopenharmony_ci		return 0;
219462306a36Sopenharmony_ci
219562306a36Sopenharmony_ci	ret = is_inode_existent(sctx, dir, dir_gen, &send_root_dir_gen, NULL);
219662306a36Sopenharmony_ci	if (ret <= 0)
219762306a36Sopenharmony_ci		return ret;
219862306a36Sopenharmony_ci
219962306a36Sopenharmony_ci	/*
220062306a36Sopenharmony_ci	 * @send_root_dir_gen was set to 0 if the inode does not exist in the
220162306a36Sopenharmony_ci	 * send root.
220262306a36Sopenharmony_ci	 */
220362306a36Sopenharmony_ci	if (dir != BTRFS_FIRST_FREE_OBJECTID && send_root_dir_gen != dir_gen)
220462306a36Sopenharmony_ci		return 0;
220562306a36Sopenharmony_ci
220662306a36Sopenharmony_ci	/* check if the ref was overwritten by another ref */
220762306a36Sopenharmony_ci	ret = lookup_dir_item_inode(sctx->send_root, dir, name, name_len,
220862306a36Sopenharmony_ci				    &ow_inode);
220962306a36Sopenharmony_ci	if (ret == -ENOENT) {
221062306a36Sopenharmony_ci		/* was never and will never be overwritten */
221162306a36Sopenharmony_ci		return 0;
221262306a36Sopenharmony_ci	} else if (ret < 0) {
221362306a36Sopenharmony_ci		return ret;
221462306a36Sopenharmony_ci	}
221562306a36Sopenharmony_ci
221662306a36Sopenharmony_ci	if (ow_inode == ino) {
221762306a36Sopenharmony_ci		ret = get_inode_gen(sctx->send_root, ow_inode, &ow_gen);
221862306a36Sopenharmony_ci		if (ret < 0)
221962306a36Sopenharmony_ci			return ret;
222062306a36Sopenharmony_ci
222162306a36Sopenharmony_ci		/* It's the same inode, so no overwrite happened. */
222262306a36Sopenharmony_ci		if (ow_gen == ino_gen)
222362306a36Sopenharmony_ci			return 0;
222462306a36Sopenharmony_ci	}
222562306a36Sopenharmony_ci
222662306a36Sopenharmony_ci	/*
222762306a36Sopenharmony_ci	 * We know that it is or will be overwritten. Check this now.
222862306a36Sopenharmony_ci	 * The current inode being processed might have been the one that caused
222962306a36Sopenharmony_ci	 * inode 'ino' to be orphanized, therefore check if ow_inode matches
223062306a36Sopenharmony_ci	 * the current inode being processed.
223162306a36Sopenharmony_ci	 */
223262306a36Sopenharmony_ci	if (ow_inode < sctx->send_progress)
223362306a36Sopenharmony_ci		return 1;
223462306a36Sopenharmony_ci
223562306a36Sopenharmony_ci	if (ino != sctx->cur_ino && ow_inode == sctx->cur_ino) {
223662306a36Sopenharmony_ci		if (ow_gen == 0) {
223762306a36Sopenharmony_ci			ret = get_inode_gen(sctx->send_root, ow_inode, &ow_gen);
223862306a36Sopenharmony_ci			if (ret < 0)
223962306a36Sopenharmony_ci				return ret;
224062306a36Sopenharmony_ci		}
224162306a36Sopenharmony_ci		if (ow_gen == sctx->cur_inode_gen)
224262306a36Sopenharmony_ci			return 1;
224362306a36Sopenharmony_ci	}
224462306a36Sopenharmony_ci
224562306a36Sopenharmony_ci	return 0;
224662306a36Sopenharmony_ci}
224762306a36Sopenharmony_ci
224862306a36Sopenharmony_ci/*
224962306a36Sopenharmony_ci * Same as did_overwrite_ref, but also checks if it is the first ref of an inode
225062306a36Sopenharmony_ci * that got overwritten. This is used by process_recorded_refs to determine
225162306a36Sopenharmony_ci * if it has to use the path as returned by get_cur_path or the orphan name.
225262306a36Sopenharmony_ci */
225362306a36Sopenharmony_cistatic int did_overwrite_first_ref(struct send_ctx *sctx, u64 ino, u64 gen)
225462306a36Sopenharmony_ci{
225562306a36Sopenharmony_ci	int ret = 0;
225662306a36Sopenharmony_ci	struct fs_path *name = NULL;
225762306a36Sopenharmony_ci	u64 dir;
225862306a36Sopenharmony_ci	u64 dir_gen;
225962306a36Sopenharmony_ci
226062306a36Sopenharmony_ci	if (!sctx->parent_root)
226162306a36Sopenharmony_ci		goto out;
226262306a36Sopenharmony_ci
226362306a36Sopenharmony_ci	name = fs_path_alloc();
226462306a36Sopenharmony_ci	if (!name)
226562306a36Sopenharmony_ci		return -ENOMEM;
226662306a36Sopenharmony_ci
226762306a36Sopenharmony_ci	ret = get_first_ref(sctx->parent_root, ino, &dir, &dir_gen, name);
226862306a36Sopenharmony_ci	if (ret < 0)
226962306a36Sopenharmony_ci		goto out;
227062306a36Sopenharmony_ci
227162306a36Sopenharmony_ci	ret = did_overwrite_ref(sctx, dir, dir_gen, ino, gen,
227262306a36Sopenharmony_ci			name->start, fs_path_len(name));
227362306a36Sopenharmony_ci
227462306a36Sopenharmony_ciout:
227562306a36Sopenharmony_ci	fs_path_free(name);
227662306a36Sopenharmony_ci	return ret;
227762306a36Sopenharmony_ci}
227862306a36Sopenharmony_ci
227962306a36Sopenharmony_cistatic inline struct name_cache_entry *name_cache_search(struct send_ctx *sctx,
228062306a36Sopenharmony_ci							 u64 ino, u64 gen)
228162306a36Sopenharmony_ci{
228262306a36Sopenharmony_ci	struct btrfs_lru_cache_entry *entry;
228362306a36Sopenharmony_ci
228462306a36Sopenharmony_ci	entry = btrfs_lru_cache_lookup(&sctx->name_cache, ino, gen);
228562306a36Sopenharmony_ci	if (!entry)
228662306a36Sopenharmony_ci		return NULL;
228762306a36Sopenharmony_ci
228862306a36Sopenharmony_ci	return container_of(entry, struct name_cache_entry, entry);
228962306a36Sopenharmony_ci}
229062306a36Sopenharmony_ci
229162306a36Sopenharmony_ci/*
229262306a36Sopenharmony_ci * Used by get_cur_path for each ref up to the root.
229362306a36Sopenharmony_ci * Returns 0 if it succeeded.
229462306a36Sopenharmony_ci * Returns 1 if the inode is not existent or got overwritten. In that case, the
229562306a36Sopenharmony_ci * name is an orphan name. This instructs get_cur_path to stop iterating. If 1
229662306a36Sopenharmony_ci * is returned, parent_ino/parent_gen are not guaranteed to be valid.
229762306a36Sopenharmony_ci * Returns <0 in case of error.
229862306a36Sopenharmony_ci */
229962306a36Sopenharmony_cistatic int __get_cur_name_and_parent(struct send_ctx *sctx,
230062306a36Sopenharmony_ci				     u64 ino, u64 gen,
230162306a36Sopenharmony_ci				     u64 *parent_ino,
230262306a36Sopenharmony_ci				     u64 *parent_gen,
230362306a36Sopenharmony_ci				     struct fs_path *dest)
230462306a36Sopenharmony_ci{
230562306a36Sopenharmony_ci	int ret;
230662306a36Sopenharmony_ci	int nce_ret;
230762306a36Sopenharmony_ci	struct name_cache_entry *nce;
230862306a36Sopenharmony_ci
230962306a36Sopenharmony_ci	/*
231062306a36Sopenharmony_ci	 * First check if we already did a call to this function with the same
231162306a36Sopenharmony_ci	 * ino/gen. If yes, check if the cache entry is still up-to-date. If yes
231262306a36Sopenharmony_ci	 * return the cached result.
231362306a36Sopenharmony_ci	 */
231462306a36Sopenharmony_ci	nce = name_cache_search(sctx, ino, gen);
231562306a36Sopenharmony_ci	if (nce) {
231662306a36Sopenharmony_ci		if (ino < sctx->send_progress && nce->need_later_update) {
231762306a36Sopenharmony_ci			btrfs_lru_cache_remove(&sctx->name_cache, &nce->entry);
231862306a36Sopenharmony_ci			nce = NULL;
231962306a36Sopenharmony_ci		} else {
232062306a36Sopenharmony_ci			*parent_ino = nce->parent_ino;
232162306a36Sopenharmony_ci			*parent_gen = nce->parent_gen;
232262306a36Sopenharmony_ci			ret = fs_path_add(dest, nce->name, nce->name_len);
232362306a36Sopenharmony_ci			if (ret < 0)
232462306a36Sopenharmony_ci				goto out;
232562306a36Sopenharmony_ci			ret = nce->ret;
232662306a36Sopenharmony_ci			goto out;
232762306a36Sopenharmony_ci		}
232862306a36Sopenharmony_ci	}
232962306a36Sopenharmony_ci
233062306a36Sopenharmony_ci	/*
233162306a36Sopenharmony_ci	 * If the inode is not existent yet, add the orphan name and return 1.
233262306a36Sopenharmony_ci	 * This should only happen for the parent dir that we determine in
233362306a36Sopenharmony_ci	 * record_new_ref_if_needed().
233462306a36Sopenharmony_ci	 */
233562306a36Sopenharmony_ci	ret = is_inode_existent(sctx, ino, gen, NULL, NULL);
233662306a36Sopenharmony_ci	if (ret < 0)
233762306a36Sopenharmony_ci		goto out;
233862306a36Sopenharmony_ci
233962306a36Sopenharmony_ci	if (!ret) {
234062306a36Sopenharmony_ci		ret = gen_unique_name(sctx, ino, gen, dest);
234162306a36Sopenharmony_ci		if (ret < 0)
234262306a36Sopenharmony_ci			goto out;
234362306a36Sopenharmony_ci		ret = 1;
234462306a36Sopenharmony_ci		goto out_cache;
234562306a36Sopenharmony_ci	}
234662306a36Sopenharmony_ci
234762306a36Sopenharmony_ci	/*
234862306a36Sopenharmony_ci	 * Depending on whether the inode was already processed or not, use
234962306a36Sopenharmony_ci	 * send_root or parent_root for ref lookup.
235062306a36Sopenharmony_ci	 */
235162306a36Sopenharmony_ci	if (ino < sctx->send_progress)
235262306a36Sopenharmony_ci		ret = get_first_ref(sctx->send_root, ino,
235362306a36Sopenharmony_ci				    parent_ino, parent_gen, dest);
235462306a36Sopenharmony_ci	else
235562306a36Sopenharmony_ci		ret = get_first_ref(sctx->parent_root, ino,
235662306a36Sopenharmony_ci				    parent_ino, parent_gen, dest);
235762306a36Sopenharmony_ci	if (ret < 0)
235862306a36Sopenharmony_ci		goto out;
235962306a36Sopenharmony_ci
236062306a36Sopenharmony_ci	/*
236162306a36Sopenharmony_ci	 * Check if the ref was overwritten by an inode's ref that was processed
236262306a36Sopenharmony_ci	 * earlier. If yes, treat as orphan and return 1.
236362306a36Sopenharmony_ci	 */
236462306a36Sopenharmony_ci	ret = did_overwrite_ref(sctx, *parent_ino, *parent_gen, ino, gen,
236562306a36Sopenharmony_ci			dest->start, dest->end - dest->start);
236662306a36Sopenharmony_ci	if (ret < 0)
236762306a36Sopenharmony_ci		goto out;
236862306a36Sopenharmony_ci	if (ret) {
236962306a36Sopenharmony_ci		fs_path_reset(dest);
237062306a36Sopenharmony_ci		ret = gen_unique_name(sctx, ino, gen, dest);
237162306a36Sopenharmony_ci		if (ret < 0)
237262306a36Sopenharmony_ci			goto out;
237362306a36Sopenharmony_ci		ret = 1;
237462306a36Sopenharmony_ci	}
237562306a36Sopenharmony_ci
237662306a36Sopenharmony_ciout_cache:
237762306a36Sopenharmony_ci	/*
237862306a36Sopenharmony_ci	 * Store the result of the lookup in the name cache.
237962306a36Sopenharmony_ci	 */
238062306a36Sopenharmony_ci	nce = kmalloc(sizeof(*nce) + fs_path_len(dest) + 1, GFP_KERNEL);
238162306a36Sopenharmony_ci	if (!nce) {
238262306a36Sopenharmony_ci		ret = -ENOMEM;
238362306a36Sopenharmony_ci		goto out;
238462306a36Sopenharmony_ci	}
238562306a36Sopenharmony_ci
238662306a36Sopenharmony_ci	nce->entry.key = ino;
238762306a36Sopenharmony_ci	nce->entry.gen = gen;
238862306a36Sopenharmony_ci	nce->parent_ino = *parent_ino;
238962306a36Sopenharmony_ci	nce->parent_gen = *parent_gen;
239062306a36Sopenharmony_ci	nce->name_len = fs_path_len(dest);
239162306a36Sopenharmony_ci	nce->ret = ret;
239262306a36Sopenharmony_ci	strcpy(nce->name, dest->start);
239362306a36Sopenharmony_ci
239462306a36Sopenharmony_ci	if (ino < sctx->send_progress)
239562306a36Sopenharmony_ci		nce->need_later_update = 0;
239662306a36Sopenharmony_ci	else
239762306a36Sopenharmony_ci		nce->need_later_update = 1;
239862306a36Sopenharmony_ci
239962306a36Sopenharmony_ci	nce_ret = btrfs_lru_cache_store(&sctx->name_cache, &nce->entry, GFP_KERNEL);
240062306a36Sopenharmony_ci	if (nce_ret < 0) {
240162306a36Sopenharmony_ci		kfree(nce);
240262306a36Sopenharmony_ci		ret = nce_ret;
240362306a36Sopenharmony_ci	}
240462306a36Sopenharmony_ci
240562306a36Sopenharmony_ciout:
240662306a36Sopenharmony_ci	return ret;
240762306a36Sopenharmony_ci}
240862306a36Sopenharmony_ci
240962306a36Sopenharmony_ci/*
241062306a36Sopenharmony_ci * Magic happens here. This function returns the first ref to an inode as it
241162306a36Sopenharmony_ci * would look like while receiving the stream at this point in time.
241262306a36Sopenharmony_ci * We walk the path up to the root. For every inode in between, we check if it
241362306a36Sopenharmony_ci * was already processed/sent. If yes, we continue with the parent as found
241462306a36Sopenharmony_ci * in send_root. If not, we continue with the parent as found in parent_root.
241562306a36Sopenharmony_ci * If we encounter an inode that was deleted at this point in time, we use the
241662306a36Sopenharmony_ci * inodes "orphan" name instead of the real name and stop. Same with new inodes
241762306a36Sopenharmony_ci * that were not created yet and overwritten inodes/refs.
241862306a36Sopenharmony_ci *
241962306a36Sopenharmony_ci * When do we have orphan inodes:
242062306a36Sopenharmony_ci * 1. When an inode is freshly created and thus no valid refs are available yet
242162306a36Sopenharmony_ci * 2. When a directory lost all it's refs (deleted) but still has dir items
242262306a36Sopenharmony_ci *    inside which were not processed yet (pending for move/delete). If anyone
242362306a36Sopenharmony_ci *    tried to get the path to the dir items, it would get a path inside that
242462306a36Sopenharmony_ci *    orphan directory.
242562306a36Sopenharmony_ci * 3. When an inode is moved around or gets new links, it may overwrite the ref
242662306a36Sopenharmony_ci *    of an unprocessed inode. If in that case the first ref would be
242762306a36Sopenharmony_ci *    overwritten, the overwritten inode gets "orphanized". Later when we
242862306a36Sopenharmony_ci *    process this overwritten inode, it is restored at a new place by moving
242962306a36Sopenharmony_ci *    the orphan inode.
243062306a36Sopenharmony_ci *
243162306a36Sopenharmony_ci * sctx->send_progress tells this function at which point in time receiving
243262306a36Sopenharmony_ci * would be.
243362306a36Sopenharmony_ci */
243462306a36Sopenharmony_cistatic int get_cur_path(struct send_ctx *sctx, u64 ino, u64 gen,
243562306a36Sopenharmony_ci			struct fs_path *dest)
243662306a36Sopenharmony_ci{
243762306a36Sopenharmony_ci	int ret = 0;
243862306a36Sopenharmony_ci	struct fs_path *name = NULL;
243962306a36Sopenharmony_ci	u64 parent_inode = 0;
244062306a36Sopenharmony_ci	u64 parent_gen = 0;
244162306a36Sopenharmony_ci	int stop = 0;
244262306a36Sopenharmony_ci
244362306a36Sopenharmony_ci	name = fs_path_alloc();
244462306a36Sopenharmony_ci	if (!name) {
244562306a36Sopenharmony_ci		ret = -ENOMEM;
244662306a36Sopenharmony_ci		goto out;
244762306a36Sopenharmony_ci	}
244862306a36Sopenharmony_ci
244962306a36Sopenharmony_ci	dest->reversed = 1;
245062306a36Sopenharmony_ci	fs_path_reset(dest);
245162306a36Sopenharmony_ci
245262306a36Sopenharmony_ci	while (!stop && ino != BTRFS_FIRST_FREE_OBJECTID) {
245362306a36Sopenharmony_ci		struct waiting_dir_move *wdm;
245462306a36Sopenharmony_ci
245562306a36Sopenharmony_ci		fs_path_reset(name);
245662306a36Sopenharmony_ci
245762306a36Sopenharmony_ci		if (is_waiting_for_rm(sctx, ino, gen)) {
245862306a36Sopenharmony_ci			ret = gen_unique_name(sctx, ino, gen, name);
245962306a36Sopenharmony_ci			if (ret < 0)
246062306a36Sopenharmony_ci				goto out;
246162306a36Sopenharmony_ci			ret = fs_path_add_path(dest, name);
246262306a36Sopenharmony_ci			break;
246362306a36Sopenharmony_ci		}
246462306a36Sopenharmony_ci
246562306a36Sopenharmony_ci		wdm = get_waiting_dir_move(sctx, ino);
246662306a36Sopenharmony_ci		if (wdm && wdm->orphanized) {
246762306a36Sopenharmony_ci			ret = gen_unique_name(sctx, ino, gen, name);
246862306a36Sopenharmony_ci			stop = 1;
246962306a36Sopenharmony_ci		} else if (wdm) {
247062306a36Sopenharmony_ci			ret = get_first_ref(sctx->parent_root, ino,
247162306a36Sopenharmony_ci					    &parent_inode, &parent_gen, name);
247262306a36Sopenharmony_ci		} else {
247362306a36Sopenharmony_ci			ret = __get_cur_name_and_parent(sctx, ino, gen,
247462306a36Sopenharmony_ci							&parent_inode,
247562306a36Sopenharmony_ci							&parent_gen, name);
247662306a36Sopenharmony_ci			if (ret)
247762306a36Sopenharmony_ci				stop = 1;
247862306a36Sopenharmony_ci		}
247962306a36Sopenharmony_ci
248062306a36Sopenharmony_ci		if (ret < 0)
248162306a36Sopenharmony_ci			goto out;
248262306a36Sopenharmony_ci
248362306a36Sopenharmony_ci		ret = fs_path_add_path(dest, name);
248462306a36Sopenharmony_ci		if (ret < 0)
248562306a36Sopenharmony_ci			goto out;
248662306a36Sopenharmony_ci
248762306a36Sopenharmony_ci		ino = parent_inode;
248862306a36Sopenharmony_ci		gen = parent_gen;
248962306a36Sopenharmony_ci	}
249062306a36Sopenharmony_ci
249162306a36Sopenharmony_ciout:
249262306a36Sopenharmony_ci	fs_path_free(name);
249362306a36Sopenharmony_ci	if (!ret)
249462306a36Sopenharmony_ci		fs_path_unreverse(dest);
249562306a36Sopenharmony_ci	return ret;
249662306a36Sopenharmony_ci}
249762306a36Sopenharmony_ci
249862306a36Sopenharmony_ci/*
249962306a36Sopenharmony_ci * Sends a BTRFS_SEND_C_SUBVOL command/item to userspace
250062306a36Sopenharmony_ci */
250162306a36Sopenharmony_cistatic int send_subvol_begin(struct send_ctx *sctx)
250262306a36Sopenharmony_ci{
250362306a36Sopenharmony_ci	int ret;
250462306a36Sopenharmony_ci	struct btrfs_root *send_root = sctx->send_root;
250562306a36Sopenharmony_ci	struct btrfs_root *parent_root = sctx->parent_root;
250662306a36Sopenharmony_ci	struct btrfs_path *path;
250762306a36Sopenharmony_ci	struct btrfs_key key;
250862306a36Sopenharmony_ci	struct btrfs_root_ref *ref;
250962306a36Sopenharmony_ci	struct extent_buffer *leaf;
251062306a36Sopenharmony_ci	char *name = NULL;
251162306a36Sopenharmony_ci	int namelen;
251262306a36Sopenharmony_ci
251362306a36Sopenharmony_ci	path = btrfs_alloc_path();
251462306a36Sopenharmony_ci	if (!path)
251562306a36Sopenharmony_ci		return -ENOMEM;
251662306a36Sopenharmony_ci
251762306a36Sopenharmony_ci	name = kmalloc(BTRFS_PATH_NAME_MAX, GFP_KERNEL);
251862306a36Sopenharmony_ci	if (!name) {
251962306a36Sopenharmony_ci		btrfs_free_path(path);
252062306a36Sopenharmony_ci		return -ENOMEM;
252162306a36Sopenharmony_ci	}
252262306a36Sopenharmony_ci
252362306a36Sopenharmony_ci	key.objectid = send_root->root_key.objectid;
252462306a36Sopenharmony_ci	key.type = BTRFS_ROOT_BACKREF_KEY;
252562306a36Sopenharmony_ci	key.offset = 0;
252662306a36Sopenharmony_ci
252762306a36Sopenharmony_ci	ret = btrfs_search_slot_for_read(send_root->fs_info->tree_root,
252862306a36Sopenharmony_ci				&key, path, 1, 0);
252962306a36Sopenharmony_ci	if (ret < 0)
253062306a36Sopenharmony_ci		goto out;
253162306a36Sopenharmony_ci	if (ret) {
253262306a36Sopenharmony_ci		ret = -ENOENT;
253362306a36Sopenharmony_ci		goto out;
253462306a36Sopenharmony_ci	}
253562306a36Sopenharmony_ci
253662306a36Sopenharmony_ci	leaf = path->nodes[0];
253762306a36Sopenharmony_ci	btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
253862306a36Sopenharmony_ci	if (key.type != BTRFS_ROOT_BACKREF_KEY ||
253962306a36Sopenharmony_ci	    key.objectid != send_root->root_key.objectid) {
254062306a36Sopenharmony_ci		ret = -ENOENT;
254162306a36Sopenharmony_ci		goto out;
254262306a36Sopenharmony_ci	}
254362306a36Sopenharmony_ci	ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref);
254462306a36Sopenharmony_ci	namelen = btrfs_root_ref_name_len(leaf, ref);
254562306a36Sopenharmony_ci	read_extent_buffer(leaf, name, (unsigned long)(ref + 1), namelen);
254662306a36Sopenharmony_ci	btrfs_release_path(path);
254762306a36Sopenharmony_ci
254862306a36Sopenharmony_ci	if (parent_root) {
254962306a36Sopenharmony_ci		ret = begin_cmd(sctx, BTRFS_SEND_C_SNAPSHOT);
255062306a36Sopenharmony_ci		if (ret < 0)
255162306a36Sopenharmony_ci			goto out;
255262306a36Sopenharmony_ci	} else {
255362306a36Sopenharmony_ci		ret = begin_cmd(sctx, BTRFS_SEND_C_SUBVOL);
255462306a36Sopenharmony_ci		if (ret < 0)
255562306a36Sopenharmony_ci			goto out;
255662306a36Sopenharmony_ci	}
255762306a36Sopenharmony_ci
255862306a36Sopenharmony_ci	TLV_PUT_STRING(sctx, BTRFS_SEND_A_PATH, name, namelen);
255962306a36Sopenharmony_ci
256062306a36Sopenharmony_ci	if (!btrfs_is_empty_uuid(sctx->send_root->root_item.received_uuid))
256162306a36Sopenharmony_ci		TLV_PUT_UUID(sctx, BTRFS_SEND_A_UUID,
256262306a36Sopenharmony_ci			    sctx->send_root->root_item.received_uuid);
256362306a36Sopenharmony_ci	else
256462306a36Sopenharmony_ci		TLV_PUT_UUID(sctx, BTRFS_SEND_A_UUID,
256562306a36Sopenharmony_ci			    sctx->send_root->root_item.uuid);
256662306a36Sopenharmony_ci
256762306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_CTRANSID,
256862306a36Sopenharmony_ci		    btrfs_root_ctransid(&sctx->send_root->root_item));
256962306a36Sopenharmony_ci	if (parent_root) {
257062306a36Sopenharmony_ci		if (!btrfs_is_empty_uuid(parent_root->root_item.received_uuid))
257162306a36Sopenharmony_ci			TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID,
257262306a36Sopenharmony_ci				     parent_root->root_item.received_uuid);
257362306a36Sopenharmony_ci		else
257462306a36Sopenharmony_ci			TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID,
257562306a36Sopenharmony_ci				     parent_root->root_item.uuid);
257662306a36Sopenharmony_ci		TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_CTRANSID,
257762306a36Sopenharmony_ci			    btrfs_root_ctransid(&sctx->parent_root->root_item));
257862306a36Sopenharmony_ci	}
257962306a36Sopenharmony_ci
258062306a36Sopenharmony_ci	ret = send_cmd(sctx);
258162306a36Sopenharmony_ci
258262306a36Sopenharmony_citlv_put_failure:
258362306a36Sopenharmony_ciout:
258462306a36Sopenharmony_ci	btrfs_free_path(path);
258562306a36Sopenharmony_ci	kfree(name);
258662306a36Sopenharmony_ci	return ret;
258762306a36Sopenharmony_ci}
258862306a36Sopenharmony_ci
258962306a36Sopenharmony_cistatic int send_truncate(struct send_ctx *sctx, u64 ino, u64 gen, u64 size)
259062306a36Sopenharmony_ci{
259162306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
259262306a36Sopenharmony_ci	int ret = 0;
259362306a36Sopenharmony_ci	struct fs_path *p;
259462306a36Sopenharmony_ci
259562306a36Sopenharmony_ci	btrfs_debug(fs_info, "send_truncate %llu size=%llu", ino, size);
259662306a36Sopenharmony_ci
259762306a36Sopenharmony_ci	p = fs_path_alloc();
259862306a36Sopenharmony_ci	if (!p)
259962306a36Sopenharmony_ci		return -ENOMEM;
260062306a36Sopenharmony_ci
260162306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_TRUNCATE);
260262306a36Sopenharmony_ci	if (ret < 0)
260362306a36Sopenharmony_ci		goto out;
260462306a36Sopenharmony_ci
260562306a36Sopenharmony_ci	ret = get_cur_path(sctx, ino, gen, p);
260662306a36Sopenharmony_ci	if (ret < 0)
260762306a36Sopenharmony_ci		goto out;
260862306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
260962306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_SIZE, size);
261062306a36Sopenharmony_ci
261162306a36Sopenharmony_ci	ret = send_cmd(sctx);
261262306a36Sopenharmony_ci
261362306a36Sopenharmony_citlv_put_failure:
261462306a36Sopenharmony_ciout:
261562306a36Sopenharmony_ci	fs_path_free(p);
261662306a36Sopenharmony_ci	return ret;
261762306a36Sopenharmony_ci}
261862306a36Sopenharmony_ci
261962306a36Sopenharmony_cistatic int send_chmod(struct send_ctx *sctx, u64 ino, u64 gen, u64 mode)
262062306a36Sopenharmony_ci{
262162306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
262262306a36Sopenharmony_ci	int ret = 0;
262362306a36Sopenharmony_ci	struct fs_path *p;
262462306a36Sopenharmony_ci
262562306a36Sopenharmony_ci	btrfs_debug(fs_info, "send_chmod %llu mode=%llu", ino, mode);
262662306a36Sopenharmony_ci
262762306a36Sopenharmony_ci	p = fs_path_alloc();
262862306a36Sopenharmony_ci	if (!p)
262962306a36Sopenharmony_ci		return -ENOMEM;
263062306a36Sopenharmony_ci
263162306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_CHMOD);
263262306a36Sopenharmony_ci	if (ret < 0)
263362306a36Sopenharmony_ci		goto out;
263462306a36Sopenharmony_ci
263562306a36Sopenharmony_ci	ret = get_cur_path(sctx, ino, gen, p);
263662306a36Sopenharmony_ci	if (ret < 0)
263762306a36Sopenharmony_ci		goto out;
263862306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
263962306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_MODE, mode & 07777);
264062306a36Sopenharmony_ci
264162306a36Sopenharmony_ci	ret = send_cmd(sctx);
264262306a36Sopenharmony_ci
264362306a36Sopenharmony_citlv_put_failure:
264462306a36Sopenharmony_ciout:
264562306a36Sopenharmony_ci	fs_path_free(p);
264662306a36Sopenharmony_ci	return ret;
264762306a36Sopenharmony_ci}
264862306a36Sopenharmony_ci
264962306a36Sopenharmony_cistatic int send_fileattr(struct send_ctx *sctx, u64 ino, u64 gen, u64 fileattr)
265062306a36Sopenharmony_ci{
265162306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
265262306a36Sopenharmony_ci	int ret = 0;
265362306a36Sopenharmony_ci	struct fs_path *p;
265462306a36Sopenharmony_ci
265562306a36Sopenharmony_ci	if (sctx->proto < 2)
265662306a36Sopenharmony_ci		return 0;
265762306a36Sopenharmony_ci
265862306a36Sopenharmony_ci	btrfs_debug(fs_info, "send_fileattr %llu fileattr=%llu", ino, fileattr);
265962306a36Sopenharmony_ci
266062306a36Sopenharmony_ci	p = fs_path_alloc();
266162306a36Sopenharmony_ci	if (!p)
266262306a36Sopenharmony_ci		return -ENOMEM;
266362306a36Sopenharmony_ci
266462306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_FILEATTR);
266562306a36Sopenharmony_ci	if (ret < 0)
266662306a36Sopenharmony_ci		goto out;
266762306a36Sopenharmony_ci
266862306a36Sopenharmony_ci	ret = get_cur_path(sctx, ino, gen, p);
266962306a36Sopenharmony_ci	if (ret < 0)
267062306a36Sopenharmony_ci		goto out;
267162306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
267262306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILEATTR, fileattr);
267362306a36Sopenharmony_ci
267462306a36Sopenharmony_ci	ret = send_cmd(sctx);
267562306a36Sopenharmony_ci
267662306a36Sopenharmony_citlv_put_failure:
267762306a36Sopenharmony_ciout:
267862306a36Sopenharmony_ci	fs_path_free(p);
267962306a36Sopenharmony_ci	return ret;
268062306a36Sopenharmony_ci}
268162306a36Sopenharmony_ci
268262306a36Sopenharmony_cistatic int send_chown(struct send_ctx *sctx, u64 ino, u64 gen, u64 uid, u64 gid)
268362306a36Sopenharmony_ci{
268462306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
268562306a36Sopenharmony_ci	int ret = 0;
268662306a36Sopenharmony_ci	struct fs_path *p;
268762306a36Sopenharmony_ci
268862306a36Sopenharmony_ci	btrfs_debug(fs_info, "send_chown %llu uid=%llu, gid=%llu",
268962306a36Sopenharmony_ci		    ino, uid, gid);
269062306a36Sopenharmony_ci
269162306a36Sopenharmony_ci	p = fs_path_alloc();
269262306a36Sopenharmony_ci	if (!p)
269362306a36Sopenharmony_ci		return -ENOMEM;
269462306a36Sopenharmony_ci
269562306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_CHOWN);
269662306a36Sopenharmony_ci	if (ret < 0)
269762306a36Sopenharmony_ci		goto out;
269862306a36Sopenharmony_ci
269962306a36Sopenharmony_ci	ret = get_cur_path(sctx, ino, gen, p);
270062306a36Sopenharmony_ci	if (ret < 0)
270162306a36Sopenharmony_ci		goto out;
270262306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
270362306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_UID, uid);
270462306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_GID, gid);
270562306a36Sopenharmony_ci
270662306a36Sopenharmony_ci	ret = send_cmd(sctx);
270762306a36Sopenharmony_ci
270862306a36Sopenharmony_citlv_put_failure:
270962306a36Sopenharmony_ciout:
271062306a36Sopenharmony_ci	fs_path_free(p);
271162306a36Sopenharmony_ci	return ret;
271262306a36Sopenharmony_ci}
271362306a36Sopenharmony_ci
271462306a36Sopenharmony_cistatic int send_utimes(struct send_ctx *sctx, u64 ino, u64 gen)
271562306a36Sopenharmony_ci{
271662306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
271762306a36Sopenharmony_ci	int ret = 0;
271862306a36Sopenharmony_ci	struct fs_path *p = NULL;
271962306a36Sopenharmony_ci	struct btrfs_inode_item *ii;
272062306a36Sopenharmony_ci	struct btrfs_path *path = NULL;
272162306a36Sopenharmony_ci	struct extent_buffer *eb;
272262306a36Sopenharmony_ci	struct btrfs_key key;
272362306a36Sopenharmony_ci	int slot;
272462306a36Sopenharmony_ci
272562306a36Sopenharmony_ci	btrfs_debug(fs_info, "send_utimes %llu", ino);
272662306a36Sopenharmony_ci
272762306a36Sopenharmony_ci	p = fs_path_alloc();
272862306a36Sopenharmony_ci	if (!p)
272962306a36Sopenharmony_ci		return -ENOMEM;
273062306a36Sopenharmony_ci
273162306a36Sopenharmony_ci	path = alloc_path_for_send();
273262306a36Sopenharmony_ci	if (!path) {
273362306a36Sopenharmony_ci		ret = -ENOMEM;
273462306a36Sopenharmony_ci		goto out;
273562306a36Sopenharmony_ci	}
273662306a36Sopenharmony_ci
273762306a36Sopenharmony_ci	key.objectid = ino;
273862306a36Sopenharmony_ci	key.type = BTRFS_INODE_ITEM_KEY;
273962306a36Sopenharmony_ci	key.offset = 0;
274062306a36Sopenharmony_ci	ret = btrfs_search_slot(NULL, sctx->send_root, &key, path, 0, 0);
274162306a36Sopenharmony_ci	if (ret > 0)
274262306a36Sopenharmony_ci		ret = -ENOENT;
274362306a36Sopenharmony_ci	if (ret < 0)
274462306a36Sopenharmony_ci		goto out;
274562306a36Sopenharmony_ci
274662306a36Sopenharmony_ci	eb = path->nodes[0];
274762306a36Sopenharmony_ci	slot = path->slots[0];
274862306a36Sopenharmony_ci	ii = btrfs_item_ptr(eb, slot, struct btrfs_inode_item);
274962306a36Sopenharmony_ci
275062306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_UTIMES);
275162306a36Sopenharmony_ci	if (ret < 0)
275262306a36Sopenharmony_ci		goto out;
275362306a36Sopenharmony_ci
275462306a36Sopenharmony_ci	ret = get_cur_path(sctx, ino, gen, p);
275562306a36Sopenharmony_ci	if (ret < 0)
275662306a36Sopenharmony_ci		goto out;
275762306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
275862306a36Sopenharmony_ci	TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_ATIME, eb, &ii->atime);
275962306a36Sopenharmony_ci	TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_MTIME, eb, &ii->mtime);
276062306a36Sopenharmony_ci	TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_CTIME, eb, &ii->ctime);
276162306a36Sopenharmony_ci	if (sctx->proto >= 2)
276262306a36Sopenharmony_ci		TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_OTIME, eb, &ii->otime);
276362306a36Sopenharmony_ci
276462306a36Sopenharmony_ci	ret = send_cmd(sctx);
276562306a36Sopenharmony_ci
276662306a36Sopenharmony_citlv_put_failure:
276762306a36Sopenharmony_ciout:
276862306a36Sopenharmony_ci	fs_path_free(p);
276962306a36Sopenharmony_ci	btrfs_free_path(path);
277062306a36Sopenharmony_ci	return ret;
277162306a36Sopenharmony_ci}
277262306a36Sopenharmony_ci
277362306a36Sopenharmony_ci/*
277462306a36Sopenharmony_ci * If the cache is full, we can't remove entries from it and do a call to
277562306a36Sopenharmony_ci * send_utimes() for each respective inode, because we might be finishing
277662306a36Sopenharmony_ci * processing an inode that is a directory and it just got renamed, and existing
277762306a36Sopenharmony_ci * entries in the cache may refer to inodes that have the directory in their
277862306a36Sopenharmony_ci * full path - in which case we would generate outdated paths (pre-rename)
277962306a36Sopenharmony_ci * for the inodes that the cache entries point to. Instead of prunning the
278062306a36Sopenharmony_ci * cache when inserting, do it after we finish processing each inode at
278162306a36Sopenharmony_ci * finish_inode_if_needed().
278262306a36Sopenharmony_ci */
278362306a36Sopenharmony_cistatic int cache_dir_utimes(struct send_ctx *sctx, u64 dir, u64 gen)
278462306a36Sopenharmony_ci{
278562306a36Sopenharmony_ci	struct btrfs_lru_cache_entry *entry;
278662306a36Sopenharmony_ci	int ret;
278762306a36Sopenharmony_ci
278862306a36Sopenharmony_ci	entry = btrfs_lru_cache_lookup(&sctx->dir_utimes_cache, dir, gen);
278962306a36Sopenharmony_ci	if (entry != NULL)
279062306a36Sopenharmony_ci		return 0;
279162306a36Sopenharmony_ci
279262306a36Sopenharmony_ci	/* Caching is optional, don't fail if we can't allocate memory. */
279362306a36Sopenharmony_ci	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
279462306a36Sopenharmony_ci	if (!entry)
279562306a36Sopenharmony_ci		return send_utimes(sctx, dir, gen);
279662306a36Sopenharmony_ci
279762306a36Sopenharmony_ci	entry->key = dir;
279862306a36Sopenharmony_ci	entry->gen = gen;
279962306a36Sopenharmony_ci
280062306a36Sopenharmony_ci	ret = btrfs_lru_cache_store(&sctx->dir_utimes_cache, entry, GFP_KERNEL);
280162306a36Sopenharmony_ci	ASSERT(ret != -EEXIST);
280262306a36Sopenharmony_ci	if (ret) {
280362306a36Sopenharmony_ci		kfree(entry);
280462306a36Sopenharmony_ci		return send_utimes(sctx, dir, gen);
280562306a36Sopenharmony_ci	}
280662306a36Sopenharmony_ci
280762306a36Sopenharmony_ci	return 0;
280862306a36Sopenharmony_ci}
280962306a36Sopenharmony_ci
281062306a36Sopenharmony_cistatic int trim_dir_utimes_cache(struct send_ctx *sctx)
281162306a36Sopenharmony_ci{
281262306a36Sopenharmony_ci	while (btrfs_lru_cache_size(&sctx->dir_utimes_cache) >
281362306a36Sopenharmony_ci	       SEND_MAX_DIR_UTIMES_CACHE_SIZE) {
281462306a36Sopenharmony_ci		struct btrfs_lru_cache_entry *lru;
281562306a36Sopenharmony_ci		int ret;
281662306a36Sopenharmony_ci
281762306a36Sopenharmony_ci		lru = btrfs_lru_cache_lru_entry(&sctx->dir_utimes_cache);
281862306a36Sopenharmony_ci		ASSERT(lru != NULL);
281962306a36Sopenharmony_ci
282062306a36Sopenharmony_ci		ret = send_utimes(sctx, lru->key, lru->gen);
282162306a36Sopenharmony_ci		if (ret)
282262306a36Sopenharmony_ci			return ret;
282362306a36Sopenharmony_ci
282462306a36Sopenharmony_ci		btrfs_lru_cache_remove(&sctx->dir_utimes_cache, lru);
282562306a36Sopenharmony_ci	}
282662306a36Sopenharmony_ci
282762306a36Sopenharmony_ci	return 0;
282862306a36Sopenharmony_ci}
282962306a36Sopenharmony_ci
283062306a36Sopenharmony_ci/*
283162306a36Sopenharmony_ci * Sends a BTRFS_SEND_C_MKXXX or SYMLINK command to user space. We don't have
283262306a36Sopenharmony_ci * a valid path yet because we did not process the refs yet. So, the inode
283362306a36Sopenharmony_ci * is created as orphan.
283462306a36Sopenharmony_ci */
283562306a36Sopenharmony_cistatic int send_create_inode(struct send_ctx *sctx, u64 ino)
283662306a36Sopenharmony_ci{
283762306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
283862306a36Sopenharmony_ci	int ret = 0;
283962306a36Sopenharmony_ci	struct fs_path *p;
284062306a36Sopenharmony_ci	int cmd;
284162306a36Sopenharmony_ci	struct btrfs_inode_info info;
284262306a36Sopenharmony_ci	u64 gen;
284362306a36Sopenharmony_ci	u64 mode;
284462306a36Sopenharmony_ci	u64 rdev;
284562306a36Sopenharmony_ci
284662306a36Sopenharmony_ci	btrfs_debug(fs_info, "send_create_inode %llu", ino);
284762306a36Sopenharmony_ci
284862306a36Sopenharmony_ci	p = fs_path_alloc();
284962306a36Sopenharmony_ci	if (!p)
285062306a36Sopenharmony_ci		return -ENOMEM;
285162306a36Sopenharmony_ci
285262306a36Sopenharmony_ci	if (ino != sctx->cur_ino) {
285362306a36Sopenharmony_ci		ret = get_inode_info(sctx->send_root, ino, &info);
285462306a36Sopenharmony_ci		if (ret < 0)
285562306a36Sopenharmony_ci			goto out;
285662306a36Sopenharmony_ci		gen = info.gen;
285762306a36Sopenharmony_ci		mode = info.mode;
285862306a36Sopenharmony_ci		rdev = info.rdev;
285962306a36Sopenharmony_ci	} else {
286062306a36Sopenharmony_ci		gen = sctx->cur_inode_gen;
286162306a36Sopenharmony_ci		mode = sctx->cur_inode_mode;
286262306a36Sopenharmony_ci		rdev = sctx->cur_inode_rdev;
286362306a36Sopenharmony_ci	}
286462306a36Sopenharmony_ci
286562306a36Sopenharmony_ci	if (S_ISREG(mode)) {
286662306a36Sopenharmony_ci		cmd = BTRFS_SEND_C_MKFILE;
286762306a36Sopenharmony_ci	} else if (S_ISDIR(mode)) {
286862306a36Sopenharmony_ci		cmd = BTRFS_SEND_C_MKDIR;
286962306a36Sopenharmony_ci	} else if (S_ISLNK(mode)) {
287062306a36Sopenharmony_ci		cmd = BTRFS_SEND_C_SYMLINK;
287162306a36Sopenharmony_ci	} else if (S_ISCHR(mode) || S_ISBLK(mode)) {
287262306a36Sopenharmony_ci		cmd = BTRFS_SEND_C_MKNOD;
287362306a36Sopenharmony_ci	} else if (S_ISFIFO(mode)) {
287462306a36Sopenharmony_ci		cmd = BTRFS_SEND_C_MKFIFO;
287562306a36Sopenharmony_ci	} else if (S_ISSOCK(mode)) {
287662306a36Sopenharmony_ci		cmd = BTRFS_SEND_C_MKSOCK;
287762306a36Sopenharmony_ci	} else {
287862306a36Sopenharmony_ci		btrfs_warn(sctx->send_root->fs_info, "unexpected inode type %o",
287962306a36Sopenharmony_ci				(int)(mode & S_IFMT));
288062306a36Sopenharmony_ci		ret = -EOPNOTSUPP;
288162306a36Sopenharmony_ci		goto out;
288262306a36Sopenharmony_ci	}
288362306a36Sopenharmony_ci
288462306a36Sopenharmony_ci	ret = begin_cmd(sctx, cmd);
288562306a36Sopenharmony_ci	if (ret < 0)
288662306a36Sopenharmony_ci		goto out;
288762306a36Sopenharmony_ci
288862306a36Sopenharmony_ci	ret = gen_unique_name(sctx, ino, gen, p);
288962306a36Sopenharmony_ci	if (ret < 0)
289062306a36Sopenharmony_ci		goto out;
289162306a36Sopenharmony_ci
289262306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
289362306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_INO, ino);
289462306a36Sopenharmony_ci
289562306a36Sopenharmony_ci	if (S_ISLNK(mode)) {
289662306a36Sopenharmony_ci		fs_path_reset(p);
289762306a36Sopenharmony_ci		ret = read_symlink(sctx->send_root, ino, p);
289862306a36Sopenharmony_ci		if (ret < 0)
289962306a36Sopenharmony_ci			goto out;
290062306a36Sopenharmony_ci		TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_LINK, p);
290162306a36Sopenharmony_ci	} else if (S_ISCHR(mode) || S_ISBLK(mode) ||
290262306a36Sopenharmony_ci		   S_ISFIFO(mode) || S_ISSOCK(mode)) {
290362306a36Sopenharmony_ci		TLV_PUT_U64(sctx, BTRFS_SEND_A_RDEV, new_encode_dev(rdev));
290462306a36Sopenharmony_ci		TLV_PUT_U64(sctx, BTRFS_SEND_A_MODE, mode);
290562306a36Sopenharmony_ci	}
290662306a36Sopenharmony_ci
290762306a36Sopenharmony_ci	ret = send_cmd(sctx);
290862306a36Sopenharmony_ci	if (ret < 0)
290962306a36Sopenharmony_ci		goto out;
291062306a36Sopenharmony_ci
291162306a36Sopenharmony_ci
291262306a36Sopenharmony_citlv_put_failure:
291362306a36Sopenharmony_ciout:
291462306a36Sopenharmony_ci	fs_path_free(p);
291562306a36Sopenharmony_ci	return ret;
291662306a36Sopenharmony_ci}
291762306a36Sopenharmony_ci
291862306a36Sopenharmony_cistatic void cache_dir_created(struct send_ctx *sctx, u64 dir)
291962306a36Sopenharmony_ci{
292062306a36Sopenharmony_ci	struct btrfs_lru_cache_entry *entry;
292162306a36Sopenharmony_ci	int ret;
292262306a36Sopenharmony_ci
292362306a36Sopenharmony_ci	/* Caching is optional, ignore any failures. */
292462306a36Sopenharmony_ci	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
292562306a36Sopenharmony_ci	if (!entry)
292662306a36Sopenharmony_ci		return;
292762306a36Sopenharmony_ci
292862306a36Sopenharmony_ci	entry->key = dir;
292962306a36Sopenharmony_ci	entry->gen = 0;
293062306a36Sopenharmony_ci	ret = btrfs_lru_cache_store(&sctx->dir_created_cache, entry, GFP_KERNEL);
293162306a36Sopenharmony_ci	if (ret < 0)
293262306a36Sopenharmony_ci		kfree(entry);
293362306a36Sopenharmony_ci}
293462306a36Sopenharmony_ci
293562306a36Sopenharmony_ci/*
293662306a36Sopenharmony_ci * We need some special handling for inodes that get processed before the parent
293762306a36Sopenharmony_ci * directory got created. See process_recorded_refs for details.
293862306a36Sopenharmony_ci * This function does the check if we already created the dir out of order.
293962306a36Sopenharmony_ci */
294062306a36Sopenharmony_cistatic int did_create_dir(struct send_ctx *sctx, u64 dir)
294162306a36Sopenharmony_ci{
294262306a36Sopenharmony_ci	int ret = 0;
294362306a36Sopenharmony_ci	int iter_ret = 0;
294462306a36Sopenharmony_ci	struct btrfs_path *path = NULL;
294562306a36Sopenharmony_ci	struct btrfs_key key;
294662306a36Sopenharmony_ci	struct btrfs_key found_key;
294762306a36Sopenharmony_ci	struct btrfs_key di_key;
294862306a36Sopenharmony_ci	struct btrfs_dir_item *di;
294962306a36Sopenharmony_ci
295062306a36Sopenharmony_ci	if (btrfs_lru_cache_lookup(&sctx->dir_created_cache, dir, 0))
295162306a36Sopenharmony_ci		return 1;
295262306a36Sopenharmony_ci
295362306a36Sopenharmony_ci	path = alloc_path_for_send();
295462306a36Sopenharmony_ci	if (!path)
295562306a36Sopenharmony_ci		return -ENOMEM;
295662306a36Sopenharmony_ci
295762306a36Sopenharmony_ci	key.objectid = dir;
295862306a36Sopenharmony_ci	key.type = BTRFS_DIR_INDEX_KEY;
295962306a36Sopenharmony_ci	key.offset = 0;
296062306a36Sopenharmony_ci
296162306a36Sopenharmony_ci	btrfs_for_each_slot(sctx->send_root, &key, &found_key, path, iter_ret) {
296262306a36Sopenharmony_ci		struct extent_buffer *eb = path->nodes[0];
296362306a36Sopenharmony_ci
296462306a36Sopenharmony_ci		if (found_key.objectid != key.objectid ||
296562306a36Sopenharmony_ci		    found_key.type != key.type) {
296662306a36Sopenharmony_ci			ret = 0;
296762306a36Sopenharmony_ci			break;
296862306a36Sopenharmony_ci		}
296962306a36Sopenharmony_ci
297062306a36Sopenharmony_ci		di = btrfs_item_ptr(eb, path->slots[0], struct btrfs_dir_item);
297162306a36Sopenharmony_ci		btrfs_dir_item_key_to_cpu(eb, di, &di_key);
297262306a36Sopenharmony_ci
297362306a36Sopenharmony_ci		if (di_key.type != BTRFS_ROOT_ITEM_KEY &&
297462306a36Sopenharmony_ci		    di_key.objectid < sctx->send_progress) {
297562306a36Sopenharmony_ci			ret = 1;
297662306a36Sopenharmony_ci			cache_dir_created(sctx, dir);
297762306a36Sopenharmony_ci			break;
297862306a36Sopenharmony_ci		}
297962306a36Sopenharmony_ci	}
298062306a36Sopenharmony_ci	/* Catch error found during iteration */
298162306a36Sopenharmony_ci	if (iter_ret < 0)
298262306a36Sopenharmony_ci		ret = iter_ret;
298362306a36Sopenharmony_ci
298462306a36Sopenharmony_ci	btrfs_free_path(path);
298562306a36Sopenharmony_ci	return ret;
298662306a36Sopenharmony_ci}
298762306a36Sopenharmony_ci
298862306a36Sopenharmony_ci/*
298962306a36Sopenharmony_ci * Only creates the inode if it is:
299062306a36Sopenharmony_ci * 1. Not a directory
299162306a36Sopenharmony_ci * 2. Or a directory which was not created already due to out of order
299262306a36Sopenharmony_ci *    directories. See did_create_dir and process_recorded_refs for details.
299362306a36Sopenharmony_ci */
299462306a36Sopenharmony_cistatic int send_create_inode_if_needed(struct send_ctx *sctx)
299562306a36Sopenharmony_ci{
299662306a36Sopenharmony_ci	int ret;
299762306a36Sopenharmony_ci
299862306a36Sopenharmony_ci	if (S_ISDIR(sctx->cur_inode_mode)) {
299962306a36Sopenharmony_ci		ret = did_create_dir(sctx, sctx->cur_ino);
300062306a36Sopenharmony_ci		if (ret < 0)
300162306a36Sopenharmony_ci			return ret;
300262306a36Sopenharmony_ci		else if (ret > 0)
300362306a36Sopenharmony_ci			return 0;
300462306a36Sopenharmony_ci	}
300562306a36Sopenharmony_ci
300662306a36Sopenharmony_ci	ret = send_create_inode(sctx, sctx->cur_ino);
300762306a36Sopenharmony_ci
300862306a36Sopenharmony_ci	if (ret == 0 && S_ISDIR(sctx->cur_inode_mode))
300962306a36Sopenharmony_ci		cache_dir_created(sctx, sctx->cur_ino);
301062306a36Sopenharmony_ci
301162306a36Sopenharmony_ci	return ret;
301262306a36Sopenharmony_ci}
301362306a36Sopenharmony_ci
301462306a36Sopenharmony_cistruct recorded_ref {
301562306a36Sopenharmony_ci	struct list_head list;
301662306a36Sopenharmony_ci	char *name;
301762306a36Sopenharmony_ci	struct fs_path *full_path;
301862306a36Sopenharmony_ci	u64 dir;
301962306a36Sopenharmony_ci	u64 dir_gen;
302062306a36Sopenharmony_ci	int name_len;
302162306a36Sopenharmony_ci	struct rb_node node;
302262306a36Sopenharmony_ci	struct rb_root *root;
302362306a36Sopenharmony_ci};
302462306a36Sopenharmony_ci
302562306a36Sopenharmony_cistatic struct recorded_ref *recorded_ref_alloc(void)
302662306a36Sopenharmony_ci{
302762306a36Sopenharmony_ci	struct recorded_ref *ref;
302862306a36Sopenharmony_ci
302962306a36Sopenharmony_ci	ref = kzalloc(sizeof(*ref), GFP_KERNEL);
303062306a36Sopenharmony_ci	if (!ref)
303162306a36Sopenharmony_ci		return NULL;
303262306a36Sopenharmony_ci	RB_CLEAR_NODE(&ref->node);
303362306a36Sopenharmony_ci	INIT_LIST_HEAD(&ref->list);
303462306a36Sopenharmony_ci	return ref;
303562306a36Sopenharmony_ci}
303662306a36Sopenharmony_ci
303762306a36Sopenharmony_cistatic void recorded_ref_free(struct recorded_ref *ref)
303862306a36Sopenharmony_ci{
303962306a36Sopenharmony_ci	if (!ref)
304062306a36Sopenharmony_ci		return;
304162306a36Sopenharmony_ci	if (!RB_EMPTY_NODE(&ref->node))
304262306a36Sopenharmony_ci		rb_erase(&ref->node, ref->root);
304362306a36Sopenharmony_ci	list_del(&ref->list);
304462306a36Sopenharmony_ci	fs_path_free(ref->full_path);
304562306a36Sopenharmony_ci	kfree(ref);
304662306a36Sopenharmony_ci}
304762306a36Sopenharmony_ci
304862306a36Sopenharmony_cistatic void set_ref_path(struct recorded_ref *ref, struct fs_path *path)
304962306a36Sopenharmony_ci{
305062306a36Sopenharmony_ci	ref->full_path = path;
305162306a36Sopenharmony_ci	ref->name = (char *)kbasename(ref->full_path->start);
305262306a36Sopenharmony_ci	ref->name_len = ref->full_path->end - ref->name;
305362306a36Sopenharmony_ci}
305462306a36Sopenharmony_ci
305562306a36Sopenharmony_cistatic int dup_ref(struct recorded_ref *ref, struct list_head *list)
305662306a36Sopenharmony_ci{
305762306a36Sopenharmony_ci	struct recorded_ref *new;
305862306a36Sopenharmony_ci
305962306a36Sopenharmony_ci	new = recorded_ref_alloc();
306062306a36Sopenharmony_ci	if (!new)
306162306a36Sopenharmony_ci		return -ENOMEM;
306262306a36Sopenharmony_ci
306362306a36Sopenharmony_ci	new->dir = ref->dir;
306462306a36Sopenharmony_ci	new->dir_gen = ref->dir_gen;
306562306a36Sopenharmony_ci	list_add_tail(&new->list, list);
306662306a36Sopenharmony_ci	return 0;
306762306a36Sopenharmony_ci}
306862306a36Sopenharmony_ci
306962306a36Sopenharmony_cistatic void __free_recorded_refs(struct list_head *head)
307062306a36Sopenharmony_ci{
307162306a36Sopenharmony_ci	struct recorded_ref *cur;
307262306a36Sopenharmony_ci
307362306a36Sopenharmony_ci	while (!list_empty(head)) {
307462306a36Sopenharmony_ci		cur = list_entry(head->next, struct recorded_ref, list);
307562306a36Sopenharmony_ci		recorded_ref_free(cur);
307662306a36Sopenharmony_ci	}
307762306a36Sopenharmony_ci}
307862306a36Sopenharmony_ci
307962306a36Sopenharmony_cistatic void free_recorded_refs(struct send_ctx *sctx)
308062306a36Sopenharmony_ci{
308162306a36Sopenharmony_ci	__free_recorded_refs(&sctx->new_refs);
308262306a36Sopenharmony_ci	__free_recorded_refs(&sctx->deleted_refs);
308362306a36Sopenharmony_ci}
308462306a36Sopenharmony_ci
308562306a36Sopenharmony_ci/*
308662306a36Sopenharmony_ci * Renames/moves a file/dir to its orphan name. Used when the first
308762306a36Sopenharmony_ci * ref of an unprocessed inode gets overwritten and for all non empty
308862306a36Sopenharmony_ci * directories.
308962306a36Sopenharmony_ci */
309062306a36Sopenharmony_cistatic int orphanize_inode(struct send_ctx *sctx, u64 ino, u64 gen,
309162306a36Sopenharmony_ci			  struct fs_path *path)
309262306a36Sopenharmony_ci{
309362306a36Sopenharmony_ci	int ret;
309462306a36Sopenharmony_ci	struct fs_path *orphan;
309562306a36Sopenharmony_ci
309662306a36Sopenharmony_ci	orphan = fs_path_alloc();
309762306a36Sopenharmony_ci	if (!orphan)
309862306a36Sopenharmony_ci		return -ENOMEM;
309962306a36Sopenharmony_ci
310062306a36Sopenharmony_ci	ret = gen_unique_name(sctx, ino, gen, orphan);
310162306a36Sopenharmony_ci	if (ret < 0)
310262306a36Sopenharmony_ci		goto out;
310362306a36Sopenharmony_ci
310462306a36Sopenharmony_ci	ret = send_rename(sctx, path, orphan);
310562306a36Sopenharmony_ci
310662306a36Sopenharmony_ciout:
310762306a36Sopenharmony_ci	fs_path_free(orphan);
310862306a36Sopenharmony_ci	return ret;
310962306a36Sopenharmony_ci}
311062306a36Sopenharmony_ci
311162306a36Sopenharmony_cistatic struct orphan_dir_info *add_orphan_dir_info(struct send_ctx *sctx,
311262306a36Sopenharmony_ci						   u64 dir_ino, u64 dir_gen)
311362306a36Sopenharmony_ci{
311462306a36Sopenharmony_ci	struct rb_node **p = &sctx->orphan_dirs.rb_node;
311562306a36Sopenharmony_ci	struct rb_node *parent = NULL;
311662306a36Sopenharmony_ci	struct orphan_dir_info *entry, *odi;
311762306a36Sopenharmony_ci
311862306a36Sopenharmony_ci	while (*p) {
311962306a36Sopenharmony_ci		parent = *p;
312062306a36Sopenharmony_ci		entry = rb_entry(parent, struct orphan_dir_info, node);
312162306a36Sopenharmony_ci		if (dir_ino < entry->ino)
312262306a36Sopenharmony_ci			p = &(*p)->rb_left;
312362306a36Sopenharmony_ci		else if (dir_ino > entry->ino)
312462306a36Sopenharmony_ci			p = &(*p)->rb_right;
312562306a36Sopenharmony_ci		else if (dir_gen < entry->gen)
312662306a36Sopenharmony_ci			p = &(*p)->rb_left;
312762306a36Sopenharmony_ci		else if (dir_gen > entry->gen)
312862306a36Sopenharmony_ci			p = &(*p)->rb_right;
312962306a36Sopenharmony_ci		else
313062306a36Sopenharmony_ci			return entry;
313162306a36Sopenharmony_ci	}
313262306a36Sopenharmony_ci
313362306a36Sopenharmony_ci	odi = kmalloc(sizeof(*odi), GFP_KERNEL);
313462306a36Sopenharmony_ci	if (!odi)
313562306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
313662306a36Sopenharmony_ci	odi->ino = dir_ino;
313762306a36Sopenharmony_ci	odi->gen = dir_gen;
313862306a36Sopenharmony_ci	odi->last_dir_index_offset = 0;
313962306a36Sopenharmony_ci	odi->dir_high_seq_ino = 0;
314062306a36Sopenharmony_ci
314162306a36Sopenharmony_ci	rb_link_node(&odi->node, parent, p);
314262306a36Sopenharmony_ci	rb_insert_color(&odi->node, &sctx->orphan_dirs);
314362306a36Sopenharmony_ci	return odi;
314462306a36Sopenharmony_ci}
314562306a36Sopenharmony_ci
314662306a36Sopenharmony_cistatic struct orphan_dir_info *get_orphan_dir_info(struct send_ctx *sctx,
314762306a36Sopenharmony_ci						   u64 dir_ino, u64 gen)
314862306a36Sopenharmony_ci{
314962306a36Sopenharmony_ci	struct rb_node *n = sctx->orphan_dirs.rb_node;
315062306a36Sopenharmony_ci	struct orphan_dir_info *entry;
315162306a36Sopenharmony_ci
315262306a36Sopenharmony_ci	while (n) {
315362306a36Sopenharmony_ci		entry = rb_entry(n, struct orphan_dir_info, node);
315462306a36Sopenharmony_ci		if (dir_ino < entry->ino)
315562306a36Sopenharmony_ci			n = n->rb_left;
315662306a36Sopenharmony_ci		else if (dir_ino > entry->ino)
315762306a36Sopenharmony_ci			n = n->rb_right;
315862306a36Sopenharmony_ci		else if (gen < entry->gen)
315962306a36Sopenharmony_ci			n = n->rb_left;
316062306a36Sopenharmony_ci		else if (gen > entry->gen)
316162306a36Sopenharmony_ci			n = n->rb_right;
316262306a36Sopenharmony_ci		else
316362306a36Sopenharmony_ci			return entry;
316462306a36Sopenharmony_ci	}
316562306a36Sopenharmony_ci	return NULL;
316662306a36Sopenharmony_ci}
316762306a36Sopenharmony_ci
316862306a36Sopenharmony_cistatic int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino, u64 gen)
316962306a36Sopenharmony_ci{
317062306a36Sopenharmony_ci	struct orphan_dir_info *odi = get_orphan_dir_info(sctx, dir_ino, gen);
317162306a36Sopenharmony_ci
317262306a36Sopenharmony_ci	return odi != NULL;
317362306a36Sopenharmony_ci}
317462306a36Sopenharmony_ci
317562306a36Sopenharmony_cistatic void free_orphan_dir_info(struct send_ctx *sctx,
317662306a36Sopenharmony_ci				 struct orphan_dir_info *odi)
317762306a36Sopenharmony_ci{
317862306a36Sopenharmony_ci	if (!odi)
317962306a36Sopenharmony_ci		return;
318062306a36Sopenharmony_ci	rb_erase(&odi->node, &sctx->orphan_dirs);
318162306a36Sopenharmony_ci	kfree(odi);
318262306a36Sopenharmony_ci}
318362306a36Sopenharmony_ci
318462306a36Sopenharmony_ci/*
318562306a36Sopenharmony_ci * Returns 1 if a directory can be removed at this point in time.
318662306a36Sopenharmony_ci * We check this by iterating all dir items and checking if the inode behind
318762306a36Sopenharmony_ci * the dir item was already processed.
318862306a36Sopenharmony_ci */
318962306a36Sopenharmony_cistatic int can_rmdir(struct send_ctx *sctx, u64 dir, u64 dir_gen)
319062306a36Sopenharmony_ci{
319162306a36Sopenharmony_ci	int ret = 0;
319262306a36Sopenharmony_ci	int iter_ret = 0;
319362306a36Sopenharmony_ci	struct btrfs_root *root = sctx->parent_root;
319462306a36Sopenharmony_ci	struct btrfs_path *path;
319562306a36Sopenharmony_ci	struct btrfs_key key;
319662306a36Sopenharmony_ci	struct btrfs_key found_key;
319762306a36Sopenharmony_ci	struct btrfs_key loc;
319862306a36Sopenharmony_ci	struct btrfs_dir_item *di;
319962306a36Sopenharmony_ci	struct orphan_dir_info *odi = NULL;
320062306a36Sopenharmony_ci	u64 dir_high_seq_ino = 0;
320162306a36Sopenharmony_ci	u64 last_dir_index_offset = 0;
320262306a36Sopenharmony_ci
320362306a36Sopenharmony_ci	/*
320462306a36Sopenharmony_ci	 * Don't try to rmdir the top/root subvolume dir.
320562306a36Sopenharmony_ci	 */
320662306a36Sopenharmony_ci	if (dir == BTRFS_FIRST_FREE_OBJECTID)
320762306a36Sopenharmony_ci		return 0;
320862306a36Sopenharmony_ci
320962306a36Sopenharmony_ci	odi = get_orphan_dir_info(sctx, dir, dir_gen);
321062306a36Sopenharmony_ci	if (odi && sctx->cur_ino < odi->dir_high_seq_ino)
321162306a36Sopenharmony_ci		return 0;
321262306a36Sopenharmony_ci
321362306a36Sopenharmony_ci	path = alloc_path_for_send();
321462306a36Sopenharmony_ci	if (!path)
321562306a36Sopenharmony_ci		return -ENOMEM;
321662306a36Sopenharmony_ci
321762306a36Sopenharmony_ci	if (!odi) {
321862306a36Sopenharmony_ci		/*
321962306a36Sopenharmony_ci		 * Find the inode number associated with the last dir index
322062306a36Sopenharmony_ci		 * entry. This is very likely the inode with the highest number
322162306a36Sopenharmony_ci		 * of all inodes that have an entry in the directory. We can
322262306a36Sopenharmony_ci		 * then use it to avoid future calls to can_rmdir(), when
322362306a36Sopenharmony_ci		 * processing inodes with a lower number, from having to search
322462306a36Sopenharmony_ci		 * the parent root b+tree for dir index keys.
322562306a36Sopenharmony_ci		 */
322662306a36Sopenharmony_ci		key.objectid = dir;
322762306a36Sopenharmony_ci		key.type = BTRFS_DIR_INDEX_KEY;
322862306a36Sopenharmony_ci		key.offset = (u64)-1;
322962306a36Sopenharmony_ci
323062306a36Sopenharmony_ci		ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
323162306a36Sopenharmony_ci		if (ret < 0) {
323262306a36Sopenharmony_ci			goto out;
323362306a36Sopenharmony_ci		} else if (ret > 0) {
323462306a36Sopenharmony_ci			/* Can't happen, the root is never empty. */
323562306a36Sopenharmony_ci			ASSERT(path->slots[0] > 0);
323662306a36Sopenharmony_ci			if (WARN_ON(path->slots[0] == 0)) {
323762306a36Sopenharmony_ci				ret = -EUCLEAN;
323862306a36Sopenharmony_ci				goto out;
323962306a36Sopenharmony_ci			}
324062306a36Sopenharmony_ci			path->slots[0]--;
324162306a36Sopenharmony_ci		}
324262306a36Sopenharmony_ci
324362306a36Sopenharmony_ci		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
324462306a36Sopenharmony_ci		if (key.objectid != dir || key.type != BTRFS_DIR_INDEX_KEY) {
324562306a36Sopenharmony_ci			/* No index keys, dir can be removed. */
324662306a36Sopenharmony_ci			ret = 1;
324762306a36Sopenharmony_ci			goto out;
324862306a36Sopenharmony_ci		}
324962306a36Sopenharmony_ci
325062306a36Sopenharmony_ci		di = btrfs_item_ptr(path->nodes[0], path->slots[0],
325162306a36Sopenharmony_ci				    struct btrfs_dir_item);
325262306a36Sopenharmony_ci		btrfs_dir_item_key_to_cpu(path->nodes[0], di, &loc);
325362306a36Sopenharmony_ci		dir_high_seq_ino = loc.objectid;
325462306a36Sopenharmony_ci		if (sctx->cur_ino < dir_high_seq_ino) {
325562306a36Sopenharmony_ci			ret = 0;
325662306a36Sopenharmony_ci			goto out;
325762306a36Sopenharmony_ci		}
325862306a36Sopenharmony_ci
325962306a36Sopenharmony_ci		btrfs_release_path(path);
326062306a36Sopenharmony_ci	}
326162306a36Sopenharmony_ci
326262306a36Sopenharmony_ci	key.objectid = dir;
326362306a36Sopenharmony_ci	key.type = BTRFS_DIR_INDEX_KEY;
326462306a36Sopenharmony_ci	key.offset = (odi ? odi->last_dir_index_offset : 0);
326562306a36Sopenharmony_ci
326662306a36Sopenharmony_ci	btrfs_for_each_slot(root, &key, &found_key, path, iter_ret) {
326762306a36Sopenharmony_ci		struct waiting_dir_move *dm;
326862306a36Sopenharmony_ci
326962306a36Sopenharmony_ci		if (found_key.objectid != key.objectid ||
327062306a36Sopenharmony_ci		    found_key.type != key.type)
327162306a36Sopenharmony_ci			break;
327262306a36Sopenharmony_ci
327362306a36Sopenharmony_ci		di = btrfs_item_ptr(path->nodes[0], path->slots[0],
327462306a36Sopenharmony_ci				struct btrfs_dir_item);
327562306a36Sopenharmony_ci		btrfs_dir_item_key_to_cpu(path->nodes[0], di, &loc);
327662306a36Sopenharmony_ci
327762306a36Sopenharmony_ci		dir_high_seq_ino = max(dir_high_seq_ino, loc.objectid);
327862306a36Sopenharmony_ci		last_dir_index_offset = found_key.offset;
327962306a36Sopenharmony_ci
328062306a36Sopenharmony_ci		dm = get_waiting_dir_move(sctx, loc.objectid);
328162306a36Sopenharmony_ci		if (dm) {
328262306a36Sopenharmony_ci			dm->rmdir_ino = dir;
328362306a36Sopenharmony_ci			dm->rmdir_gen = dir_gen;
328462306a36Sopenharmony_ci			ret = 0;
328562306a36Sopenharmony_ci			goto out;
328662306a36Sopenharmony_ci		}
328762306a36Sopenharmony_ci
328862306a36Sopenharmony_ci		if (loc.objectid > sctx->cur_ino) {
328962306a36Sopenharmony_ci			ret = 0;
329062306a36Sopenharmony_ci			goto out;
329162306a36Sopenharmony_ci		}
329262306a36Sopenharmony_ci	}
329362306a36Sopenharmony_ci	if (iter_ret < 0) {
329462306a36Sopenharmony_ci		ret = iter_ret;
329562306a36Sopenharmony_ci		goto out;
329662306a36Sopenharmony_ci	}
329762306a36Sopenharmony_ci	free_orphan_dir_info(sctx, odi);
329862306a36Sopenharmony_ci
329962306a36Sopenharmony_ci	ret = 1;
330062306a36Sopenharmony_ci
330162306a36Sopenharmony_ciout:
330262306a36Sopenharmony_ci	btrfs_free_path(path);
330362306a36Sopenharmony_ci
330462306a36Sopenharmony_ci	if (ret)
330562306a36Sopenharmony_ci		return ret;
330662306a36Sopenharmony_ci
330762306a36Sopenharmony_ci	if (!odi) {
330862306a36Sopenharmony_ci		odi = add_orphan_dir_info(sctx, dir, dir_gen);
330962306a36Sopenharmony_ci		if (IS_ERR(odi))
331062306a36Sopenharmony_ci			return PTR_ERR(odi);
331162306a36Sopenharmony_ci
331262306a36Sopenharmony_ci		odi->gen = dir_gen;
331362306a36Sopenharmony_ci	}
331462306a36Sopenharmony_ci
331562306a36Sopenharmony_ci	odi->last_dir_index_offset = last_dir_index_offset;
331662306a36Sopenharmony_ci	odi->dir_high_seq_ino = max(odi->dir_high_seq_ino, dir_high_seq_ino);
331762306a36Sopenharmony_ci
331862306a36Sopenharmony_ci	return 0;
331962306a36Sopenharmony_ci}
332062306a36Sopenharmony_ci
332162306a36Sopenharmony_cistatic int is_waiting_for_move(struct send_ctx *sctx, u64 ino)
332262306a36Sopenharmony_ci{
332362306a36Sopenharmony_ci	struct waiting_dir_move *entry = get_waiting_dir_move(sctx, ino);
332462306a36Sopenharmony_ci
332562306a36Sopenharmony_ci	return entry != NULL;
332662306a36Sopenharmony_ci}
332762306a36Sopenharmony_ci
332862306a36Sopenharmony_cistatic int add_waiting_dir_move(struct send_ctx *sctx, u64 ino, bool orphanized)
332962306a36Sopenharmony_ci{
333062306a36Sopenharmony_ci	struct rb_node **p = &sctx->waiting_dir_moves.rb_node;
333162306a36Sopenharmony_ci	struct rb_node *parent = NULL;
333262306a36Sopenharmony_ci	struct waiting_dir_move *entry, *dm;
333362306a36Sopenharmony_ci
333462306a36Sopenharmony_ci	dm = kmalloc(sizeof(*dm), GFP_KERNEL);
333562306a36Sopenharmony_ci	if (!dm)
333662306a36Sopenharmony_ci		return -ENOMEM;
333762306a36Sopenharmony_ci	dm->ino = ino;
333862306a36Sopenharmony_ci	dm->rmdir_ino = 0;
333962306a36Sopenharmony_ci	dm->rmdir_gen = 0;
334062306a36Sopenharmony_ci	dm->orphanized = orphanized;
334162306a36Sopenharmony_ci
334262306a36Sopenharmony_ci	while (*p) {
334362306a36Sopenharmony_ci		parent = *p;
334462306a36Sopenharmony_ci		entry = rb_entry(parent, struct waiting_dir_move, node);
334562306a36Sopenharmony_ci		if (ino < entry->ino) {
334662306a36Sopenharmony_ci			p = &(*p)->rb_left;
334762306a36Sopenharmony_ci		} else if (ino > entry->ino) {
334862306a36Sopenharmony_ci			p = &(*p)->rb_right;
334962306a36Sopenharmony_ci		} else {
335062306a36Sopenharmony_ci			kfree(dm);
335162306a36Sopenharmony_ci			return -EEXIST;
335262306a36Sopenharmony_ci		}
335362306a36Sopenharmony_ci	}
335462306a36Sopenharmony_ci
335562306a36Sopenharmony_ci	rb_link_node(&dm->node, parent, p);
335662306a36Sopenharmony_ci	rb_insert_color(&dm->node, &sctx->waiting_dir_moves);
335762306a36Sopenharmony_ci	return 0;
335862306a36Sopenharmony_ci}
335962306a36Sopenharmony_ci
336062306a36Sopenharmony_cistatic struct waiting_dir_move *
336162306a36Sopenharmony_ciget_waiting_dir_move(struct send_ctx *sctx, u64 ino)
336262306a36Sopenharmony_ci{
336362306a36Sopenharmony_ci	struct rb_node *n = sctx->waiting_dir_moves.rb_node;
336462306a36Sopenharmony_ci	struct waiting_dir_move *entry;
336562306a36Sopenharmony_ci
336662306a36Sopenharmony_ci	while (n) {
336762306a36Sopenharmony_ci		entry = rb_entry(n, struct waiting_dir_move, node);
336862306a36Sopenharmony_ci		if (ino < entry->ino)
336962306a36Sopenharmony_ci			n = n->rb_left;
337062306a36Sopenharmony_ci		else if (ino > entry->ino)
337162306a36Sopenharmony_ci			n = n->rb_right;
337262306a36Sopenharmony_ci		else
337362306a36Sopenharmony_ci			return entry;
337462306a36Sopenharmony_ci	}
337562306a36Sopenharmony_ci	return NULL;
337662306a36Sopenharmony_ci}
337762306a36Sopenharmony_ci
337862306a36Sopenharmony_cistatic void free_waiting_dir_move(struct send_ctx *sctx,
337962306a36Sopenharmony_ci				  struct waiting_dir_move *dm)
338062306a36Sopenharmony_ci{
338162306a36Sopenharmony_ci	if (!dm)
338262306a36Sopenharmony_ci		return;
338362306a36Sopenharmony_ci	rb_erase(&dm->node, &sctx->waiting_dir_moves);
338462306a36Sopenharmony_ci	kfree(dm);
338562306a36Sopenharmony_ci}
338662306a36Sopenharmony_ci
338762306a36Sopenharmony_cistatic int add_pending_dir_move(struct send_ctx *sctx,
338862306a36Sopenharmony_ci				u64 ino,
338962306a36Sopenharmony_ci				u64 ino_gen,
339062306a36Sopenharmony_ci				u64 parent_ino,
339162306a36Sopenharmony_ci				struct list_head *new_refs,
339262306a36Sopenharmony_ci				struct list_head *deleted_refs,
339362306a36Sopenharmony_ci				const bool is_orphan)
339462306a36Sopenharmony_ci{
339562306a36Sopenharmony_ci	struct rb_node **p = &sctx->pending_dir_moves.rb_node;
339662306a36Sopenharmony_ci	struct rb_node *parent = NULL;
339762306a36Sopenharmony_ci	struct pending_dir_move *entry = NULL, *pm;
339862306a36Sopenharmony_ci	struct recorded_ref *cur;
339962306a36Sopenharmony_ci	int exists = 0;
340062306a36Sopenharmony_ci	int ret;
340162306a36Sopenharmony_ci
340262306a36Sopenharmony_ci	pm = kmalloc(sizeof(*pm), GFP_KERNEL);
340362306a36Sopenharmony_ci	if (!pm)
340462306a36Sopenharmony_ci		return -ENOMEM;
340562306a36Sopenharmony_ci	pm->parent_ino = parent_ino;
340662306a36Sopenharmony_ci	pm->ino = ino;
340762306a36Sopenharmony_ci	pm->gen = ino_gen;
340862306a36Sopenharmony_ci	INIT_LIST_HEAD(&pm->list);
340962306a36Sopenharmony_ci	INIT_LIST_HEAD(&pm->update_refs);
341062306a36Sopenharmony_ci	RB_CLEAR_NODE(&pm->node);
341162306a36Sopenharmony_ci
341262306a36Sopenharmony_ci	while (*p) {
341362306a36Sopenharmony_ci		parent = *p;
341462306a36Sopenharmony_ci		entry = rb_entry(parent, struct pending_dir_move, node);
341562306a36Sopenharmony_ci		if (parent_ino < entry->parent_ino) {
341662306a36Sopenharmony_ci			p = &(*p)->rb_left;
341762306a36Sopenharmony_ci		} else if (parent_ino > entry->parent_ino) {
341862306a36Sopenharmony_ci			p = &(*p)->rb_right;
341962306a36Sopenharmony_ci		} else {
342062306a36Sopenharmony_ci			exists = 1;
342162306a36Sopenharmony_ci			break;
342262306a36Sopenharmony_ci		}
342362306a36Sopenharmony_ci	}
342462306a36Sopenharmony_ci
342562306a36Sopenharmony_ci	list_for_each_entry(cur, deleted_refs, list) {
342662306a36Sopenharmony_ci		ret = dup_ref(cur, &pm->update_refs);
342762306a36Sopenharmony_ci		if (ret < 0)
342862306a36Sopenharmony_ci			goto out;
342962306a36Sopenharmony_ci	}
343062306a36Sopenharmony_ci	list_for_each_entry(cur, new_refs, list) {
343162306a36Sopenharmony_ci		ret = dup_ref(cur, &pm->update_refs);
343262306a36Sopenharmony_ci		if (ret < 0)
343362306a36Sopenharmony_ci			goto out;
343462306a36Sopenharmony_ci	}
343562306a36Sopenharmony_ci
343662306a36Sopenharmony_ci	ret = add_waiting_dir_move(sctx, pm->ino, is_orphan);
343762306a36Sopenharmony_ci	if (ret)
343862306a36Sopenharmony_ci		goto out;
343962306a36Sopenharmony_ci
344062306a36Sopenharmony_ci	if (exists) {
344162306a36Sopenharmony_ci		list_add_tail(&pm->list, &entry->list);
344262306a36Sopenharmony_ci	} else {
344362306a36Sopenharmony_ci		rb_link_node(&pm->node, parent, p);
344462306a36Sopenharmony_ci		rb_insert_color(&pm->node, &sctx->pending_dir_moves);
344562306a36Sopenharmony_ci	}
344662306a36Sopenharmony_ci	ret = 0;
344762306a36Sopenharmony_ciout:
344862306a36Sopenharmony_ci	if (ret) {
344962306a36Sopenharmony_ci		__free_recorded_refs(&pm->update_refs);
345062306a36Sopenharmony_ci		kfree(pm);
345162306a36Sopenharmony_ci	}
345262306a36Sopenharmony_ci	return ret;
345362306a36Sopenharmony_ci}
345462306a36Sopenharmony_ci
345562306a36Sopenharmony_cistatic struct pending_dir_move *get_pending_dir_moves(struct send_ctx *sctx,
345662306a36Sopenharmony_ci						      u64 parent_ino)
345762306a36Sopenharmony_ci{
345862306a36Sopenharmony_ci	struct rb_node *n = sctx->pending_dir_moves.rb_node;
345962306a36Sopenharmony_ci	struct pending_dir_move *entry;
346062306a36Sopenharmony_ci
346162306a36Sopenharmony_ci	while (n) {
346262306a36Sopenharmony_ci		entry = rb_entry(n, struct pending_dir_move, node);
346362306a36Sopenharmony_ci		if (parent_ino < entry->parent_ino)
346462306a36Sopenharmony_ci			n = n->rb_left;
346562306a36Sopenharmony_ci		else if (parent_ino > entry->parent_ino)
346662306a36Sopenharmony_ci			n = n->rb_right;
346762306a36Sopenharmony_ci		else
346862306a36Sopenharmony_ci			return entry;
346962306a36Sopenharmony_ci	}
347062306a36Sopenharmony_ci	return NULL;
347162306a36Sopenharmony_ci}
347262306a36Sopenharmony_ci
347362306a36Sopenharmony_cistatic int path_loop(struct send_ctx *sctx, struct fs_path *name,
347462306a36Sopenharmony_ci		     u64 ino, u64 gen, u64 *ancestor_ino)
347562306a36Sopenharmony_ci{
347662306a36Sopenharmony_ci	int ret = 0;
347762306a36Sopenharmony_ci	u64 parent_inode = 0;
347862306a36Sopenharmony_ci	u64 parent_gen = 0;
347962306a36Sopenharmony_ci	u64 start_ino = ino;
348062306a36Sopenharmony_ci
348162306a36Sopenharmony_ci	*ancestor_ino = 0;
348262306a36Sopenharmony_ci	while (ino != BTRFS_FIRST_FREE_OBJECTID) {
348362306a36Sopenharmony_ci		fs_path_reset(name);
348462306a36Sopenharmony_ci
348562306a36Sopenharmony_ci		if (is_waiting_for_rm(sctx, ino, gen))
348662306a36Sopenharmony_ci			break;
348762306a36Sopenharmony_ci		if (is_waiting_for_move(sctx, ino)) {
348862306a36Sopenharmony_ci			if (*ancestor_ino == 0)
348962306a36Sopenharmony_ci				*ancestor_ino = ino;
349062306a36Sopenharmony_ci			ret = get_first_ref(sctx->parent_root, ino,
349162306a36Sopenharmony_ci					    &parent_inode, &parent_gen, name);
349262306a36Sopenharmony_ci		} else {
349362306a36Sopenharmony_ci			ret = __get_cur_name_and_parent(sctx, ino, gen,
349462306a36Sopenharmony_ci							&parent_inode,
349562306a36Sopenharmony_ci							&parent_gen, name);
349662306a36Sopenharmony_ci			if (ret > 0) {
349762306a36Sopenharmony_ci				ret = 0;
349862306a36Sopenharmony_ci				break;
349962306a36Sopenharmony_ci			}
350062306a36Sopenharmony_ci		}
350162306a36Sopenharmony_ci		if (ret < 0)
350262306a36Sopenharmony_ci			break;
350362306a36Sopenharmony_ci		if (parent_inode == start_ino) {
350462306a36Sopenharmony_ci			ret = 1;
350562306a36Sopenharmony_ci			if (*ancestor_ino == 0)
350662306a36Sopenharmony_ci				*ancestor_ino = ino;
350762306a36Sopenharmony_ci			break;
350862306a36Sopenharmony_ci		}
350962306a36Sopenharmony_ci		ino = parent_inode;
351062306a36Sopenharmony_ci		gen = parent_gen;
351162306a36Sopenharmony_ci	}
351262306a36Sopenharmony_ci	return ret;
351362306a36Sopenharmony_ci}
351462306a36Sopenharmony_ci
351562306a36Sopenharmony_cistatic int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm)
351662306a36Sopenharmony_ci{
351762306a36Sopenharmony_ci	struct fs_path *from_path = NULL;
351862306a36Sopenharmony_ci	struct fs_path *to_path = NULL;
351962306a36Sopenharmony_ci	struct fs_path *name = NULL;
352062306a36Sopenharmony_ci	u64 orig_progress = sctx->send_progress;
352162306a36Sopenharmony_ci	struct recorded_ref *cur;
352262306a36Sopenharmony_ci	u64 parent_ino, parent_gen;
352362306a36Sopenharmony_ci	struct waiting_dir_move *dm = NULL;
352462306a36Sopenharmony_ci	u64 rmdir_ino = 0;
352562306a36Sopenharmony_ci	u64 rmdir_gen;
352662306a36Sopenharmony_ci	u64 ancestor;
352762306a36Sopenharmony_ci	bool is_orphan;
352862306a36Sopenharmony_ci	int ret;
352962306a36Sopenharmony_ci
353062306a36Sopenharmony_ci	name = fs_path_alloc();
353162306a36Sopenharmony_ci	from_path = fs_path_alloc();
353262306a36Sopenharmony_ci	if (!name || !from_path) {
353362306a36Sopenharmony_ci		ret = -ENOMEM;
353462306a36Sopenharmony_ci		goto out;
353562306a36Sopenharmony_ci	}
353662306a36Sopenharmony_ci
353762306a36Sopenharmony_ci	dm = get_waiting_dir_move(sctx, pm->ino);
353862306a36Sopenharmony_ci	ASSERT(dm);
353962306a36Sopenharmony_ci	rmdir_ino = dm->rmdir_ino;
354062306a36Sopenharmony_ci	rmdir_gen = dm->rmdir_gen;
354162306a36Sopenharmony_ci	is_orphan = dm->orphanized;
354262306a36Sopenharmony_ci	free_waiting_dir_move(sctx, dm);
354362306a36Sopenharmony_ci
354462306a36Sopenharmony_ci	if (is_orphan) {
354562306a36Sopenharmony_ci		ret = gen_unique_name(sctx, pm->ino,
354662306a36Sopenharmony_ci				      pm->gen, from_path);
354762306a36Sopenharmony_ci	} else {
354862306a36Sopenharmony_ci		ret = get_first_ref(sctx->parent_root, pm->ino,
354962306a36Sopenharmony_ci				    &parent_ino, &parent_gen, name);
355062306a36Sopenharmony_ci		if (ret < 0)
355162306a36Sopenharmony_ci			goto out;
355262306a36Sopenharmony_ci		ret = get_cur_path(sctx, parent_ino, parent_gen,
355362306a36Sopenharmony_ci				   from_path);
355462306a36Sopenharmony_ci		if (ret < 0)
355562306a36Sopenharmony_ci			goto out;
355662306a36Sopenharmony_ci		ret = fs_path_add_path(from_path, name);
355762306a36Sopenharmony_ci	}
355862306a36Sopenharmony_ci	if (ret < 0)
355962306a36Sopenharmony_ci		goto out;
356062306a36Sopenharmony_ci
356162306a36Sopenharmony_ci	sctx->send_progress = sctx->cur_ino + 1;
356262306a36Sopenharmony_ci	ret = path_loop(sctx, name, pm->ino, pm->gen, &ancestor);
356362306a36Sopenharmony_ci	if (ret < 0)
356462306a36Sopenharmony_ci		goto out;
356562306a36Sopenharmony_ci	if (ret) {
356662306a36Sopenharmony_ci		LIST_HEAD(deleted_refs);
356762306a36Sopenharmony_ci		ASSERT(ancestor > BTRFS_FIRST_FREE_OBJECTID);
356862306a36Sopenharmony_ci		ret = add_pending_dir_move(sctx, pm->ino, pm->gen, ancestor,
356962306a36Sopenharmony_ci					   &pm->update_refs, &deleted_refs,
357062306a36Sopenharmony_ci					   is_orphan);
357162306a36Sopenharmony_ci		if (ret < 0)
357262306a36Sopenharmony_ci			goto out;
357362306a36Sopenharmony_ci		if (rmdir_ino) {
357462306a36Sopenharmony_ci			dm = get_waiting_dir_move(sctx, pm->ino);
357562306a36Sopenharmony_ci			ASSERT(dm);
357662306a36Sopenharmony_ci			dm->rmdir_ino = rmdir_ino;
357762306a36Sopenharmony_ci			dm->rmdir_gen = rmdir_gen;
357862306a36Sopenharmony_ci		}
357962306a36Sopenharmony_ci		goto out;
358062306a36Sopenharmony_ci	}
358162306a36Sopenharmony_ci	fs_path_reset(name);
358262306a36Sopenharmony_ci	to_path = name;
358362306a36Sopenharmony_ci	name = NULL;
358462306a36Sopenharmony_ci	ret = get_cur_path(sctx, pm->ino, pm->gen, to_path);
358562306a36Sopenharmony_ci	if (ret < 0)
358662306a36Sopenharmony_ci		goto out;
358762306a36Sopenharmony_ci
358862306a36Sopenharmony_ci	ret = send_rename(sctx, from_path, to_path);
358962306a36Sopenharmony_ci	if (ret < 0)
359062306a36Sopenharmony_ci		goto out;
359162306a36Sopenharmony_ci
359262306a36Sopenharmony_ci	if (rmdir_ino) {
359362306a36Sopenharmony_ci		struct orphan_dir_info *odi;
359462306a36Sopenharmony_ci		u64 gen;
359562306a36Sopenharmony_ci
359662306a36Sopenharmony_ci		odi = get_orphan_dir_info(sctx, rmdir_ino, rmdir_gen);
359762306a36Sopenharmony_ci		if (!odi) {
359862306a36Sopenharmony_ci			/* already deleted */
359962306a36Sopenharmony_ci			goto finish;
360062306a36Sopenharmony_ci		}
360162306a36Sopenharmony_ci		gen = odi->gen;
360262306a36Sopenharmony_ci
360362306a36Sopenharmony_ci		ret = can_rmdir(sctx, rmdir_ino, gen);
360462306a36Sopenharmony_ci		if (ret < 0)
360562306a36Sopenharmony_ci			goto out;
360662306a36Sopenharmony_ci		if (!ret)
360762306a36Sopenharmony_ci			goto finish;
360862306a36Sopenharmony_ci
360962306a36Sopenharmony_ci		name = fs_path_alloc();
361062306a36Sopenharmony_ci		if (!name) {
361162306a36Sopenharmony_ci			ret = -ENOMEM;
361262306a36Sopenharmony_ci			goto out;
361362306a36Sopenharmony_ci		}
361462306a36Sopenharmony_ci		ret = get_cur_path(sctx, rmdir_ino, gen, name);
361562306a36Sopenharmony_ci		if (ret < 0)
361662306a36Sopenharmony_ci			goto out;
361762306a36Sopenharmony_ci		ret = send_rmdir(sctx, name);
361862306a36Sopenharmony_ci		if (ret < 0)
361962306a36Sopenharmony_ci			goto out;
362062306a36Sopenharmony_ci	}
362162306a36Sopenharmony_ci
362262306a36Sopenharmony_cifinish:
362362306a36Sopenharmony_ci	ret = cache_dir_utimes(sctx, pm->ino, pm->gen);
362462306a36Sopenharmony_ci	if (ret < 0)
362562306a36Sopenharmony_ci		goto out;
362662306a36Sopenharmony_ci
362762306a36Sopenharmony_ci	/*
362862306a36Sopenharmony_ci	 * After rename/move, need to update the utimes of both new parent(s)
362962306a36Sopenharmony_ci	 * and old parent(s).
363062306a36Sopenharmony_ci	 */
363162306a36Sopenharmony_ci	list_for_each_entry(cur, &pm->update_refs, list) {
363262306a36Sopenharmony_ci		/*
363362306a36Sopenharmony_ci		 * The parent inode might have been deleted in the send snapshot
363462306a36Sopenharmony_ci		 */
363562306a36Sopenharmony_ci		ret = get_inode_info(sctx->send_root, cur->dir, NULL);
363662306a36Sopenharmony_ci		if (ret == -ENOENT) {
363762306a36Sopenharmony_ci			ret = 0;
363862306a36Sopenharmony_ci			continue;
363962306a36Sopenharmony_ci		}
364062306a36Sopenharmony_ci		if (ret < 0)
364162306a36Sopenharmony_ci			goto out;
364262306a36Sopenharmony_ci
364362306a36Sopenharmony_ci		ret = cache_dir_utimes(sctx, cur->dir, cur->dir_gen);
364462306a36Sopenharmony_ci		if (ret < 0)
364562306a36Sopenharmony_ci			goto out;
364662306a36Sopenharmony_ci	}
364762306a36Sopenharmony_ci
364862306a36Sopenharmony_ciout:
364962306a36Sopenharmony_ci	fs_path_free(name);
365062306a36Sopenharmony_ci	fs_path_free(from_path);
365162306a36Sopenharmony_ci	fs_path_free(to_path);
365262306a36Sopenharmony_ci	sctx->send_progress = orig_progress;
365362306a36Sopenharmony_ci
365462306a36Sopenharmony_ci	return ret;
365562306a36Sopenharmony_ci}
365662306a36Sopenharmony_ci
365762306a36Sopenharmony_cistatic void free_pending_move(struct send_ctx *sctx, struct pending_dir_move *m)
365862306a36Sopenharmony_ci{
365962306a36Sopenharmony_ci	if (!list_empty(&m->list))
366062306a36Sopenharmony_ci		list_del(&m->list);
366162306a36Sopenharmony_ci	if (!RB_EMPTY_NODE(&m->node))
366262306a36Sopenharmony_ci		rb_erase(&m->node, &sctx->pending_dir_moves);
366362306a36Sopenharmony_ci	__free_recorded_refs(&m->update_refs);
366462306a36Sopenharmony_ci	kfree(m);
366562306a36Sopenharmony_ci}
366662306a36Sopenharmony_ci
366762306a36Sopenharmony_cistatic void tail_append_pending_moves(struct send_ctx *sctx,
366862306a36Sopenharmony_ci				      struct pending_dir_move *moves,
366962306a36Sopenharmony_ci				      struct list_head *stack)
367062306a36Sopenharmony_ci{
367162306a36Sopenharmony_ci	if (list_empty(&moves->list)) {
367262306a36Sopenharmony_ci		list_add_tail(&moves->list, stack);
367362306a36Sopenharmony_ci	} else {
367462306a36Sopenharmony_ci		LIST_HEAD(list);
367562306a36Sopenharmony_ci		list_splice_init(&moves->list, &list);
367662306a36Sopenharmony_ci		list_add_tail(&moves->list, stack);
367762306a36Sopenharmony_ci		list_splice_tail(&list, stack);
367862306a36Sopenharmony_ci	}
367962306a36Sopenharmony_ci	if (!RB_EMPTY_NODE(&moves->node)) {
368062306a36Sopenharmony_ci		rb_erase(&moves->node, &sctx->pending_dir_moves);
368162306a36Sopenharmony_ci		RB_CLEAR_NODE(&moves->node);
368262306a36Sopenharmony_ci	}
368362306a36Sopenharmony_ci}
368462306a36Sopenharmony_ci
368562306a36Sopenharmony_cistatic int apply_children_dir_moves(struct send_ctx *sctx)
368662306a36Sopenharmony_ci{
368762306a36Sopenharmony_ci	struct pending_dir_move *pm;
368862306a36Sopenharmony_ci	LIST_HEAD(stack);
368962306a36Sopenharmony_ci	u64 parent_ino = sctx->cur_ino;
369062306a36Sopenharmony_ci	int ret = 0;
369162306a36Sopenharmony_ci
369262306a36Sopenharmony_ci	pm = get_pending_dir_moves(sctx, parent_ino);
369362306a36Sopenharmony_ci	if (!pm)
369462306a36Sopenharmony_ci		return 0;
369562306a36Sopenharmony_ci
369662306a36Sopenharmony_ci	tail_append_pending_moves(sctx, pm, &stack);
369762306a36Sopenharmony_ci
369862306a36Sopenharmony_ci	while (!list_empty(&stack)) {
369962306a36Sopenharmony_ci		pm = list_first_entry(&stack, struct pending_dir_move, list);
370062306a36Sopenharmony_ci		parent_ino = pm->ino;
370162306a36Sopenharmony_ci		ret = apply_dir_move(sctx, pm);
370262306a36Sopenharmony_ci		free_pending_move(sctx, pm);
370362306a36Sopenharmony_ci		if (ret)
370462306a36Sopenharmony_ci			goto out;
370562306a36Sopenharmony_ci		pm = get_pending_dir_moves(sctx, parent_ino);
370662306a36Sopenharmony_ci		if (pm)
370762306a36Sopenharmony_ci			tail_append_pending_moves(sctx, pm, &stack);
370862306a36Sopenharmony_ci	}
370962306a36Sopenharmony_ci	return 0;
371062306a36Sopenharmony_ci
371162306a36Sopenharmony_ciout:
371262306a36Sopenharmony_ci	while (!list_empty(&stack)) {
371362306a36Sopenharmony_ci		pm = list_first_entry(&stack, struct pending_dir_move, list);
371462306a36Sopenharmony_ci		free_pending_move(sctx, pm);
371562306a36Sopenharmony_ci	}
371662306a36Sopenharmony_ci	return ret;
371762306a36Sopenharmony_ci}
371862306a36Sopenharmony_ci
371962306a36Sopenharmony_ci/*
372062306a36Sopenharmony_ci * We might need to delay a directory rename even when no ancestor directory
372162306a36Sopenharmony_ci * (in the send root) with a higher inode number than ours (sctx->cur_ino) was
372262306a36Sopenharmony_ci * renamed. This happens when we rename a directory to the old name (the name
372362306a36Sopenharmony_ci * in the parent root) of some other unrelated directory that got its rename
372462306a36Sopenharmony_ci * delayed due to some ancestor with higher number that got renamed.
372562306a36Sopenharmony_ci *
372662306a36Sopenharmony_ci * Example:
372762306a36Sopenharmony_ci *
372862306a36Sopenharmony_ci * Parent snapshot:
372962306a36Sopenharmony_ci * .                                       (ino 256)
373062306a36Sopenharmony_ci * |---- a/                                (ino 257)
373162306a36Sopenharmony_ci * |     |---- file                        (ino 260)
373262306a36Sopenharmony_ci * |
373362306a36Sopenharmony_ci * |---- b/                                (ino 258)
373462306a36Sopenharmony_ci * |---- c/                                (ino 259)
373562306a36Sopenharmony_ci *
373662306a36Sopenharmony_ci * Send snapshot:
373762306a36Sopenharmony_ci * .                                       (ino 256)
373862306a36Sopenharmony_ci * |---- a/                                (ino 258)
373962306a36Sopenharmony_ci * |---- x/                                (ino 259)
374062306a36Sopenharmony_ci *       |---- y/                          (ino 257)
374162306a36Sopenharmony_ci *             |----- file                 (ino 260)
374262306a36Sopenharmony_ci *
374362306a36Sopenharmony_ci * Here we can not rename 258 from 'b' to 'a' without the rename of inode 257
374462306a36Sopenharmony_ci * from 'a' to 'x/y' happening first, which in turn depends on the rename of
374562306a36Sopenharmony_ci * inode 259 from 'c' to 'x'. So the order of rename commands the send stream
374662306a36Sopenharmony_ci * must issue is:
374762306a36Sopenharmony_ci *
374862306a36Sopenharmony_ci * 1 - rename 259 from 'c' to 'x'
374962306a36Sopenharmony_ci * 2 - rename 257 from 'a' to 'x/y'
375062306a36Sopenharmony_ci * 3 - rename 258 from 'b' to 'a'
375162306a36Sopenharmony_ci *
375262306a36Sopenharmony_ci * Returns 1 if the rename of sctx->cur_ino needs to be delayed, 0 if it can
375362306a36Sopenharmony_ci * be done right away and < 0 on error.
375462306a36Sopenharmony_ci */
375562306a36Sopenharmony_cistatic int wait_for_dest_dir_move(struct send_ctx *sctx,
375662306a36Sopenharmony_ci				  struct recorded_ref *parent_ref,
375762306a36Sopenharmony_ci				  const bool is_orphan)
375862306a36Sopenharmony_ci{
375962306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->parent_root->fs_info;
376062306a36Sopenharmony_ci	struct btrfs_path *path;
376162306a36Sopenharmony_ci	struct btrfs_key key;
376262306a36Sopenharmony_ci	struct btrfs_key di_key;
376362306a36Sopenharmony_ci	struct btrfs_dir_item *di;
376462306a36Sopenharmony_ci	u64 left_gen;
376562306a36Sopenharmony_ci	u64 right_gen;
376662306a36Sopenharmony_ci	int ret = 0;
376762306a36Sopenharmony_ci	struct waiting_dir_move *wdm;
376862306a36Sopenharmony_ci
376962306a36Sopenharmony_ci	if (RB_EMPTY_ROOT(&sctx->waiting_dir_moves))
377062306a36Sopenharmony_ci		return 0;
377162306a36Sopenharmony_ci
377262306a36Sopenharmony_ci	path = alloc_path_for_send();
377362306a36Sopenharmony_ci	if (!path)
377462306a36Sopenharmony_ci		return -ENOMEM;
377562306a36Sopenharmony_ci
377662306a36Sopenharmony_ci	key.objectid = parent_ref->dir;
377762306a36Sopenharmony_ci	key.type = BTRFS_DIR_ITEM_KEY;
377862306a36Sopenharmony_ci	key.offset = btrfs_name_hash(parent_ref->name, parent_ref->name_len);
377962306a36Sopenharmony_ci
378062306a36Sopenharmony_ci	ret = btrfs_search_slot(NULL, sctx->parent_root, &key, path, 0, 0);
378162306a36Sopenharmony_ci	if (ret < 0) {
378262306a36Sopenharmony_ci		goto out;
378362306a36Sopenharmony_ci	} else if (ret > 0) {
378462306a36Sopenharmony_ci		ret = 0;
378562306a36Sopenharmony_ci		goto out;
378662306a36Sopenharmony_ci	}
378762306a36Sopenharmony_ci
378862306a36Sopenharmony_ci	di = btrfs_match_dir_item_name(fs_info, path, parent_ref->name,
378962306a36Sopenharmony_ci				       parent_ref->name_len);
379062306a36Sopenharmony_ci	if (!di) {
379162306a36Sopenharmony_ci		ret = 0;
379262306a36Sopenharmony_ci		goto out;
379362306a36Sopenharmony_ci	}
379462306a36Sopenharmony_ci	/*
379562306a36Sopenharmony_ci	 * di_key.objectid has the number of the inode that has a dentry in the
379662306a36Sopenharmony_ci	 * parent directory with the same name that sctx->cur_ino is being
379762306a36Sopenharmony_ci	 * renamed to. We need to check if that inode is in the send root as
379862306a36Sopenharmony_ci	 * well and if it is currently marked as an inode with a pending rename,
379962306a36Sopenharmony_ci	 * if it is, we need to delay the rename of sctx->cur_ino as well, so
380062306a36Sopenharmony_ci	 * that it happens after that other inode is renamed.
380162306a36Sopenharmony_ci	 */
380262306a36Sopenharmony_ci	btrfs_dir_item_key_to_cpu(path->nodes[0], di, &di_key);
380362306a36Sopenharmony_ci	if (di_key.type != BTRFS_INODE_ITEM_KEY) {
380462306a36Sopenharmony_ci		ret = 0;
380562306a36Sopenharmony_ci		goto out;
380662306a36Sopenharmony_ci	}
380762306a36Sopenharmony_ci
380862306a36Sopenharmony_ci	ret = get_inode_gen(sctx->parent_root, di_key.objectid, &left_gen);
380962306a36Sopenharmony_ci	if (ret < 0)
381062306a36Sopenharmony_ci		goto out;
381162306a36Sopenharmony_ci	ret = get_inode_gen(sctx->send_root, di_key.objectid, &right_gen);
381262306a36Sopenharmony_ci	if (ret < 0) {
381362306a36Sopenharmony_ci		if (ret == -ENOENT)
381462306a36Sopenharmony_ci			ret = 0;
381562306a36Sopenharmony_ci		goto out;
381662306a36Sopenharmony_ci	}
381762306a36Sopenharmony_ci
381862306a36Sopenharmony_ci	/* Different inode, no need to delay the rename of sctx->cur_ino */
381962306a36Sopenharmony_ci	if (right_gen != left_gen) {
382062306a36Sopenharmony_ci		ret = 0;
382162306a36Sopenharmony_ci		goto out;
382262306a36Sopenharmony_ci	}
382362306a36Sopenharmony_ci
382462306a36Sopenharmony_ci	wdm = get_waiting_dir_move(sctx, di_key.objectid);
382562306a36Sopenharmony_ci	if (wdm && !wdm->orphanized) {
382662306a36Sopenharmony_ci		ret = add_pending_dir_move(sctx,
382762306a36Sopenharmony_ci					   sctx->cur_ino,
382862306a36Sopenharmony_ci					   sctx->cur_inode_gen,
382962306a36Sopenharmony_ci					   di_key.objectid,
383062306a36Sopenharmony_ci					   &sctx->new_refs,
383162306a36Sopenharmony_ci					   &sctx->deleted_refs,
383262306a36Sopenharmony_ci					   is_orphan);
383362306a36Sopenharmony_ci		if (!ret)
383462306a36Sopenharmony_ci			ret = 1;
383562306a36Sopenharmony_ci	}
383662306a36Sopenharmony_ciout:
383762306a36Sopenharmony_ci	btrfs_free_path(path);
383862306a36Sopenharmony_ci	return ret;
383962306a36Sopenharmony_ci}
384062306a36Sopenharmony_ci
384162306a36Sopenharmony_ci/*
384262306a36Sopenharmony_ci * Check if inode ino2, or any of its ancestors, is inode ino1.
384362306a36Sopenharmony_ci * Return 1 if true, 0 if false and < 0 on error.
384462306a36Sopenharmony_ci */
384562306a36Sopenharmony_cistatic int check_ino_in_path(struct btrfs_root *root,
384662306a36Sopenharmony_ci			     const u64 ino1,
384762306a36Sopenharmony_ci			     const u64 ino1_gen,
384862306a36Sopenharmony_ci			     const u64 ino2,
384962306a36Sopenharmony_ci			     const u64 ino2_gen,
385062306a36Sopenharmony_ci			     struct fs_path *fs_path)
385162306a36Sopenharmony_ci{
385262306a36Sopenharmony_ci	u64 ino = ino2;
385362306a36Sopenharmony_ci
385462306a36Sopenharmony_ci	if (ino1 == ino2)
385562306a36Sopenharmony_ci		return ino1_gen == ino2_gen;
385662306a36Sopenharmony_ci
385762306a36Sopenharmony_ci	while (ino > BTRFS_FIRST_FREE_OBJECTID) {
385862306a36Sopenharmony_ci		u64 parent;
385962306a36Sopenharmony_ci		u64 parent_gen;
386062306a36Sopenharmony_ci		int ret;
386162306a36Sopenharmony_ci
386262306a36Sopenharmony_ci		fs_path_reset(fs_path);
386362306a36Sopenharmony_ci		ret = get_first_ref(root, ino, &parent, &parent_gen, fs_path);
386462306a36Sopenharmony_ci		if (ret < 0)
386562306a36Sopenharmony_ci			return ret;
386662306a36Sopenharmony_ci		if (parent == ino1)
386762306a36Sopenharmony_ci			return parent_gen == ino1_gen;
386862306a36Sopenharmony_ci		ino = parent;
386962306a36Sopenharmony_ci	}
387062306a36Sopenharmony_ci	return 0;
387162306a36Sopenharmony_ci}
387262306a36Sopenharmony_ci
387362306a36Sopenharmony_ci/*
387462306a36Sopenharmony_ci * Check if inode ino1 is an ancestor of inode ino2 in the given root for any
387562306a36Sopenharmony_ci * possible path (in case ino2 is not a directory and has multiple hard links).
387662306a36Sopenharmony_ci * Return 1 if true, 0 if false and < 0 on error.
387762306a36Sopenharmony_ci */
387862306a36Sopenharmony_cistatic int is_ancestor(struct btrfs_root *root,
387962306a36Sopenharmony_ci		       const u64 ino1,
388062306a36Sopenharmony_ci		       const u64 ino1_gen,
388162306a36Sopenharmony_ci		       const u64 ino2,
388262306a36Sopenharmony_ci		       struct fs_path *fs_path)
388362306a36Sopenharmony_ci{
388462306a36Sopenharmony_ci	bool free_fs_path = false;
388562306a36Sopenharmony_ci	int ret = 0;
388662306a36Sopenharmony_ci	int iter_ret = 0;
388762306a36Sopenharmony_ci	struct btrfs_path *path = NULL;
388862306a36Sopenharmony_ci	struct btrfs_key key;
388962306a36Sopenharmony_ci
389062306a36Sopenharmony_ci	if (!fs_path) {
389162306a36Sopenharmony_ci		fs_path = fs_path_alloc();
389262306a36Sopenharmony_ci		if (!fs_path)
389362306a36Sopenharmony_ci			return -ENOMEM;
389462306a36Sopenharmony_ci		free_fs_path = true;
389562306a36Sopenharmony_ci	}
389662306a36Sopenharmony_ci
389762306a36Sopenharmony_ci	path = alloc_path_for_send();
389862306a36Sopenharmony_ci	if (!path) {
389962306a36Sopenharmony_ci		ret = -ENOMEM;
390062306a36Sopenharmony_ci		goto out;
390162306a36Sopenharmony_ci	}
390262306a36Sopenharmony_ci
390362306a36Sopenharmony_ci	key.objectid = ino2;
390462306a36Sopenharmony_ci	key.type = BTRFS_INODE_REF_KEY;
390562306a36Sopenharmony_ci	key.offset = 0;
390662306a36Sopenharmony_ci
390762306a36Sopenharmony_ci	btrfs_for_each_slot(root, &key, &key, path, iter_ret) {
390862306a36Sopenharmony_ci		struct extent_buffer *leaf = path->nodes[0];
390962306a36Sopenharmony_ci		int slot = path->slots[0];
391062306a36Sopenharmony_ci		u32 cur_offset = 0;
391162306a36Sopenharmony_ci		u32 item_size;
391262306a36Sopenharmony_ci
391362306a36Sopenharmony_ci		if (key.objectid != ino2)
391462306a36Sopenharmony_ci			break;
391562306a36Sopenharmony_ci		if (key.type != BTRFS_INODE_REF_KEY &&
391662306a36Sopenharmony_ci		    key.type != BTRFS_INODE_EXTREF_KEY)
391762306a36Sopenharmony_ci			break;
391862306a36Sopenharmony_ci
391962306a36Sopenharmony_ci		item_size = btrfs_item_size(leaf, slot);
392062306a36Sopenharmony_ci		while (cur_offset < item_size) {
392162306a36Sopenharmony_ci			u64 parent;
392262306a36Sopenharmony_ci			u64 parent_gen;
392362306a36Sopenharmony_ci
392462306a36Sopenharmony_ci			if (key.type == BTRFS_INODE_EXTREF_KEY) {
392562306a36Sopenharmony_ci				unsigned long ptr;
392662306a36Sopenharmony_ci				struct btrfs_inode_extref *extref;
392762306a36Sopenharmony_ci
392862306a36Sopenharmony_ci				ptr = btrfs_item_ptr_offset(leaf, slot);
392962306a36Sopenharmony_ci				extref = (struct btrfs_inode_extref *)
393062306a36Sopenharmony_ci					(ptr + cur_offset);
393162306a36Sopenharmony_ci				parent = btrfs_inode_extref_parent(leaf,
393262306a36Sopenharmony_ci								   extref);
393362306a36Sopenharmony_ci				cur_offset += sizeof(*extref);
393462306a36Sopenharmony_ci				cur_offset += btrfs_inode_extref_name_len(leaf,
393562306a36Sopenharmony_ci								  extref);
393662306a36Sopenharmony_ci			} else {
393762306a36Sopenharmony_ci				parent = key.offset;
393862306a36Sopenharmony_ci				cur_offset = item_size;
393962306a36Sopenharmony_ci			}
394062306a36Sopenharmony_ci
394162306a36Sopenharmony_ci			ret = get_inode_gen(root, parent, &parent_gen);
394262306a36Sopenharmony_ci			if (ret < 0)
394362306a36Sopenharmony_ci				goto out;
394462306a36Sopenharmony_ci			ret = check_ino_in_path(root, ino1, ino1_gen,
394562306a36Sopenharmony_ci						parent, parent_gen, fs_path);
394662306a36Sopenharmony_ci			if (ret)
394762306a36Sopenharmony_ci				goto out;
394862306a36Sopenharmony_ci		}
394962306a36Sopenharmony_ci	}
395062306a36Sopenharmony_ci	ret = 0;
395162306a36Sopenharmony_ci	if (iter_ret < 0)
395262306a36Sopenharmony_ci		ret = iter_ret;
395362306a36Sopenharmony_ci
395462306a36Sopenharmony_ciout:
395562306a36Sopenharmony_ci	btrfs_free_path(path);
395662306a36Sopenharmony_ci	if (free_fs_path)
395762306a36Sopenharmony_ci		fs_path_free(fs_path);
395862306a36Sopenharmony_ci	return ret;
395962306a36Sopenharmony_ci}
396062306a36Sopenharmony_ci
396162306a36Sopenharmony_cistatic int wait_for_parent_move(struct send_ctx *sctx,
396262306a36Sopenharmony_ci				struct recorded_ref *parent_ref,
396362306a36Sopenharmony_ci				const bool is_orphan)
396462306a36Sopenharmony_ci{
396562306a36Sopenharmony_ci	int ret = 0;
396662306a36Sopenharmony_ci	u64 ino = parent_ref->dir;
396762306a36Sopenharmony_ci	u64 ino_gen = parent_ref->dir_gen;
396862306a36Sopenharmony_ci	u64 parent_ino_before, parent_ino_after;
396962306a36Sopenharmony_ci	struct fs_path *path_before = NULL;
397062306a36Sopenharmony_ci	struct fs_path *path_after = NULL;
397162306a36Sopenharmony_ci	int len1, len2;
397262306a36Sopenharmony_ci
397362306a36Sopenharmony_ci	path_after = fs_path_alloc();
397462306a36Sopenharmony_ci	path_before = fs_path_alloc();
397562306a36Sopenharmony_ci	if (!path_after || !path_before) {
397662306a36Sopenharmony_ci		ret = -ENOMEM;
397762306a36Sopenharmony_ci		goto out;
397862306a36Sopenharmony_ci	}
397962306a36Sopenharmony_ci
398062306a36Sopenharmony_ci	/*
398162306a36Sopenharmony_ci	 * Our current directory inode may not yet be renamed/moved because some
398262306a36Sopenharmony_ci	 * ancestor (immediate or not) has to be renamed/moved first. So find if
398362306a36Sopenharmony_ci	 * such ancestor exists and make sure our own rename/move happens after
398462306a36Sopenharmony_ci	 * that ancestor is processed to avoid path build infinite loops (done
398562306a36Sopenharmony_ci	 * at get_cur_path()).
398662306a36Sopenharmony_ci	 */
398762306a36Sopenharmony_ci	while (ino > BTRFS_FIRST_FREE_OBJECTID) {
398862306a36Sopenharmony_ci		u64 parent_ino_after_gen;
398962306a36Sopenharmony_ci
399062306a36Sopenharmony_ci		if (is_waiting_for_move(sctx, ino)) {
399162306a36Sopenharmony_ci			/*
399262306a36Sopenharmony_ci			 * If the current inode is an ancestor of ino in the
399362306a36Sopenharmony_ci			 * parent root, we need to delay the rename of the
399462306a36Sopenharmony_ci			 * current inode, otherwise don't delayed the rename
399562306a36Sopenharmony_ci			 * because we can end up with a circular dependency
399662306a36Sopenharmony_ci			 * of renames, resulting in some directories never
399762306a36Sopenharmony_ci			 * getting the respective rename operations issued in
399862306a36Sopenharmony_ci			 * the send stream or getting into infinite path build
399962306a36Sopenharmony_ci			 * loops.
400062306a36Sopenharmony_ci			 */
400162306a36Sopenharmony_ci			ret = is_ancestor(sctx->parent_root,
400262306a36Sopenharmony_ci					  sctx->cur_ino, sctx->cur_inode_gen,
400362306a36Sopenharmony_ci					  ino, path_before);
400462306a36Sopenharmony_ci			if (ret)
400562306a36Sopenharmony_ci				break;
400662306a36Sopenharmony_ci		}
400762306a36Sopenharmony_ci
400862306a36Sopenharmony_ci		fs_path_reset(path_before);
400962306a36Sopenharmony_ci		fs_path_reset(path_after);
401062306a36Sopenharmony_ci
401162306a36Sopenharmony_ci		ret = get_first_ref(sctx->send_root, ino, &parent_ino_after,
401262306a36Sopenharmony_ci				    &parent_ino_after_gen, path_after);
401362306a36Sopenharmony_ci		if (ret < 0)
401462306a36Sopenharmony_ci			goto out;
401562306a36Sopenharmony_ci		ret = get_first_ref(sctx->parent_root, ino, &parent_ino_before,
401662306a36Sopenharmony_ci				    NULL, path_before);
401762306a36Sopenharmony_ci		if (ret < 0 && ret != -ENOENT) {
401862306a36Sopenharmony_ci			goto out;
401962306a36Sopenharmony_ci		} else if (ret == -ENOENT) {
402062306a36Sopenharmony_ci			ret = 0;
402162306a36Sopenharmony_ci			break;
402262306a36Sopenharmony_ci		}
402362306a36Sopenharmony_ci
402462306a36Sopenharmony_ci		len1 = fs_path_len(path_before);
402562306a36Sopenharmony_ci		len2 = fs_path_len(path_after);
402662306a36Sopenharmony_ci		if (ino > sctx->cur_ino &&
402762306a36Sopenharmony_ci		    (parent_ino_before != parent_ino_after || len1 != len2 ||
402862306a36Sopenharmony_ci		     memcmp(path_before->start, path_after->start, len1))) {
402962306a36Sopenharmony_ci			u64 parent_ino_gen;
403062306a36Sopenharmony_ci
403162306a36Sopenharmony_ci			ret = get_inode_gen(sctx->parent_root, ino, &parent_ino_gen);
403262306a36Sopenharmony_ci			if (ret < 0)
403362306a36Sopenharmony_ci				goto out;
403462306a36Sopenharmony_ci			if (ino_gen == parent_ino_gen) {
403562306a36Sopenharmony_ci				ret = 1;
403662306a36Sopenharmony_ci				break;
403762306a36Sopenharmony_ci			}
403862306a36Sopenharmony_ci		}
403962306a36Sopenharmony_ci		ino = parent_ino_after;
404062306a36Sopenharmony_ci		ino_gen = parent_ino_after_gen;
404162306a36Sopenharmony_ci	}
404262306a36Sopenharmony_ci
404362306a36Sopenharmony_ciout:
404462306a36Sopenharmony_ci	fs_path_free(path_before);
404562306a36Sopenharmony_ci	fs_path_free(path_after);
404662306a36Sopenharmony_ci
404762306a36Sopenharmony_ci	if (ret == 1) {
404862306a36Sopenharmony_ci		ret = add_pending_dir_move(sctx,
404962306a36Sopenharmony_ci					   sctx->cur_ino,
405062306a36Sopenharmony_ci					   sctx->cur_inode_gen,
405162306a36Sopenharmony_ci					   ino,
405262306a36Sopenharmony_ci					   &sctx->new_refs,
405362306a36Sopenharmony_ci					   &sctx->deleted_refs,
405462306a36Sopenharmony_ci					   is_orphan);
405562306a36Sopenharmony_ci		if (!ret)
405662306a36Sopenharmony_ci			ret = 1;
405762306a36Sopenharmony_ci	}
405862306a36Sopenharmony_ci
405962306a36Sopenharmony_ci	return ret;
406062306a36Sopenharmony_ci}
406162306a36Sopenharmony_ci
406262306a36Sopenharmony_cistatic int update_ref_path(struct send_ctx *sctx, struct recorded_ref *ref)
406362306a36Sopenharmony_ci{
406462306a36Sopenharmony_ci	int ret;
406562306a36Sopenharmony_ci	struct fs_path *new_path;
406662306a36Sopenharmony_ci
406762306a36Sopenharmony_ci	/*
406862306a36Sopenharmony_ci	 * Our reference's name member points to its full_path member string, so
406962306a36Sopenharmony_ci	 * we use here a new path.
407062306a36Sopenharmony_ci	 */
407162306a36Sopenharmony_ci	new_path = fs_path_alloc();
407262306a36Sopenharmony_ci	if (!new_path)
407362306a36Sopenharmony_ci		return -ENOMEM;
407462306a36Sopenharmony_ci
407562306a36Sopenharmony_ci	ret = get_cur_path(sctx, ref->dir, ref->dir_gen, new_path);
407662306a36Sopenharmony_ci	if (ret < 0) {
407762306a36Sopenharmony_ci		fs_path_free(new_path);
407862306a36Sopenharmony_ci		return ret;
407962306a36Sopenharmony_ci	}
408062306a36Sopenharmony_ci	ret = fs_path_add(new_path, ref->name, ref->name_len);
408162306a36Sopenharmony_ci	if (ret < 0) {
408262306a36Sopenharmony_ci		fs_path_free(new_path);
408362306a36Sopenharmony_ci		return ret;
408462306a36Sopenharmony_ci	}
408562306a36Sopenharmony_ci
408662306a36Sopenharmony_ci	fs_path_free(ref->full_path);
408762306a36Sopenharmony_ci	set_ref_path(ref, new_path);
408862306a36Sopenharmony_ci
408962306a36Sopenharmony_ci	return 0;
409062306a36Sopenharmony_ci}
409162306a36Sopenharmony_ci
409262306a36Sopenharmony_ci/*
409362306a36Sopenharmony_ci * When processing the new references for an inode we may orphanize an existing
409462306a36Sopenharmony_ci * directory inode because its old name conflicts with one of the new references
409562306a36Sopenharmony_ci * of the current inode. Later, when processing another new reference of our
409662306a36Sopenharmony_ci * inode, we might need to orphanize another inode, but the path we have in the
409762306a36Sopenharmony_ci * reference reflects the pre-orphanization name of the directory we previously
409862306a36Sopenharmony_ci * orphanized. For example:
409962306a36Sopenharmony_ci *
410062306a36Sopenharmony_ci * parent snapshot looks like:
410162306a36Sopenharmony_ci *
410262306a36Sopenharmony_ci * .                                     (ino 256)
410362306a36Sopenharmony_ci * |----- f1                             (ino 257)
410462306a36Sopenharmony_ci * |----- f2                             (ino 258)
410562306a36Sopenharmony_ci * |----- d1/                            (ino 259)
410662306a36Sopenharmony_ci *        |----- d2/                     (ino 260)
410762306a36Sopenharmony_ci *
410862306a36Sopenharmony_ci * send snapshot looks like:
410962306a36Sopenharmony_ci *
411062306a36Sopenharmony_ci * .                                     (ino 256)
411162306a36Sopenharmony_ci * |----- d1                             (ino 258)
411262306a36Sopenharmony_ci * |----- f2/                            (ino 259)
411362306a36Sopenharmony_ci *        |----- f2_link/                (ino 260)
411462306a36Sopenharmony_ci *        |       |----- f1              (ino 257)
411562306a36Sopenharmony_ci *        |
411662306a36Sopenharmony_ci *        |----- d2                      (ino 258)
411762306a36Sopenharmony_ci *
411862306a36Sopenharmony_ci * When processing inode 257 we compute the name for inode 259 as "d1", and we
411962306a36Sopenharmony_ci * cache it in the name cache. Later when we start processing inode 258, when
412062306a36Sopenharmony_ci * collecting all its new references we set a full path of "d1/d2" for its new
412162306a36Sopenharmony_ci * reference with name "d2". When we start processing the new references we
412262306a36Sopenharmony_ci * start by processing the new reference with name "d1", and this results in
412362306a36Sopenharmony_ci * orphanizing inode 259, since its old reference causes a conflict. Then we
412462306a36Sopenharmony_ci * move on the next new reference, with name "d2", and we find out we must
412562306a36Sopenharmony_ci * orphanize inode 260, as its old reference conflicts with ours - but for the
412662306a36Sopenharmony_ci * orphanization we use a source path corresponding to the path we stored in the
412762306a36Sopenharmony_ci * new reference, which is "d1/d2" and not "o259-6-0/d2" - this makes the
412862306a36Sopenharmony_ci * receiver fail since the path component "d1/" no longer exists, it was renamed
412962306a36Sopenharmony_ci * to "o259-6-0/" when processing the previous new reference. So in this case we
413062306a36Sopenharmony_ci * must recompute the path in the new reference and use it for the new
413162306a36Sopenharmony_ci * orphanization operation.
413262306a36Sopenharmony_ci */
413362306a36Sopenharmony_cistatic int refresh_ref_path(struct send_ctx *sctx, struct recorded_ref *ref)
413462306a36Sopenharmony_ci{
413562306a36Sopenharmony_ci	char *name;
413662306a36Sopenharmony_ci	int ret;
413762306a36Sopenharmony_ci
413862306a36Sopenharmony_ci	name = kmemdup(ref->name, ref->name_len, GFP_KERNEL);
413962306a36Sopenharmony_ci	if (!name)
414062306a36Sopenharmony_ci		return -ENOMEM;
414162306a36Sopenharmony_ci
414262306a36Sopenharmony_ci	fs_path_reset(ref->full_path);
414362306a36Sopenharmony_ci	ret = get_cur_path(sctx, ref->dir, ref->dir_gen, ref->full_path);
414462306a36Sopenharmony_ci	if (ret < 0)
414562306a36Sopenharmony_ci		goto out;
414662306a36Sopenharmony_ci
414762306a36Sopenharmony_ci	ret = fs_path_add(ref->full_path, name, ref->name_len);
414862306a36Sopenharmony_ci	if (ret < 0)
414962306a36Sopenharmony_ci		goto out;
415062306a36Sopenharmony_ci
415162306a36Sopenharmony_ci	/* Update the reference's base name pointer. */
415262306a36Sopenharmony_ci	set_ref_path(ref, ref->full_path);
415362306a36Sopenharmony_ciout:
415462306a36Sopenharmony_ci	kfree(name);
415562306a36Sopenharmony_ci	return ret;
415662306a36Sopenharmony_ci}
415762306a36Sopenharmony_ci
415862306a36Sopenharmony_ci/*
415962306a36Sopenharmony_ci * This does all the move/link/unlink/rmdir magic.
416062306a36Sopenharmony_ci */
416162306a36Sopenharmony_cistatic int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
416262306a36Sopenharmony_ci{
416362306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
416462306a36Sopenharmony_ci	int ret = 0;
416562306a36Sopenharmony_ci	struct recorded_ref *cur;
416662306a36Sopenharmony_ci	struct recorded_ref *cur2;
416762306a36Sopenharmony_ci	LIST_HEAD(check_dirs);
416862306a36Sopenharmony_ci	struct fs_path *valid_path = NULL;
416962306a36Sopenharmony_ci	u64 ow_inode = 0;
417062306a36Sopenharmony_ci	u64 ow_gen;
417162306a36Sopenharmony_ci	u64 ow_mode;
417262306a36Sopenharmony_ci	int did_overwrite = 0;
417362306a36Sopenharmony_ci	int is_orphan = 0;
417462306a36Sopenharmony_ci	u64 last_dir_ino_rm = 0;
417562306a36Sopenharmony_ci	bool can_rename = true;
417662306a36Sopenharmony_ci	bool orphanized_dir = false;
417762306a36Sopenharmony_ci	bool orphanized_ancestor = false;
417862306a36Sopenharmony_ci
417962306a36Sopenharmony_ci	btrfs_debug(fs_info, "process_recorded_refs %llu", sctx->cur_ino);
418062306a36Sopenharmony_ci
418162306a36Sopenharmony_ci	/*
418262306a36Sopenharmony_ci	 * This should never happen as the root dir always has the same ref
418362306a36Sopenharmony_ci	 * which is always '..'
418462306a36Sopenharmony_ci	 */
418562306a36Sopenharmony_ci	BUG_ON(sctx->cur_ino <= BTRFS_FIRST_FREE_OBJECTID);
418662306a36Sopenharmony_ci
418762306a36Sopenharmony_ci	valid_path = fs_path_alloc();
418862306a36Sopenharmony_ci	if (!valid_path) {
418962306a36Sopenharmony_ci		ret = -ENOMEM;
419062306a36Sopenharmony_ci		goto out;
419162306a36Sopenharmony_ci	}
419262306a36Sopenharmony_ci
419362306a36Sopenharmony_ci	/*
419462306a36Sopenharmony_ci	 * First, check if the first ref of the current inode was overwritten
419562306a36Sopenharmony_ci	 * before. If yes, we know that the current inode was already orphanized
419662306a36Sopenharmony_ci	 * and thus use the orphan name. If not, we can use get_cur_path to
419762306a36Sopenharmony_ci	 * get the path of the first ref as it would like while receiving at
419862306a36Sopenharmony_ci	 * this point in time.
419962306a36Sopenharmony_ci	 * New inodes are always orphan at the beginning, so force to use the
420062306a36Sopenharmony_ci	 * orphan name in this case.
420162306a36Sopenharmony_ci	 * The first ref is stored in valid_path and will be updated if it
420262306a36Sopenharmony_ci	 * gets moved around.
420362306a36Sopenharmony_ci	 */
420462306a36Sopenharmony_ci	if (!sctx->cur_inode_new) {
420562306a36Sopenharmony_ci		ret = did_overwrite_first_ref(sctx, sctx->cur_ino,
420662306a36Sopenharmony_ci				sctx->cur_inode_gen);
420762306a36Sopenharmony_ci		if (ret < 0)
420862306a36Sopenharmony_ci			goto out;
420962306a36Sopenharmony_ci		if (ret)
421062306a36Sopenharmony_ci			did_overwrite = 1;
421162306a36Sopenharmony_ci	}
421262306a36Sopenharmony_ci	if (sctx->cur_inode_new || did_overwrite) {
421362306a36Sopenharmony_ci		ret = gen_unique_name(sctx, sctx->cur_ino,
421462306a36Sopenharmony_ci				sctx->cur_inode_gen, valid_path);
421562306a36Sopenharmony_ci		if (ret < 0)
421662306a36Sopenharmony_ci			goto out;
421762306a36Sopenharmony_ci		is_orphan = 1;
421862306a36Sopenharmony_ci	} else {
421962306a36Sopenharmony_ci		ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen,
422062306a36Sopenharmony_ci				valid_path);
422162306a36Sopenharmony_ci		if (ret < 0)
422262306a36Sopenharmony_ci			goto out;
422362306a36Sopenharmony_ci	}
422462306a36Sopenharmony_ci
422562306a36Sopenharmony_ci	/*
422662306a36Sopenharmony_ci	 * Before doing any rename and link operations, do a first pass on the
422762306a36Sopenharmony_ci	 * new references to orphanize any unprocessed inodes that may have a
422862306a36Sopenharmony_ci	 * reference that conflicts with one of the new references of the current
422962306a36Sopenharmony_ci	 * inode. This needs to happen first because a new reference may conflict
423062306a36Sopenharmony_ci	 * with the old reference of a parent directory, so we must make sure
423162306a36Sopenharmony_ci	 * that the path used for link and rename commands don't use an
423262306a36Sopenharmony_ci	 * orphanized name when an ancestor was not yet orphanized.
423362306a36Sopenharmony_ci	 *
423462306a36Sopenharmony_ci	 * Example:
423562306a36Sopenharmony_ci	 *
423662306a36Sopenharmony_ci	 * Parent snapshot:
423762306a36Sopenharmony_ci	 *
423862306a36Sopenharmony_ci	 * .                                                      (ino 256)
423962306a36Sopenharmony_ci	 * |----- testdir/                                        (ino 259)
424062306a36Sopenharmony_ci	 * |          |----- a                                    (ino 257)
424162306a36Sopenharmony_ci	 * |
424262306a36Sopenharmony_ci	 * |----- b                                               (ino 258)
424362306a36Sopenharmony_ci	 *
424462306a36Sopenharmony_ci	 * Send snapshot:
424562306a36Sopenharmony_ci	 *
424662306a36Sopenharmony_ci	 * .                                                      (ino 256)
424762306a36Sopenharmony_ci	 * |----- testdir_2/                                      (ino 259)
424862306a36Sopenharmony_ci	 * |          |----- a                                    (ino 260)
424962306a36Sopenharmony_ci	 * |
425062306a36Sopenharmony_ci	 * |----- testdir                                         (ino 257)
425162306a36Sopenharmony_ci	 * |----- b                                               (ino 257)
425262306a36Sopenharmony_ci	 * |----- b2                                              (ino 258)
425362306a36Sopenharmony_ci	 *
425462306a36Sopenharmony_ci	 * Processing the new reference for inode 257 with name "b" may happen
425562306a36Sopenharmony_ci	 * before processing the new reference with name "testdir". If so, we
425662306a36Sopenharmony_ci	 * must make sure that by the time we send a link command to create the
425762306a36Sopenharmony_ci	 * hard link "b", inode 259 was already orphanized, since the generated
425862306a36Sopenharmony_ci	 * path in "valid_path" already contains the orphanized name for 259.
425962306a36Sopenharmony_ci	 * We are processing inode 257, so only later when processing 259 we do
426062306a36Sopenharmony_ci	 * the rename operation to change its temporary (orphanized) name to
426162306a36Sopenharmony_ci	 * "testdir_2".
426262306a36Sopenharmony_ci	 */
426362306a36Sopenharmony_ci	list_for_each_entry(cur, &sctx->new_refs, list) {
426462306a36Sopenharmony_ci		ret = get_cur_inode_state(sctx, cur->dir, cur->dir_gen, NULL, NULL);
426562306a36Sopenharmony_ci		if (ret < 0)
426662306a36Sopenharmony_ci			goto out;
426762306a36Sopenharmony_ci		if (ret == inode_state_will_create)
426862306a36Sopenharmony_ci			continue;
426962306a36Sopenharmony_ci
427062306a36Sopenharmony_ci		/*
427162306a36Sopenharmony_ci		 * Check if this new ref would overwrite the first ref of another
427262306a36Sopenharmony_ci		 * unprocessed inode. If yes, orphanize the overwritten inode.
427362306a36Sopenharmony_ci		 * If we find an overwritten ref that is not the first ref,
427462306a36Sopenharmony_ci		 * simply unlink it.
427562306a36Sopenharmony_ci		 */
427662306a36Sopenharmony_ci		ret = will_overwrite_ref(sctx, cur->dir, cur->dir_gen,
427762306a36Sopenharmony_ci				cur->name, cur->name_len,
427862306a36Sopenharmony_ci				&ow_inode, &ow_gen, &ow_mode);
427962306a36Sopenharmony_ci		if (ret < 0)
428062306a36Sopenharmony_ci			goto out;
428162306a36Sopenharmony_ci		if (ret) {
428262306a36Sopenharmony_ci			ret = is_first_ref(sctx->parent_root,
428362306a36Sopenharmony_ci					   ow_inode, cur->dir, cur->name,
428462306a36Sopenharmony_ci					   cur->name_len);
428562306a36Sopenharmony_ci			if (ret < 0)
428662306a36Sopenharmony_ci				goto out;
428762306a36Sopenharmony_ci			if (ret) {
428862306a36Sopenharmony_ci				struct name_cache_entry *nce;
428962306a36Sopenharmony_ci				struct waiting_dir_move *wdm;
429062306a36Sopenharmony_ci
429162306a36Sopenharmony_ci				if (orphanized_dir) {
429262306a36Sopenharmony_ci					ret = refresh_ref_path(sctx, cur);
429362306a36Sopenharmony_ci					if (ret < 0)
429462306a36Sopenharmony_ci						goto out;
429562306a36Sopenharmony_ci				}
429662306a36Sopenharmony_ci
429762306a36Sopenharmony_ci				ret = orphanize_inode(sctx, ow_inode, ow_gen,
429862306a36Sopenharmony_ci						cur->full_path);
429962306a36Sopenharmony_ci				if (ret < 0)
430062306a36Sopenharmony_ci					goto out;
430162306a36Sopenharmony_ci				if (S_ISDIR(ow_mode))
430262306a36Sopenharmony_ci					orphanized_dir = true;
430362306a36Sopenharmony_ci
430462306a36Sopenharmony_ci				/*
430562306a36Sopenharmony_ci				 * If ow_inode has its rename operation delayed
430662306a36Sopenharmony_ci				 * make sure that its orphanized name is used in
430762306a36Sopenharmony_ci				 * the source path when performing its rename
430862306a36Sopenharmony_ci				 * operation.
430962306a36Sopenharmony_ci				 */
431062306a36Sopenharmony_ci				wdm = get_waiting_dir_move(sctx, ow_inode);
431162306a36Sopenharmony_ci				if (wdm)
431262306a36Sopenharmony_ci					wdm->orphanized = true;
431362306a36Sopenharmony_ci
431462306a36Sopenharmony_ci				/*
431562306a36Sopenharmony_ci				 * Make sure we clear our orphanized inode's
431662306a36Sopenharmony_ci				 * name from the name cache. This is because the
431762306a36Sopenharmony_ci				 * inode ow_inode might be an ancestor of some
431862306a36Sopenharmony_ci				 * other inode that will be orphanized as well
431962306a36Sopenharmony_ci				 * later and has an inode number greater than
432062306a36Sopenharmony_ci				 * sctx->send_progress. We need to prevent
432162306a36Sopenharmony_ci				 * future name lookups from using the old name
432262306a36Sopenharmony_ci				 * and get instead the orphan name.
432362306a36Sopenharmony_ci				 */
432462306a36Sopenharmony_ci				nce = name_cache_search(sctx, ow_inode, ow_gen);
432562306a36Sopenharmony_ci				if (nce)
432662306a36Sopenharmony_ci					btrfs_lru_cache_remove(&sctx->name_cache,
432762306a36Sopenharmony_ci							       &nce->entry);
432862306a36Sopenharmony_ci
432962306a36Sopenharmony_ci				/*
433062306a36Sopenharmony_ci				 * ow_inode might currently be an ancestor of
433162306a36Sopenharmony_ci				 * cur_ino, therefore compute valid_path (the
433262306a36Sopenharmony_ci				 * current path of cur_ino) again because it
433362306a36Sopenharmony_ci				 * might contain the pre-orphanization name of
433462306a36Sopenharmony_ci				 * ow_inode, which is no longer valid.
433562306a36Sopenharmony_ci				 */
433662306a36Sopenharmony_ci				ret = is_ancestor(sctx->parent_root,
433762306a36Sopenharmony_ci						  ow_inode, ow_gen,
433862306a36Sopenharmony_ci						  sctx->cur_ino, NULL);
433962306a36Sopenharmony_ci				if (ret > 0) {
434062306a36Sopenharmony_ci					orphanized_ancestor = true;
434162306a36Sopenharmony_ci					fs_path_reset(valid_path);
434262306a36Sopenharmony_ci					ret = get_cur_path(sctx, sctx->cur_ino,
434362306a36Sopenharmony_ci							   sctx->cur_inode_gen,
434462306a36Sopenharmony_ci							   valid_path);
434562306a36Sopenharmony_ci				}
434662306a36Sopenharmony_ci				if (ret < 0)
434762306a36Sopenharmony_ci					goto out;
434862306a36Sopenharmony_ci			} else {
434962306a36Sopenharmony_ci				/*
435062306a36Sopenharmony_ci				 * If we previously orphanized a directory that
435162306a36Sopenharmony_ci				 * collided with a new reference that we already
435262306a36Sopenharmony_ci				 * processed, recompute the current path because
435362306a36Sopenharmony_ci				 * that directory may be part of the path.
435462306a36Sopenharmony_ci				 */
435562306a36Sopenharmony_ci				if (orphanized_dir) {
435662306a36Sopenharmony_ci					ret = refresh_ref_path(sctx, cur);
435762306a36Sopenharmony_ci					if (ret < 0)
435862306a36Sopenharmony_ci						goto out;
435962306a36Sopenharmony_ci				}
436062306a36Sopenharmony_ci				ret = send_unlink(sctx, cur->full_path);
436162306a36Sopenharmony_ci				if (ret < 0)
436262306a36Sopenharmony_ci					goto out;
436362306a36Sopenharmony_ci			}
436462306a36Sopenharmony_ci		}
436562306a36Sopenharmony_ci
436662306a36Sopenharmony_ci	}
436762306a36Sopenharmony_ci
436862306a36Sopenharmony_ci	list_for_each_entry(cur, &sctx->new_refs, list) {
436962306a36Sopenharmony_ci		/*
437062306a36Sopenharmony_ci		 * We may have refs where the parent directory does not exist
437162306a36Sopenharmony_ci		 * yet. This happens if the parent directories inum is higher
437262306a36Sopenharmony_ci		 * than the current inum. To handle this case, we create the
437362306a36Sopenharmony_ci		 * parent directory out of order. But we need to check if this
437462306a36Sopenharmony_ci		 * did already happen before due to other refs in the same dir.
437562306a36Sopenharmony_ci		 */
437662306a36Sopenharmony_ci		ret = get_cur_inode_state(sctx, cur->dir, cur->dir_gen, NULL, NULL);
437762306a36Sopenharmony_ci		if (ret < 0)
437862306a36Sopenharmony_ci			goto out;
437962306a36Sopenharmony_ci		if (ret == inode_state_will_create) {
438062306a36Sopenharmony_ci			ret = 0;
438162306a36Sopenharmony_ci			/*
438262306a36Sopenharmony_ci			 * First check if any of the current inodes refs did
438362306a36Sopenharmony_ci			 * already create the dir.
438462306a36Sopenharmony_ci			 */
438562306a36Sopenharmony_ci			list_for_each_entry(cur2, &sctx->new_refs, list) {
438662306a36Sopenharmony_ci				if (cur == cur2)
438762306a36Sopenharmony_ci					break;
438862306a36Sopenharmony_ci				if (cur2->dir == cur->dir) {
438962306a36Sopenharmony_ci					ret = 1;
439062306a36Sopenharmony_ci					break;
439162306a36Sopenharmony_ci				}
439262306a36Sopenharmony_ci			}
439362306a36Sopenharmony_ci
439462306a36Sopenharmony_ci			/*
439562306a36Sopenharmony_ci			 * If that did not happen, check if a previous inode
439662306a36Sopenharmony_ci			 * did already create the dir.
439762306a36Sopenharmony_ci			 */
439862306a36Sopenharmony_ci			if (!ret)
439962306a36Sopenharmony_ci				ret = did_create_dir(sctx, cur->dir);
440062306a36Sopenharmony_ci			if (ret < 0)
440162306a36Sopenharmony_ci				goto out;
440262306a36Sopenharmony_ci			if (!ret) {
440362306a36Sopenharmony_ci				ret = send_create_inode(sctx, cur->dir);
440462306a36Sopenharmony_ci				if (ret < 0)
440562306a36Sopenharmony_ci					goto out;
440662306a36Sopenharmony_ci				cache_dir_created(sctx, cur->dir);
440762306a36Sopenharmony_ci			}
440862306a36Sopenharmony_ci		}
440962306a36Sopenharmony_ci
441062306a36Sopenharmony_ci		if (S_ISDIR(sctx->cur_inode_mode) && sctx->parent_root) {
441162306a36Sopenharmony_ci			ret = wait_for_dest_dir_move(sctx, cur, is_orphan);
441262306a36Sopenharmony_ci			if (ret < 0)
441362306a36Sopenharmony_ci				goto out;
441462306a36Sopenharmony_ci			if (ret == 1) {
441562306a36Sopenharmony_ci				can_rename = false;
441662306a36Sopenharmony_ci				*pending_move = 1;
441762306a36Sopenharmony_ci			}
441862306a36Sopenharmony_ci		}
441962306a36Sopenharmony_ci
442062306a36Sopenharmony_ci		if (S_ISDIR(sctx->cur_inode_mode) && sctx->parent_root &&
442162306a36Sopenharmony_ci		    can_rename) {
442262306a36Sopenharmony_ci			ret = wait_for_parent_move(sctx, cur, is_orphan);
442362306a36Sopenharmony_ci			if (ret < 0)
442462306a36Sopenharmony_ci				goto out;
442562306a36Sopenharmony_ci			if (ret == 1) {
442662306a36Sopenharmony_ci				can_rename = false;
442762306a36Sopenharmony_ci				*pending_move = 1;
442862306a36Sopenharmony_ci			}
442962306a36Sopenharmony_ci		}
443062306a36Sopenharmony_ci
443162306a36Sopenharmony_ci		/*
443262306a36Sopenharmony_ci		 * link/move the ref to the new place. If we have an orphan
443362306a36Sopenharmony_ci		 * inode, move it and update valid_path. If not, link or move
443462306a36Sopenharmony_ci		 * it depending on the inode mode.
443562306a36Sopenharmony_ci		 */
443662306a36Sopenharmony_ci		if (is_orphan && can_rename) {
443762306a36Sopenharmony_ci			ret = send_rename(sctx, valid_path, cur->full_path);
443862306a36Sopenharmony_ci			if (ret < 0)
443962306a36Sopenharmony_ci				goto out;
444062306a36Sopenharmony_ci			is_orphan = 0;
444162306a36Sopenharmony_ci			ret = fs_path_copy(valid_path, cur->full_path);
444262306a36Sopenharmony_ci			if (ret < 0)
444362306a36Sopenharmony_ci				goto out;
444462306a36Sopenharmony_ci		} else if (can_rename) {
444562306a36Sopenharmony_ci			if (S_ISDIR(sctx->cur_inode_mode)) {
444662306a36Sopenharmony_ci				/*
444762306a36Sopenharmony_ci				 * Dirs can't be linked, so move it. For moved
444862306a36Sopenharmony_ci				 * dirs, we always have one new and one deleted
444962306a36Sopenharmony_ci				 * ref. The deleted ref is ignored later.
445062306a36Sopenharmony_ci				 */
445162306a36Sopenharmony_ci				ret = send_rename(sctx, valid_path,
445262306a36Sopenharmony_ci						  cur->full_path);
445362306a36Sopenharmony_ci				if (!ret)
445462306a36Sopenharmony_ci					ret = fs_path_copy(valid_path,
445562306a36Sopenharmony_ci							   cur->full_path);
445662306a36Sopenharmony_ci				if (ret < 0)
445762306a36Sopenharmony_ci					goto out;
445862306a36Sopenharmony_ci			} else {
445962306a36Sopenharmony_ci				/*
446062306a36Sopenharmony_ci				 * We might have previously orphanized an inode
446162306a36Sopenharmony_ci				 * which is an ancestor of our current inode,
446262306a36Sopenharmony_ci				 * so our reference's full path, which was
446362306a36Sopenharmony_ci				 * computed before any such orphanizations, must
446462306a36Sopenharmony_ci				 * be updated.
446562306a36Sopenharmony_ci				 */
446662306a36Sopenharmony_ci				if (orphanized_dir) {
446762306a36Sopenharmony_ci					ret = update_ref_path(sctx, cur);
446862306a36Sopenharmony_ci					if (ret < 0)
446962306a36Sopenharmony_ci						goto out;
447062306a36Sopenharmony_ci				}
447162306a36Sopenharmony_ci				ret = send_link(sctx, cur->full_path,
447262306a36Sopenharmony_ci						valid_path);
447362306a36Sopenharmony_ci				if (ret < 0)
447462306a36Sopenharmony_ci					goto out;
447562306a36Sopenharmony_ci			}
447662306a36Sopenharmony_ci		}
447762306a36Sopenharmony_ci		ret = dup_ref(cur, &check_dirs);
447862306a36Sopenharmony_ci		if (ret < 0)
447962306a36Sopenharmony_ci			goto out;
448062306a36Sopenharmony_ci	}
448162306a36Sopenharmony_ci
448262306a36Sopenharmony_ci	if (S_ISDIR(sctx->cur_inode_mode) && sctx->cur_inode_deleted) {
448362306a36Sopenharmony_ci		/*
448462306a36Sopenharmony_ci		 * Check if we can already rmdir the directory. If not,
448562306a36Sopenharmony_ci		 * orphanize it. For every dir item inside that gets deleted
448662306a36Sopenharmony_ci		 * later, we do this check again and rmdir it then if possible.
448762306a36Sopenharmony_ci		 * See the use of check_dirs for more details.
448862306a36Sopenharmony_ci		 */
448962306a36Sopenharmony_ci		ret = can_rmdir(sctx, sctx->cur_ino, sctx->cur_inode_gen);
449062306a36Sopenharmony_ci		if (ret < 0)
449162306a36Sopenharmony_ci			goto out;
449262306a36Sopenharmony_ci		if (ret) {
449362306a36Sopenharmony_ci			ret = send_rmdir(sctx, valid_path);
449462306a36Sopenharmony_ci			if (ret < 0)
449562306a36Sopenharmony_ci				goto out;
449662306a36Sopenharmony_ci		} else if (!is_orphan) {
449762306a36Sopenharmony_ci			ret = orphanize_inode(sctx, sctx->cur_ino,
449862306a36Sopenharmony_ci					sctx->cur_inode_gen, valid_path);
449962306a36Sopenharmony_ci			if (ret < 0)
450062306a36Sopenharmony_ci				goto out;
450162306a36Sopenharmony_ci			is_orphan = 1;
450262306a36Sopenharmony_ci		}
450362306a36Sopenharmony_ci
450462306a36Sopenharmony_ci		list_for_each_entry(cur, &sctx->deleted_refs, list) {
450562306a36Sopenharmony_ci			ret = dup_ref(cur, &check_dirs);
450662306a36Sopenharmony_ci			if (ret < 0)
450762306a36Sopenharmony_ci				goto out;
450862306a36Sopenharmony_ci		}
450962306a36Sopenharmony_ci	} else if (S_ISDIR(sctx->cur_inode_mode) &&
451062306a36Sopenharmony_ci		   !list_empty(&sctx->deleted_refs)) {
451162306a36Sopenharmony_ci		/*
451262306a36Sopenharmony_ci		 * We have a moved dir. Add the old parent to check_dirs
451362306a36Sopenharmony_ci		 */
451462306a36Sopenharmony_ci		cur = list_entry(sctx->deleted_refs.next, struct recorded_ref,
451562306a36Sopenharmony_ci				list);
451662306a36Sopenharmony_ci		ret = dup_ref(cur, &check_dirs);
451762306a36Sopenharmony_ci		if (ret < 0)
451862306a36Sopenharmony_ci			goto out;
451962306a36Sopenharmony_ci	} else if (!S_ISDIR(sctx->cur_inode_mode)) {
452062306a36Sopenharmony_ci		/*
452162306a36Sopenharmony_ci		 * We have a non dir inode. Go through all deleted refs and
452262306a36Sopenharmony_ci		 * unlink them if they were not already overwritten by other
452362306a36Sopenharmony_ci		 * inodes.
452462306a36Sopenharmony_ci		 */
452562306a36Sopenharmony_ci		list_for_each_entry(cur, &sctx->deleted_refs, list) {
452662306a36Sopenharmony_ci			ret = did_overwrite_ref(sctx, cur->dir, cur->dir_gen,
452762306a36Sopenharmony_ci					sctx->cur_ino, sctx->cur_inode_gen,
452862306a36Sopenharmony_ci					cur->name, cur->name_len);
452962306a36Sopenharmony_ci			if (ret < 0)
453062306a36Sopenharmony_ci				goto out;
453162306a36Sopenharmony_ci			if (!ret) {
453262306a36Sopenharmony_ci				/*
453362306a36Sopenharmony_ci				 * If we orphanized any ancestor before, we need
453462306a36Sopenharmony_ci				 * to recompute the full path for deleted names,
453562306a36Sopenharmony_ci				 * since any such path was computed before we
453662306a36Sopenharmony_ci				 * processed any references and orphanized any
453762306a36Sopenharmony_ci				 * ancestor inode.
453862306a36Sopenharmony_ci				 */
453962306a36Sopenharmony_ci				if (orphanized_ancestor) {
454062306a36Sopenharmony_ci					ret = update_ref_path(sctx, cur);
454162306a36Sopenharmony_ci					if (ret < 0)
454262306a36Sopenharmony_ci						goto out;
454362306a36Sopenharmony_ci				}
454462306a36Sopenharmony_ci				ret = send_unlink(sctx, cur->full_path);
454562306a36Sopenharmony_ci				if (ret < 0)
454662306a36Sopenharmony_ci					goto out;
454762306a36Sopenharmony_ci			}
454862306a36Sopenharmony_ci			ret = dup_ref(cur, &check_dirs);
454962306a36Sopenharmony_ci			if (ret < 0)
455062306a36Sopenharmony_ci				goto out;
455162306a36Sopenharmony_ci		}
455262306a36Sopenharmony_ci		/*
455362306a36Sopenharmony_ci		 * If the inode is still orphan, unlink the orphan. This may
455462306a36Sopenharmony_ci		 * happen when a previous inode did overwrite the first ref
455562306a36Sopenharmony_ci		 * of this inode and no new refs were added for the current
455662306a36Sopenharmony_ci		 * inode. Unlinking does not mean that the inode is deleted in
455762306a36Sopenharmony_ci		 * all cases. There may still be links to this inode in other
455862306a36Sopenharmony_ci		 * places.
455962306a36Sopenharmony_ci		 */
456062306a36Sopenharmony_ci		if (is_orphan) {
456162306a36Sopenharmony_ci			ret = send_unlink(sctx, valid_path);
456262306a36Sopenharmony_ci			if (ret < 0)
456362306a36Sopenharmony_ci				goto out;
456462306a36Sopenharmony_ci		}
456562306a36Sopenharmony_ci	}
456662306a36Sopenharmony_ci
456762306a36Sopenharmony_ci	/*
456862306a36Sopenharmony_ci	 * We did collect all parent dirs where cur_inode was once located. We
456962306a36Sopenharmony_ci	 * now go through all these dirs and check if they are pending for
457062306a36Sopenharmony_ci	 * deletion and if it's finally possible to perform the rmdir now.
457162306a36Sopenharmony_ci	 * We also update the inode stats of the parent dirs here.
457262306a36Sopenharmony_ci	 */
457362306a36Sopenharmony_ci	list_for_each_entry(cur, &check_dirs, list) {
457462306a36Sopenharmony_ci		/*
457562306a36Sopenharmony_ci		 * In case we had refs into dirs that were not processed yet,
457662306a36Sopenharmony_ci		 * we don't need to do the utime and rmdir logic for these dirs.
457762306a36Sopenharmony_ci		 * The dir will be processed later.
457862306a36Sopenharmony_ci		 */
457962306a36Sopenharmony_ci		if (cur->dir > sctx->cur_ino)
458062306a36Sopenharmony_ci			continue;
458162306a36Sopenharmony_ci
458262306a36Sopenharmony_ci		ret = get_cur_inode_state(sctx, cur->dir, cur->dir_gen, NULL, NULL);
458362306a36Sopenharmony_ci		if (ret < 0)
458462306a36Sopenharmony_ci			goto out;
458562306a36Sopenharmony_ci
458662306a36Sopenharmony_ci		if (ret == inode_state_did_create ||
458762306a36Sopenharmony_ci		    ret == inode_state_no_change) {
458862306a36Sopenharmony_ci			ret = cache_dir_utimes(sctx, cur->dir, cur->dir_gen);
458962306a36Sopenharmony_ci			if (ret < 0)
459062306a36Sopenharmony_ci				goto out;
459162306a36Sopenharmony_ci		} else if (ret == inode_state_did_delete &&
459262306a36Sopenharmony_ci			   cur->dir != last_dir_ino_rm) {
459362306a36Sopenharmony_ci			ret = can_rmdir(sctx, cur->dir, cur->dir_gen);
459462306a36Sopenharmony_ci			if (ret < 0)
459562306a36Sopenharmony_ci				goto out;
459662306a36Sopenharmony_ci			if (ret) {
459762306a36Sopenharmony_ci				ret = get_cur_path(sctx, cur->dir,
459862306a36Sopenharmony_ci						   cur->dir_gen, valid_path);
459962306a36Sopenharmony_ci				if (ret < 0)
460062306a36Sopenharmony_ci					goto out;
460162306a36Sopenharmony_ci				ret = send_rmdir(sctx, valid_path);
460262306a36Sopenharmony_ci				if (ret < 0)
460362306a36Sopenharmony_ci					goto out;
460462306a36Sopenharmony_ci				last_dir_ino_rm = cur->dir;
460562306a36Sopenharmony_ci			}
460662306a36Sopenharmony_ci		}
460762306a36Sopenharmony_ci	}
460862306a36Sopenharmony_ci
460962306a36Sopenharmony_ci	ret = 0;
461062306a36Sopenharmony_ci
461162306a36Sopenharmony_ciout:
461262306a36Sopenharmony_ci	__free_recorded_refs(&check_dirs);
461362306a36Sopenharmony_ci	free_recorded_refs(sctx);
461462306a36Sopenharmony_ci	fs_path_free(valid_path);
461562306a36Sopenharmony_ci	return ret;
461662306a36Sopenharmony_ci}
461762306a36Sopenharmony_ci
461862306a36Sopenharmony_cistatic int rbtree_ref_comp(const void *k, const struct rb_node *node)
461962306a36Sopenharmony_ci{
462062306a36Sopenharmony_ci	const struct recorded_ref *data = k;
462162306a36Sopenharmony_ci	const struct recorded_ref *ref = rb_entry(node, struct recorded_ref, node);
462262306a36Sopenharmony_ci	int result;
462362306a36Sopenharmony_ci
462462306a36Sopenharmony_ci	if (data->dir > ref->dir)
462562306a36Sopenharmony_ci		return 1;
462662306a36Sopenharmony_ci	if (data->dir < ref->dir)
462762306a36Sopenharmony_ci		return -1;
462862306a36Sopenharmony_ci	if (data->dir_gen > ref->dir_gen)
462962306a36Sopenharmony_ci		return 1;
463062306a36Sopenharmony_ci	if (data->dir_gen < ref->dir_gen)
463162306a36Sopenharmony_ci		return -1;
463262306a36Sopenharmony_ci	if (data->name_len > ref->name_len)
463362306a36Sopenharmony_ci		return 1;
463462306a36Sopenharmony_ci	if (data->name_len < ref->name_len)
463562306a36Sopenharmony_ci		return -1;
463662306a36Sopenharmony_ci	result = strcmp(data->name, ref->name);
463762306a36Sopenharmony_ci	if (result > 0)
463862306a36Sopenharmony_ci		return 1;
463962306a36Sopenharmony_ci	if (result < 0)
464062306a36Sopenharmony_ci		return -1;
464162306a36Sopenharmony_ci	return 0;
464262306a36Sopenharmony_ci}
464362306a36Sopenharmony_ci
464462306a36Sopenharmony_cistatic bool rbtree_ref_less(struct rb_node *node, const struct rb_node *parent)
464562306a36Sopenharmony_ci{
464662306a36Sopenharmony_ci	const struct recorded_ref *entry = rb_entry(node, struct recorded_ref, node);
464762306a36Sopenharmony_ci
464862306a36Sopenharmony_ci	return rbtree_ref_comp(entry, parent) < 0;
464962306a36Sopenharmony_ci}
465062306a36Sopenharmony_ci
465162306a36Sopenharmony_cistatic int record_ref_in_tree(struct rb_root *root, struct list_head *refs,
465262306a36Sopenharmony_ci			      struct fs_path *name, u64 dir, u64 dir_gen,
465362306a36Sopenharmony_ci			      struct send_ctx *sctx)
465462306a36Sopenharmony_ci{
465562306a36Sopenharmony_ci	int ret = 0;
465662306a36Sopenharmony_ci	struct fs_path *path = NULL;
465762306a36Sopenharmony_ci	struct recorded_ref *ref = NULL;
465862306a36Sopenharmony_ci
465962306a36Sopenharmony_ci	path = fs_path_alloc();
466062306a36Sopenharmony_ci	if (!path) {
466162306a36Sopenharmony_ci		ret = -ENOMEM;
466262306a36Sopenharmony_ci		goto out;
466362306a36Sopenharmony_ci	}
466462306a36Sopenharmony_ci
466562306a36Sopenharmony_ci	ref = recorded_ref_alloc();
466662306a36Sopenharmony_ci	if (!ref) {
466762306a36Sopenharmony_ci		ret = -ENOMEM;
466862306a36Sopenharmony_ci		goto out;
466962306a36Sopenharmony_ci	}
467062306a36Sopenharmony_ci
467162306a36Sopenharmony_ci	ret = get_cur_path(sctx, dir, dir_gen, path);
467262306a36Sopenharmony_ci	if (ret < 0)
467362306a36Sopenharmony_ci		goto out;
467462306a36Sopenharmony_ci	ret = fs_path_add_path(path, name);
467562306a36Sopenharmony_ci	if (ret < 0)
467662306a36Sopenharmony_ci		goto out;
467762306a36Sopenharmony_ci
467862306a36Sopenharmony_ci	ref->dir = dir;
467962306a36Sopenharmony_ci	ref->dir_gen = dir_gen;
468062306a36Sopenharmony_ci	set_ref_path(ref, path);
468162306a36Sopenharmony_ci	list_add_tail(&ref->list, refs);
468262306a36Sopenharmony_ci	rb_add(&ref->node, root, rbtree_ref_less);
468362306a36Sopenharmony_ci	ref->root = root;
468462306a36Sopenharmony_ciout:
468562306a36Sopenharmony_ci	if (ret) {
468662306a36Sopenharmony_ci		if (path && (!ref || !ref->full_path))
468762306a36Sopenharmony_ci			fs_path_free(path);
468862306a36Sopenharmony_ci		recorded_ref_free(ref);
468962306a36Sopenharmony_ci	}
469062306a36Sopenharmony_ci	return ret;
469162306a36Sopenharmony_ci}
469262306a36Sopenharmony_ci
469362306a36Sopenharmony_cistatic int record_new_ref_if_needed(int num, u64 dir, int index,
469462306a36Sopenharmony_ci				    struct fs_path *name, void *ctx)
469562306a36Sopenharmony_ci{
469662306a36Sopenharmony_ci	int ret = 0;
469762306a36Sopenharmony_ci	struct send_ctx *sctx = ctx;
469862306a36Sopenharmony_ci	struct rb_node *node = NULL;
469962306a36Sopenharmony_ci	struct recorded_ref data;
470062306a36Sopenharmony_ci	struct recorded_ref *ref;
470162306a36Sopenharmony_ci	u64 dir_gen;
470262306a36Sopenharmony_ci
470362306a36Sopenharmony_ci	ret = get_inode_gen(sctx->send_root, dir, &dir_gen);
470462306a36Sopenharmony_ci	if (ret < 0)
470562306a36Sopenharmony_ci		goto out;
470662306a36Sopenharmony_ci
470762306a36Sopenharmony_ci	data.dir = dir;
470862306a36Sopenharmony_ci	data.dir_gen = dir_gen;
470962306a36Sopenharmony_ci	set_ref_path(&data, name);
471062306a36Sopenharmony_ci	node = rb_find(&data, &sctx->rbtree_deleted_refs, rbtree_ref_comp);
471162306a36Sopenharmony_ci	if (node) {
471262306a36Sopenharmony_ci		ref = rb_entry(node, struct recorded_ref, node);
471362306a36Sopenharmony_ci		recorded_ref_free(ref);
471462306a36Sopenharmony_ci	} else {
471562306a36Sopenharmony_ci		ret = record_ref_in_tree(&sctx->rbtree_new_refs,
471662306a36Sopenharmony_ci					 &sctx->new_refs, name, dir, dir_gen,
471762306a36Sopenharmony_ci					 sctx);
471862306a36Sopenharmony_ci	}
471962306a36Sopenharmony_ciout:
472062306a36Sopenharmony_ci	return ret;
472162306a36Sopenharmony_ci}
472262306a36Sopenharmony_ci
472362306a36Sopenharmony_cistatic int record_deleted_ref_if_needed(int num, u64 dir, int index,
472462306a36Sopenharmony_ci					struct fs_path *name, void *ctx)
472562306a36Sopenharmony_ci{
472662306a36Sopenharmony_ci	int ret = 0;
472762306a36Sopenharmony_ci	struct send_ctx *sctx = ctx;
472862306a36Sopenharmony_ci	struct rb_node *node = NULL;
472962306a36Sopenharmony_ci	struct recorded_ref data;
473062306a36Sopenharmony_ci	struct recorded_ref *ref;
473162306a36Sopenharmony_ci	u64 dir_gen;
473262306a36Sopenharmony_ci
473362306a36Sopenharmony_ci	ret = get_inode_gen(sctx->parent_root, dir, &dir_gen);
473462306a36Sopenharmony_ci	if (ret < 0)
473562306a36Sopenharmony_ci		goto out;
473662306a36Sopenharmony_ci
473762306a36Sopenharmony_ci	data.dir = dir;
473862306a36Sopenharmony_ci	data.dir_gen = dir_gen;
473962306a36Sopenharmony_ci	set_ref_path(&data, name);
474062306a36Sopenharmony_ci	node = rb_find(&data, &sctx->rbtree_new_refs, rbtree_ref_comp);
474162306a36Sopenharmony_ci	if (node) {
474262306a36Sopenharmony_ci		ref = rb_entry(node, struct recorded_ref, node);
474362306a36Sopenharmony_ci		recorded_ref_free(ref);
474462306a36Sopenharmony_ci	} else {
474562306a36Sopenharmony_ci		ret = record_ref_in_tree(&sctx->rbtree_deleted_refs,
474662306a36Sopenharmony_ci					 &sctx->deleted_refs, name, dir,
474762306a36Sopenharmony_ci					 dir_gen, sctx);
474862306a36Sopenharmony_ci	}
474962306a36Sopenharmony_ciout:
475062306a36Sopenharmony_ci	return ret;
475162306a36Sopenharmony_ci}
475262306a36Sopenharmony_ci
475362306a36Sopenharmony_cistatic int record_new_ref(struct send_ctx *sctx)
475462306a36Sopenharmony_ci{
475562306a36Sopenharmony_ci	int ret;
475662306a36Sopenharmony_ci
475762306a36Sopenharmony_ci	ret = iterate_inode_ref(sctx->send_root, sctx->left_path,
475862306a36Sopenharmony_ci				sctx->cmp_key, 0, record_new_ref_if_needed, sctx);
475962306a36Sopenharmony_ci	if (ret < 0)
476062306a36Sopenharmony_ci		goto out;
476162306a36Sopenharmony_ci	ret = 0;
476262306a36Sopenharmony_ci
476362306a36Sopenharmony_ciout:
476462306a36Sopenharmony_ci	return ret;
476562306a36Sopenharmony_ci}
476662306a36Sopenharmony_ci
476762306a36Sopenharmony_cistatic int record_deleted_ref(struct send_ctx *sctx)
476862306a36Sopenharmony_ci{
476962306a36Sopenharmony_ci	int ret;
477062306a36Sopenharmony_ci
477162306a36Sopenharmony_ci	ret = iterate_inode_ref(sctx->parent_root, sctx->right_path,
477262306a36Sopenharmony_ci				sctx->cmp_key, 0, record_deleted_ref_if_needed,
477362306a36Sopenharmony_ci				sctx);
477462306a36Sopenharmony_ci	if (ret < 0)
477562306a36Sopenharmony_ci		goto out;
477662306a36Sopenharmony_ci	ret = 0;
477762306a36Sopenharmony_ci
477862306a36Sopenharmony_ciout:
477962306a36Sopenharmony_ci	return ret;
478062306a36Sopenharmony_ci}
478162306a36Sopenharmony_ci
478262306a36Sopenharmony_cistatic int record_changed_ref(struct send_ctx *sctx)
478362306a36Sopenharmony_ci{
478462306a36Sopenharmony_ci	int ret = 0;
478562306a36Sopenharmony_ci
478662306a36Sopenharmony_ci	ret = iterate_inode_ref(sctx->send_root, sctx->left_path,
478762306a36Sopenharmony_ci			sctx->cmp_key, 0, record_new_ref_if_needed, sctx);
478862306a36Sopenharmony_ci	if (ret < 0)
478962306a36Sopenharmony_ci		goto out;
479062306a36Sopenharmony_ci	ret = iterate_inode_ref(sctx->parent_root, sctx->right_path,
479162306a36Sopenharmony_ci			sctx->cmp_key, 0, record_deleted_ref_if_needed, sctx);
479262306a36Sopenharmony_ci	if (ret < 0)
479362306a36Sopenharmony_ci		goto out;
479462306a36Sopenharmony_ci	ret = 0;
479562306a36Sopenharmony_ci
479662306a36Sopenharmony_ciout:
479762306a36Sopenharmony_ci	return ret;
479862306a36Sopenharmony_ci}
479962306a36Sopenharmony_ci
480062306a36Sopenharmony_ci/*
480162306a36Sopenharmony_ci * Record and process all refs at once. Needed when an inode changes the
480262306a36Sopenharmony_ci * generation number, which means that it was deleted and recreated.
480362306a36Sopenharmony_ci */
480462306a36Sopenharmony_cistatic int process_all_refs(struct send_ctx *sctx,
480562306a36Sopenharmony_ci			    enum btrfs_compare_tree_result cmd)
480662306a36Sopenharmony_ci{
480762306a36Sopenharmony_ci	int ret = 0;
480862306a36Sopenharmony_ci	int iter_ret = 0;
480962306a36Sopenharmony_ci	struct btrfs_root *root;
481062306a36Sopenharmony_ci	struct btrfs_path *path;
481162306a36Sopenharmony_ci	struct btrfs_key key;
481262306a36Sopenharmony_ci	struct btrfs_key found_key;
481362306a36Sopenharmony_ci	iterate_inode_ref_t cb;
481462306a36Sopenharmony_ci	int pending_move = 0;
481562306a36Sopenharmony_ci
481662306a36Sopenharmony_ci	path = alloc_path_for_send();
481762306a36Sopenharmony_ci	if (!path)
481862306a36Sopenharmony_ci		return -ENOMEM;
481962306a36Sopenharmony_ci
482062306a36Sopenharmony_ci	if (cmd == BTRFS_COMPARE_TREE_NEW) {
482162306a36Sopenharmony_ci		root = sctx->send_root;
482262306a36Sopenharmony_ci		cb = record_new_ref_if_needed;
482362306a36Sopenharmony_ci	} else if (cmd == BTRFS_COMPARE_TREE_DELETED) {
482462306a36Sopenharmony_ci		root = sctx->parent_root;
482562306a36Sopenharmony_ci		cb = record_deleted_ref_if_needed;
482662306a36Sopenharmony_ci	} else {
482762306a36Sopenharmony_ci		btrfs_err(sctx->send_root->fs_info,
482862306a36Sopenharmony_ci				"Wrong command %d in process_all_refs", cmd);
482962306a36Sopenharmony_ci		ret = -EINVAL;
483062306a36Sopenharmony_ci		goto out;
483162306a36Sopenharmony_ci	}
483262306a36Sopenharmony_ci
483362306a36Sopenharmony_ci	key.objectid = sctx->cmp_key->objectid;
483462306a36Sopenharmony_ci	key.type = BTRFS_INODE_REF_KEY;
483562306a36Sopenharmony_ci	key.offset = 0;
483662306a36Sopenharmony_ci	btrfs_for_each_slot(root, &key, &found_key, path, iter_ret) {
483762306a36Sopenharmony_ci		if (found_key.objectid != key.objectid ||
483862306a36Sopenharmony_ci		    (found_key.type != BTRFS_INODE_REF_KEY &&
483962306a36Sopenharmony_ci		     found_key.type != BTRFS_INODE_EXTREF_KEY))
484062306a36Sopenharmony_ci			break;
484162306a36Sopenharmony_ci
484262306a36Sopenharmony_ci		ret = iterate_inode_ref(root, path, &found_key, 0, cb, sctx);
484362306a36Sopenharmony_ci		if (ret < 0)
484462306a36Sopenharmony_ci			goto out;
484562306a36Sopenharmony_ci	}
484662306a36Sopenharmony_ci	/* Catch error found during iteration */
484762306a36Sopenharmony_ci	if (iter_ret < 0) {
484862306a36Sopenharmony_ci		ret = iter_ret;
484962306a36Sopenharmony_ci		goto out;
485062306a36Sopenharmony_ci	}
485162306a36Sopenharmony_ci	btrfs_release_path(path);
485262306a36Sopenharmony_ci
485362306a36Sopenharmony_ci	/*
485462306a36Sopenharmony_ci	 * We don't actually care about pending_move as we are simply
485562306a36Sopenharmony_ci	 * re-creating this inode and will be rename'ing it into place once we
485662306a36Sopenharmony_ci	 * rename the parent directory.
485762306a36Sopenharmony_ci	 */
485862306a36Sopenharmony_ci	ret = process_recorded_refs(sctx, &pending_move);
485962306a36Sopenharmony_ciout:
486062306a36Sopenharmony_ci	btrfs_free_path(path);
486162306a36Sopenharmony_ci	return ret;
486262306a36Sopenharmony_ci}
486362306a36Sopenharmony_ci
486462306a36Sopenharmony_cistatic int send_set_xattr(struct send_ctx *sctx,
486562306a36Sopenharmony_ci			  struct fs_path *path,
486662306a36Sopenharmony_ci			  const char *name, int name_len,
486762306a36Sopenharmony_ci			  const char *data, int data_len)
486862306a36Sopenharmony_ci{
486962306a36Sopenharmony_ci	int ret = 0;
487062306a36Sopenharmony_ci
487162306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_SET_XATTR);
487262306a36Sopenharmony_ci	if (ret < 0)
487362306a36Sopenharmony_ci		goto out;
487462306a36Sopenharmony_ci
487562306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path);
487662306a36Sopenharmony_ci	TLV_PUT_STRING(sctx, BTRFS_SEND_A_XATTR_NAME, name, name_len);
487762306a36Sopenharmony_ci	TLV_PUT(sctx, BTRFS_SEND_A_XATTR_DATA, data, data_len);
487862306a36Sopenharmony_ci
487962306a36Sopenharmony_ci	ret = send_cmd(sctx);
488062306a36Sopenharmony_ci
488162306a36Sopenharmony_citlv_put_failure:
488262306a36Sopenharmony_ciout:
488362306a36Sopenharmony_ci	return ret;
488462306a36Sopenharmony_ci}
488562306a36Sopenharmony_ci
488662306a36Sopenharmony_cistatic int send_remove_xattr(struct send_ctx *sctx,
488762306a36Sopenharmony_ci			  struct fs_path *path,
488862306a36Sopenharmony_ci			  const char *name, int name_len)
488962306a36Sopenharmony_ci{
489062306a36Sopenharmony_ci	int ret = 0;
489162306a36Sopenharmony_ci
489262306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_REMOVE_XATTR);
489362306a36Sopenharmony_ci	if (ret < 0)
489462306a36Sopenharmony_ci		goto out;
489562306a36Sopenharmony_ci
489662306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path);
489762306a36Sopenharmony_ci	TLV_PUT_STRING(sctx, BTRFS_SEND_A_XATTR_NAME, name, name_len);
489862306a36Sopenharmony_ci
489962306a36Sopenharmony_ci	ret = send_cmd(sctx);
490062306a36Sopenharmony_ci
490162306a36Sopenharmony_citlv_put_failure:
490262306a36Sopenharmony_ciout:
490362306a36Sopenharmony_ci	return ret;
490462306a36Sopenharmony_ci}
490562306a36Sopenharmony_ci
490662306a36Sopenharmony_cistatic int __process_new_xattr(int num, struct btrfs_key *di_key,
490762306a36Sopenharmony_ci			       const char *name, int name_len, const char *data,
490862306a36Sopenharmony_ci			       int data_len, void *ctx)
490962306a36Sopenharmony_ci{
491062306a36Sopenharmony_ci	int ret;
491162306a36Sopenharmony_ci	struct send_ctx *sctx = ctx;
491262306a36Sopenharmony_ci	struct fs_path *p;
491362306a36Sopenharmony_ci	struct posix_acl_xattr_header dummy_acl;
491462306a36Sopenharmony_ci
491562306a36Sopenharmony_ci	/* Capabilities are emitted by finish_inode_if_needed */
491662306a36Sopenharmony_ci	if (!strncmp(name, XATTR_NAME_CAPS, name_len))
491762306a36Sopenharmony_ci		return 0;
491862306a36Sopenharmony_ci
491962306a36Sopenharmony_ci	p = fs_path_alloc();
492062306a36Sopenharmony_ci	if (!p)
492162306a36Sopenharmony_ci		return -ENOMEM;
492262306a36Sopenharmony_ci
492362306a36Sopenharmony_ci	/*
492462306a36Sopenharmony_ci	 * This hack is needed because empty acls are stored as zero byte
492562306a36Sopenharmony_ci	 * data in xattrs. Problem with that is, that receiving these zero byte
492662306a36Sopenharmony_ci	 * acls will fail later. To fix this, we send a dummy acl list that
492762306a36Sopenharmony_ci	 * only contains the version number and no entries.
492862306a36Sopenharmony_ci	 */
492962306a36Sopenharmony_ci	if (!strncmp(name, XATTR_NAME_POSIX_ACL_ACCESS, name_len) ||
493062306a36Sopenharmony_ci	    !strncmp(name, XATTR_NAME_POSIX_ACL_DEFAULT, name_len)) {
493162306a36Sopenharmony_ci		if (data_len == 0) {
493262306a36Sopenharmony_ci			dummy_acl.a_version =
493362306a36Sopenharmony_ci					cpu_to_le32(POSIX_ACL_XATTR_VERSION);
493462306a36Sopenharmony_ci			data = (char *)&dummy_acl;
493562306a36Sopenharmony_ci			data_len = sizeof(dummy_acl);
493662306a36Sopenharmony_ci		}
493762306a36Sopenharmony_ci	}
493862306a36Sopenharmony_ci
493962306a36Sopenharmony_ci	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
494062306a36Sopenharmony_ci	if (ret < 0)
494162306a36Sopenharmony_ci		goto out;
494262306a36Sopenharmony_ci
494362306a36Sopenharmony_ci	ret = send_set_xattr(sctx, p, name, name_len, data, data_len);
494462306a36Sopenharmony_ci
494562306a36Sopenharmony_ciout:
494662306a36Sopenharmony_ci	fs_path_free(p);
494762306a36Sopenharmony_ci	return ret;
494862306a36Sopenharmony_ci}
494962306a36Sopenharmony_ci
495062306a36Sopenharmony_cistatic int __process_deleted_xattr(int num, struct btrfs_key *di_key,
495162306a36Sopenharmony_ci				   const char *name, int name_len,
495262306a36Sopenharmony_ci				   const char *data, int data_len, void *ctx)
495362306a36Sopenharmony_ci{
495462306a36Sopenharmony_ci	int ret;
495562306a36Sopenharmony_ci	struct send_ctx *sctx = ctx;
495662306a36Sopenharmony_ci	struct fs_path *p;
495762306a36Sopenharmony_ci
495862306a36Sopenharmony_ci	p = fs_path_alloc();
495962306a36Sopenharmony_ci	if (!p)
496062306a36Sopenharmony_ci		return -ENOMEM;
496162306a36Sopenharmony_ci
496262306a36Sopenharmony_ci	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
496362306a36Sopenharmony_ci	if (ret < 0)
496462306a36Sopenharmony_ci		goto out;
496562306a36Sopenharmony_ci
496662306a36Sopenharmony_ci	ret = send_remove_xattr(sctx, p, name, name_len);
496762306a36Sopenharmony_ci
496862306a36Sopenharmony_ciout:
496962306a36Sopenharmony_ci	fs_path_free(p);
497062306a36Sopenharmony_ci	return ret;
497162306a36Sopenharmony_ci}
497262306a36Sopenharmony_ci
497362306a36Sopenharmony_cistatic int process_new_xattr(struct send_ctx *sctx)
497462306a36Sopenharmony_ci{
497562306a36Sopenharmony_ci	int ret = 0;
497662306a36Sopenharmony_ci
497762306a36Sopenharmony_ci	ret = iterate_dir_item(sctx->send_root, sctx->left_path,
497862306a36Sopenharmony_ci			       __process_new_xattr, sctx);
497962306a36Sopenharmony_ci
498062306a36Sopenharmony_ci	return ret;
498162306a36Sopenharmony_ci}
498262306a36Sopenharmony_ci
498362306a36Sopenharmony_cistatic int process_deleted_xattr(struct send_ctx *sctx)
498462306a36Sopenharmony_ci{
498562306a36Sopenharmony_ci	return iterate_dir_item(sctx->parent_root, sctx->right_path,
498662306a36Sopenharmony_ci				__process_deleted_xattr, sctx);
498762306a36Sopenharmony_ci}
498862306a36Sopenharmony_ci
498962306a36Sopenharmony_cistruct find_xattr_ctx {
499062306a36Sopenharmony_ci	const char *name;
499162306a36Sopenharmony_ci	int name_len;
499262306a36Sopenharmony_ci	int found_idx;
499362306a36Sopenharmony_ci	char *found_data;
499462306a36Sopenharmony_ci	int found_data_len;
499562306a36Sopenharmony_ci};
499662306a36Sopenharmony_ci
499762306a36Sopenharmony_cistatic int __find_xattr(int num, struct btrfs_key *di_key, const char *name,
499862306a36Sopenharmony_ci			int name_len, const char *data, int data_len, void *vctx)
499962306a36Sopenharmony_ci{
500062306a36Sopenharmony_ci	struct find_xattr_ctx *ctx = vctx;
500162306a36Sopenharmony_ci
500262306a36Sopenharmony_ci	if (name_len == ctx->name_len &&
500362306a36Sopenharmony_ci	    strncmp(name, ctx->name, name_len) == 0) {
500462306a36Sopenharmony_ci		ctx->found_idx = num;
500562306a36Sopenharmony_ci		ctx->found_data_len = data_len;
500662306a36Sopenharmony_ci		ctx->found_data = kmemdup(data, data_len, GFP_KERNEL);
500762306a36Sopenharmony_ci		if (!ctx->found_data)
500862306a36Sopenharmony_ci			return -ENOMEM;
500962306a36Sopenharmony_ci		return 1;
501062306a36Sopenharmony_ci	}
501162306a36Sopenharmony_ci	return 0;
501262306a36Sopenharmony_ci}
501362306a36Sopenharmony_ci
501462306a36Sopenharmony_cistatic int find_xattr(struct btrfs_root *root,
501562306a36Sopenharmony_ci		      struct btrfs_path *path,
501662306a36Sopenharmony_ci		      struct btrfs_key *key,
501762306a36Sopenharmony_ci		      const char *name, int name_len,
501862306a36Sopenharmony_ci		      char **data, int *data_len)
501962306a36Sopenharmony_ci{
502062306a36Sopenharmony_ci	int ret;
502162306a36Sopenharmony_ci	struct find_xattr_ctx ctx;
502262306a36Sopenharmony_ci
502362306a36Sopenharmony_ci	ctx.name = name;
502462306a36Sopenharmony_ci	ctx.name_len = name_len;
502562306a36Sopenharmony_ci	ctx.found_idx = -1;
502662306a36Sopenharmony_ci	ctx.found_data = NULL;
502762306a36Sopenharmony_ci	ctx.found_data_len = 0;
502862306a36Sopenharmony_ci
502962306a36Sopenharmony_ci	ret = iterate_dir_item(root, path, __find_xattr, &ctx);
503062306a36Sopenharmony_ci	if (ret < 0)
503162306a36Sopenharmony_ci		return ret;
503262306a36Sopenharmony_ci
503362306a36Sopenharmony_ci	if (ctx.found_idx == -1)
503462306a36Sopenharmony_ci		return -ENOENT;
503562306a36Sopenharmony_ci	if (data) {
503662306a36Sopenharmony_ci		*data = ctx.found_data;
503762306a36Sopenharmony_ci		*data_len = ctx.found_data_len;
503862306a36Sopenharmony_ci	} else {
503962306a36Sopenharmony_ci		kfree(ctx.found_data);
504062306a36Sopenharmony_ci	}
504162306a36Sopenharmony_ci	return ctx.found_idx;
504262306a36Sopenharmony_ci}
504362306a36Sopenharmony_ci
504462306a36Sopenharmony_ci
504562306a36Sopenharmony_cistatic int __process_changed_new_xattr(int num, struct btrfs_key *di_key,
504662306a36Sopenharmony_ci				       const char *name, int name_len,
504762306a36Sopenharmony_ci				       const char *data, int data_len,
504862306a36Sopenharmony_ci				       void *ctx)
504962306a36Sopenharmony_ci{
505062306a36Sopenharmony_ci	int ret;
505162306a36Sopenharmony_ci	struct send_ctx *sctx = ctx;
505262306a36Sopenharmony_ci	char *found_data = NULL;
505362306a36Sopenharmony_ci	int found_data_len  = 0;
505462306a36Sopenharmony_ci
505562306a36Sopenharmony_ci	ret = find_xattr(sctx->parent_root, sctx->right_path,
505662306a36Sopenharmony_ci			 sctx->cmp_key, name, name_len, &found_data,
505762306a36Sopenharmony_ci			 &found_data_len);
505862306a36Sopenharmony_ci	if (ret == -ENOENT) {
505962306a36Sopenharmony_ci		ret = __process_new_xattr(num, di_key, name, name_len, data,
506062306a36Sopenharmony_ci					  data_len, ctx);
506162306a36Sopenharmony_ci	} else if (ret >= 0) {
506262306a36Sopenharmony_ci		if (data_len != found_data_len ||
506362306a36Sopenharmony_ci		    memcmp(data, found_data, data_len)) {
506462306a36Sopenharmony_ci			ret = __process_new_xattr(num, di_key, name, name_len,
506562306a36Sopenharmony_ci						  data, data_len, ctx);
506662306a36Sopenharmony_ci		} else {
506762306a36Sopenharmony_ci			ret = 0;
506862306a36Sopenharmony_ci		}
506962306a36Sopenharmony_ci	}
507062306a36Sopenharmony_ci
507162306a36Sopenharmony_ci	kfree(found_data);
507262306a36Sopenharmony_ci	return ret;
507362306a36Sopenharmony_ci}
507462306a36Sopenharmony_ci
507562306a36Sopenharmony_cistatic int __process_changed_deleted_xattr(int num, struct btrfs_key *di_key,
507662306a36Sopenharmony_ci					   const char *name, int name_len,
507762306a36Sopenharmony_ci					   const char *data, int data_len,
507862306a36Sopenharmony_ci					   void *ctx)
507962306a36Sopenharmony_ci{
508062306a36Sopenharmony_ci	int ret;
508162306a36Sopenharmony_ci	struct send_ctx *sctx = ctx;
508262306a36Sopenharmony_ci
508362306a36Sopenharmony_ci	ret = find_xattr(sctx->send_root, sctx->left_path, sctx->cmp_key,
508462306a36Sopenharmony_ci			 name, name_len, NULL, NULL);
508562306a36Sopenharmony_ci	if (ret == -ENOENT)
508662306a36Sopenharmony_ci		ret = __process_deleted_xattr(num, di_key, name, name_len, data,
508762306a36Sopenharmony_ci					      data_len, ctx);
508862306a36Sopenharmony_ci	else if (ret >= 0)
508962306a36Sopenharmony_ci		ret = 0;
509062306a36Sopenharmony_ci
509162306a36Sopenharmony_ci	return ret;
509262306a36Sopenharmony_ci}
509362306a36Sopenharmony_ci
509462306a36Sopenharmony_cistatic int process_changed_xattr(struct send_ctx *sctx)
509562306a36Sopenharmony_ci{
509662306a36Sopenharmony_ci	int ret = 0;
509762306a36Sopenharmony_ci
509862306a36Sopenharmony_ci	ret = iterate_dir_item(sctx->send_root, sctx->left_path,
509962306a36Sopenharmony_ci			__process_changed_new_xattr, sctx);
510062306a36Sopenharmony_ci	if (ret < 0)
510162306a36Sopenharmony_ci		goto out;
510262306a36Sopenharmony_ci	ret = iterate_dir_item(sctx->parent_root, sctx->right_path,
510362306a36Sopenharmony_ci			__process_changed_deleted_xattr, sctx);
510462306a36Sopenharmony_ci
510562306a36Sopenharmony_ciout:
510662306a36Sopenharmony_ci	return ret;
510762306a36Sopenharmony_ci}
510862306a36Sopenharmony_ci
510962306a36Sopenharmony_cistatic int process_all_new_xattrs(struct send_ctx *sctx)
511062306a36Sopenharmony_ci{
511162306a36Sopenharmony_ci	int ret = 0;
511262306a36Sopenharmony_ci	int iter_ret = 0;
511362306a36Sopenharmony_ci	struct btrfs_root *root;
511462306a36Sopenharmony_ci	struct btrfs_path *path;
511562306a36Sopenharmony_ci	struct btrfs_key key;
511662306a36Sopenharmony_ci	struct btrfs_key found_key;
511762306a36Sopenharmony_ci
511862306a36Sopenharmony_ci	path = alloc_path_for_send();
511962306a36Sopenharmony_ci	if (!path)
512062306a36Sopenharmony_ci		return -ENOMEM;
512162306a36Sopenharmony_ci
512262306a36Sopenharmony_ci	root = sctx->send_root;
512362306a36Sopenharmony_ci
512462306a36Sopenharmony_ci	key.objectid = sctx->cmp_key->objectid;
512562306a36Sopenharmony_ci	key.type = BTRFS_XATTR_ITEM_KEY;
512662306a36Sopenharmony_ci	key.offset = 0;
512762306a36Sopenharmony_ci	btrfs_for_each_slot(root, &key, &found_key, path, iter_ret) {
512862306a36Sopenharmony_ci		if (found_key.objectid != key.objectid ||
512962306a36Sopenharmony_ci		    found_key.type != key.type) {
513062306a36Sopenharmony_ci			ret = 0;
513162306a36Sopenharmony_ci			break;
513262306a36Sopenharmony_ci		}
513362306a36Sopenharmony_ci
513462306a36Sopenharmony_ci		ret = iterate_dir_item(root, path, __process_new_xattr, sctx);
513562306a36Sopenharmony_ci		if (ret < 0)
513662306a36Sopenharmony_ci			break;
513762306a36Sopenharmony_ci	}
513862306a36Sopenharmony_ci	/* Catch error found during iteration */
513962306a36Sopenharmony_ci	if (iter_ret < 0)
514062306a36Sopenharmony_ci		ret = iter_ret;
514162306a36Sopenharmony_ci
514262306a36Sopenharmony_ci	btrfs_free_path(path);
514362306a36Sopenharmony_ci	return ret;
514462306a36Sopenharmony_ci}
514562306a36Sopenharmony_ci
514662306a36Sopenharmony_cistatic int send_verity(struct send_ctx *sctx, struct fs_path *path,
514762306a36Sopenharmony_ci		       struct fsverity_descriptor *desc)
514862306a36Sopenharmony_ci{
514962306a36Sopenharmony_ci	int ret;
515062306a36Sopenharmony_ci
515162306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_ENABLE_VERITY);
515262306a36Sopenharmony_ci	if (ret < 0)
515362306a36Sopenharmony_ci		goto out;
515462306a36Sopenharmony_ci
515562306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path);
515662306a36Sopenharmony_ci	TLV_PUT_U8(sctx, BTRFS_SEND_A_VERITY_ALGORITHM,
515762306a36Sopenharmony_ci			le8_to_cpu(desc->hash_algorithm));
515862306a36Sopenharmony_ci	TLV_PUT_U32(sctx, BTRFS_SEND_A_VERITY_BLOCK_SIZE,
515962306a36Sopenharmony_ci			1U << le8_to_cpu(desc->log_blocksize));
516062306a36Sopenharmony_ci	TLV_PUT(sctx, BTRFS_SEND_A_VERITY_SALT_DATA, desc->salt,
516162306a36Sopenharmony_ci			le8_to_cpu(desc->salt_size));
516262306a36Sopenharmony_ci	TLV_PUT(sctx, BTRFS_SEND_A_VERITY_SIG_DATA, desc->signature,
516362306a36Sopenharmony_ci			le32_to_cpu(desc->sig_size));
516462306a36Sopenharmony_ci
516562306a36Sopenharmony_ci	ret = send_cmd(sctx);
516662306a36Sopenharmony_ci
516762306a36Sopenharmony_citlv_put_failure:
516862306a36Sopenharmony_ciout:
516962306a36Sopenharmony_ci	return ret;
517062306a36Sopenharmony_ci}
517162306a36Sopenharmony_ci
517262306a36Sopenharmony_cistatic int process_verity(struct send_ctx *sctx)
517362306a36Sopenharmony_ci{
517462306a36Sopenharmony_ci	int ret = 0;
517562306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
517662306a36Sopenharmony_ci	struct inode *inode;
517762306a36Sopenharmony_ci	struct fs_path *p;
517862306a36Sopenharmony_ci
517962306a36Sopenharmony_ci	inode = btrfs_iget(fs_info->sb, sctx->cur_ino, sctx->send_root);
518062306a36Sopenharmony_ci	if (IS_ERR(inode))
518162306a36Sopenharmony_ci		return PTR_ERR(inode);
518262306a36Sopenharmony_ci
518362306a36Sopenharmony_ci	ret = btrfs_get_verity_descriptor(inode, NULL, 0);
518462306a36Sopenharmony_ci	if (ret < 0)
518562306a36Sopenharmony_ci		goto iput;
518662306a36Sopenharmony_ci
518762306a36Sopenharmony_ci	if (ret > FS_VERITY_MAX_DESCRIPTOR_SIZE) {
518862306a36Sopenharmony_ci		ret = -EMSGSIZE;
518962306a36Sopenharmony_ci		goto iput;
519062306a36Sopenharmony_ci	}
519162306a36Sopenharmony_ci	if (!sctx->verity_descriptor) {
519262306a36Sopenharmony_ci		sctx->verity_descriptor = kvmalloc(FS_VERITY_MAX_DESCRIPTOR_SIZE,
519362306a36Sopenharmony_ci						   GFP_KERNEL);
519462306a36Sopenharmony_ci		if (!sctx->verity_descriptor) {
519562306a36Sopenharmony_ci			ret = -ENOMEM;
519662306a36Sopenharmony_ci			goto iput;
519762306a36Sopenharmony_ci		}
519862306a36Sopenharmony_ci	}
519962306a36Sopenharmony_ci
520062306a36Sopenharmony_ci	ret = btrfs_get_verity_descriptor(inode, sctx->verity_descriptor, ret);
520162306a36Sopenharmony_ci	if (ret < 0)
520262306a36Sopenharmony_ci		goto iput;
520362306a36Sopenharmony_ci
520462306a36Sopenharmony_ci	p = fs_path_alloc();
520562306a36Sopenharmony_ci	if (!p) {
520662306a36Sopenharmony_ci		ret = -ENOMEM;
520762306a36Sopenharmony_ci		goto iput;
520862306a36Sopenharmony_ci	}
520962306a36Sopenharmony_ci	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
521062306a36Sopenharmony_ci	if (ret < 0)
521162306a36Sopenharmony_ci		goto free_path;
521262306a36Sopenharmony_ci
521362306a36Sopenharmony_ci	ret = send_verity(sctx, p, sctx->verity_descriptor);
521462306a36Sopenharmony_ci	if (ret < 0)
521562306a36Sopenharmony_ci		goto free_path;
521662306a36Sopenharmony_ci
521762306a36Sopenharmony_cifree_path:
521862306a36Sopenharmony_ci	fs_path_free(p);
521962306a36Sopenharmony_ciiput:
522062306a36Sopenharmony_ci	iput(inode);
522162306a36Sopenharmony_ci	return ret;
522262306a36Sopenharmony_ci}
522362306a36Sopenharmony_ci
522462306a36Sopenharmony_cistatic inline u64 max_send_read_size(const struct send_ctx *sctx)
522562306a36Sopenharmony_ci{
522662306a36Sopenharmony_ci	return sctx->send_max_size - SZ_16K;
522762306a36Sopenharmony_ci}
522862306a36Sopenharmony_ci
522962306a36Sopenharmony_cistatic int put_data_header(struct send_ctx *sctx, u32 len)
523062306a36Sopenharmony_ci{
523162306a36Sopenharmony_ci	if (WARN_ON_ONCE(sctx->put_data))
523262306a36Sopenharmony_ci		return -EINVAL;
523362306a36Sopenharmony_ci	sctx->put_data = true;
523462306a36Sopenharmony_ci	if (sctx->proto >= 2) {
523562306a36Sopenharmony_ci		/*
523662306a36Sopenharmony_ci		 * Since v2, the data attribute header doesn't include a length,
523762306a36Sopenharmony_ci		 * it is implicitly to the end of the command.
523862306a36Sopenharmony_ci		 */
523962306a36Sopenharmony_ci		if (sctx->send_max_size - sctx->send_size < sizeof(__le16) + len)
524062306a36Sopenharmony_ci			return -EOVERFLOW;
524162306a36Sopenharmony_ci		put_unaligned_le16(BTRFS_SEND_A_DATA, sctx->send_buf + sctx->send_size);
524262306a36Sopenharmony_ci		sctx->send_size += sizeof(__le16);
524362306a36Sopenharmony_ci	} else {
524462306a36Sopenharmony_ci		struct btrfs_tlv_header *hdr;
524562306a36Sopenharmony_ci
524662306a36Sopenharmony_ci		if (sctx->send_max_size - sctx->send_size < sizeof(*hdr) + len)
524762306a36Sopenharmony_ci			return -EOVERFLOW;
524862306a36Sopenharmony_ci		hdr = (struct btrfs_tlv_header *)(sctx->send_buf + sctx->send_size);
524962306a36Sopenharmony_ci		put_unaligned_le16(BTRFS_SEND_A_DATA, &hdr->tlv_type);
525062306a36Sopenharmony_ci		put_unaligned_le16(len, &hdr->tlv_len);
525162306a36Sopenharmony_ci		sctx->send_size += sizeof(*hdr);
525262306a36Sopenharmony_ci	}
525362306a36Sopenharmony_ci	return 0;
525462306a36Sopenharmony_ci}
525562306a36Sopenharmony_ci
525662306a36Sopenharmony_cistatic int put_file_data(struct send_ctx *sctx, u64 offset, u32 len)
525762306a36Sopenharmony_ci{
525862306a36Sopenharmony_ci	struct btrfs_root *root = sctx->send_root;
525962306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = root->fs_info;
526062306a36Sopenharmony_ci	struct page *page;
526162306a36Sopenharmony_ci	pgoff_t index = offset >> PAGE_SHIFT;
526262306a36Sopenharmony_ci	pgoff_t last_index;
526362306a36Sopenharmony_ci	unsigned pg_offset = offset_in_page(offset);
526462306a36Sopenharmony_ci	int ret;
526562306a36Sopenharmony_ci
526662306a36Sopenharmony_ci	ret = put_data_header(sctx, len);
526762306a36Sopenharmony_ci	if (ret)
526862306a36Sopenharmony_ci		return ret;
526962306a36Sopenharmony_ci
527062306a36Sopenharmony_ci	last_index = (offset + len - 1) >> PAGE_SHIFT;
527162306a36Sopenharmony_ci
527262306a36Sopenharmony_ci	while (index <= last_index) {
527362306a36Sopenharmony_ci		unsigned cur_len = min_t(unsigned, len,
527462306a36Sopenharmony_ci					 PAGE_SIZE - pg_offset);
527562306a36Sopenharmony_ci
527662306a36Sopenharmony_ci		page = find_lock_page(sctx->cur_inode->i_mapping, index);
527762306a36Sopenharmony_ci		if (!page) {
527862306a36Sopenharmony_ci			page_cache_sync_readahead(sctx->cur_inode->i_mapping,
527962306a36Sopenharmony_ci						  &sctx->ra, NULL, index,
528062306a36Sopenharmony_ci						  last_index + 1 - index);
528162306a36Sopenharmony_ci
528262306a36Sopenharmony_ci			page = find_or_create_page(sctx->cur_inode->i_mapping,
528362306a36Sopenharmony_ci						   index, GFP_KERNEL);
528462306a36Sopenharmony_ci			if (!page) {
528562306a36Sopenharmony_ci				ret = -ENOMEM;
528662306a36Sopenharmony_ci				break;
528762306a36Sopenharmony_ci			}
528862306a36Sopenharmony_ci		}
528962306a36Sopenharmony_ci
529062306a36Sopenharmony_ci		if (PageReadahead(page))
529162306a36Sopenharmony_ci			page_cache_async_readahead(sctx->cur_inode->i_mapping,
529262306a36Sopenharmony_ci						   &sctx->ra, NULL, page_folio(page),
529362306a36Sopenharmony_ci						   index, last_index + 1 - index);
529462306a36Sopenharmony_ci
529562306a36Sopenharmony_ci		if (!PageUptodate(page)) {
529662306a36Sopenharmony_ci			btrfs_read_folio(NULL, page_folio(page));
529762306a36Sopenharmony_ci			lock_page(page);
529862306a36Sopenharmony_ci			if (!PageUptodate(page)) {
529962306a36Sopenharmony_ci				unlock_page(page);
530062306a36Sopenharmony_ci				btrfs_err(fs_info,
530162306a36Sopenharmony_ci			"send: IO error at offset %llu for inode %llu root %llu",
530262306a36Sopenharmony_ci					page_offset(page), sctx->cur_ino,
530362306a36Sopenharmony_ci					sctx->send_root->root_key.objectid);
530462306a36Sopenharmony_ci				put_page(page);
530562306a36Sopenharmony_ci				ret = -EIO;
530662306a36Sopenharmony_ci				break;
530762306a36Sopenharmony_ci			}
530862306a36Sopenharmony_ci		}
530962306a36Sopenharmony_ci
531062306a36Sopenharmony_ci		memcpy_from_page(sctx->send_buf + sctx->send_size, page,
531162306a36Sopenharmony_ci				 pg_offset, cur_len);
531262306a36Sopenharmony_ci		unlock_page(page);
531362306a36Sopenharmony_ci		put_page(page);
531462306a36Sopenharmony_ci		index++;
531562306a36Sopenharmony_ci		pg_offset = 0;
531662306a36Sopenharmony_ci		len -= cur_len;
531762306a36Sopenharmony_ci		sctx->send_size += cur_len;
531862306a36Sopenharmony_ci	}
531962306a36Sopenharmony_ci
532062306a36Sopenharmony_ci	return ret;
532162306a36Sopenharmony_ci}
532262306a36Sopenharmony_ci
532362306a36Sopenharmony_ci/*
532462306a36Sopenharmony_ci * Read some bytes from the current inode/file and send a write command to
532562306a36Sopenharmony_ci * user space.
532662306a36Sopenharmony_ci */
532762306a36Sopenharmony_cistatic int send_write(struct send_ctx *sctx, u64 offset, u32 len)
532862306a36Sopenharmony_ci{
532962306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
533062306a36Sopenharmony_ci	int ret = 0;
533162306a36Sopenharmony_ci	struct fs_path *p;
533262306a36Sopenharmony_ci
533362306a36Sopenharmony_ci	p = fs_path_alloc();
533462306a36Sopenharmony_ci	if (!p)
533562306a36Sopenharmony_ci		return -ENOMEM;
533662306a36Sopenharmony_ci
533762306a36Sopenharmony_ci	btrfs_debug(fs_info, "send_write offset=%llu, len=%d", offset, len);
533862306a36Sopenharmony_ci
533962306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE);
534062306a36Sopenharmony_ci	if (ret < 0)
534162306a36Sopenharmony_ci		goto out;
534262306a36Sopenharmony_ci
534362306a36Sopenharmony_ci	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
534462306a36Sopenharmony_ci	if (ret < 0)
534562306a36Sopenharmony_ci		goto out;
534662306a36Sopenharmony_ci
534762306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
534862306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
534962306a36Sopenharmony_ci	ret = put_file_data(sctx, offset, len);
535062306a36Sopenharmony_ci	if (ret < 0)
535162306a36Sopenharmony_ci		goto out;
535262306a36Sopenharmony_ci
535362306a36Sopenharmony_ci	ret = send_cmd(sctx);
535462306a36Sopenharmony_ci
535562306a36Sopenharmony_citlv_put_failure:
535662306a36Sopenharmony_ciout:
535762306a36Sopenharmony_ci	fs_path_free(p);
535862306a36Sopenharmony_ci	return ret;
535962306a36Sopenharmony_ci}
536062306a36Sopenharmony_ci
536162306a36Sopenharmony_ci/*
536262306a36Sopenharmony_ci * Send a clone command to user space.
536362306a36Sopenharmony_ci */
536462306a36Sopenharmony_cistatic int send_clone(struct send_ctx *sctx,
536562306a36Sopenharmony_ci		      u64 offset, u32 len,
536662306a36Sopenharmony_ci		      struct clone_root *clone_root)
536762306a36Sopenharmony_ci{
536862306a36Sopenharmony_ci	int ret = 0;
536962306a36Sopenharmony_ci	struct fs_path *p;
537062306a36Sopenharmony_ci	u64 gen;
537162306a36Sopenharmony_ci
537262306a36Sopenharmony_ci	btrfs_debug(sctx->send_root->fs_info,
537362306a36Sopenharmony_ci		    "send_clone offset=%llu, len=%d, clone_root=%llu, clone_inode=%llu, clone_offset=%llu",
537462306a36Sopenharmony_ci		    offset, len, clone_root->root->root_key.objectid,
537562306a36Sopenharmony_ci		    clone_root->ino, clone_root->offset);
537662306a36Sopenharmony_ci
537762306a36Sopenharmony_ci	p = fs_path_alloc();
537862306a36Sopenharmony_ci	if (!p)
537962306a36Sopenharmony_ci		return -ENOMEM;
538062306a36Sopenharmony_ci
538162306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_CLONE);
538262306a36Sopenharmony_ci	if (ret < 0)
538362306a36Sopenharmony_ci		goto out;
538462306a36Sopenharmony_ci
538562306a36Sopenharmony_ci	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
538662306a36Sopenharmony_ci	if (ret < 0)
538762306a36Sopenharmony_ci		goto out;
538862306a36Sopenharmony_ci
538962306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
539062306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_LEN, len);
539162306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
539262306a36Sopenharmony_ci
539362306a36Sopenharmony_ci	if (clone_root->root == sctx->send_root) {
539462306a36Sopenharmony_ci		ret = get_inode_gen(sctx->send_root, clone_root->ino, &gen);
539562306a36Sopenharmony_ci		if (ret < 0)
539662306a36Sopenharmony_ci			goto out;
539762306a36Sopenharmony_ci		ret = get_cur_path(sctx, clone_root->ino, gen, p);
539862306a36Sopenharmony_ci	} else {
539962306a36Sopenharmony_ci		ret = get_inode_path(clone_root->root, clone_root->ino, p);
540062306a36Sopenharmony_ci	}
540162306a36Sopenharmony_ci	if (ret < 0)
540262306a36Sopenharmony_ci		goto out;
540362306a36Sopenharmony_ci
540462306a36Sopenharmony_ci	/*
540562306a36Sopenharmony_ci	 * If the parent we're using has a received_uuid set then use that as
540662306a36Sopenharmony_ci	 * our clone source as that is what we will look for when doing a
540762306a36Sopenharmony_ci	 * receive.
540862306a36Sopenharmony_ci	 *
540962306a36Sopenharmony_ci	 * This covers the case that we create a snapshot off of a received
541062306a36Sopenharmony_ci	 * subvolume and then use that as the parent and try to receive on a
541162306a36Sopenharmony_ci	 * different host.
541262306a36Sopenharmony_ci	 */
541362306a36Sopenharmony_ci	if (!btrfs_is_empty_uuid(clone_root->root->root_item.received_uuid))
541462306a36Sopenharmony_ci		TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID,
541562306a36Sopenharmony_ci			     clone_root->root->root_item.received_uuid);
541662306a36Sopenharmony_ci	else
541762306a36Sopenharmony_ci		TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID,
541862306a36Sopenharmony_ci			     clone_root->root->root_item.uuid);
541962306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_CTRANSID,
542062306a36Sopenharmony_ci		    btrfs_root_ctransid(&clone_root->root->root_item));
542162306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_CLONE_PATH, p);
542262306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_OFFSET,
542362306a36Sopenharmony_ci			clone_root->offset);
542462306a36Sopenharmony_ci
542562306a36Sopenharmony_ci	ret = send_cmd(sctx);
542662306a36Sopenharmony_ci
542762306a36Sopenharmony_citlv_put_failure:
542862306a36Sopenharmony_ciout:
542962306a36Sopenharmony_ci	fs_path_free(p);
543062306a36Sopenharmony_ci	return ret;
543162306a36Sopenharmony_ci}
543262306a36Sopenharmony_ci
543362306a36Sopenharmony_ci/*
543462306a36Sopenharmony_ci * Send an update extent command to user space.
543562306a36Sopenharmony_ci */
543662306a36Sopenharmony_cistatic int send_update_extent(struct send_ctx *sctx,
543762306a36Sopenharmony_ci			      u64 offset, u32 len)
543862306a36Sopenharmony_ci{
543962306a36Sopenharmony_ci	int ret = 0;
544062306a36Sopenharmony_ci	struct fs_path *p;
544162306a36Sopenharmony_ci
544262306a36Sopenharmony_ci	p = fs_path_alloc();
544362306a36Sopenharmony_ci	if (!p)
544462306a36Sopenharmony_ci		return -ENOMEM;
544562306a36Sopenharmony_ci
544662306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_UPDATE_EXTENT);
544762306a36Sopenharmony_ci	if (ret < 0)
544862306a36Sopenharmony_ci		goto out;
544962306a36Sopenharmony_ci
545062306a36Sopenharmony_ci	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
545162306a36Sopenharmony_ci	if (ret < 0)
545262306a36Sopenharmony_ci		goto out;
545362306a36Sopenharmony_ci
545462306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
545562306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
545662306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_SIZE, len);
545762306a36Sopenharmony_ci
545862306a36Sopenharmony_ci	ret = send_cmd(sctx);
545962306a36Sopenharmony_ci
546062306a36Sopenharmony_citlv_put_failure:
546162306a36Sopenharmony_ciout:
546262306a36Sopenharmony_ci	fs_path_free(p);
546362306a36Sopenharmony_ci	return ret;
546462306a36Sopenharmony_ci}
546562306a36Sopenharmony_ci
546662306a36Sopenharmony_cistatic int send_hole(struct send_ctx *sctx, u64 end)
546762306a36Sopenharmony_ci{
546862306a36Sopenharmony_ci	struct fs_path *p = NULL;
546962306a36Sopenharmony_ci	u64 read_size = max_send_read_size(sctx);
547062306a36Sopenharmony_ci	u64 offset = sctx->cur_inode_last_extent;
547162306a36Sopenharmony_ci	int ret = 0;
547262306a36Sopenharmony_ci
547362306a36Sopenharmony_ci	/*
547462306a36Sopenharmony_ci	 * A hole that starts at EOF or beyond it. Since we do not yet support
547562306a36Sopenharmony_ci	 * fallocate (for extent preallocation and hole punching), sending a
547662306a36Sopenharmony_ci	 * write of zeroes starting at EOF or beyond would later require issuing
547762306a36Sopenharmony_ci	 * a truncate operation which would undo the write and achieve nothing.
547862306a36Sopenharmony_ci	 */
547962306a36Sopenharmony_ci	if (offset >= sctx->cur_inode_size)
548062306a36Sopenharmony_ci		return 0;
548162306a36Sopenharmony_ci
548262306a36Sopenharmony_ci	/*
548362306a36Sopenharmony_ci	 * Don't go beyond the inode's i_size due to prealloc extents that start
548462306a36Sopenharmony_ci	 * after the i_size.
548562306a36Sopenharmony_ci	 */
548662306a36Sopenharmony_ci	end = min_t(u64, end, sctx->cur_inode_size);
548762306a36Sopenharmony_ci
548862306a36Sopenharmony_ci	if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA)
548962306a36Sopenharmony_ci		return send_update_extent(sctx, offset, end - offset);
549062306a36Sopenharmony_ci
549162306a36Sopenharmony_ci	p = fs_path_alloc();
549262306a36Sopenharmony_ci	if (!p)
549362306a36Sopenharmony_ci		return -ENOMEM;
549462306a36Sopenharmony_ci	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
549562306a36Sopenharmony_ci	if (ret < 0)
549662306a36Sopenharmony_ci		goto tlv_put_failure;
549762306a36Sopenharmony_ci	while (offset < end) {
549862306a36Sopenharmony_ci		u64 len = min(end - offset, read_size);
549962306a36Sopenharmony_ci
550062306a36Sopenharmony_ci		ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE);
550162306a36Sopenharmony_ci		if (ret < 0)
550262306a36Sopenharmony_ci			break;
550362306a36Sopenharmony_ci		TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
550462306a36Sopenharmony_ci		TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
550562306a36Sopenharmony_ci		ret = put_data_header(sctx, len);
550662306a36Sopenharmony_ci		if (ret < 0)
550762306a36Sopenharmony_ci			break;
550862306a36Sopenharmony_ci		memset(sctx->send_buf + sctx->send_size, 0, len);
550962306a36Sopenharmony_ci		sctx->send_size += len;
551062306a36Sopenharmony_ci		ret = send_cmd(sctx);
551162306a36Sopenharmony_ci		if (ret < 0)
551262306a36Sopenharmony_ci			break;
551362306a36Sopenharmony_ci		offset += len;
551462306a36Sopenharmony_ci	}
551562306a36Sopenharmony_ci	sctx->cur_inode_next_write_offset = offset;
551662306a36Sopenharmony_citlv_put_failure:
551762306a36Sopenharmony_ci	fs_path_free(p);
551862306a36Sopenharmony_ci	return ret;
551962306a36Sopenharmony_ci}
552062306a36Sopenharmony_ci
552162306a36Sopenharmony_cistatic int send_encoded_inline_extent(struct send_ctx *sctx,
552262306a36Sopenharmony_ci				      struct btrfs_path *path, u64 offset,
552362306a36Sopenharmony_ci				      u64 len)
552462306a36Sopenharmony_ci{
552562306a36Sopenharmony_ci	struct btrfs_root *root = sctx->send_root;
552662306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = root->fs_info;
552762306a36Sopenharmony_ci	struct inode *inode;
552862306a36Sopenharmony_ci	struct fs_path *fspath;
552962306a36Sopenharmony_ci	struct extent_buffer *leaf = path->nodes[0];
553062306a36Sopenharmony_ci	struct btrfs_key key;
553162306a36Sopenharmony_ci	struct btrfs_file_extent_item *ei;
553262306a36Sopenharmony_ci	u64 ram_bytes;
553362306a36Sopenharmony_ci	size_t inline_size;
553462306a36Sopenharmony_ci	int ret;
553562306a36Sopenharmony_ci
553662306a36Sopenharmony_ci	inode = btrfs_iget(fs_info->sb, sctx->cur_ino, root);
553762306a36Sopenharmony_ci	if (IS_ERR(inode))
553862306a36Sopenharmony_ci		return PTR_ERR(inode);
553962306a36Sopenharmony_ci
554062306a36Sopenharmony_ci	fspath = fs_path_alloc();
554162306a36Sopenharmony_ci	if (!fspath) {
554262306a36Sopenharmony_ci		ret = -ENOMEM;
554362306a36Sopenharmony_ci		goto out;
554462306a36Sopenharmony_ci	}
554562306a36Sopenharmony_ci
554662306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_ENCODED_WRITE);
554762306a36Sopenharmony_ci	if (ret < 0)
554862306a36Sopenharmony_ci		goto out;
554962306a36Sopenharmony_ci
555062306a36Sopenharmony_ci	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath);
555162306a36Sopenharmony_ci	if (ret < 0)
555262306a36Sopenharmony_ci		goto out;
555362306a36Sopenharmony_ci
555462306a36Sopenharmony_ci	btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
555562306a36Sopenharmony_ci	ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item);
555662306a36Sopenharmony_ci	ram_bytes = btrfs_file_extent_ram_bytes(leaf, ei);
555762306a36Sopenharmony_ci	inline_size = btrfs_file_extent_inline_item_len(leaf, path->slots[0]);
555862306a36Sopenharmony_ci
555962306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, fspath);
556062306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
556162306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_UNENCODED_FILE_LEN,
556262306a36Sopenharmony_ci		    min(key.offset + ram_bytes - offset, len));
556362306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_UNENCODED_LEN, ram_bytes);
556462306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_UNENCODED_OFFSET, offset - key.offset);
556562306a36Sopenharmony_ci	ret = btrfs_encoded_io_compression_from_extent(fs_info,
556662306a36Sopenharmony_ci				btrfs_file_extent_compression(leaf, ei));
556762306a36Sopenharmony_ci	if (ret < 0)
556862306a36Sopenharmony_ci		goto out;
556962306a36Sopenharmony_ci	TLV_PUT_U32(sctx, BTRFS_SEND_A_COMPRESSION, ret);
557062306a36Sopenharmony_ci
557162306a36Sopenharmony_ci	ret = put_data_header(sctx, inline_size);
557262306a36Sopenharmony_ci	if (ret < 0)
557362306a36Sopenharmony_ci		goto out;
557462306a36Sopenharmony_ci	read_extent_buffer(leaf, sctx->send_buf + sctx->send_size,
557562306a36Sopenharmony_ci			   btrfs_file_extent_inline_start(ei), inline_size);
557662306a36Sopenharmony_ci	sctx->send_size += inline_size;
557762306a36Sopenharmony_ci
557862306a36Sopenharmony_ci	ret = send_cmd(sctx);
557962306a36Sopenharmony_ci
558062306a36Sopenharmony_citlv_put_failure:
558162306a36Sopenharmony_ciout:
558262306a36Sopenharmony_ci	fs_path_free(fspath);
558362306a36Sopenharmony_ci	iput(inode);
558462306a36Sopenharmony_ci	return ret;
558562306a36Sopenharmony_ci}
558662306a36Sopenharmony_ci
558762306a36Sopenharmony_cistatic int send_encoded_extent(struct send_ctx *sctx, struct btrfs_path *path,
558862306a36Sopenharmony_ci			       u64 offset, u64 len)
558962306a36Sopenharmony_ci{
559062306a36Sopenharmony_ci	struct btrfs_root *root = sctx->send_root;
559162306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = root->fs_info;
559262306a36Sopenharmony_ci	struct inode *inode;
559362306a36Sopenharmony_ci	struct fs_path *fspath;
559462306a36Sopenharmony_ci	struct extent_buffer *leaf = path->nodes[0];
559562306a36Sopenharmony_ci	struct btrfs_key key;
559662306a36Sopenharmony_ci	struct btrfs_file_extent_item *ei;
559762306a36Sopenharmony_ci	u64 disk_bytenr, disk_num_bytes;
559862306a36Sopenharmony_ci	u32 data_offset;
559962306a36Sopenharmony_ci	struct btrfs_cmd_header *hdr;
560062306a36Sopenharmony_ci	u32 crc;
560162306a36Sopenharmony_ci	int ret;
560262306a36Sopenharmony_ci
560362306a36Sopenharmony_ci	inode = btrfs_iget(fs_info->sb, sctx->cur_ino, root);
560462306a36Sopenharmony_ci	if (IS_ERR(inode))
560562306a36Sopenharmony_ci		return PTR_ERR(inode);
560662306a36Sopenharmony_ci
560762306a36Sopenharmony_ci	fspath = fs_path_alloc();
560862306a36Sopenharmony_ci	if (!fspath) {
560962306a36Sopenharmony_ci		ret = -ENOMEM;
561062306a36Sopenharmony_ci		goto out;
561162306a36Sopenharmony_ci	}
561262306a36Sopenharmony_ci
561362306a36Sopenharmony_ci	ret = begin_cmd(sctx, BTRFS_SEND_C_ENCODED_WRITE);
561462306a36Sopenharmony_ci	if (ret < 0)
561562306a36Sopenharmony_ci		goto out;
561662306a36Sopenharmony_ci
561762306a36Sopenharmony_ci	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath);
561862306a36Sopenharmony_ci	if (ret < 0)
561962306a36Sopenharmony_ci		goto out;
562062306a36Sopenharmony_ci
562162306a36Sopenharmony_ci	btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
562262306a36Sopenharmony_ci	ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item);
562362306a36Sopenharmony_ci	disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, ei);
562462306a36Sopenharmony_ci	disk_num_bytes = btrfs_file_extent_disk_num_bytes(leaf, ei);
562562306a36Sopenharmony_ci
562662306a36Sopenharmony_ci	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, fspath);
562762306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
562862306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_UNENCODED_FILE_LEN,
562962306a36Sopenharmony_ci		    min(key.offset + btrfs_file_extent_num_bytes(leaf, ei) - offset,
563062306a36Sopenharmony_ci			len));
563162306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_UNENCODED_LEN,
563262306a36Sopenharmony_ci		    btrfs_file_extent_ram_bytes(leaf, ei));
563362306a36Sopenharmony_ci	TLV_PUT_U64(sctx, BTRFS_SEND_A_UNENCODED_OFFSET,
563462306a36Sopenharmony_ci		    offset - key.offset + btrfs_file_extent_offset(leaf, ei));
563562306a36Sopenharmony_ci	ret = btrfs_encoded_io_compression_from_extent(fs_info,
563662306a36Sopenharmony_ci				btrfs_file_extent_compression(leaf, ei));
563762306a36Sopenharmony_ci	if (ret < 0)
563862306a36Sopenharmony_ci		goto out;
563962306a36Sopenharmony_ci	TLV_PUT_U32(sctx, BTRFS_SEND_A_COMPRESSION, ret);
564062306a36Sopenharmony_ci	TLV_PUT_U32(sctx, BTRFS_SEND_A_ENCRYPTION, 0);
564162306a36Sopenharmony_ci
564262306a36Sopenharmony_ci	ret = put_data_header(sctx, disk_num_bytes);
564362306a36Sopenharmony_ci	if (ret < 0)
564462306a36Sopenharmony_ci		goto out;
564562306a36Sopenharmony_ci
564662306a36Sopenharmony_ci	/*
564762306a36Sopenharmony_ci	 * We want to do I/O directly into the send buffer, so get the next page
564862306a36Sopenharmony_ci	 * boundary in the send buffer. This means that there may be a gap
564962306a36Sopenharmony_ci	 * between the beginning of the command and the file data.
565062306a36Sopenharmony_ci	 */
565162306a36Sopenharmony_ci	data_offset = PAGE_ALIGN(sctx->send_size);
565262306a36Sopenharmony_ci	if (data_offset > sctx->send_max_size ||
565362306a36Sopenharmony_ci	    sctx->send_max_size - data_offset < disk_num_bytes) {
565462306a36Sopenharmony_ci		ret = -EOVERFLOW;
565562306a36Sopenharmony_ci		goto out;
565662306a36Sopenharmony_ci	}
565762306a36Sopenharmony_ci
565862306a36Sopenharmony_ci	/*
565962306a36Sopenharmony_ci	 * Note that send_buf is a mapping of send_buf_pages, so this is really
566062306a36Sopenharmony_ci	 * reading into send_buf.
566162306a36Sopenharmony_ci	 */
566262306a36Sopenharmony_ci	ret = btrfs_encoded_read_regular_fill_pages(BTRFS_I(inode), offset,
566362306a36Sopenharmony_ci						    disk_bytenr, disk_num_bytes,
566462306a36Sopenharmony_ci						    sctx->send_buf_pages +
566562306a36Sopenharmony_ci						    (data_offset >> PAGE_SHIFT));
566662306a36Sopenharmony_ci	if (ret)
566762306a36Sopenharmony_ci		goto out;
566862306a36Sopenharmony_ci
566962306a36Sopenharmony_ci	hdr = (struct btrfs_cmd_header *)sctx->send_buf;
567062306a36Sopenharmony_ci	hdr->len = cpu_to_le32(sctx->send_size + disk_num_bytes - sizeof(*hdr));
567162306a36Sopenharmony_ci	hdr->crc = 0;
567262306a36Sopenharmony_ci	crc = btrfs_crc32c(0, sctx->send_buf, sctx->send_size);
567362306a36Sopenharmony_ci	crc = btrfs_crc32c(crc, sctx->send_buf + data_offset, disk_num_bytes);
567462306a36Sopenharmony_ci	hdr->crc = cpu_to_le32(crc);
567562306a36Sopenharmony_ci
567662306a36Sopenharmony_ci	ret = write_buf(sctx->send_filp, sctx->send_buf, sctx->send_size,
567762306a36Sopenharmony_ci			&sctx->send_off);
567862306a36Sopenharmony_ci	if (!ret) {
567962306a36Sopenharmony_ci		ret = write_buf(sctx->send_filp, sctx->send_buf + data_offset,
568062306a36Sopenharmony_ci				disk_num_bytes, &sctx->send_off);
568162306a36Sopenharmony_ci	}
568262306a36Sopenharmony_ci	sctx->send_size = 0;
568362306a36Sopenharmony_ci	sctx->put_data = false;
568462306a36Sopenharmony_ci
568562306a36Sopenharmony_citlv_put_failure:
568662306a36Sopenharmony_ciout:
568762306a36Sopenharmony_ci	fs_path_free(fspath);
568862306a36Sopenharmony_ci	iput(inode);
568962306a36Sopenharmony_ci	return ret;
569062306a36Sopenharmony_ci}
569162306a36Sopenharmony_ci
569262306a36Sopenharmony_cistatic int send_extent_data(struct send_ctx *sctx, struct btrfs_path *path,
569362306a36Sopenharmony_ci			    const u64 offset, const u64 len)
569462306a36Sopenharmony_ci{
569562306a36Sopenharmony_ci	const u64 end = offset + len;
569662306a36Sopenharmony_ci	struct extent_buffer *leaf = path->nodes[0];
569762306a36Sopenharmony_ci	struct btrfs_file_extent_item *ei;
569862306a36Sopenharmony_ci	u64 read_size = max_send_read_size(sctx);
569962306a36Sopenharmony_ci	u64 sent = 0;
570062306a36Sopenharmony_ci
570162306a36Sopenharmony_ci	if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA)
570262306a36Sopenharmony_ci		return send_update_extent(sctx, offset, len);
570362306a36Sopenharmony_ci
570462306a36Sopenharmony_ci	ei = btrfs_item_ptr(leaf, path->slots[0],
570562306a36Sopenharmony_ci			    struct btrfs_file_extent_item);
570662306a36Sopenharmony_ci	if ((sctx->flags & BTRFS_SEND_FLAG_COMPRESSED) &&
570762306a36Sopenharmony_ci	    btrfs_file_extent_compression(leaf, ei) != BTRFS_COMPRESS_NONE) {
570862306a36Sopenharmony_ci		bool is_inline = (btrfs_file_extent_type(leaf, ei) ==
570962306a36Sopenharmony_ci				  BTRFS_FILE_EXTENT_INLINE);
571062306a36Sopenharmony_ci
571162306a36Sopenharmony_ci		/*
571262306a36Sopenharmony_ci		 * Send the compressed extent unless the compressed data is
571362306a36Sopenharmony_ci		 * larger than the decompressed data. This can happen if we're
571462306a36Sopenharmony_ci		 * not sending the entire extent, either because it has been
571562306a36Sopenharmony_ci		 * partially overwritten/truncated or because this is a part of
571662306a36Sopenharmony_ci		 * the extent that we couldn't clone in clone_range().
571762306a36Sopenharmony_ci		 */
571862306a36Sopenharmony_ci		if (is_inline &&
571962306a36Sopenharmony_ci		    btrfs_file_extent_inline_item_len(leaf,
572062306a36Sopenharmony_ci						      path->slots[0]) <= len) {
572162306a36Sopenharmony_ci			return send_encoded_inline_extent(sctx, path, offset,
572262306a36Sopenharmony_ci							  len);
572362306a36Sopenharmony_ci		} else if (!is_inline &&
572462306a36Sopenharmony_ci			   btrfs_file_extent_disk_num_bytes(leaf, ei) <= len) {
572562306a36Sopenharmony_ci			return send_encoded_extent(sctx, path, offset, len);
572662306a36Sopenharmony_ci		}
572762306a36Sopenharmony_ci	}
572862306a36Sopenharmony_ci
572962306a36Sopenharmony_ci	if (sctx->cur_inode == NULL) {
573062306a36Sopenharmony_ci		struct btrfs_root *root = sctx->send_root;
573162306a36Sopenharmony_ci
573262306a36Sopenharmony_ci		sctx->cur_inode = btrfs_iget(root->fs_info->sb, sctx->cur_ino, root);
573362306a36Sopenharmony_ci		if (IS_ERR(sctx->cur_inode)) {
573462306a36Sopenharmony_ci			int err = PTR_ERR(sctx->cur_inode);
573562306a36Sopenharmony_ci
573662306a36Sopenharmony_ci			sctx->cur_inode = NULL;
573762306a36Sopenharmony_ci			return err;
573862306a36Sopenharmony_ci		}
573962306a36Sopenharmony_ci		memset(&sctx->ra, 0, sizeof(struct file_ra_state));
574062306a36Sopenharmony_ci		file_ra_state_init(&sctx->ra, sctx->cur_inode->i_mapping);
574162306a36Sopenharmony_ci
574262306a36Sopenharmony_ci		/*
574362306a36Sopenharmony_ci		 * It's very likely there are no pages from this inode in the page
574462306a36Sopenharmony_ci		 * cache, so after reading extents and sending their data, we clean
574562306a36Sopenharmony_ci		 * the page cache to avoid trashing the page cache (adding pressure
574662306a36Sopenharmony_ci		 * to the page cache and forcing eviction of other data more useful
574762306a36Sopenharmony_ci		 * for applications).
574862306a36Sopenharmony_ci		 *
574962306a36Sopenharmony_ci		 * We decide if we should clean the page cache simply by checking
575062306a36Sopenharmony_ci		 * if the inode's mapping nrpages is 0 when we first open it, and
575162306a36Sopenharmony_ci		 * not by using something like filemap_range_has_page() before
575262306a36Sopenharmony_ci		 * reading an extent because when we ask the readahead code to
575362306a36Sopenharmony_ci		 * read a given file range, it may (and almost always does) read
575462306a36Sopenharmony_ci		 * pages from beyond that range (see the documentation for
575562306a36Sopenharmony_ci		 * page_cache_sync_readahead()), so it would not be reliable,
575662306a36Sopenharmony_ci		 * because after reading the first extent future calls to
575762306a36Sopenharmony_ci		 * filemap_range_has_page() would return true because the readahead
575862306a36Sopenharmony_ci		 * on the previous extent resulted in reading pages of the current
575962306a36Sopenharmony_ci		 * extent as well.
576062306a36Sopenharmony_ci		 */
576162306a36Sopenharmony_ci		sctx->clean_page_cache = (sctx->cur_inode->i_mapping->nrpages == 0);
576262306a36Sopenharmony_ci		sctx->page_cache_clear_start = round_down(offset, PAGE_SIZE);
576362306a36Sopenharmony_ci	}
576462306a36Sopenharmony_ci
576562306a36Sopenharmony_ci	while (sent < len) {
576662306a36Sopenharmony_ci		u64 size = min(len - sent, read_size);
576762306a36Sopenharmony_ci		int ret;
576862306a36Sopenharmony_ci
576962306a36Sopenharmony_ci		ret = send_write(sctx, offset + sent, size);
577062306a36Sopenharmony_ci		if (ret < 0)
577162306a36Sopenharmony_ci			return ret;
577262306a36Sopenharmony_ci		sent += size;
577362306a36Sopenharmony_ci	}
577462306a36Sopenharmony_ci
577562306a36Sopenharmony_ci	if (sctx->clean_page_cache && PAGE_ALIGNED(end)) {
577662306a36Sopenharmony_ci		/*
577762306a36Sopenharmony_ci		 * Always operate only on ranges that are a multiple of the page
577862306a36Sopenharmony_ci		 * size. This is not only to prevent zeroing parts of a page in
577962306a36Sopenharmony_ci		 * the case of subpage sector size, but also to guarantee we evict
578062306a36Sopenharmony_ci		 * pages, as passing a range that is smaller than page size does
578162306a36Sopenharmony_ci		 * not evict the respective page (only zeroes part of its content).
578262306a36Sopenharmony_ci		 *
578362306a36Sopenharmony_ci		 * Always start from the end offset of the last range cleared.
578462306a36Sopenharmony_ci		 * This is because the readahead code may (and very often does)
578562306a36Sopenharmony_ci		 * reads pages beyond the range we request for readahead. So if
578662306a36Sopenharmony_ci		 * we have an extent layout like this:
578762306a36Sopenharmony_ci		 *
578862306a36Sopenharmony_ci		 *            [ extent A ] [ extent B ] [ extent C ]
578962306a36Sopenharmony_ci		 *
579062306a36Sopenharmony_ci		 * When we ask page_cache_sync_readahead() to read extent A, it
579162306a36Sopenharmony_ci		 * may also trigger reads for pages of extent B. If we are doing
579262306a36Sopenharmony_ci		 * an incremental send and extent B has not changed between the
579362306a36Sopenharmony_ci		 * parent and send snapshots, some or all of its pages may end
579462306a36Sopenharmony_ci		 * up being read and placed in the page cache. So when truncating
579562306a36Sopenharmony_ci		 * the page cache we always start from the end offset of the
579662306a36Sopenharmony_ci		 * previously processed extent up to the end of the current
579762306a36Sopenharmony_ci		 * extent.
579862306a36Sopenharmony_ci		 */
579962306a36Sopenharmony_ci		truncate_inode_pages_range(&sctx->cur_inode->i_data,
580062306a36Sopenharmony_ci					   sctx->page_cache_clear_start,
580162306a36Sopenharmony_ci					   end - 1);
580262306a36Sopenharmony_ci		sctx->page_cache_clear_start = end;
580362306a36Sopenharmony_ci	}
580462306a36Sopenharmony_ci
580562306a36Sopenharmony_ci	return 0;
580662306a36Sopenharmony_ci}
580762306a36Sopenharmony_ci
580862306a36Sopenharmony_ci/*
580962306a36Sopenharmony_ci * Search for a capability xattr related to sctx->cur_ino. If the capability is
581062306a36Sopenharmony_ci * found, call send_set_xattr function to emit it.
581162306a36Sopenharmony_ci *
581262306a36Sopenharmony_ci * Return 0 if there isn't a capability, or when the capability was emitted
581362306a36Sopenharmony_ci * successfully, or < 0 if an error occurred.
581462306a36Sopenharmony_ci */
581562306a36Sopenharmony_cistatic int send_capabilities(struct send_ctx *sctx)
581662306a36Sopenharmony_ci{
581762306a36Sopenharmony_ci	struct fs_path *fspath = NULL;
581862306a36Sopenharmony_ci	struct btrfs_path *path;
581962306a36Sopenharmony_ci	struct btrfs_dir_item *di;
582062306a36Sopenharmony_ci	struct extent_buffer *leaf;
582162306a36Sopenharmony_ci	unsigned long data_ptr;
582262306a36Sopenharmony_ci	char *buf = NULL;
582362306a36Sopenharmony_ci	int buf_len;
582462306a36Sopenharmony_ci	int ret = 0;
582562306a36Sopenharmony_ci
582662306a36Sopenharmony_ci	path = alloc_path_for_send();
582762306a36Sopenharmony_ci	if (!path)
582862306a36Sopenharmony_ci		return -ENOMEM;
582962306a36Sopenharmony_ci
583062306a36Sopenharmony_ci	di = btrfs_lookup_xattr(NULL, sctx->send_root, path, sctx->cur_ino,
583162306a36Sopenharmony_ci				XATTR_NAME_CAPS, strlen(XATTR_NAME_CAPS), 0);
583262306a36Sopenharmony_ci	if (!di) {
583362306a36Sopenharmony_ci		/* There is no xattr for this inode */
583462306a36Sopenharmony_ci		goto out;
583562306a36Sopenharmony_ci	} else if (IS_ERR(di)) {
583662306a36Sopenharmony_ci		ret = PTR_ERR(di);
583762306a36Sopenharmony_ci		goto out;
583862306a36Sopenharmony_ci	}
583962306a36Sopenharmony_ci
584062306a36Sopenharmony_ci	leaf = path->nodes[0];
584162306a36Sopenharmony_ci	buf_len = btrfs_dir_data_len(leaf, di);
584262306a36Sopenharmony_ci
584362306a36Sopenharmony_ci	fspath = fs_path_alloc();
584462306a36Sopenharmony_ci	buf = kmalloc(buf_len, GFP_KERNEL);
584562306a36Sopenharmony_ci	if (!fspath || !buf) {
584662306a36Sopenharmony_ci		ret = -ENOMEM;
584762306a36Sopenharmony_ci		goto out;
584862306a36Sopenharmony_ci	}
584962306a36Sopenharmony_ci
585062306a36Sopenharmony_ci	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath);
585162306a36Sopenharmony_ci	if (ret < 0)
585262306a36Sopenharmony_ci		goto out;
585362306a36Sopenharmony_ci
585462306a36Sopenharmony_ci	data_ptr = (unsigned long)(di + 1) + btrfs_dir_name_len(leaf, di);
585562306a36Sopenharmony_ci	read_extent_buffer(leaf, buf, data_ptr, buf_len);
585662306a36Sopenharmony_ci
585762306a36Sopenharmony_ci	ret = send_set_xattr(sctx, fspath, XATTR_NAME_CAPS,
585862306a36Sopenharmony_ci			strlen(XATTR_NAME_CAPS), buf, buf_len);
585962306a36Sopenharmony_ciout:
586062306a36Sopenharmony_ci	kfree(buf);
586162306a36Sopenharmony_ci	fs_path_free(fspath);
586262306a36Sopenharmony_ci	btrfs_free_path(path);
586362306a36Sopenharmony_ci	return ret;
586462306a36Sopenharmony_ci}
586562306a36Sopenharmony_ci
586662306a36Sopenharmony_cistatic int clone_range(struct send_ctx *sctx, struct btrfs_path *dst_path,
586762306a36Sopenharmony_ci		       struct clone_root *clone_root, const u64 disk_byte,
586862306a36Sopenharmony_ci		       u64 data_offset, u64 offset, u64 len)
586962306a36Sopenharmony_ci{
587062306a36Sopenharmony_ci	struct btrfs_path *path;
587162306a36Sopenharmony_ci	struct btrfs_key key;
587262306a36Sopenharmony_ci	int ret;
587362306a36Sopenharmony_ci	struct btrfs_inode_info info;
587462306a36Sopenharmony_ci	u64 clone_src_i_size = 0;
587562306a36Sopenharmony_ci
587662306a36Sopenharmony_ci	/*
587762306a36Sopenharmony_ci	 * Prevent cloning from a zero offset with a length matching the sector
587862306a36Sopenharmony_ci	 * size because in some scenarios this will make the receiver fail.
587962306a36Sopenharmony_ci	 *
588062306a36Sopenharmony_ci	 * For example, if in the source filesystem the extent at offset 0
588162306a36Sopenharmony_ci	 * has a length of sectorsize and it was written using direct IO, then
588262306a36Sopenharmony_ci	 * it can never be an inline extent (even if compression is enabled).
588362306a36Sopenharmony_ci	 * Then this extent can be cloned in the original filesystem to a non
588462306a36Sopenharmony_ci	 * zero file offset, but it may not be possible to clone in the
588562306a36Sopenharmony_ci	 * destination filesystem because it can be inlined due to compression
588662306a36Sopenharmony_ci	 * on the destination filesystem (as the receiver's write operations are
588762306a36Sopenharmony_ci	 * always done using buffered IO). The same happens when the original
588862306a36Sopenharmony_ci	 * filesystem does not have compression enabled but the destination
588962306a36Sopenharmony_ci	 * filesystem has.
589062306a36Sopenharmony_ci	 */
589162306a36Sopenharmony_ci	if (clone_root->offset == 0 &&
589262306a36Sopenharmony_ci	    len == sctx->send_root->fs_info->sectorsize)
589362306a36Sopenharmony_ci		return send_extent_data(sctx, dst_path, offset, len);
589462306a36Sopenharmony_ci
589562306a36Sopenharmony_ci	path = alloc_path_for_send();
589662306a36Sopenharmony_ci	if (!path)
589762306a36Sopenharmony_ci		return -ENOMEM;
589862306a36Sopenharmony_ci
589962306a36Sopenharmony_ci	/*
590062306a36Sopenharmony_ci	 * There are inodes that have extents that lie behind its i_size. Don't
590162306a36Sopenharmony_ci	 * accept clones from these extents.
590262306a36Sopenharmony_ci	 */
590362306a36Sopenharmony_ci	ret = get_inode_info(clone_root->root, clone_root->ino, &info);
590462306a36Sopenharmony_ci	btrfs_release_path(path);
590562306a36Sopenharmony_ci	if (ret < 0)
590662306a36Sopenharmony_ci		goto out;
590762306a36Sopenharmony_ci	clone_src_i_size = info.size;
590862306a36Sopenharmony_ci
590962306a36Sopenharmony_ci	/*
591062306a36Sopenharmony_ci	 * We can't send a clone operation for the entire range if we find
591162306a36Sopenharmony_ci	 * extent items in the respective range in the source file that
591262306a36Sopenharmony_ci	 * refer to different extents or if we find holes.
591362306a36Sopenharmony_ci	 * So check for that and do a mix of clone and regular write/copy
591462306a36Sopenharmony_ci	 * operations if needed.
591562306a36Sopenharmony_ci	 *
591662306a36Sopenharmony_ci	 * Example:
591762306a36Sopenharmony_ci	 *
591862306a36Sopenharmony_ci	 * mkfs.btrfs -f /dev/sda
591962306a36Sopenharmony_ci	 * mount /dev/sda /mnt
592062306a36Sopenharmony_ci	 * xfs_io -f -c "pwrite -S 0xaa 0K 100K" /mnt/foo
592162306a36Sopenharmony_ci	 * cp --reflink=always /mnt/foo /mnt/bar
592262306a36Sopenharmony_ci	 * xfs_io -c "pwrite -S 0xbb 50K 50K" /mnt/foo
592362306a36Sopenharmony_ci	 * btrfs subvolume snapshot -r /mnt /mnt/snap
592462306a36Sopenharmony_ci	 *
592562306a36Sopenharmony_ci	 * If when we send the snapshot and we are processing file bar (which
592662306a36Sopenharmony_ci	 * has a higher inode number than foo) we blindly send a clone operation
592762306a36Sopenharmony_ci	 * for the [0, 100K[ range from foo to bar, the receiver ends up getting
592862306a36Sopenharmony_ci	 * a file bar that matches the content of file foo - iow, doesn't match
592962306a36Sopenharmony_ci	 * the content from bar in the original filesystem.
593062306a36Sopenharmony_ci	 */
593162306a36Sopenharmony_ci	key.objectid = clone_root->ino;
593262306a36Sopenharmony_ci	key.type = BTRFS_EXTENT_DATA_KEY;
593362306a36Sopenharmony_ci	key.offset = clone_root->offset;
593462306a36Sopenharmony_ci	ret = btrfs_search_slot(NULL, clone_root->root, &key, path, 0, 0);
593562306a36Sopenharmony_ci	if (ret < 0)
593662306a36Sopenharmony_ci		goto out;
593762306a36Sopenharmony_ci	if (ret > 0 && path->slots[0] > 0) {
593862306a36Sopenharmony_ci		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0] - 1);
593962306a36Sopenharmony_ci		if (key.objectid == clone_root->ino &&
594062306a36Sopenharmony_ci		    key.type == BTRFS_EXTENT_DATA_KEY)
594162306a36Sopenharmony_ci			path->slots[0]--;
594262306a36Sopenharmony_ci	}
594362306a36Sopenharmony_ci
594462306a36Sopenharmony_ci	while (true) {
594562306a36Sopenharmony_ci		struct extent_buffer *leaf = path->nodes[0];
594662306a36Sopenharmony_ci		int slot = path->slots[0];
594762306a36Sopenharmony_ci		struct btrfs_file_extent_item *ei;
594862306a36Sopenharmony_ci		u8 type;
594962306a36Sopenharmony_ci		u64 ext_len;
595062306a36Sopenharmony_ci		u64 clone_len;
595162306a36Sopenharmony_ci		u64 clone_data_offset;
595262306a36Sopenharmony_ci		bool crossed_src_i_size = false;
595362306a36Sopenharmony_ci
595462306a36Sopenharmony_ci		if (slot >= btrfs_header_nritems(leaf)) {
595562306a36Sopenharmony_ci			ret = btrfs_next_leaf(clone_root->root, path);
595662306a36Sopenharmony_ci			if (ret < 0)
595762306a36Sopenharmony_ci				goto out;
595862306a36Sopenharmony_ci			else if (ret > 0)
595962306a36Sopenharmony_ci				break;
596062306a36Sopenharmony_ci			continue;
596162306a36Sopenharmony_ci		}
596262306a36Sopenharmony_ci
596362306a36Sopenharmony_ci		btrfs_item_key_to_cpu(leaf, &key, slot);
596462306a36Sopenharmony_ci
596562306a36Sopenharmony_ci		/*
596662306a36Sopenharmony_ci		 * We might have an implicit trailing hole (NO_HOLES feature
596762306a36Sopenharmony_ci		 * enabled). We deal with it after leaving this loop.
596862306a36Sopenharmony_ci		 */
596962306a36Sopenharmony_ci		if (key.objectid != clone_root->ino ||
597062306a36Sopenharmony_ci		    key.type != BTRFS_EXTENT_DATA_KEY)
597162306a36Sopenharmony_ci			break;
597262306a36Sopenharmony_ci
597362306a36Sopenharmony_ci		ei = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
597462306a36Sopenharmony_ci		type = btrfs_file_extent_type(leaf, ei);
597562306a36Sopenharmony_ci		if (type == BTRFS_FILE_EXTENT_INLINE) {
597662306a36Sopenharmony_ci			ext_len = btrfs_file_extent_ram_bytes(leaf, ei);
597762306a36Sopenharmony_ci			ext_len = PAGE_ALIGN(ext_len);
597862306a36Sopenharmony_ci		} else {
597962306a36Sopenharmony_ci			ext_len = btrfs_file_extent_num_bytes(leaf, ei);
598062306a36Sopenharmony_ci		}
598162306a36Sopenharmony_ci
598262306a36Sopenharmony_ci		if (key.offset + ext_len <= clone_root->offset)
598362306a36Sopenharmony_ci			goto next;
598462306a36Sopenharmony_ci
598562306a36Sopenharmony_ci		if (key.offset > clone_root->offset) {
598662306a36Sopenharmony_ci			/* Implicit hole, NO_HOLES feature enabled. */
598762306a36Sopenharmony_ci			u64 hole_len = key.offset - clone_root->offset;
598862306a36Sopenharmony_ci
598962306a36Sopenharmony_ci			if (hole_len > len)
599062306a36Sopenharmony_ci				hole_len = len;
599162306a36Sopenharmony_ci			ret = send_extent_data(sctx, dst_path, offset,
599262306a36Sopenharmony_ci					       hole_len);
599362306a36Sopenharmony_ci			if (ret < 0)
599462306a36Sopenharmony_ci				goto out;
599562306a36Sopenharmony_ci
599662306a36Sopenharmony_ci			len -= hole_len;
599762306a36Sopenharmony_ci			if (len == 0)
599862306a36Sopenharmony_ci				break;
599962306a36Sopenharmony_ci			offset += hole_len;
600062306a36Sopenharmony_ci			clone_root->offset += hole_len;
600162306a36Sopenharmony_ci			data_offset += hole_len;
600262306a36Sopenharmony_ci		}
600362306a36Sopenharmony_ci
600462306a36Sopenharmony_ci		if (key.offset >= clone_root->offset + len)
600562306a36Sopenharmony_ci			break;
600662306a36Sopenharmony_ci
600762306a36Sopenharmony_ci		if (key.offset >= clone_src_i_size)
600862306a36Sopenharmony_ci			break;
600962306a36Sopenharmony_ci
601062306a36Sopenharmony_ci		if (key.offset + ext_len > clone_src_i_size) {
601162306a36Sopenharmony_ci			ext_len = clone_src_i_size - key.offset;
601262306a36Sopenharmony_ci			crossed_src_i_size = true;
601362306a36Sopenharmony_ci		}
601462306a36Sopenharmony_ci
601562306a36Sopenharmony_ci		clone_data_offset = btrfs_file_extent_offset(leaf, ei);
601662306a36Sopenharmony_ci		if (btrfs_file_extent_disk_bytenr(leaf, ei) == disk_byte) {
601762306a36Sopenharmony_ci			clone_root->offset = key.offset;
601862306a36Sopenharmony_ci			if (clone_data_offset < data_offset &&
601962306a36Sopenharmony_ci				clone_data_offset + ext_len > data_offset) {
602062306a36Sopenharmony_ci				u64 extent_offset;
602162306a36Sopenharmony_ci
602262306a36Sopenharmony_ci				extent_offset = data_offset - clone_data_offset;
602362306a36Sopenharmony_ci				ext_len -= extent_offset;
602462306a36Sopenharmony_ci				clone_data_offset += extent_offset;
602562306a36Sopenharmony_ci				clone_root->offset += extent_offset;
602662306a36Sopenharmony_ci			}
602762306a36Sopenharmony_ci		}
602862306a36Sopenharmony_ci
602962306a36Sopenharmony_ci		clone_len = min_t(u64, ext_len, len);
603062306a36Sopenharmony_ci
603162306a36Sopenharmony_ci		if (btrfs_file_extent_disk_bytenr(leaf, ei) == disk_byte &&
603262306a36Sopenharmony_ci		    clone_data_offset == data_offset) {
603362306a36Sopenharmony_ci			const u64 src_end = clone_root->offset + clone_len;
603462306a36Sopenharmony_ci			const u64 sectorsize = SZ_64K;
603562306a36Sopenharmony_ci
603662306a36Sopenharmony_ci			/*
603762306a36Sopenharmony_ci			 * We can't clone the last block, when its size is not
603862306a36Sopenharmony_ci			 * sector size aligned, into the middle of a file. If we
603962306a36Sopenharmony_ci			 * do so, the receiver will get a failure (-EINVAL) when
604062306a36Sopenharmony_ci			 * trying to clone or will silently corrupt the data in
604162306a36Sopenharmony_ci			 * the destination file if it's on a kernel without the
604262306a36Sopenharmony_ci			 * fix introduced by commit ac765f83f1397646
604362306a36Sopenharmony_ci			 * ("Btrfs: fix data corruption due to cloning of eof
604462306a36Sopenharmony_ci			 * block).
604562306a36Sopenharmony_ci			 *
604662306a36Sopenharmony_ci			 * So issue a clone of the aligned down range plus a
604762306a36Sopenharmony_ci			 * regular write for the eof block, if we hit that case.
604862306a36Sopenharmony_ci			 *
604962306a36Sopenharmony_ci			 * Also, we use the maximum possible sector size, 64K,
605062306a36Sopenharmony_ci			 * because we don't know what's the sector size of the
605162306a36Sopenharmony_ci			 * filesystem that receives the stream, so we have to
605262306a36Sopenharmony_ci			 * assume the largest possible sector size.
605362306a36Sopenharmony_ci			 */
605462306a36Sopenharmony_ci			if (src_end == clone_src_i_size &&
605562306a36Sopenharmony_ci			    !IS_ALIGNED(src_end, sectorsize) &&
605662306a36Sopenharmony_ci			    offset + clone_len < sctx->cur_inode_size) {
605762306a36Sopenharmony_ci				u64 slen;
605862306a36Sopenharmony_ci
605962306a36Sopenharmony_ci				slen = ALIGN_DOWN(src_end - clone_root->offset,
606062306a36Sopenharmony_ci						  sectorsize);
606162306a36Sopenharmony_ci				if (slen > 0) {
606262306a36Sopenharmony_ci					ret = send_clone(sctx, offset, slen,
606362306a36Sopenharmony_ci							 clone_root);
606462306a36Sopenharmony_ci					if (ret < 0)
606562306a36Sopenharmony_ci						goto out;
606662306a36Sopenharmony_ci				}
606762306a36Sopenharmony_ci				ret = send_extent_data(sctx, dst_path,
606862306a36Sopenharmony_ci						       offset + slen,
606962306a36Sopenharmony_ci						       clone_len - slen);
607062306a36Sopenharmony_ci			} else {
607162306a36Sopenharmony_ci				ret = send_clone(sctx, offset, clone_len,
607262306a36Sopenharmony_ci						 clone_root);
607362306a36Sopenharmony_ci			}
607462306a36Sopenharmony_ci		} else if (crossed_src_i_size && clone_len < len) {
607562306a36Sopenharmony_ci			/*
607662306a36Sopenharmony_ci			 * If we are at i_size of the clone source inode and we
607762306a36Sopenharmony_ci			 * can not clone from it, terminate the loop. This is
607862306a36Sopenharmony_ci			 * to avoid sending two write operations, one with a
607962306a36Sopenharmony_ci			 * length matching clone_len and the final one after
608062306a36Sopenharmony_ci			 * this loop with a length of len - clone_len.
608162306a36Sopenharmony_ci			 *
608262306a36Sopenharmony_ci			 * When using encoded writes (BTRFS_SEND_FLAG_COMPRESSED
608362306a36Sopenharmony_ci			 * was passed to the send ioctl), this helps avoid
608462306a36Sopenharmony_ci			 * sending an encoded write for an offset that is not
608562306a36Sopenharmony_ci			 * sector size aligned, in case the i_size of the source
608662306a36Sopenharmony_ci			 * inode is not sector size aligned. That will make the
608762306a36Sopenharmony_ci			 * receiver fallback to decompression of the data and
608862306a36Sopenharmony_ci			 * writing it using regular buffered IO, therefore while
608962306a36Sopenharmony_ci			 * not incorrect, it's not optimal due decompression and
609062306a36Sopenharmony_ci			 * possible re-compression at the receiver.
609162306a36Sopenharmony_ci			 */
609262306a36Sopenharmony_ci			break;
609362306a36Sopenharmony_ci		} else {
609462306a36Sopenharmony_ci			ret = send_extent_data(sctx, dst_path, offset,
609562306a36Sopenharmony_ci					       clone_len);
609662306a36Sopenharmony_ci		}
609762306a36Sopenharmony_ci
609862306a36Sopenharmony_ci		if (ret < 0)
609962306a36Sopenharmony_ci			goto out;
610062306a36Sopenharmony_ci
610162306a36Sopenharmony_ci		len -= clone_len;
610262306a36Sopenharmony_ci		if (len == 0)
610362306a36Sopenharmony_ci			break;
610462306a36Sopenharmony_ci		offset += clone_len;
610562306a36Sopenharmony_ci		clone_root->offset += clone_len;
610662306a36Sopenharmony_ci
610762306a36Sopenharmony_ci		/*
610862306a36Sopenharmony_ci		 * If we are cloning from the file we are currently processing,
610962306a36Sopenharmony_ci		 * and using the send root as the clone root, we must stop once
611062306a36Sopenharmony_ci		 * the current clone offset reaches the current eof of the file
611162306a36Sopenharmony_ci		 * at the receiver, otherwise we would issue an invalid clone
611262306a36Sopenharmony_ci		 * operation (source range going beyond eof) and cause the
611362306a36Sopenharmony_ci		 * receiver to fail. So if we reach the current eof, bail out
611462306a36Sopenharmony_ci		 * and fallback to a regular write.
611562306a36Sopenharmony_ci		 */
611662306a36Sopenharmony_ci		if (clone_root->root == sctx->send_root &&
611762306a36Sopenharmony_ci		    clone_root->ino == sctx->cur_ino &&
611862306a36Sopenharmony_ci		    clone_root->offset >= sctx->cur_inode_next_write_offset)
611962306a36Sopenharmony_ci			break;
612062306a36Sopenharmony_ci
612162306a36Sopenharmony_ci		data_offset += clone_len;
612262306a36Sopenharmony_cinext:
612362306a36Sopenharmony_ci		path->slots[0]++;
612462306a36Sopenharmony_ci	}
612562306a36Sopenharmony_ci
612662306a36Sopenharmony_ci	if (len > 0)
612762306a36Sopenharmony_ci		ret = send_extent_data(sctx, dst_path, offset, len);
612862306a36Sopenharmony_ci	else
612962306a36Sopenharmony_ci		ret = 0;
613062306a36Sopenharmony_ciout:
613162306a36Sopenharmony_ci	btrfs_free_path(path);
613262306a36Sopenharmony_ci	return ret;
613362306a36Sopenharmony_ci}
613462306a36Sopenharmony_ci
613562306a36Sopenharmony_cistatic int send_write_or_clone(struct send_ctx *sctx,
613662306a36Sopenharmony_ci			       struct btrfs_path *path,
613762306a36Sopenharmony_ci			       struct btrfs_key *key,
613862306a36Sopenharmony_ci			       struct clone_root *clone_root)
613962306a36Sopenharmony_ci{
614062306a36Sopenharmony_ci	int ret = 0;
614162306a36Sopenharmony_ci	u64 offset = key->offset;
614262306a36Sopenharmony_ci	u64 end;
614362306a36Sopenharmony_ci	u64 bs = sctx->send_root->fs_info->sb->s_blocksize;
614462306a36Sopenharmony_ci
614562306a36Sopenharmony_ci	end = min_t(u64, btrfs_file_extent_end(path), sctx->cur_inode_size);
614662306a36Sopenharmony_ci	if (offset >= end)
614762306a36Sopenharmony_ci		return 0;
614862306a36Sopenharmony_ci
614962306a36Sopenharmony_ci	if (clone_root && IS_ALIGNED(end, bs)) {
615062306a36Sopenharmony_ci		struct btrfs_file_extent_item *ei;
615162306a36Sopenharmony_ci		u64 disk_byte;
615262306a36Sopenharmony_ci		u64 data_offset;
615362306a36Sopenharmony_ci
615462306a36Sopenharmony_ci		ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
615562306a36Sopenharmony_ci				    struct btrfs_file_extent_item);
615662306a36Sopenharmony_ci		disk_byte = btrfs_file_extent_disk_bytenr(path->nodes[0], ei);
615762306a36Sopenharmony_ci		data_offset = btrfs_file_extent_offset(path->nodes[0], ei);
615862306a36Sopenharmony_ci		ret = clone_range(sctx, path, clone_root, disk_byte,
615962306a36Sopenharmony_ci				  data_offset, offset, end - offset);
616062306a36Sopenharmony_ci	} else {
616162306a36Sopenharmony_ci		ret = send_extent_data(sctx, path, offset, end - offset);
616262306a36Sopenharmony_ci	}
616362306a36Sopenharmony_ci	sctx->cur_inode_next_write_offset = end;
616462306a36Sopenharmony_ci	return ret;
616562306a36Sopenharmony_ci}
616662306a36Sopenharmony_ci
616762306a36Sopenharmony_cistatic int is_extent_unchanged(struct send_ctx *sctx,
616862306a36Sopenharmony_ci			       struct btrfs_path *left_path,
616962306a36Sopenharmony_ci			       struct btrfs_key *ekey)
617062306a36Sopenharmony_ci{
617162306a36Sopenharmony_ci	int ret = 0;
617262306a36Sopenharmony_ci	struct btrfs_key key;
617362306a36Sopenharmony_ci	struct btrfs_path *path = NULL;
617462306a36Sopenharmony_ci	struct extent_buffer *eb;
617562306a36Sopenharmony_ci	int slot;
617662306a36Sopenharmony_ci	struct btrfs_key found_key;
617762306a36Sopenharmony_ci	struct btrfs_file_extent_item *ei;
617862306a36Sopenharmony_ci	u64 left_disknr;
617962306a36Sopenharmony_ci	u64 right_disknr;
618062306a36Sopenharmony_ci	u64 left_offset;
618162306a36Sopenharmony_ci	u64 right_offset;
618262306a36Sopenharmony_ci	u64 left_offset_fixed;
618362306a36Sopenharmony_ci	u64 left_len;
618462306a36Sopenharmony_ci	u64 right_len;
618562306a36Sopenharmony_ci	u64 left_gen;
618662306a36Sopenharmony_ci	u64 right_gen;
618762306a36Sopenharmony_ci	u8 left_type;
618862306a36Sopenharmony_ci	u8 right_type;
618962306a36Sopenharmony_ci
619062306a36Sopenharmony_ci	path = alloc_path_for_send();
619162306a36Sopenharmony_ci	if (!path)
619262306a36Sopenharmony_ci		return -ENOMEM;
619362306a36Sopenharmony_ci
619462306a36Sopenharmony_ci	eb = left_path->nodes[0];
619562306a36Sopenharmony_ci	slot = left_path->slots[0];
619662306a36Sopenharmony_ci	ei = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
619762306a36Sopenharmony_ci	left_type = btrfs_file_extent_type(eb, ei);
619862306a36Sopenharmony_ci
619962306a36Sopenharmony_ci	if (left_type != BTRFS_FILE_EXTENT_REG) {
620062306a36Sopenharmony_ci		ret = 0;
620162306a36Sopenharmony_ci		goto out;
620262306a36Sopenharmony_ci	}
620362306a36Sopenharmony_ci	left_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
620462306a36Sopenharmony_ci	left_len = btrfs_file_extent_num_bytes(eb, ei);
620562306a36Sopenharmony_ci	left_offset = btrfs_file_extent_offset(eb, ei);
620662306a36Sopenharmony_ci	left_gen = btrfs_file_extent_generation(eb, ei);
620762306a36Sopenharmony_ci
620862306a36Sopenharmony_ci	/*
620962306a36Sopenharmony_ci	 * Following comments will refer to these graphics. L is the left
621062306a36Sopenharmony_ci	 * extents which we are checking at the moment. 1-8 are the right
621162306a36Sopenharmony_ci	 * extents that we iterate.
621262306a36Sopenharmony_ci	 *
621362306a36Sopenharmony_ci	 *       |-----L-----|
621462306a36Sopenharmony_ci	 * |-1-|-2a-|-3-|-4-|-5-|-6-|
621562306a36Sopenharmony_ci	 *
621662306a36Sopenharmony_ci	 *       |-----L-----|
621762306a36Sopenharmony_ci	 * |--1--|-2b-|...(same as above)
621862306a36Sopenharmony_ci	 *
621962306a36Sopenharmony_ci	 * Alternative situation. Happens on files where extents got split.
622062306a36Sopenharmony_ci	 *       |-----L-----|
622162306a36Sopenharmony_ci	 * |-----------7-----------|-6-|
622262306a36Sopenharmony_ci	 *
622362306a36Sopenharmony_ci	 * Alternative situation. Happens on files which got larger.
622462306a36Sopenharmony_ci	 *       |-----L-----|
622562306a36Sopenharmony_ci	 * |-8-|
622662306a36Sopenharmony_ci	 * Nothing follows after 8.
622762306a36Sopenharmony_ci	 */
622862306a36Sopenharmony_ci
622962306a36Sopenharmony_ci	key.objectid = ekey->objectid;
623062306a36Sopenharmony_ci	key.type = BTRFS_EXTENT_DATA_KEY;
623162306a36Sopenharmony_ci	key.offset = ekey->offset;
623262306a36Sopenharmony_ci	ret = btrfs_search_slot_for_read(sctx->parent_root, &key, path, 0, 0);
623362306a36Sopenharmony_ci	if (ret < 0)
623462306a36Sopenharmony_ci		goto out;
623562306a36Sopenharmony_ci	if (ret) {
623662306a36Sopenharmony_ci		ret = 0;
623762306a36Sopenharmony_ci		goto out;
623862306a36Sopenharmony_ci	}
623962306a36Sopenharmony_ci
624062306a36Sopenharmony_ci	/*
624162306a36Sopenharmony_ci	 * Handle special case where the right side has no extents at all.
624262306a36Sopenharmony_ci	 */
624362306a36Sopenharmony_ci	eb = path->nodes[0];
624462306a36Sopenharmony_ci	slot = path->slots[0];
624562306a36Sopenharmony_ci	btrfs_item_key_to_cpu(eb, &found_key, slot);
624662306a36Sopenharmony_ci	if (found_key.objectid != key.objectid ||
624762306a36Sopenharmony_ci	    found_key.type != key.type) {
624862306a36Sopenharmony_ci		/* If we're a hole then just pretend nothing changed */
624962306a36Sopenharmony_ci		ret = (left_disknr) ? 0 : 1;
625062306a36Sopenharmony_ci		goto out;
625162306a36Sopenharmony_ci	}
625262306a36Sopenharmony_ci
625362306a36Sopenharmony_ci	/*
625462306a36Sopenharmony_ci	 * We're now on 2a, 2b or 7.
625562306a36Sopenharmony_ci	 */
625662306a36Sopenharmony_ci	key = found_key;
625762306a36Sopenharmony_ci	while (key.offset < ekey->offset + left_len) {
625862306a36Sopenharmony_ci		ei = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
625962306a36Sopenharmony_ci		right_type = btrfs_file_extent_type(eb, ei);
626062306a36Sopenharmony_ci		if (right_type != BTRFS_FILE_EXTENT_REG &&
626162306a36Sopenharmony_ci		    right_type != BTRFS_FILE_EXTENT_INLINE) {
626262306a36Sopenharmony_ci			ret = 0;
626362306a36Sopenharmony_ci			goto out;
626462306a36Sopenharmony_ci		}
626562306a36Sopenharmony_ci
626662306a36Sopenharmony_ci		if (right_type == BTRFS_FILE_EXTENT_INLINE) {
626762306a36Sopenharmony_ci			right_len = btrfs_file_extent_ram_bytes(eb, ei);
626862306a36Sopenharmony_ci			right_len = PAGE_ALIGN(right_len);
626962306a36Sopenharmony_ci		} else {
627062306a36Sopenharmony_ci			right_len = btrfs_file_extent_num_bytes(eb, ei);
627162306a36Sopenharmony_ci		}
627262306a36Sopenharmony_ci
627362306a36Sopenharmony_ci		/*
627462306a36Sopenharmony_ci		 * Are we at extent 8? If yes, we know the extent is changed.
627562306a36Sopenharmony_ci		 * This may only happen on the first iteration.
627662306a36Sopenharmony_ci		 */
627762306a36Sopenharmony_ci		if (found_key.offset + right_len <= ekey->offset) {
627862306a36Sopenharmony_ci			/* If we're a hole just pretend nothing changed */
627962306a36Sopenharmony_ci			ret = (left_disknr) ? 0 : 1;
628062306a36Sopenharmony_ci			goto out;
628162306a36Sopenharmony_ci		}
628262306a36Sopenharmony_ci
628362306a36Sopenharmony_ci		/*
628462306a36Sopenharmony_ci		 * We just wanted to see if when we have an inline extent, what
628562306a36Sopenharmony_ci		 * follows it is a regular extent (wanted to check the above
628662306a36Sopenharmony_ci		 * condition for inline extents too). This should normally not
628762306a36Sopenharmony_ci		 * happen but it's possible for example when we have an inline
628862306a36Sopenharmony_ci		 * compressed extent representing data with a size matching
628962306a36Sopenharmony_ci		 * the page size (currently the same as sector size).
629062306a36Sopenharmony_ci		 */
629162306a36Sopenharmony_ci		if (right_type == BTRFS_FILE_EXTENT_INLINE) {
629262306a36Sopenharmony_ci			ret = 0;
629362306a36Sopenharmony_ci			goto out;
629462306a36Sopenharmony_ci		}
629562306a36Sopenharmony_ci
629662306a36Sopenharmony_ci		right_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
629762306a36Sopenharmony_ci		right_offset = btrfs_file_extent_offset(eb, ei);
629862306a36Sopenharmony_ci		right_gen = btrfs_file_extent_generation(eb, ei);
629962306a36Sopenharmony_ci
630062306a36Sopenharmony_ci		left_offset_fixed = left_offset;
630162306a36Sopenharmony_ci		if (key.offset < ekey->offset) {
630262306a36Sopenharmony_ci			/* Fix the right offset for 2a and 7. */
630362306a36Sopenharmony_ci			right_offset += ekey->offset - key.offset;
630462306a36Sopenharmony_ci		} else {
630562306a36Sopenharmony_ci			/* Fix the left offset for all behind 2a and 2b */
630662306a36Sopenharmony_ci			left_offset_fixed += key.offset - ekey->offset;
630762306a36Sopenharmony_ci		}
630862306a36Sopenharmony_ci
630962306a36Sopenharmony_ci		/*
631062306a36Sopenharmony_ci		 * Check if we have the same extent.
631162306a36Sopenharmony_ci		 */
631262306a36Sopenharmony_ci		if (left_disknr != right_disknr ||
631362306a36Sopenharmony_ci		    left_offset_fixed != right_offset ||
631462306a36Sopenharmony_ci		    left_gen != right_gen) {
631562306a36Sopenharmony_ci			ret = 0;
631662306a36Sopenharmony_ci			goto out;
631762306a36Sopenharmony_ci		}
631862306a36Sopenharmony_ci
631962306a36Sopenharmony_ci		/*
632062306a36Sopenharmony_ci		 * Go to the next extent.
632162306a36Sopenharmony_ci		 */
632262306a36Sopenharmony_ci		ret = btrfs_next_item(sctx->parent_root, path);
632362306a36Sopenharmony_ci		if (ret < 0)
632462306a36Sopenharmony_ci			goto out;
632562306a36Sopenharmony_ci		if (!ret) {
632662306a36Sopenharmony_ci			eb = path->nodes[0];
632762306a36Sopenharmony_ci			slot = path->slots[0];
632862306a36Sopenharmony_ci			btrfs_item_key_to_cpu(eb, &found_key, slot);
632962306a36Sopenharmony_ci		}
633062306a36Sopenharmony_ci		if (ret || found_key.objectid != key.objectid ||
633162306a36Sopenharmony_ci		    found_key.type != key.type) {
633262306a36Sopenharmony_ci			key.offset += right_len;
633362306a36Sopenharmony_ci			break;
633462306a36Sopenharmony_ci		}
633562306a36Sopenharmony_ci		if (found_key.offset != key.offset + right_len) {
633662306a36Sopenharmony_ci			ret = 0;
633762306a36Sopenharmony_ci			goto out;
633862306a36Sopenharmony_ci		}
633962306a36Sopenharmony_ci		key = found_key;
634062306a36Sopenharmony_ci	}
634162306a36Sopenharmony_ci
634262306a36Sopenharmony_ci	/*
634362306a36Sopenharmony_ci	 * We're now behind the left extent (treat as unchanged) or at the end
634462306a36Sopenharmony_ci	 * of the right side (treat as changed).
634562306a36Sopenharmony_ci	 */
634662306a36Sopenharmony_ci	if (key.offset >= ekey->offset + left_len)
634762306a36Sopenharmony_ci		ret = 1;
634862306a36Sopenharmony_ci	else
634962306a36Sopenharmony_ci		ret = 0;
635062306a36Sopenharmony_ci
635162306a36Sopenharmony_ci
635262306a36Sopenharmony_ciout:
635362306a36Sopenharmony_ci	btrfs_free_path(path);
635462306a36Sopenharmony_ci	return ret;
635562306a36Sopenharmony_ci}
635662306a36Sopenharmony_ci
635762306a36Sopenharmony_cistatic int get_last_extent(struct send_ctx *sctx, u64 offset)
635862306a36Sopenharmony_ci{
635962306a36Sopenharmony_ci	struct btrfs_path *path;
636062306a36Sopenharmony_ci	struct btrfs_root *root = sctx->send_root;
636162306a36Sopenharmony_ci	struct btrfs_key key;
636262306a36Sopenharmony_ci	int ret;
636362306a36Sopenharmony_ci
636462306a36Sopenharmony_ci	path = alloc_path_for_send();
636562306a36Sopenharmony_ci	if (!path)
636662306a36Sopenharmony_ci		return -ENOMEM;
636762306a36Sopenharmony_ci
636862306a36Sopenharmony_ci	sctx->cur_inode_last_extent = 0;
636962306a36Sopenharmony_ci
637062306a36Sopenharmony_ci	key.objectid = sctx->cur_ino;
637162306a36Sopenharmony_ci	key.type = BTRFS_EXTENT_DATA_KEY;
637262306a36Sopenharmony_ci	key.offset = offset;
637362306a36Sopenharmony_ci	ret = btrfs_search_slot_for_read(root, &key, path, 0, 1);
637462306a36Sopenharmony_ci	if (ret < 0)
637562306a36Sopenharmony_ci		goto out;
637662306a36Sopenharmony_ci	ret = 0;
637762306a36Sopenharmony_ci	btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
637862306a36Sopenharmony_ci	if (key.objectid != sctx->cur_ino || key.type != BTRFS_EXTENT_DATA_KEY)
637962306a36Sopenharmony_ci		goto out;
638062306a36Sopenharmony_ci
638162306a36Sopenharmony_ci	sctx->cur_inode_last_extent = btrfs_file_extent_end(path);
638262306a36Sopenharmony_ciout:
638362306a36Sopenharmony_ci	btrfs_free_path(path);
638462306a36Sopenharmony_ci	return ret;
638562306a36Sopenharmony_ci}
638662306a36Sopenharmony_ci
638762306a36Sopenharmony_cistatic int range_is_hole_in_parent(struct send_ctx *sctx,
638862306a36Sopenharmony_ci				   const u64 start,
638962306a36Sopenharmony_ci				   const u64 end)
639062306a36Sopenharmony_ci{
639162306a36Sopenharmony_ci	struct btrfs_path *path;
639262306a36Sopenharmony_ci	struct btrfs_key key;
639362306a36Sopenharmony_ci	struct btrfs_root *root = sctx->parent_root;
639462306a36Sopenharmony_ci	u64 search_start = start;
639562306a36Sopenharmony_ci	int ret;
639662306a36Sopenharmony_ci
639762306a36Sopenharmony_ci	path = alloc_path_for_send();
639862306a36Sopenharmony_ci	if (!path)
639962306a36Sopenharmony_ci		return -ENOMEM;
640062306a36Sopenharmony_ci
640162306a36Sopenharmony_ci	key.objectid = sctx->cur_ino;
640262306a36Sopenharmony_ci	key.type = BTRFS_EXTENT_DATA_KEY;
640362306a36Sopenharmony_ci	key.offset = search_start;
640462306a36Sopenharmony_ci	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
640562306a36Sopenharmony_ci	if (ret < 0)
640662306a36Sopenharmony_ci		goto out;
640762306a36Sopenharmony_ci	if (ret > 0 && path->slots[0] > 0)
640862306a36Sopenharmony_ci		path->slots[0]--;
640962306a36Sopenharmony_ci
641062306a36Sopenharmony_ci	while (search_start < end) {
641162306a36Sopenharmony_ci		struct extent_buffer *leaf = path->nodes[0];
641262306a36Sopenharmony_ci		int slot = path->slots[0];
641362306a36Sopenharmony_ci		struct btrfs_file_extent_item *fi;
641462306a36Sopenharmony_ci		u64 extent_end;
641562306a36Sopenharmony_ci
641662306a36Sopenharmony_ci		if (slot >= btrfs_header_nritems(leaf)) {
641762306a36Sopenharmony_ci			ret = btrfs_next_leaf(root, path);
641862306a36Sopenharmony_ci			if (ret < 0)
641962306a36Sopenharmony_ci				goto out;
642062306a36Sopenharmony_ci			else if (ret > 0)
642162306a36Sopenharmony_ci				break;
642262306a36Sopenharmony_ci			continue;
642362306a36Sopenharmony_ci		}
642462306a36Sopenharmony_ci
642562306a36Sopenharmony_ci		btrfs_item_key_to_cpu(leaf, &key, slot);
642662306a36Sopenharmony_ci		if (key.objectid < sctx->cur_ino ||
642762306a36Sopenharmony_ci		    key.type < BTRFS_EXTENT_DATA_KEY)
642862306a36Sopenharmony_ci			goto next;
642962306a36Sopenharmony_ci		if (key.objectid > sctx->cur_ino ||
643062306a36Sopenharmony_ci		    key.type > BTRFS_EXTENT_DATA_KEY ||
643162306a36Sopenharmony_ci		    key.offset >= end)
643262306a36Sopenharmony_ci			break;
643362306a36Sopenharmony_ci
643462306a36Sopenharmony_ci		fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
643562306a36Sopenharmony_ci		extent_end = btrfs_file_extent_end(path);
643662306a36Sopenharmony_ci		if (extent_end <= start)
643762306a36Sopenharmony_ci			goto next;
643862306a36Sopenharmony_ci		if (btrfs_file_extent_disk_bytenr(leaf, fi) == 0) {
643962306a36Sopenharmony_ci			search_start = extent_end;
644062306a36Sopenharmony_ci			goto next;
644162306a36Sopenharmony_ci		}
644262306a36Sopenharmony_ci		ret = 0;
644362306a36Sopenharmony_ci		goto out;
644462306a36Sopenharmony_cinext:
644562306a36Sopenharmony_ci		path->slots[0]++;
644662306a36Sopenharmony_ci	}
644762306a36Sopenharmony_ci	ret = 1;
644862306a36Sopenharmony_ciout:
644962306a36Sopenharmony_ci	btrfs_free_path(path);
645062306a36Sopenharmony_ci	return ret;
645162306a36Sopenharmony_ci}
645262306a36Sopenharmony_ci
645362306a36Sopenharmony_cistatic int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path,
645462306a36Sopenharmony_ci			   struct btrfs_key *key)
645562306a36Sopenharmony_ci{
645662306a36Sopenharmony_ci	int ret = 0;
645762306a36Sopenharmony_ci
645862306a36Sopenharmony_ci	if (sctx->cur_ino != key->objectid || !need_send_hole(sctx))
645962306a36Sopenharmony_ci		return 0;
646062306a36Sopenharmony_ci
646162306a36Sopenharmony_ci	if (sctx->cur_inode_last_extent == (u64)-1) {
646262306a36Sopenharmony_ci		ret = get_last_extent(sctx, key->offset - 1);
646362306a36Sopenharmony_ci		if (ret)
646462306a36Sopenharmony_ci			return ret;
646562306a36Sopenharmony_ci	}
646662306a36Sopenharmony_ci
646762306a36Sopenharmony_ci	if (path->slots[0] == 0 &&
646862306a36Sopenharmony_ci	    sctx->cur_inode_last_extent < key->offset) {
646962306a36Sopenharmony_ci		/*
647062306a36Sopenharmony_ci		 * We might have skipped entire leafs that contained only
647162306a36Sopenharmony_ci		 * file extent items for our current inode. These leafs have
647262306a36Sopenharmony_ci		 * a generation number smaller (older) than the one in the
647362306a36Sopenharmony_ci		 * current leaf and the leaf our last extent came from, and
647462306a36Sopenharmony_ci		 * are located between these 2 leafs.
647562306a36Sopenharmony_ci		 */
647662306a36Sopenharmony_ci		ret = get_last_extent(sctx, key->offset - 1);
647762306a36Sopenharmony_ci		if (ret)
647862306a36Sopenharmony_ci			return ret;
647962306a36Sopenharmony_ci	}
648062306a36Sopenharmony_ci
648162306a36Sopenharmony_ci	if (sctx->cur_inode_last_extent < key->offset) {
648262306a36Sopenharmony_ci		ret = range_is_hole_in_parent(sctx,
648362306a36Sopenharmony_ci					      sctx->cur_inode_last_extent,
648462306a36Sopenharmony_ci					      key->offset);
648562306a36Sopenharmony_ci		if (ret < 0)
648662306a36Sopenharmony_ci			return ret;
648762306a36Sopenharmony_ci		else if (ret == 0)
648862306a36Sopenharmony_ci			ret = send_hole(sctx, key->offset);
648962306a36Sopenharmony_ci		else
649062306a36Sopenharmony_ci			ret = 0;
649162306a36Sopenharmony_ci	}
649262306a36Sopenharmony_ci	sctx->cur_inode_last_extent = btrfs_file_extent_end(path);
649362306a36Sopenharmony_ci	return ret;
649462306a36Sopenharmony_ci}
649562306a36Sopenharmony_ci
649662306a36Sopenharmony_cistatic int process_extent(struct send_ctx *sctx,
649762306a36Sopenharmony_ci			  struct btrfs_path *path,
649862306a36Sopenharmony_ci			  struct btrfs_key *key)
649962306a36Sopenharmony_ci{
650062306a36Sopenharmony_ci	struct clone_root *found_clone = NULL;
650162306a36Sopenharmony_ci	int ret = 0;
650262306a36Sopenharmony_ci
650362306a36Sopenharmony_ci	if (S_ISLNK(sctx->cur_inode_mode))
650462306a36Sopenharmony_ci		return 0;
650562306a36Sopenharmony_ci
650662306a36Sopenharmony_ci	if (sctx->parent_root && !sctx->cur_inode_new) {
650762306a36Sopenharmony_ci		ret = is_extent_unchanged(sctx, path, key);
650862306a36Sopenharmony_ci		if (ret < 0)
650962306a36Sopenharmony_ci			goto out;
651062306a36Sopenharmony_ci		if (ret) {
651162306a36Sopenharmony_ci			ret = 0;
651262306a36Sopenharmony_ci			goto out_hole;
651362306a36Sopenharmony_ci		}
651462306a36Sopenharmony_ci	} else {
651562306a36Sopenharmony_ci		struct btrfs_file_extent_item *ei;
651662306a36Sopenharmony_ci		u8 type;
651762306a36Sopenharmony_ci
651862306a36Sopenharmony_ci		ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
651962306a36Sopenharmony_ci				    struct btrfs_file_extent_item);
652062306a36Sopenharmony_ci		type = btrfs_file_extent_type(path->nodes[0], ei);
652162306a36Sopenharmony_ci		if (type == BTRFS_FILE_EXTENT_PREALLOC ||
652262306a36Sopenharmony_ci		    type == BTRFS_FILE_EXTENT_REG) {
652362306a36Sopenharmony_ci			/*
652462306a36Sopenharmony_ci			 * The send spec does not have a prealloc command yet,
652562306a36Sopenharmony_ci			 * so just leave a hole for prealloc'ed extents until
652662306a36Sopenharmony_ci			 * we have enough commands queued up to justify rev'ing
652762306a36Sopenharmony_ci			 * the send spec.
652862306a36Sopenharmony_ci			 */
652962306a36Sopenharmony_ci			if (type == BTRFS_FILE_EXTENT_PREALLOC) {
653062306a36Sopenharmony_ci				ret = 0;
653162306a36Sopenharmony_ci				goto out;
653262306a36Sopenharmony_ci			}
653362306a36Sopenharmony_ci
653462306a36Sopenharmony_ci			/* Have a hole, just skip it. */
653562306a36Sopenharmony_ci			if (btrfs_file_extent_disk_bytenr(path->nodes[0], ei) == 0) {
653662306a36Sopenharmony_ci				ret = 0;
653762306a36Sopenharmony_ci				goto out;
653862306a36Sopenharmony_ci			}
653962306a36Sopenharmony_ci		}
654062306a36Sopenharmony_ci	}
654162306a36Sopenharmony_ci
654262306a36Sopenharmony_ci	ret = find_extent_clone(sctx, path, key->objectid, key->offset,
654362306a36Sopenharmony_ci			sctx->cur_inode_size, &found_clone);
654462306a36Sopenharmony_ci	if (ret != -ENOENT && ret < 0)
654562306a36Sopenharmony_ci		goto out;
654662306a36Sopenharmony_ci
654762306a36Sopenharmony_ci	ret = send_write_or_clone(sctx, path, key, found_clone);
654862306a36Sopenharmony_ci	if (ret)
654962306a36Sopenharmony_ci		goto out;
655062306a36Sopenharmony_ciout_hole:
655162306a36Sopenharmony_ci	ret = maybe_send_hole(sctx, path, key);
655262306a36Sopenharmony_ciout:
655362306a36Sopenharmony_ci	return ret;
655462306a36Sopenharmony_ci}
655562306a36Sopenharmony_ci
655662306a36Sopenharmony_cistatic int process_all_extents(struct send_ctx *sctx)
655762306a36Sopenharmony_ci{
655862306a36Sopenharmony_ci	int ret = 0;
655962306a36Sopenharmony_ci	int iter_ret = 0;
656062306a36Sopenharmony_ci	struct btrfs_root *root;
656162306a36Sopenharmony_ci	struct btrfs_path *path;
656262306a36Sopenharmony_ci	struct btrfs_key key;
656362306a36Sopenharmony_ci	struct btrfs_key found_key;
656462306a36Sopenharmony_ci
656562306a36Sopenharmony_ci	root = sctx->send_root;
656662306a36Sopenharmony_ci	path = alloc_path_for_send();
656762306a36Sopenharmony_ci	if (!path)
656862306a36Sopenharmony_ci		return -ENOMEM;
656962306a36Sopenharmony_ci
657062306a36Sopenharmony_ci	key.objectid = sctx->cmp_key->objectid;
657162306a36Sopenharmony_ci	key.type = BTRFS_EXTENT_DATA_KEY;
657262306a36Sopenharmony_ci	key.offset = 0;
657362306a36Sopenharmony_ci	btrfs_for_each_slot(root, &key, &found_key, path, iter_ret) {
657462306a36Sopenharmony_ci		if (found_key.objectid != key.objectid ||
657562306a36Sopenharmony_ci		    found_key.type != key.type) {
657662306a36Sopenharmony_ci			ret = 0;
657762306a36Sopenharmony_ci			break;
657862306a36Sopenharmony_ci		}
657962306a36Sopenharmony_ci
658062306a36Sopenharmony_ci		ret = process_extent(sctx, path, &found_key);
658162306a36Sopenharmony_ci		if (ret < 0)
658262306a36Sopenharmony_ci			break;
658362306a36Sopenharmony_ci	}
658462306a36Sopenharmony_ci	/* Catch error found during iteration */
658562306a36Sopenharmony_ci	if (iter_ret < 0)
658662306a36Sopenharmony_ci		ret = iter_ret;
658762306a36Sopenharmony_ci
658862306a36Sopenharmony_ci	btrfs_free_path(path);
658962306a36Sopenharmony_ci	return ret;
659062306a36Sopenharmony_ci}
659162306a36Sopenharmony_ci
659262306a36Sopenharmony_cistatic int process_recorded_refs_if_needed(struct send_ctx *sctx, int at_end,
659362306a36Sopenharmony_ci					   int *pending_move,
659462306a36Sopenharmony_ci					   int *refs_processed)
659562306a36Sopenharmony_ci{
659662306a36Sopenharmony_ci	int ret = 0;
659762306a36Sopenharmony_ci
659862306a36Sopenharmony_ci	if (sctx->cur_ino == 0)
659962306a36Sopenharmony_ci		goto out;
660062306a36Sopenharmony_ci	if (!at_end && sctx->cur_ino == sctx->cmp_key->objectid &&
660162306a36Sopenharmony_ci	    sctx->cmp_key->type <= BTRFS_INODE_EXTREF_KEY)
660262306a36Sopenharmony_ci		goto out;
660362306a36Sopenharmony_ci	if (list_empty(&sctx->new_refs) && list_empty(&sctx->deleted_refs))
660462306a36Sopenharmony_ci		goto out;
660562306a36Sopenharmony_ci
660662306a36Sopenharmony_ci	ret = process_recorded_refs(sctx, pending_move);
660762306a36Sopenharmony_ci	if (ret < 0)
660862306a36Sopenharmony_ci		goto out;
660962306a36Sopenharmony_ci
661062306a36Sopenharmony_ci	*refs_processed = 1;
661162306a36Sopenharmony_ciout:
661262306a36Sopenharmony_ci	return ret;
661362306a36Sopenharmony_ci}
661462306a36Sopenharmony_ci
661562306a36Sopenharmony_cistatic int finish_inode_if_needed(struct send_ctx *sctx, int at_end)
661662306a36Sopenharmony_ci{
661762306a36Sopenharmony_ci	int ret = 0;
661862306a36Sopenharmony_ci	struct btrfs_inode_info info;
661962306a36Sopenharmony_ci	u64 left_mode;
662062306a36Sopenharmony_ci	u64 left_uid;
662162306a36Sopenharmony_ci	u64 left_gid;
662262306a36Sopenharmony_ci	u64 left_fileattr;
662362306a36Sopenharmony_ci	u64 right_mode;
662462306a36Sopenharmony_ci	u64 right_uid;
662562306a36Sopenharmony_ci	u64 right_gid;
662662306a36Sopenharmony_ci	u64 right_fileattr;
662762306a36Sopenharmony_ci	int need_chmod = 0;
662862306a36Sopenharmony_ci	int need_chown = 0;
662962306a36Sopenharmony_ci	bool need_fileattr = false;
663062306a36Sopenharmony_ci	int need_truncate = 1;
663162306a36Sopenharmony_ci	int pending_move = 0;
663262306a36Sopenharmony_ci	int refs_processed = 0;
663362306a36Sopenharmony_ci
663462306a36Sopenharmony_ci	if (sctx->ignore_cur_inode)
663562306a36Sopenharmony_ci		return 0;
663662306a36Sopenharmony_ci
663762306a36Sopenharmony_ci	ret = process_recorded_refs_if_needed(sctx, at_end, &pending_move,
663862306a36Sopenharmony_ci					      &refs_processed);
663962306a36Sopenharmony_ci	if (ret < 0)
664062306a36Sopenharmony_ci		goto out;
664162306a36Sopenharmony_ci
664262306a36Sopenharmony_ci	/*
664362306a36Sopenharmony_ci	 * We have processed the refs and thus need to advance send_progress.
664462306a36Sopenharmony_ci	 * Now, calls to get_cur_xxx will take the updated refs of the current
664562306a36Sopenharmony_ci	 * inode into account.
664662306a36Sopenharmony_ci	 *
664762306a36Sopenharmony_ci	 * On the other hand, if our current inode is a directory and couldn't
664862306a36Sopenharmony_ci	 * be moved/renamed because its parent was renamed/moved too and it has
664962306a36Sopenharmony_ci	 * a higher inode number, we can only move/rename our current inode
665062306a36Sopenharmony_ci	 * after we moved/renamed its parent. Therefore in this case operate on
665162306a36Sopenharmony_ci	 * the old path (pre move/rename) of our current inode, and the
665262306a36Sopenharmony_ci	 * move/rename will be performed later.
665362306a36Sopenharmony_ci	 */
665462306a36Sopenharmony_ci	if (refs_processed && !pending_move)
665562306a36Sopenharmony_ci		sctx->send_progress = sctx->cur_ino + 1;
665662306a36Sopenharmony_ci
665762306a36Sopenharmony_ci	if (sctx->cur_ino == 0 || sctx->cur_inode_deleted)
665862306a36Sopenharmony_ci		goto out;
665962306a36Sopenharmony_ci	if (!at_end && sctx->cmp_key->objectid == sctx->cur_ino)
666062306a36Sopenharmony_ci		goto out;
666162306a36Sopenharmony_ci	ret = get_inode_info(sctx->send_root, sctx->cur_ino, &info);
666262306a36Sopenharmony_ci	if (ret < 0)
666362306a36Sopenharmony_ci		goto out;
666462306a36Sopenharmony_ci	left_mode = info.mode;
666562306a36Sopenharmony_ci	left_uid = info.uid;
666662306a36Sopenharmony_ci	left_gid = info.gid;
666762306a36Sopenharmony_ci	left_fileattr = info.fileattr;
666862306a36Sopenharmony_ci
666962306a36Sopenharmony_ci	if (!sctx->parent_root || sctx->cur_inode_new) {
667062306a36Sopenharmony_ci		need_chown = 1;
667162306a36Sopenharmony_ci		if (!S_ISLNK(sctx->cur_inode_mode))
667262306a36Sopenharmony_ci			need_chmod = 1;
667362306a36Sopenharmony_ci		if (sctx->cur_inode_next_write_offset == sctx->cur_inode_size)
667462306a36Sopenharmony_ci			need_truncate = 0;
667562306a36Sopenharmony_ci	} else {
667662306a36Sopenharmony_ci		u64 old_size;
667762306a36Sopenharmony_ci
667862306a36Sopenharmony_ci		ret = get_inode_info(sctx->parent_root, sctx->cur_ino, &info);
667962306a36Sopenharmony_ci		if (ret < 0)
668062306a36Sopenharmony_ci			goto out;
668162306a36Sopenharmony_ci		old_size = info.size;
668262306a36Sopenharmony_ci		right_mode = info.mode;
668362306a36Sopenharmony_ci		right_uid = info.uid;
668462306a36Sopenharmony_ci		right_gid = info.gid;
668562306a36Sopenharmony_ci		right_fileattr = info.fileattr;
668662306a36Sopenharmony_ci
668762306a36Sopenharmony_ci		if (left_uid != right_uid || left_gid != right_gid)
668862306a36Sopenharmony_ci			need_chown = 1;
668962306a36Sopenharmony_ci		if (!S_ISLNK(sctx->cur_inode_mode) && left_mode != right_mode)
669062306a36Sopenharmony_ci			need_chmod = 1;
669162306a36Sopenharmony_ci		if (!S_ISLNK(sctx->cur_inode_mode) && left_fileattr != right_fileattr)
669262306a36Sopenharmony_ci			need_fileattr = true;
669362306a36Sopenharmony_ci		if ((old_size == sctx->cur_inode_size) ||
669462306a36Sopenharmony_ci		    (sctx->cur_inode_size > old_size &&
669562306a36Sopenharmony_ci		     sctx->cur_inode_next_write_offset == sctx->cur_inode_size))
669662306a36Sopenharmony_ci			need_truncate = 0;
669762306a36Sopenharmony_ci	}
669862306a36Sopenharmony_ci
669962306a36Sopenharmony_ci	if (S_ISREG(sctx->cur_inode_mode)) {
670062306a36Sopenharmony_ci		if (need_send_hole(sctx)) {
670162306a36Sopenharmony_ci			if (sctx->cur_inode_last_extent == (u64)-1 ||
670262306a36Sopenharmony_ci			    sctx->cur_inode_last_extent <
670362306a36Sopenharmony_ci			    sctx->cur_inode_size) {
670462306a36Sopenharmony_ci				ret = get_last_extent(sctx, (u64)-1);
670562306a36Sopenharmony_ci				if (ret)
670662306a36Sopenharmony_ci					goto out;
670762306a36Sopenharmony_ci			}
670862306a36Sopenharmony_ci			if (sctx->cur_inode_last_extent < sctx->cur_inode_size) {
670962306a36Sopenharmony_ci				ret = range_is_hole_in_parent(sctx,
671062306a36Sopenharmony_ci						      sctx->cur_inode_last_extent,
671162306a36Sopenharmony_ci						      sctx->cur_inode_size);
671262306a36Sopenharmony_ci				if (ret < 0) {
671362306a36Sopenharmony_ci					goto out;
671462306a36Sopenharmony_ci				} else if (ret == 0) {
671562306a36Sopenharmony_ci					ret = send_hole(sctx, sctx->cur_inode_size);
671662306a36Sopenharmony_ci					if (ret < 0)
671762306a36Sopenharmony_ci						goto out;
671862306a36Sopenharmony_ci				} else {
671962306a36Sopenharmony_ci					/* Range is already a hole, skip. */
672062306a36Sopenharmony_ci					ret = 0;
672162306a36Sopenharmony_ci				}
672262306a36Sopenharmony_ci			}
672362306a36Sopenharmony_ci		}
672462306a36Sopenharmony_ci		if (need_truncate) {
672562306a36Sopenharmony_ci			ret = send_truncate(sctx, sctx->cur_ino,
672662306a36Sopenharmony_ci					    sctx->cur_inode_gen,
672762306a36Sopenharmony_ci					    sctx->cur_inode_size);
672862306a36Sopenharmony_ci			if (ret < 0)
672962306a36Sopenharmony_ci				goto out;
673062306a36Sopenharmony_ci		}
673162306a36Sopenharmony_ci	}
673262306a36Sopenharmony_ci
673362306a36Sopenharmony_ci	if (need_chown) {
673462306a36Sopenharmony_ci		ret = send_chown(sctx, sctx->cur_ino, sctx->cur_inode_gen,
673562306a36Sopenharmony_ci				left_uid, left_gid);
673662306a36Sopenharmony_ci		if (ret < 0)
673762306a36Sopenharmony_ci			goto out;
673862306a36Sopenharmony_ci	}
673962306a36Sopenharmony_ci	if (need_chmod) {
674062306a36Sopenharmony_ci		ret = send_chmod(sctx, sctx->cur_ino, sctx->cur_inode_gen,
674162306a36Sopenharmony_ci				left_mode);
674262306a36Sopenharmony_ci		if (ret < 0)
674362306a36Sopenharmony_ci			goto out;
674462306a36Sopenharmony_ci	}
674562306a36Sopenharmony_ci	if (need_fileattr) {
674662306a36Sopenharmony_ci		ret = send_fileattr(sctx, sctx->cur_ino, sctx->cur_inode_gen,
674762306a36Sopenharmony_ci				    left_fileattr);
674862306a36Sopenharmony_ci		if (ret < 0)
674962306a36Sopenharmony_ci			goto out;
675062306a36Sopenharmony_ci	}
675162306a36Sopenharmony_ci
675262306a36Sopenharmony_ci	if (proto_cmd_ok(sctx, BTRFS_SEND_C_ENABLE_VERITY)
675362306a36Sopenharmony_ci	    && sctx->cur_inode_needs_verity) {
675462306a36Sopenharmony_ci		ret = process_verity(sctx);
675562306a36Sopenharmony_ci		if (ret < 0)
675662306a36Sopenharmony_ci			goto out;
675762306a36Sopenharmony_ci	}
675862306a36Sopenharmony_ci
675962306a36Sopenharmony_ci	ret = send_capabilities(sctx);
676062306a36Sopenharmony_ci	if (ret < 0)
676162306a36Sopenharmony_ci		goto out;
676262306a36Sopenharmony_ci
676362306a36Sopenharmony_ci	/*
676462306a36Sopenharmony_ci	 * If other directory inodes depended on our current directory
676562306a36Sopenharmony_ci	 * inode's move/rename, now do their move/rename operations.
676662306a36Sopenharmony_ci	 */
676762306a36Sopenharmony_ci	if (!is_waiting_for_move(sctx, sctx->cur_ino)) {
676862306a36Sopenharmony_ci		ret = apply_children_dir_moves(sctx);
676962306a36Sopenharmony_ci		if (ret)
677062306a36Sopenharmony_ci			goto out;
677162306a36Sopenharmony_ci		/*
677262306a36Sopenharmony_ci		 * Need to send that every time, no matter if it actually
677362306a36Sopenharmony_ci		 * changed between the two trees as we have done changes to
677462306a36Sopenharmony_ci		 * the inode before. If our inode is a directory and it's
677562306a36Sopenharmony_ci		 * waiting to be moved/renamed, we will send its utimes when
677662306a36Sopenharmony_ci		 * it's moved/renamed, therefore we don't need to do it here.
677762306a36Sopenharmony_ci		 */
677862306a36Sopenharmony_ci		sctx->send_progress = sctx->cur_ino + 1;
677962306a36Sopenharmony_ci
678062306a36Sopenharmony_ci		/*
678162306a36Sopenharmony_ci		 * If the current inode is a non-empty directory, delay issuing
678262306a36Sopenharmony_ci		 * the utimes command for it, as it's very likely we have inodes
678362306a36Sopenharmony_ci		 * with an higher number inside it. We want to issue the utimes
678462306a36Sopenharmony_ci		 * command only after adding all dentries to it.
678562306a36Sopenharmony_ci		 */
678662306a36Sopenharmony_ci		if (S_ISDIR(sctx->cur_inode_mode) && sctx->cur_inode_size > 0)
678762306a36Sopenharmony_ci			ret = cache_dir_utimes(sctx, sctx->cur_ino, sctx->cur_inode_gen);
678862306a36Sopenharmony_ci		else
678962306a36Sopenharmony_ci			ret = send_utimes(sctx, sctx->cur_ino, sctx->cur_inode_gen);
679062306a36Sopenharmony_ci
679162306a36Sopenharmony_ci		if (ret < 0)
679262306a36Sopenharmony_ci			goto out;
679362306a36Sopenharmony_ci	}
679462306a36Sopenharmony_ci
679562306a36Sopenharmony_ciout:
679662306a36Sopenharmony_ci	if (!ret)
679762306a36Sopenharmony_ci		ret = trim_dir_utimes_cache(sctx);
679862306a36Sopenharmony_ci
679962306a36Sopenharmony_ci	return ret;
680062306a36Sopenharmony_ci}
680162306a36Sopenharmony_ci
680262306a36Sopenharmony_cistatic void close_current_inode(struct send_ctx *sctx)
680362306a36Sopenharmony_ci{
680462306a36Sopenharmony_ci	u64 i_size;
680562306a36Sopenharmony_ci
680662306a36Sopenharmony_ci	if (sctx->cur_inode == NULL)
680762306a36Sopenharmony_ci		return;
680862306a36Sopenharmony_ci
680962306a36Sopenharmony_ci	i_size = i_size_read(sctx->cur_inode);
681062306a36Sopenharmony_ci
681162306a36Sopenharmony_ci	/*
681262306a36Sopenharmony_ci	 * If we are doing an incremental send, we may have extents between the
681362306a36Sopenharmony_ci	 * last processed extent and the i_size that have not been processed
681462306a36Sopenharmony_ci	 * because they haven't changed but we may have read some of their pages
681562306a36Sopenharmony_ci	 * through readahead, see the comments at send_extent_data().
681662306a36Sopenharmony_ci	 */
681762306a36Sopenharmony_ci	if (sctx->clean_page_cache && sctx->page_cache_clear_start < i_size)
681862306a36Sopenharmony_ci		truncate_inode_pages_range(&sctx->cur_inode->i_data,
681962306a36Sopenharmony_ci					   sctx->page_cache_clear_start,
682062306a36Sopenharmony_ci					   round_up(i_size, PAGE_SIZE) - 1);
682162306a36Sopenharmony_ci
682262306a36Sopenharmony_ci	iput(sctx->cur_inode);
682362306a36Sopenharmony_ci	sctx->cur_inode = NULL;
682462306a36Sopenharmony_ci}
682562306a36Sopenharmony_ci
682662306a36Sopenharmony_cistatic int changed_inode(struct send_ctx *sctx,
682762306a36Sopenharmony_ci			 enum btrfs_compare_tree_result result)
682862306a36Sopenharmony_ci{
682962306a36Sopenharmony_ci	int ret = 0;
683062306a36Sopenharmony_ci	struct btrfs_key *key = sctx->cmp_key;
683162306a36Sopenharmony_ci	struct btrfs_inode_item *left_ii = NULL;
683262306a36Sopenharmony_ci	struct btrfs_inode_item *right_ii = NULL;
683362306a36Sopenharmony_ci	u64 left_gen = 0;
683462306a36Sopenharmony_ci	u64 right_gen = 0;
683562306a36Sopenharmony_ci
683662306a36Sopenharmony_ci	close_current_inode(sctx);
683762306a36Sopenharmony_ci
683862306a36Sopenharmony_ci	sctx->cur_ino = key->objectid;
683962306a36Sopenharmony_ci	sctx->cur_inode_new_gen = false;
684062306a36Sopenharmony_ci	sctx->cur_inode_last_extent = (u64)-1;
684162306a36Sopenharmony_ci	sctx->cur_inode_next_write_offset = 0;
684262306a36Sopenharmony_ci	sctx->ignore_cur_inode = false;
684362306a36Sopenharmony_ci
684462306a36Sopenharmony_ci	/*
684562306a36Sopenharmony_ci	 * Set send_progress to current inode. This will tell all get_cur_xxx
684662306a36Sopenharmony_ci	 * functions that the current inode's refs are not updated yet. Later,
684762306a36Sopenharmony_ci	 * when process_recorded_refs is finished, it is set to cur_ino + 1.
684862306a36Sopenharmony_ci	 */
684962306a36Sopenharmony_ci	sctx->send_progress = sctx->cur_ino;
685062306a36Sopenharmony_ci
685162306a36Sopenharmony_ci	if (result == BTRFS_COMPARE_TREE_NEW ||
685262306a36Sopenharmony_ci	    result == BTRFS_COMPARE_TREE_CHANGED) {
685362306a36Sopenharmony_ci		left_ii = btrfs_item_ptr(sctx->left_path->nodes[0],
685462306a36Sopenharmony_ci				sctx->left_path->slots[0],
685562306a36Sopenharmony_ci				struct btrfs_inode_item);
685662306a36Sopenharmony_ci		left_gen = btrfs_inode_generation(sctx->left_path->nodes[0],
685762306a36Sopenharmony_ci				left_ii);
685862306a36Sopenharmony_ci	} else {
685962306a36Sopenharmony_ci		right_ii = btrfs_item_ptr(sctx->right_path->nodes[0],
686062306a36Sopenharmony_ci				sctx->right_path->slots[0],
686162306a36Sopenharmony_ci				struct btrfs_inode_item);
686262306a36Sopenharmony_ci		right_gen = btrfs_inode_generation(sctx->right_path->nodes[0],
686362306a36Sopenharmony_ci				right_ii);
686462306a36Sopenharmony_ci	}
686562306a36Sopenharmony_ci	if (result == BTRFS_COMPARE_TREE_CHANGED) {
686662306a36Sopenharmony_ci		right_ii = btrfs_item_ptr(sctx->right_path->nodes[0],
686762306a36Sopenharmony_ci				sctx->right_path->slots[0],
686862306a36Sopenharmony_ci				struct btrfs_inode_item);
686962306a36Sopenharmony_ci
687062306a36Sopenharmony_ci		right_gen = btrfs_inode_generation(sctx->right_path->nodes[0],
687162306a36Sopenharmony_ci				right_ii);
687262306a36Sopenharmony_ci
687362306a36Sopenharmony_ci		/*
687462306a36Sopenharmony_ci		 * The cur_ino = root dir case is special here. We can't treat
687562306a36Sopenharmony_ci		 * the inode as deleted+reused because it would generate a
687662306a36Sopenharmony_ci		 * stream that tries to delete/mkdir the root dir.
687762306a36Sopenharmony_ci		 */
687862306a36Sopenharmony_ci		if (left_gen != right_gen &&
687962306a36Sopenharmony_ci		    sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID)
688062306a36Sopenharmony_ci			sctx->cur_inode_new_gen = true;
688162306a36Sopenharmony_ci	}
688262306a36Sopenharmony_ci
688362306a36Sopenharmony_ci	/*
688462306a36Sopenharmony_ci	 * Normally we do not find inodes with a link count of zero (orphans)
688562306a36Sopenharmony_ci	 * because the most common case is to create a snapshot and use it
688662306a36Sopenharmony_ci	 * for a send operation. However other less common use cases involve
688762306a36Sopenharmony_ci	 * using a subvolume and send it after turning it to RO mode just
688862306a36Sopenharmony_ci	 * after deleting all hard links of a file while holding an open
688962306a36Sopenharmony_ci	 * file descriptor against it or turning a RO snapshot into RW mode,
689062306a36Sopenharmony_ci	 * keep an open file descriptor against a file, delete it and then
689162306a36Sopenharmony_ci	 * turn the snapshot back to RO mode before using it for a send
689262306a36Sopenharmony_ci	 * operation. The former is what the receiver operation does.
689362306a36Sopenharmony_ci	 * Therefore, if we want to send these snapshots soon after they're
689462306a36Sopenharmony_ci	 * received, we need to handle orphan inodes as well. Moreover, orphans
689562306a36Sopenharmony_ci	 * can appear not only in the send snapshot but also in the parent
689662306a36Sopenharmony_ci	 * snapshot. Here are several cases:
689762306a36Sopenharmony_ci	 *
689862306a36Sopenharmony_ci	 * Case 1: BTRFS_COMPARE_TREE_NEW
689962306a36Sopenharmony_ci	 *       |  send snapshot  | action
690062306a36Sopenharmony_ci	 * --------------------------------
690162306a36Sopenharmony_ci	 * nlink |        0        | ignore
690262306a36Sopenharmony_ci	 *
690362306a36Sopenharmony_ci	 * Case 2: BTRFS_COMPARE_TREE_DELETED
690462306a36Sopenharmony_ci	 *       | parent snapshot | action
690562306a36Sopenharmony_ci	 * ----------------------------------
690662306a36Sopenharmony_ci	 * nlink |        0        | as usual
690762306a36Sopenharmony_ci	 * Note: No unlinks will be sent because there're no paths for it.
690862306a36Sopenharmony_ci	 *
690962306a36Sopenharmony_ci	 * Case 3: BTRFS_COMPARE_TREE_CHANGED
691062306a36Sopenharmony_ci	 *           |       | parent snapshot | send snapshot | action
691162306a36Sopenharmony_ci	 * -----------------------------------------------------------------------
691262306a36Sopenharmony_ci	 * subcase 1 | nlink |        0        |       0       | ignore
691362306a36Sopenharmony_ci	 * subcase 2 | nlink |       >0        |       0       | new_gen(deletion)
691462306a36Sopenharmony_ci	 * subcase 3 | nlink |        0        |      >0       | new_gen(creation)
691562306a36Sopenharmony_ci	 *
691662306a36Sopenharmony_ci	 */
691762306a36Sopenharmony_ci	if (result == BTRFS_COMPARE_TREE_NEW) {
691862306a36Sopenharmony_ci		if (btrfs_inode_nlink(sctx->left_path->nodes[0], left_ii) == 0) {
691962306a36Sopenharmony_ci			sctx->ignore_cur_inode = true;
692062306a36Sopenharmony_ci			goto out;
692162306a36Sopenharmony_ci		}
692262306a36Sopenharmony_ci		sctx->cur_inode_gen = left_gen;
692362306a36Sopenharmony_ci		sctx->cur_inode_new = true;
692462306a36Sopenharmony_ci		sctx->cur_inode_deleted = false;
692562306a36Sopenharmony_ci		sctx->cur_inode_size = btrfs_inode_size(
692662306a36Sopenharmony_ci				sctx->left_path->nodes[0], left_ii);
692762306a36Sopenharmony_ci		sctx->cur_inode_mode = btrfs_inode_mode(
692862306a36Sopenharmony_ci				sctx->left_path->nodes[0], left_ii);
692962306a36Sopenharmony_ci		sctx->cur_inode_rdev = btrfs_inode_rdev(
693062306a36Sopenharmony_ci				sctx->left_path->nodes[0], left_ii);
693162306a36Sopenharmony_ci		if (sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID)
693262306a36Sopenharmony_ci			ret = send_create_inode_if_needed(sctx);
693362306a36Sopenharmony_ci	} else if (result == BTRFS_COMPARE_TREE_DELETED) {
693462306a36Sopenharmony_ci		sctx->cur_inode_gen = right_gen;
693562306a36Sopenharmony_ci		sctx->cur_inode_new = false;
693662306a36Sopenharmony_ci		sctx->cur_inode_deleted = true;
693762306a36Sopenharmony_ci		sctx->cur_inode_size = btrfs_inode_size(
693862306a36Sopenharmony_ci				sctx->right_path->nodes[0], right_ii);
693962306a36Sopenharmony_ci		sctx->cur_inode_mode = btrfs_inode_mode(
694062306a36Sopenharmony_ci				sctx->right_path->nodes[0], right_ii);
694162306a36Sopenharmony_ci	} else if (result == BTRFS_COMPARE_TREE_CHANGED) {
694262306a36Sopenharmony_ci		u32 new_nlinks, old_nlinks;
694362306a36Sopenharmony_ci
694462306a36Sopenharmony_ci		new_nlinks = btrfs_inode_nlink(sctx->left_path->nodes[0], left_ii);
694562306a36Sopenharmony_ci		old_nlinks = btrfs_inode_nlink(sctx->right_path->nodes[0], right_ii);
694662306a36Sopenharmony_ci		if (new_nlinks == 0 && old_nlinks == 0) {
694762306a36Sopenharmony_ci			sctx->ignore_cur_inode = true;
694862306a36Sopenharmony_ci			goto out;
694962306a36Sopenharmony_ci		} else if (new_nlinks == 0 || old_nlinks == 0) {
695062306a36Sopenharmony_ci			sctx->cur_inode_new_gen = 1;
695162306a36Sopenharmony_ci		}
695262306a36Sopenharmony_ci		/*
695362306a36Sopenharmony_ci		 * We need to do some special handling in case the inode was
695462306a36Sopenharmony_ci		 * reported as changed with a changed generation number. This
695562306a36Sopenharmony_ci		 * means that the original inode was deleted and new inode
695662306a36Sopenharmony_ci		 * reused the same inum. So we have to treat the old inode as
695762306a36Sopenharmony_ci		 * deleted and the new one as new.
695862306a36Sopenharmony_ci		 */
695962306a36Sopenharmony_ci		if (sctx->cur_inode_new_gen) {
696062306a36Sopenharmony_ci			/*
696162306a36Sopenharmony_ci			 * First, process the inode as if it was deleted.
696262306a36Sopenharmony_ci			 */
696362306a36Sopenharmony_ci			if (old_nlinks > 0) {
696462306a36Sopenharmony_ci				sctx->cur_inode_gen = right_gen;
696562306a36Sopenharmony_ci				sctx->cur_inode_new = false;
696662306a36Sopenharmony_ci				sctx->cur_inode_deleted = true;
696762306a36Sopenharmony_ci				sctx->cur_inode_size = btrfs_inode_size(
696862306a36Sopenharmony_ci						sctx->right_path->nodes[0], right_ii);
696962306a36Sopenharmony_ci				sctx->cur_inode_mode = btrfs_inode_mode(
697062306a36Sopenharmony_ci						sctx->right_path->nodes[0], right_ii);
697162306a36Sopenharmony_ci				ret = process_all_refs(sctx,
697262306a36Sopenharmony_ci						BTRFS_COMPARE_TREE_DELETED);
697362306a36Sopenharmony_ci				if (ret < 0)
697462306a36Sopenharmony_ci					goto out;
697562306a36Sopenharmony_ci			}
697662306a36Sopenharmony_ci
697762306a36Sopenharmony_ci			/*
697862306a36Sopenharmony_ci			 * Now process the inode as if it was new.
697962306a36Sopenharmony_ci			 */
698062306a36Sopenharmony_ci			if (new_nlinks > 0) {
698162306a36Sopenharmony_ci				sctx->cur_inode_gen = left_gen;
698262306a36Sopenharmony_ci				sctx->cur_inode_new = true;
698362306a36Sopenharmony_ci				sctx->cur_inode_deleted = false;
698462306a36Sopenharmony_ci				sctx->cur_inode_size = btrfs_inode_size(
698562306a36Sopenharmony_ci						sctx->left_path->nodes[0],
698662306a36Sopenharmony_ci						left_ii);
698762306a36Sopenharmony_ci				sctx->cur_inode_mode = btrfs_inode_mode(
698862306a36Sopenharmony_ci						sctx->left_path->nodes[0],
698962306a36Sopenharmony_ci						left_ii);
699062306a36Sopenharmony_ci				sctx->cur_inode_rdev = btrfs_inode_rdev(
699162306a36Sopenharmony_ci						sctx->left_path->nodes[0],
699262306a36Sopenharmony_ci						left_ii);
699362306a36Sopenharmony_ci				ret = send_create_inode_if_needed(sctx);
699462306a36Sopenharmony_ci				if (ret < 0)
699562306a36Sopenharmony_ci					goto out;
699662306a36Sopenharmony_ci
699762306a36Sopenharmony_ci				ret = process_all_refs(sctx, BTRFS_COMPARE_TREE_NEW);
699862306a36Sopenharmony_ci				if (ret < 0)
699962306a36Sopenharmony_ci					goto out;
700062306a36Sopenharmony_ci				/*
700162306a36Sopenharmony_ci				 * Advance send_progress now as we did not get
700262306a36Sopenharmony_ci				 * into process_recorded_refs_if_needed in the
700362306a36Sopenharmony_ci				 * new_gen case.
700462306a36Sopenharmony_ci				 */
700562306a36Sopenharmony_ci				sctx->send_progress = sctx->cur_ino + 1;
700662306a36Sopenharmony_ci
700762306a36Sopenharmony_ci				/*
700862306a36Sopenharmony_ci				 * Now process all extents and xattrs of the
700962306a36Sopenharmony_ci				 * inode as if they were all new.
701062306a36Sopenharmony_ci				 */
701162306a36Sopenharmony_ci				ret = process_all_extents(sctx);
701262306a36Sopenharmony_ci				if (ret < 0)
701362306a36Sopenharmony_ci					goto out;
701462306a36Sopenharmony_ci				ret = process_all_new_xattrs(sctx);
701562306a36Sopenharmony_ci				if (ret < 0)
701662306a36Sopenharmony_ci					goto out;
701762306a36Sopenharmony_ci			}
701862306a36Sopenharmony_ci		} else {
701962306a36Sopenharmony_ci			sctx->cur_inode_gen = left_gen;
702062306a36Sopenharmony_ci			sctx->cur_inode_new = false;
702162306a36Sopenharmony_ci			sctx->cur_inode_new_gen = false;
702262306a36Sopenharmony_ci			sctx->cur_inode_deleted = false;
702362306a36Sopenharmony_ci			sctx->cur_inode_size = btrfs_inode_size(
702462306a36Sopenharmony_ci					sctx->left_path->nodes[0], left_ii);
702562306a36Sopenharmony_ci			sctx->cur_inode_mode = btrfs_inode_mode(
702662306a36Sopenharmony_ci					sctx->left_path->nodes[0], left_ii);
702762306a36Sopenharmony_ci		}
702862306a36Sopenharmony_ci	}
702962306a36Sopenharmony_ci
703062306a36Sopenharmony_ciout:
703162306a36Sopenharmony_ci	return ret;
703262306a36Sopenharmony_ci}
703362306a36Sopenharmony_ci
703462306a36Sopenharmony_ci/*
703562306a36Sopenharmony_ci * We have to process new refs before deleted refs, but compare_trees gives us
703662306a36Sopenharmony_ci * the new and deleted refs mixed. To fix this, we record the new/deleted refs
703762306a36Sopenharmony_ci * first and later process them in process_recorded_refs.
703862306a36Sopenharmony_ci * For the cur_inode_new_gen case, we skip recording completely because
703962306a36Sopenharmony_ci * changed_inode did already initiate processing of refs. The reason for this is
704062306a36Sopenharmony_ci * that in this case, compare_tree actually compares the refs of 2 different
704162306a36Sopenharmony_ci * inodes. To fix this, process_all_refs is used in changed_inode to handle all
704262306a36Sopenharmony_ci * refs of the right tree as deleted and all refs of the left tree as new.
704362306a36Sopenharmony_ci */
704462306a36Sopenharmony_cistatic int changed_ref(struct send_ctx *sctx,
704562306a36Sopenharmony_ci		       enum btrfs_compare_tree_result result)
704662306a36Sopenharmony_ci{
704762306a36Sopenharmony_ci	int ret = 0;
704862306a36Sopenharmony_ci
704962306a36Sopenharmony_ci	if (sctx->cur_ino != sctx->cmp_key->objectid) {
705062306a36Sopenharmony_ci		inconsistent_snapshot_error(sctx, result, "reference");
705162306a36Sopenharmony_ci		return -EIO;
705262306a36Sopenharmony_ci	}
705362306a36Sopenharmony_ci
705462306a36Sopenharmony_ci	if (!sctx->cur_inode_new_gen &&
705562306a36Sopenharmony_ci	    sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID) {
705662306a36Sopenharmony_ci		if (result == BTRFS_COMPARE_TREE_NEW)
705762306a36Sopenharmony_ci			ret = record_new_ref(sctx);
705862306a36Sopenharmony_ci		else if (result == BTRFS_COMPARE_TREE_DELETED)
705962306a36Sopenharmony_ci			ret = record_deleted_ref(sctx);
706062306a36Sopenharmony_ci		else if (result == BTRFS_COMPARE_TREE_CHANGED)
706162306a36Sopenharmony_ci			ret = record_changed_ref(sctx);
706262306a36Sopenharmony_ci	}
706362306a36Sopenharmony_ci
706462306a36Sopenharmony_ci	return ret;
706562306a36Sopenharmony_ci}
706662306a36Sopenharmony_ci
706762306a36Sopenharmony_ci/*
706862306a36Sopenharmony_ci * Process new/deleted/changed xattrs. We skip processing in the
706962306a36Sopenharmony_ci * cur_inode_new_gen case because changed_inode did already initiate processing
707062306a36Sopenharmony_ci * of xattrs. The reason is the same as in changed_ref
707162306a36Sopenharmony_ci */
707262306a36Sopenharmony_cistatic int changed_xattr(struct send_ctx *sctx,
707362306a36Sopenharmony_ci			 enum btrfs_compare_tree_result result)
707462306a36Sopenharmony_ci{
707562306a36Sopenharmony_ci	int ret = 0;
707662306a36Sopenharmony_ci
707762306a36Sopenharmony_ci	if (sctx->cur_ino != sctx->cmp_key->objectid) {
707862306a36Sopenharmony_ci		inconsistent_snapshot_error(sctx, result, "xattr");
707962306a36Sopenharmony_ci		return -EIO;
708062306a36Sopenharmony_ci	}
708162306a36Sopenharmony_ci
708262306a36Sopenharmony_ci	if (!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted) {
708362306a36Sopenharmony_ci		if (result == BTRFS_COMPARE_TREE_NEW)
708462306a36Sopenharmony_ci			ret = process_new_xattr(sctx);
708562306a36Sopenharmony_ci		else if (result == BTRFS_COMPARE_TREE_DELETED)
708662306a36Sopenharmony_ci			ret = process_deleted_xattr(sctx);
708762306a36Sopenharmony_ci		else if (result == BTRFS_COMPARE_TREE_CHANGED)
708862306a36Sopenharmony_ci			ret = process_changed_xattr(sctx);
708962306a36Sopenharmony_ci	}
709062306a36Sopenharmony_ci
709162306a36Sopenharmony_ci	return ret;
709262306a36Sopenharmony_ci}
709362306a36Sopenharmony_ci
709462306a36Sopenharmony_ci/*
709562306a36Sopenharmony_ci * Process new/deleted/changed extents. We skip processing in the
709662306a36Sopenharmony_ci * cur_inode_new_gen case because changed_inode did already initiate processing
709762306a36Sopenharmony_ci * of extents. The reason is the same as in changed_ref
709862306a36Sopenharmony_ci */
709962306a36Sopenharmony_cistatic int changed_extent(struct send_ctx *sctx,
710062306a36Sopenharmony_ci			  enum btrfs_compare_tree_result result)
710162306a36Sopenharmony_ci{
710262306a36Sopenharmony_ci	int ret = 0;
710362306a36Sopenharmony_ci
710462306a36Sopenharmony_ci	/*
710562306a36Sopenharmony_ci	 * We have found an extent item that changed without the inode item
710662306a36Sopenharmony_ci	 * having changed. This can happen either after relocation (where the
710762306a36Sopenharmony_ci	 * disk_bytenr of an extent item is replaced at
710862306a36Sopenharmony_ci	 * relocation.c:replace_file_extents()) or after deduplication into a
710962306a36Sopenharmony_ci	 * file in both the parent and send snapshots (where an extent item can
711062306a36Sopenharmony_ci	 * get modified or replaced with a new one). Note that deduplication
711162306a36Sopenharmony_ci	 * updates the inode item, but it only changes the iversion (sequence
711262306a36Sopenharmony_ci	 * field in the inode item) of the inode, so if a file is deduplicated
711362306a36Sopenharmony_ci	 * the same amount of times in both the parent and send snapshots, its
711462306a36Sopenharmony_ci	 * iversion becomes the same in both snapshots, whence the inode item is
711562306a36Sopenharmony_ci	 * the same on both snapshots.
711662306a36Sopenharmony_ci	 */
711762306a36Sopenharmony_ci	if (sctx->cur_ino != sctx->cmp_key->objectid)
711862306a36Sopenharmony_ci		return 0;
711962306a36Sopenharmony_ci
712062306a36Sopenharmony_ci	if (!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted) {
712162306a36Sopenharmony_ci		if (result != BTRFS_COMPARE_TREE_DELETED)
712262306a36Sopenharmony_ci			ret = process_extent(sctx, sctx->left_path,
712362306a36Sopenharmony_ci					sctx->cmp_key);
712462306a36Sopenharmony_ci	}
712562306a36Sopenharmony_ci
712662306a36Sopenharmony_ci	return ret;
712762306a36Sopenharmony_ci}
712862306a36Sopenharmony_ci
712962306a36Sopenharmony_cistatic int changed_verity(struct send_ctx *sctx, enum btrfs_compare_tree_result result)
713062306a36Sopenharmony_ci{
713162306a36Sopenharmony_ci	int ret = 0;
713262306a36Sopenharmony_ci
713362306a36Sopenharmony_ci	if (!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted) {
713462306a36Sopenharmony_ci		if (result == BTRFS_COMPARE_TREE_NEW)
713562306a36Sopenharmony_ci			sctx->cur_inode_needs_verity = true;
713662306a36Sopenharmony_ci	}
713762306a36Sopenharmony_ci	return ret;
713862306a36Sopenharmony_ci}
713962306a36Sopenharmony_ci
714062306a36Sopenharmony_cistatic int dir_changed(struct send_ctx *sctx, u64 dir)
714162306a36Sopenharmony_ci{
714262306a36Sopenharmony_ci	u64 orig_gen, new_gen;
714362306a36Sopenharmony_ci	int ret;
714462306a36Sopenharmony_ci
714562306a36Sopenharmony_ci	ret = get_inode_gen(sctx->send_root, dir, &new_gen);
714662306a36Sopenharmony_ci	if (ret)
714762306a36Sopenharmony_ci		return ret;
714862306a36Sopenharmony_ci
714962306a36Sopenharmony_ci	ret = get_inode_gen(sctx->parent_root, dir, &orig_gen);
715062306a36Sopenharmony_ci	if (ret)
715162306a36Sopenharmony_ci		return ret;
715262306a36Sopenharmony_ci
715362306a36Sopenharmony_ci	return (orig_gen != new_gen) ? 1 : 0;
715462306a36Sopenharmony_ci}
715562306a36Sopenharmony_ci
715662306a36Sopenharmony_cistatic int compare_refs(struct send_ctx *sctx, struct btrfs_path *path,
715762306a36Sopenharmony_ci			struct btrfs_key *key)
715862306a36Sopenharmony_ci{
715962306a36Sopenharmony_ci	struct btrfs_inode_extref *extref;
716062306a36Sopenharmony_ci	struct extent_buffer *leaf;
716162306a36Sopenharmony_ci	u64 dirid = 0, last_dirid = 0;
716262306a36Sopenharmony_ci	unsigned long ptr;
716362306a36Sopenharmony_ci	u32 item_size;
716462306a36Sopenharmony_ci	u32 cur_offset = 0;
716562306a36Sopenharmony_ci	int ref_name_len;
716662306a36Sopenharmony_ci	int ret = 0;
716762306a36Sopenharmony_ci
716862306a36Sopenharmony_ci	/* Easy case, just check this one dirid */
716962306a36Sopenharmony_ci	if (key->type == BTRFS_INODE_REF_KEY) {
717062306a36Sopenharmony_ci		dirid = key->offset;
717162306a36Sopenharmony_ci
717262306a36Sopenharmony_ci		ret = dir_changed(sctx, dirid);
717362306a36Sopenharmony_ci		goto out;
717462306a36Sopenharmony_ci	}
717562306a36Sopenharmony_ci
717662306a36Sopenharmony_ci	leaf = path->nodes[0];
717762306a36Sopenharmony_ci	item_size = btrfs_item_size(leaf, path->slots[0]);
717862306a36Sopenharmony_ci	ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
717962306a36Sopenharmony_ci	while (cur_offset < item_size) {
718062306a36Sopenharmony_ci		extref = (struct btrfs_inode_extref *)(ptr +
718162306a36Sopenharmony_ci						       cur_offset);
718262306a36Sopenharmony_ci		dirid = btrfs_inode_extref_parent(leaf, extref);
718362306a36Sopenharmony_ci		ref_name_len = btrfs_inode_extref_name_len(leaf, extref);
718462306a36Sopenharmony_ci		cur_offset += ref_name_len + sizeof(*extref);
718562306a36Sopenharmony_ci		if (dirid == last_dirid)
718662306a36Sopenharmony_ci			continue;
718762306a36Sopenharmony_ci		ret = dir_changed(sctx, dirid);
718862306a36Sopenharmony_ci		if (ret)
718962306a36Sopenharmony_ci			break;
719062306a36Sopenharmony_ci		last_dirid = dirid;
719162306a36Sopenharmony_ci	}
719262306a36Sopenharmony_ciout:
719362306a36Sopenharmony_ci	return ret;
719462306a36Sopenharmony_ci}
719562306a36Sopenharmony_ci
719662306a36Sopenharmony_ci/*
719762306a36Sopenharmony_ci * Updates compare related fields in sctx and simply forwards to the actual
719862306a36Sopenharmony_ci * changed_xxx functions.
719962306a36Sopenharmony_ci */
720062306a36Sopenharmony_cistatic int changed_cb(struct btrfs_path *left_path,
720162306a36Sopenharmony_ci		      struct btrfs_path *right_path,
720262306a36Sopenharmony_ci		      struct btrfs_key *key,
720362306a36Sopenharmony_ci		      enum btrfs_compare_tree_result result,
720462306a36Sopenharmony_ci		      struct send_ctx *sctx)
720562306a36Sopenharmony_ci{
720662306a36Sopenharmony_ci	int ret = 0;
720762306a36Sopenharmony_ci
720862306a36Sopenharmony_ci	/*
720962306a36Sopenharmony_ci	 * We can not hold the commit root semaphore here. This is because in
721062306a36Sopenharmony_ci	 * the case of sending and receiving to the same filesystem, using a
721162306a36Sopenharmony_ci	 * pipe, could result in a deadlock:
721262306a36Sopenharmony_ci	 *
721362306a36Sopenharmony_ci	 * 1) The task running send blocks on the pipe because it's full;
721462306a36Sopenharmony_ci	 *
721562306a36Sopenharmony_ci	 * 2) The task running receive, which is the only consumer of the pipe,
721662306a36Sopenharmony_ci	 *    is waiting for a transaction commit (for example due to a space
721762306a36Sopenharmony_ci	 *    reservation when doing a write or triggering a transaction commit
721862306a36Sopenharmony_ci	 *    when creating a subvolume);
721962306a36Sopenharmony_ci	 *
722062306a36Sopenharmony_ci	 * 3) The transaction is waiting to write lock the commit root semaphore,
722162306a36Sopenharmony_ci	 *    but can not acquire it since it's being held at 1).
722262306a36Sopenharmony_ci	 *
722362306a36Sopenharmony_ci	 * Down this call chain we write to the pipe through kernel_write().
722462306a36Sopenharmony_ci	 * The same type of problem can also happen when sending to a file that
722562306a36Sopenharmony_ci	 * is stored in the same filesystem - when reserving space for a write
722662306a36Sopenharmony_ci	 * into the file, we can trigger a transaction commit.
722762306a36Sopenharmony_ci	 *
722862306a36Sopenharmony_ci	 * Our caller has supplied us with clones of leaves from the send and
722962306a36Sopenharmony_ci	 * parent roots, so we're safe here from a concurrent relocation and
723062306a36Sopenharmony_ci	 * further reallocation of metadata extents while we are here. Below we
723162306a36Sopenharmony_ci	 * also assert that the leaves are clones.
723262306a36Sopenharmony_ci	 */
723362306a36Sopenharmony_ci	lockdep_assert_not_held(&sctx->send_root->fs_info->commit_root_sem);
723462306a36Sopenharmony_ci
723562306a36Sopenharmony_ci	/*
723662306a36Sopenharmony_ci	 * We always have a send root, so left_path is never NULL. We will not
723762306a36Sopenharmony_ci	 * have a leaf when we have reached the end of the send root but have
723862306a36Sopenharmony_ci	 * not yet reached the end of the parent root.
723962306a36Sopenharmony_ci	 */
724062306a36Sopenharmony_ci	if (left_path->nodes[0])
724162306a36Sopenharmony_ci		ASSERT(test_bit(EXTENT_BUFFER_UNMAPPED,
724262306a36Sopenharmony_ci				&left_path->nodes[0]->bflags));
724362306a36Sopenharmony_ci	/*
724462306a36Sopenharmony_ci	 * When doing a full send we don't have a parent root, so right_path is
724562306a36Sopenharmony_ci	 * NULL. When doing an incremental send, we may have reached the end of
724662306a36Sopenharmony_ci	 * the parent root already, so we don't have a leaf at right_path.
724762306a36Sopenharmony_ci	 */
724862306a36Sopenharmony_ci	if (right_path && right_path->nodes[0])
724962306a36Sopenharmony_ci		ASSERT(test_bit(EXTENT_BUFFER_UNMAPPED,
725062306a36Sopenharmony_ci				&right_path->nodes[0]->bflags));
725162306a36Sopenharmony_ci
725262306a36Sopenharmony_ci	if (result == BTRFS_COMPARE_TREE_SAME) {
725362306a36Sopenharmony_ci		if (key->type == BTRFS_INODE_REF_KEY ||
725462306a36Sopenharmony_ci		    key->type == BTRFS_INODE_EXTREF_KEY) {
725562306a36Sopenharmony_ci			ret = compare_refs(sctx, left_path, key);
725662306a36Sopenharmony_ci			if (!ret)
725762306a36Sopenharmony_ci				return 0;
725862306a36Sopenharmony_ci			if (ret < 0)
725962306a36Sopenharmony_ci				return ret;
726062306a36Sopenharmony_ci		} else if (key->type == BTRFS_EXTENT_DATA_KEY) {
726162306a36Sopenharmony_ci			return maybe_send_hole(sctx, left_path, key);
726262306a36Sopenharmony_ci		} else {
726362306a36Sopenharmony_ci			return 0;
726462306a36Sopenharmony_ci		}
726562306a36Sopenharmony_ci		result = BTRFS_COMPARE_TREE_CHANGED;
726662306a36Sopenharmony_ci		ret = 0;
726762306a36Sopenharmony_ci	}
726862306a36Sopenharmony_ci
726962306a36Sopenharmony_ci	sctx->left_path = left_path;
727062306a36Sopenharmony_ci	sctx->right_path = right_path;
727162306a36Sopenharmony_ci	sctx->cmp_key = key;
727262306a36Sopenharmony_ci
727362306a36Sopenharmony_ci	ret = finish_inode_if_needed(sctx, 0);
727462306a36Sopenharmony_ci	if (ret < 0)
727562306a36Sopenharmony_ci		goto out;
727662306a36Sopenharmony_ci
727762306a36Sopenharmony_ci	/* Ignore non-FS objects */
727862306a36Sopenharmony_ci	if (key->objectid == BTRFS_FREE_INO_OBJECTID ||
727962306a36Sopenharmony_ci	    key->objectid == BTRFS_FREE_SPACE_OBJECTID)
728062306a36Sopenharmony_ci		goto out;
728162306a36Sopenharmony_ci
728262306a36Sopenharmony_ci	if (key->type == BTRFS_INODE_ITEM_KEY) {
728362306a36Sopenharmony_ci		ret = changed_inode(sctx, result);
728462306a36Sopenharmony_ci	} else if (!sctx->ignore_cur_inode) {
728562306a36Sopenharmony_ci		if (key->type == BTRFS_INODE_REF_KEY ||
728662306a36Sopenharmony_ci		    key->type == BTRFS_INODE_EXTREF_KEY)
728762306a36Sopenharmony_ci			ret = changed_ref(sctx, result);
728862306a36Sopenharmony_ci		else if (key->type == BTRFS_XATTR_ITEM_KEY)
728962306a36Sopenharmony_ci			ret = changed_xattr(sctx, result);
729062306a36Sopenharmony_ci		else if (key->type == BTRFS_EXTENT_DATA_KEY)
729162306a36Sopenharmony_ci			ret = changed_extent(sctx, result);
729262306a36Sopenharmony_ci		else if (key->type == BTRFS_VERITY_DESC_ITEM_KEY &&
729362306a36Sopenharmony_ci			 key->offset == 0)
729462306a36Sopenharmony_ci			ret = changed_verity(sctx, result);
729562306a36Sopenharmony_ci	}
729662306a36Sopenharmony_ci
729762306a36Sopenharmony_ciout:
729862306a36Sopenharmony_ci	return ret;
729962306a36Sopenharmony_ci}
730062306a36Sopenharmony_ci
730162306a36Sopenharmony_cistatic int search_key_again(const struct send_ctx *sctx,
730262306a36Sopenharmony_ci			    struct btrfs_root *root,
730362306a36Sopenharmony_ci			    struct btrfs_path *path,
730462306a36Sopenharmony_ci			    const struct btrfs_key *key)
730562306a36Sopenharmony_ci{
730662306a36Sopenharmony_ci	int ret;
730762306a36Sopenharmony_ci
730862306a36Sopenharmony_ci	if (!path->need_commit_sem)
730962306a36Sopenharmony_ci		lockdep_assert_held_read(&root->fs_info->commit_root_sem);
731062306a36Sopenharmony_ci
731162306a36Sopenharmony_ci	/*
731262306a36Sopenharmony_ci	 * Roots used for send operations are readonly and no one can add,
731362306a36Sopenharmony_ci	 * update or remove keys from them, so we should be able to find our
731462306a36Sopenharmony_ci	 * key again. The only exception is deduplication, which can operate on
731562306a36Sopenharmony_ci	 * readonly roots and add, update or remove keys to/from them - but at
731662306a36Sopenharmony_ci	 * the moment we don't allow it to run in parallel with send.
731762306a36Sopenharmony_ci	 */
731862306a36Sopenharmony_ci	ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
731962306a36Sopenharmony_ci	ASSERT(ret <= 0);
732062306a36Sopenharmony_ci	if (ret > 0) {
732162306a36Sopenharmony_ci		btrfs_print_tree(path->nodes[path->lowest_level], false);
732262306a36Sopenharmony_ci		btrfs_err(root->fs_info,
732362306a36Sopenharmony_ci"send: key (%llu %u %llu) not found in %s root %llu, lowest_level %d, slot %d",
732462306a36Sopenharmony_ci			  key->objectid, key->type, key->offset,
732562306a36Sopenharmony_ci			  (root == sctx->parent_root ? "parent" : "send"),
732662306a36Sopenharmony_ci			  root->root_key.objectid, path->lowest_level,
732762306a36Sopenharmony_ci			  path->slots[path->lowest_level]);
732862306a36Sopenharmony_ci		return -EUCLEAN;
732962306a36Sopenharmony_ci	}
733062306a36Sopenharmony_ci
733162306a36Sopenharmony_ci	return ret;
733262306a36Sopenharmony_ci}
733362306a36Sopenharmony_ci
733462306a36Sopenharmony_cistatic int full_send_tree(struct send_ctx *sctx)
733562306a36Sopenharmony_ci{
733662306a36Sopenharmony_ci	int ret;
733762306a36Sopenharmony_ci	struct btrfs_root *send_root = sctx->send_root;
733862306a36Sopenharmony_ci	struct btrfs_key key;
733962306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = send_root->fs_info;
734062306a36Sopenharmony_ci	struct btrfs_path *path;
734162306a36Sopenharmony_ci
734262306a36Sopenharmony_ci	path = alloc_path_for_send();
734362306a36Sopenharmony_ci	if (!path)
734462306a36Sopenharmony_ci		return -ENOMEM;
734562306a36Sopenharmony_ci	path->reada = READA_FORWARD_ALWAYS;
734662306a36Sopenharmony_ci
734762306a36Sopenharmony_ci	key.objectid = BTRFS_FIRST_FREE_OBJECTID;
734862306a36Sopenharmony_ci	key.type = BTRFS_INODE_ITEM_KEY;
734962306a36Sopenharmony_ci	key.offset = 0;
735062306a36Sopenharmony_ci
735162306a36Sopenharmony_ci	down_read(&fs_info->commit_root_sem);
735262306a36Sopenharmony_ci	sctx->last_reloc_trans = fs_info->last_reloc_trans;
735362306a36Sopenharmony_ci	up_read(&fs_info->commit_root_sem);
735462306a36Sopenharmony_ci
735562306a36Sopenharmony_ci	ret = btrfs_search_slot_for_read(send_root, &key, path, 1, 0);
735662306a36Sopenharmony_ci	if (ret < 0)
735762306a36Sopenharmony_ci		goto out;
735862306a36Sopenharmony_ci	if (ret)
735962306a36Sopenharmony_ci		goto out_finish;
736062306a36Sopenharmony_ci
736162306a36Sopenharmony_ci	while (1) {
736262306a36Sopenharmony_ci		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
736362306a36Sopenharmony_ci
736462306a36Sopenharmony_ci		ret = changed_cb(path, NULL, &key,
736562306a36Sopenharmony_ci				 BTRFS_COMPARE_TREE_NEW, sctx);
736662306a36Sopenharmony_ci		if (ret < 0)
736762306a36Sopenharmony_ci			goto out;
736862306a36Sopenharmony_ci
736962306a36Sopenharmony_ci		down_read(&fs_info->commit_root_sem);
737062306a36Sopenharmony_ci		if (fs_info->last_reloc_trans > sctx->last_reloc_trans) {
737162306a36Sopenharmony_ci			sctx->last_reloc_trans = fs_info->last_reloc_trans;
737262306a36Sopenharmony_ci			up_read(&fs_info->commit_root_sem);
737362306a36Sopenharmony_ci			/*
737462306a36Sopenharmony_ci			 * A transaction used for relocating a block group was
737562306a36Sopenharmony_ci			 * committed or is about to finish its commit. Release
737662306a36Sopenharmony_ci			 * our path (leaf) and restart the search, so that we
737762306a36Sopenharmony_ci			 * avoid operating on any file extent items that are
737862306a36Sopenharmony_ci			 * stale, with a disk_bytenr that reflects a pre
737962306a36Sopenharmony_ci			 * relocation value. This way we avoid as much as
738062306a36Sopenharmony_ci			 * possible to fallback to regular writes when checking
738162306a36Sopenharmony_ci			 * if we can clone file ranges.
738262306a36Sopenharmony_ci			 */
738362306a36Sopenharmony_ci			btrfs_release_path(path);
738462306a36Sopenharmony_ci			ret = search_key_again(sctx, send_root, path, &key);
738562306a36Sopenharmony_ci			if (ret < 0)
738662306a36Sopenharmony_ci				goto out;
738762306a36Sopenharmony_ci		} else {
738862306a36Sopenharmony_ci			up_read(&fs_info->commit_root_sem);
738962306a36Sopenharmony_ci		}
739062306a36Sopenharmony_ci
739162306a36Sopenharmony_ci		ret = btrfs_next_item(send_root, path);
739262306a36Sopenharmony_ci		if (ret < 0)
739362306a36Sopenharmony_ci			goto out;
739462306a36Sopenharmony_ci		if (ret) {
739562306a36Sopenharmony_ci			ret  = 0;
739662306a36Sopenharmony_ci			break;
739762306a36Sopenharmony_ci		}
739862306a36Sopenharmony_ci	}
739962306a36Sopenharmony_ci
740062306a36Sopenharmony_ciout_finish:
740162306a36Sopenharmony_ci	ret = finish_inode_if_needed(sctx, 1);
740262306a36Sopenharmony_ci
740362306a36Sopenharmony_ciout:
740462306a36Sopenharmony_ci	btrfs_free_path(path);
740562306a36Sopenharmony_ci	return ret;
740662306a36Sopenharmony_ci}
740762306a36Sopenharmony_ci
740862306a36Sopenharmony_cistatic int replace_node_with_clone(struct btrfs_path *path, int level)
740962306a36Sopenharmony_ci{
741062306a36Sopenharmony_ci	struct extent_buffer *clone;
741162306a36Sopenharmony_ci
741262306a36Sopenharmony_ci	clone = btrfs_clone_extent_buffer(path->nodes[level]);
741362306a36Sopenharmony_ci	if (!clone)
741462306a36Sopenharmony_ci		return -ENOMEM;
741562306a36Sopenharmony_ci
741662306a36Sopenharmony_ci	free_extent_buffer(path->nodes[level]);
741762306a36Sopenharmony_ci	path->nodes[level] = clone;
741862306a36Sopenharmony_ci
741962306a36Sopenharmony_ci	return 0;
742062306a36Sopenharmony_ci}
742162306a36Sopenharmony_ci
742262306a36Sopenharmony_cistatic int tree_move_down(struct btrfs_path *path, int *level, u64 reada_min_gen)
742362306a36Sopenharmony_ci{
742462306a36Sopenharmony_ci	struct extent_buffer *eb;
742562306a36Sopenharmony_ci	struct extent_buffer *parent = path->nodes[*level];
742662306a36Sopenharmony_ci	int slot = path->slots[*level];
742762306a36Sopenharmony_ci	const int nritems = btrfs_header_nritems(parent);
742862306a36Sopenharmony_ci	u64 reada_max;
742962306a36Sopenharmony_ci	u64 reada_done = 0;
743062306a36Sopenharmony_ci
743162306a36Sopenharmony_ci	lockdep_assert_held_read(&parent->fs_info->commit_root_sem);
743262306a36Sopenharmony_ci
743362306a36Sopenharmony_ci	BUG_ON(*level == 0);
743462306a36Sopenharmony_ci	eb = btrfs_read_node_slot(parent, slot);
743562306a36Sopenharmony_ci	if (IS_ERR(eb))
743662306a36Sopenharmony_ci		return PTR_ERR(eb);
743762306a36Sopenharmony_ci
743862306a36Sopenharmony_ci	/*
743962306a36Sopenharmony_ci	 * Trigger readahead for the next leaves we will process, so that it is
744062306a36Sopenharmony_ci	 * very likely that when we need them they are already in memory and we
744162306a36Sopenharmony_ci	 * will not block on disk IO. For nodes we only do readahead for one,
744262306a36Sopenharmony_ci	 * since the time window between processing nodes is typically larger.
744362306a36Sopenharmony_ci	 */
744462306a36Sopenharmony_ci	reada_max = (*level == 1 ? SZ_128K : eb->fs_info->nodesize);
744562306a36Sopenharmony_ci
744662306a36Sopenharmony_ci	for (slot++; slot < nritems && reada_done < reada_max; slot++) {
744762306a36Sopenharmony_ci		if (btrfs_node_ptr_generation(parent, slot) > reada_min_gen) {
744862306a36Sopenharmony_ci			btrfs_readahead_node_child(parent, slot);
744962306a36Sopenharmony_ci			reada_done += eb->fs_info->nodesize;
745062306a36Sopenharmony_ci		}
745162306a36Sopenharmony_ci	}
745262306a36Sopenharmony_ci
745362306a36Sopenharmony_ci	path->nodes[*level - 1] = eb;
745462306a36Sopenharmony_ci	path->slots[*level - 1] = 0;
745562306a36Sopenharmony_ci	(*level)--;
745662306a36Sopenharmony_ci
745762306a36Sopenharmony_ci	if (*level == 0)
745862306a36Sopenharmony_ci		return replace_node_with_clone(path, 0);
745962306a36Sopenharmony_ci
746062306a36Sopenharmony_ci	return 0;
746162306a36Sopenharmony_ci}
746262306a36Sopenharmony_ci
746362306a36Sopenharmony_cistatic int tree_move_next_or_upnext(struct btrfs_path *path,
746462306a36Sopenharmony_ci				    int *level, int root_level)
746562306a36Sopenharmony_ci{
746662306a36Sopenharmony_ci	int ret = 0;
746762306a36Sopenharmony_ci	int nritems;
746862306a36Sopenharmony_ci	nritems = btrfs_header_nritems(path->nodes[*level]);
746962306a36Sopenharmony_ci
747062306a36Sopenharmony_ci	path->slots[*level]++;
747162306a36Sopenharmony_ci
747262306a36Sopenharmony_ci	while (path->slots[*level] >= nritems) {
747362306a36Sopenharmony_ci		if (*level == root_level) {
747462306a36Sopenharmony_ci			path->slots[*level] = nritems - 1;
747562306a36Sopenharmony_ci			return -1;
747662306a36Sopenharmony_ci		}
747762306a36Sopenharmony_ci
747862306a36Sopenharmony_ci		/* move upnext */
747962306a36Sopenharmony_ci		path->slots[*level] = 0;
748062306a36Sopenharmony_ci		free_extent_buffer(path->nodes[*level]);
748162306a36Sopenharmony_ci		path->nodes[*level] = NULL;
748262306a36Sopenharmony_ci		(*level)++;
748362306a36Sopenharmony_ci		path->slots[*level]++;
748462306a36Sopenharmony_ci
748562306a36Sopenharmony_ci		nritems = btrfs_header_nritems(path->nodes[*level]);
748662306a36Sopenharmony_ci		ret = 1;
748762306a36Sopenharmony_ci	}
748862306a36Sopenharmony_ci	return ret;
748962306a36Sopenharmony_ci}
749062306a36Sopenharmony_ci
749162306a36Sopenharmony_ci/*
749262306a36Sopenharmony_ci * Returns 1 if it had to move up and next. 0 is returned if it moved only next
749362306a36Sopenharmony_ci * or down.
749462306a36Sopenharmony_ci */
749562306a36Sopenharmony_cistatic int tree_advance(struct btrfs_path *path,
749662306a36Sopenharmony_ci			int *level, int root_level,
749762306a36Sopenharmony_ci			int allow_down,
749862306a36Sopenharmony_ci			struct btrfs_key *key,
749962306a36Sopenharmony_ci			u64 reada_min_gen)
750062306a36Sopenharmony_ci{
750162306a36Sopenharmony_ci	int ret;
750262306a36Sopenharmony_ci
750362306a36Sopenharmony_ci	if (*level == 0 || !allow_down) {
750462306a36Sopenharmony_ci		ret = tree_move_next_or_upnext(path, level, root_level);
750562306a36Sopenharmony_ci	} else {
750662306a36Sopenharmony_ci		ret = tree_move_down(path, level, reada_min_gen);
750762306a36Sopenharmony_ci	}
750862306a36Sopenharmony_ci
750962306a36Sopenharmony_ci	/*
751062306a36Sopenharmony_ci	 * Even if we have reached the end of a tree, ret is -1, update the key
751162306a36Sopenharmony_ci	 * anyway, so that in case we need to restart due to a block group
751262306a36Sopenharmony_ci	 * relocation, we can assert that the last key of the root node still
751362306a36Sopenharmony_ci	 * exists in the tree.
751462306a36Sopenharmony_ci	 */
751562306a36Sopenharmony_ci	if (*level == 0)
751662306a36Sopenharmony_ci		btrfs_item_key_to_cpu(path->nodes[*level], key,
751762306a36Sopenharmony_ci				      path->slots[*level]);
751862306a36Sopenharmony_ci	else
751962306a36Sopenharmony_ci		btrfs_node_key_to_cpu(path->nodes[*level], key,
752062306a36Sopenharmony_ci				      path->slots[*level]);
752162306a36Sopenharmony_ci
752262306a36Sopenharmony_ci	return ret;
752362306a36Sopenharmony_ci}
752462306a36Sopenharmony_ci
752562306a36Sopenharmony_cistatic int tree_compare_item(struct btrfs_path *left_path,
752662306a36Sopenharmony_ci			     struct btrfs_path *right_path,
752762306a36Sopenharmony_ci			     char *tmp_buf)
752862306a36Sopenharmony_ci{
752962306a36Sopenharmony_ci	int cmp;
753062306a36Sopenharmony_ci	int len1, len2;
753162306a36Sopenharmony_ci	unsigned long off1, off2;
753262306a36Sopenharmony_ci
753362306a36Sopenharmony_ci	len1 = btrfs_item_size(left_path->nodes[0], left_path->slots[0]);
753462306a36Sopenharmony_ci	len2 = btrfs_item_size(right_path->nodes[0], right_path->slots[0]);
753562306a36Sopenharmony_ci	if (len1 != len2)
753662306a36Sopenharmony_ci		return 1;
753762306a36Sopenharmony_ci
753862306a36Sopenharmony_ci	off1 = btrfs_item_ptr_offset(left_path->nodes[0], left_path->slots[0]);
753962306a36Sopenharmony_ci	off2 = btrfs_item_ptr_offset(right_path->nodes[0],
754062306a36Sopenharmony_ci				right_path->slots[0]);
754162306a36Sopenharmony_ci
754262306a36Sopenharmony_ci	read_extent_buffer(left_path->nodes[0], tmp_buf, off1, len1);
754362306a36Sopenharmony_ci
754462306a36Sopenharmony_ci	cmp = memcmp_extent_buffer(right_path->nodes[0], tmp_buf, off2, len1);
754562306a36Sopenharmony_ci	if (cmp)
754662306a36Sopenharmony_ci		return 1;
754762306a36Sopenharmony_ci	return 0;
754862306a36Sopenharmony_ci}
754962306a36Sopenharmony_ci
755062306a36Sopenharmony_ci/*
755162306a36Sopenharmony_ci * A transaction used for relocating a block group was committed or is about to
755262306a36Sopenharmony_ci * finish its commit. Release our paths and restart the search, so that we are
755362306a36Sopenharmony_ci * not using stale extent buffers:
755462306a36Sopenharmony_ci *
755562306a36Sopenharmony_ci * 1) For levels > 0, we are only holding references of extent buffers, without
755662306a36Sopenharmony_ci *    any locks on them, which does not prevent them from having been relocated
755762306a36Sopenharmony_ci *    and reallocated after the last time we released the commit root semaphore.
755862306a36Sopenharmony_ci *    The exception are the root nodes, for which we always have a clone, see
755962306a36Sopenharmony_ci *    the comment at btrfs_compare_trees();
756062306a36Sopenharmony_ci *
756162306a36Sopenharmony_ci * 2) For leaves, level 0, we are holding copies (clones) of extent buffers, so
756262306a36Sopenharmony_ci *    we are safe from the concurrent relocation and reallocation. However they
756362306a36Sopenharmony_ci *    can have file extent items with a pre relocation disk_bytenr value, so we
756462306a36Sopenharmony_ci *    restart the start from the current commit roots and clone the new leaves so
756562306a36Sopenharmony_ci *    that we get the post relocation disk_bytenr values. Not doing so, could
756662306a36Sopenharmony_ci *    make us clone the wrong data in case there are new extents using the old
756762306a36Sopenharmony_ci *    disk_bytenr that happen to be shared.
756862306a36Sopenharmony_ci */
756962306a36Sopenharmony_cistatic int restart_after_relocation(struct btrfs_path *left_path,
757062306a36Sopenharmony_ci				    struct btrfs_path *right_path,
757162306a36Sopenharmony_ci				    const struct btrfs_key *left_key,
757262306a36Sopenharmony_ci				    const struct btrfs_key *right_key,
757362306a36Sopenharmony_ci				    int left_level,
757462306a36Sopenharmony_ci				    int right_level,
757562306a36Sopenharmony_ci				    const struct send_ctx *sctx)
757662306a36Sopenharmony_ci{
757762306a36Sopenharmony_ci	int root_level;
757862306a36Sopenharmony_ci	int ret;
757962306a36Sopenharmony_ci
758062306a36Sopenharmony_ci	lockdep_assert_held_read(&sctx->send_root->fs_info->commit_root_sem);
758162306a36Sopenharmony_ci
758262306a36Sopenharmony_ci	btrfs_release_path(left_path);
758362306a36Sopenharmony_ci	btrfs_release_path(right_path);
758462306a36Sopenharmony_ci
758562306a36Sopenharmony_ci	/*
758662306a36Sopenharmony_ci	 * Since keys can not be added or removed to/from our roots because they
758762306a36Sopenharmony_ci	 * are readonly and we do not allow deduplication to run in parallel
758862306a36Sopenharmony_ci	 * (which can add, remove or change keys), the layout of the trees should
758962306a36Sopenharmony_ci	 * not change.
759062306a36Sopenharmony_ci	 */
759162306a36Sopenharmony_ci	left_path->lowest_level = left_level;
759262306a36Sopenharmony_ci	ret = search_key_again(sctx, sctx->send_root, left_path, left_key);
759362306a36Sopenharmony_ci	if (ret < 0)
759462306a36Sopenharmony_ci		return ret;
759562306a36Sopenharmony_ci
759662306a36Sopenharmony_ci	right_path->lowest_level = right_level;
759762306a36Sopenharmony_ci	ret = search_key_again(sctx, sctx->parent_root, right_path, right_key);
759862306a36Sopenharmony_ci	if (ret < 0)
759962306a36Sopenharmony_ci		return ret;
760062306a36Sopenharmony_ci
760162306a36Sopenharmony_ci	/*
760262306a36Sopenharmony_ci	 * If the lowest level nodes are leaves, clone them so that they can be
760362306a36Sopenharmony_ci	 * safely used by changed_cb() while not under the protection of the
760462306a36Sopenharmony_ci	 * commit root semaphore, even if relocation and reallocation happens in
760562306a36Sopenharmony_ci	 * parallel.
760662306a36Sopenharmony_ci	 */
760762306a36Sopenharmony_ci	if (left_level == 0) {
760862306a36Sopenharmony_ci		ret = replace_node_with_clone(left_path, 0);
760962306a36Sopenharmony_ci		if (ret < 0)
761062306a36Sopenharmony_ci			return ret;
761162306a36Sopenharmony_ci	}
761262306a36Sopenharmony_ci
761362306a36Sopenharmony_ci	if (right_level == 0) {
761462306a36Sopenharmony_ci		ret = replace_node_with_clone(right_path, 0);
761562306a36Sopenharmony_ci		if (ret < 0)
761662306a36Sopenharmony_ci			return ret;
761762306a36Sopenharmony_ci	}
761862306a36Sopenharmony_ci
761962306a36Sopenharmony_ci	/*
762062306a36Sopenharmony_ci	 * Now clone the root nodes (unless they happen to be the leaves we have
762162306a36Sopenharmony_ci	 * already cloned). This is to protect against concurrent snapshotting of
762262306a36Sopenharmony_ci	 * the send and parent roots (see the comment at btrfs_compare_trees()).
762362306a36Sopenharmony_ci	 */
762462306a36Sopenharmony_ci	root_level = btrfs_header_level(sctx->send_root->commit_root);
762562306a36Sopenharmony_ci	if (root_level > 0) {
762662306a36Sopenharmony_ci		ret = replace_node_with_clone(left_path, root_level);
762762306a36Sopenharmony_ci		if (ret < 0)
762862306a36Sopenharmony_ci			return ret;
762962306a36Sopenharmony_ci	}
763062306a36Sopenharmony_ci
763162306a36Sopenharmony_ci	root_level = btrfs_header_level(sctx->parent_root->commit_root);
763262306a36Sopenharmony_ci	if (root_level > 0) {
763362306a36Sopenharmony_ci		ret = replace_node_with_clone(right_path, root_level);
763462306a36Sopenharmony_ci		if (ret < 0)
763562306a36Sopenharmony_ci			return ret;
763662306a36Sopenharmony_ci	}
763762306a36Sopenharmony_ci
763862306a36Sopenharmony_ci	return 0;
763962306a36Sopenharmony_ci}
764062306a36Sopenharmony_ci
764162306a36Sopenharmony_ci/*
764262306a36Sopenharmony_ci * This function compares two trees and calls the provided callback for
764362306a36Sopenharmony_ci * every changed/new/deleted item it finds.
764462306a36Sopenharmony_ci * If shared tree blocks are encountered, whole subtrees are skipped, making
764562306a36Sopenharmony_ci * the compare pretty fast on snapshotted subvolumes.
764662306a36Sopenharmony_ci *
764762306a36Sopenharmony_ci * This currently works on commit roots only. As commit roots are read only,
764862306a36Sopenharmony_ci * we don't do any locking. The commit roots are protected with transactions.
764962306a36Sopenharmony_ci * Transactions are ended and rejoined when a commit is tried in between.
765062306a36Sopenharmony_ci *
765162306a36Sopenharmony_ci * This function checks for modifications done to the trees while comparing.
765262306a36Sopenharmony_ci * If it detects a change, it aborts immediately.
765362306a36Sopenharmony_ci */
765462306a36Sopenharmony_cistatic int btrfs_compare_trees(struct btrfs_root *left_root,
765562306a36Sopenharmony_ci			struct btrfs_root *right_root, struct send_ctx *sctx)
765662306a36Sopenharmony_ci{
765762306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = left_root->fs_info;
765862306a36Sopenharmony_ci	int ret;
765962306a36Sopenharmony_ci	int cmp;
766062306a36Sopenharmony_ci	struct btrfs_path *left_path = NULL;
766162306a36Sopenharmony_ci	struct btrfs_path *right_path = NULL;
766262306a36Sopenharmony_ci	struct btrfs_key left_key;
766362306a36Sopenharmony_ci	struct btrfs_key right_key;
766462306a36Sopenharmony_ci	char *tmp_buf = NULL;
766562306a36Sopenharmony_ci	int left_root_level;
766662306a36Sopenharmony_ci	int right_root_level;
766762306a36Sopenharmony_ci	int left_level;
766862306a36Sopenharmony_ci	int right_level;
766962306a36Sopenharmony_ci	int left_end_reached = 0;
767062306a36Sopenharmony_ci	int right_end_reached = 0;
767162306a36Sopenharmony_ci	int advance_left = 0;
767262306a36Sopenharmony_ci	int advance_right = 0;
767362306a36Sopenharmony_ci	u64 left_blockptr;
767462306a36Sopenharmony_ci	u64 right_blockptr;
767562306a36Sopenharmony_ci	u64 left_gen;
767662306a36Sopenharmony_ci	u64 right_gen;
767762306a36Sopenharmony_ci	u64 reada_min_gen;
767862306a36Sopenharmony_ci
767962306a36Sopenharmony_ci	left_path = btrfs_alloc_path();
768062306a36Sopenharmony_ci	if (!left_path) {
768162306a36Sopenharmony_ci		ret = -ENOMEM;
768262306a36Sopenharmony_ci		goto out;
768362306a36Sopenharmony_ci	}
768462306a36Sopenharmony_ci	right_path = btrfs_alloc_path();
768562306a36Sopenharmony_ci	if (!right_path) {
768662306a36Sopenharmony_ci		ret = -ENOMEM;
768762306a36Sopenharmony_ci		goto out;
768862306a36Sopenharmony_ci	}
768962306a36Sopenharmony_ci
769062306a36Sopenharmony_ci	tmp_buf = kvmalloc(fs_info->nodesize, GFP_KERNEL);
769162306a36Sopenharmony_ci	if (!tmp_buf) {
769262306a36Sopenharmony_ci		ret = -ENOMEM;
769362306a36Sopenharmony_ci		goto out;
769462306a36Sopenharmony_ci	}
769562306a36Sopenharmony_ci
769662306a36Sopenharmony_ci	left_path->search_commit_root = 1;
769762306a36Sopenharmony_ci	left_path->skip_locking = 1;
769862306a36Sopenharmony_ci	right_path->search_commit_root = 1;
769962306a36Sopenharmony_ci	right_path->skip_locking = 1;
770062306a36Sopenharmony_ci
770162306a36Sopenharmony_ci	/*
770262306a36Sopenharmony_ci	 * Strategy: Go to the first items of both trees. Then do
770362306a36Sopenharmony_ci	 *
770462306a36Sopenharmony_ci	 * If both trees are at level 0
770562306a36Sopenharmony_ci	 *   Compare keys of current items
770662306a36Sopenharmony_ci	 *     If left < right treat left item as new, advance left tree
770762306a36Sopenharmony_ci	 *       and repeat
770862306a36Sopenharmony_ci	 *     If left > right treat right item as deleted, advance right tree
770962306a36Sopenharmony_ci	 *       and repeat
771062306a36Sopenharmony_ci	 *     If left == right do deep compare of items, treat as changed if
771162306a36Sopenharmony_ci	 *       needed, advance both trees and repeat
771262306a36Sopenharmony_ci	 * If both trees are at the same level but not at level 0
771362306a36Sopenharmony_ci	 *   Compare keys of current nodes/leafs
771462306a36Sopenharmony_ci	 *     If left < right advance left tree and repeat
771562306a36Sopenharmony_ci	 *     If left > right advance right tree and repeat
771662306a36Sopenharmony_ci	 *     If left == right compare blockptrs of the next nodes/leafs
771762306a36Sopenharmony_ci	 *       If they match advance both trees but stay at the same level
771862306a36Sopenharmony_ci	 *         and repeat
771962306a36Sopenharmony_ci	 *       If they don't match advance both trees while allowing to go
772062306a36Sopenharmony_ci	 *         deeper and repeat
772162306a36Sopenharmony_ci	 * If tree levels are different
772262306a36Sopenharmony_ci	 *   Advance the tree that needs it and repeat
772362306a36Sopenharmony_ci	 *
772462306a36Sopenharmony_ci	 * Advancing a tree means:
772562306a36Sopenharmony_ci	 *   If we are at level 0, try to go to the next slot. If that's not
772662306a36Sopenharmony_ci	 *   possible, go one level up and repeat. Stop when we found a level
772762306a36Sopenharmony_ci	 *   where we could go to the next slot. We may at this point be on a
772862306a36Sopenharmony_ci	 *   node or a leaf.
772962306a36Sopenharmony_ci	 *
773062306a36Sopenharmony_ci	 *   If we are not at level 0 and not on shared tree blocks, go one
773162306a36Sopenharmony_ci	 *   level deeper.
773262306a36Sopenharmony_ci	 *
773362306a36Sopenharmony_ci	 *   If we are not at level 0 and on shared tree blocks, go one slot to
773462306a36Sopenharmony_ci	 *   the right if possible or go up and right.
773562306a36Sopenharmony_ci	 */
773662306a36Sopenharmony_ci
773762306a36Sopenharmony_ci	down_read(&fs_info->commit_root_sem);
773862306a36Sopenharmony_ci	left_level = btrfs_header_level(left_root->commit_root);
773962306a36Sopenharmony_ci	left_root_level = left_level;
774062306a36Sopenharmony_ci	/*
774162306a36Sopenharmony_ci	 * We clone the root node of the send and parent roots to prevent races
774262306a36Sopenharmony_ci	 * with snapshot creation of these roots. Snapshot creation COWs the
774362306a36Sopenharmony_ci	 * root node of a tree, so after the transaction is committed the old
774462306a36Sopenharmony_ci	 * extent can be reallocated while this send operation is still ongoing.
774562306a36Sopenharmony_ci	 * So we clone them, under the commit root semaphore, to be race free.
774662306a36Sopenharmony_ci	 */
774762306a36Sopenharmony_ci	left_path->nodes[left_level] =
774862306a36Sopenharmony_ci			btrfs_clone_extent_buffer(left_root->commit_root);
774962306a36Sopenharmony_ci	if (!left_path->nodes[left_level]) {
775062306a36Sopenharmony_ci		ret = -ENOMEM;
775162306a36Sopenharmony_ci		goto out_unlock;
775262306a36Sopenharmony_ci	}
775362306a36Sopenharmony_ci
775462306a36Sopenharmony_ci	right_level = btrfs_header_level(right_root->commit_root);
775562306a36Sopenharmony_ci	right_root_level = right_level;
775662306a36Sopenharmony_ci	right_path->nodes[right_level] =
775762306a36Sopenharmony_ci			btrfs_clone_extent_buffer(right_root->commit_root);
775862306a36Sopenharmony_ci	if (!right_path->nodes[right_level]) {
775962306a36Sopenharmony_ci		ret = -ENOMEM;
776062306a36Sopenharmony_ci		goto out_unlock;
776162306a36Sopenharmony_ci	}
776262306a36Sopenharmony_ci	/*
776362306a36Sopenharmony_ci	 * Our right root is the parent root, while the left root is the "send"
776462306a36Sopenharmony_ci	 * root. We know that all new nodes/leaves in the left root must have
776562306a36Sopenharmony_ci	 * a generation greater than the right root's generation, so we trigger
776662306a36Sopenharmony_ci	 * readahead for those nodes and leaves of the left root, as we know we
776762306a36Sopenharmony_ci	 * will need to read them at some point.
776862306a36Sopenharmony_ci	 */
776962306a36Sopenharmony_ci	reada_min_gen = btrfs_header_generation(right_root->commit_root);
777062306a36Sopenharmony_ci
777162306a36Sopenharmony_ci	if (left_level == 0)
777262306a36Sopenharmony_ci		btrfs_item_key_to_cpu(left_path->nodes[left_level],
777362306a36Sopenharmony_ci				&left_key, left_path->slots[left_level]);
777462306a36Sopenharmony_ci	else
777562306a36Sopenharmony_ci		btrfs_node_key_to_cpu(left_path->nodes[left_level],
777662306a36Sopenharmony_ci				&left_key, left_path->slots[left_level]);
777762306a36Sopenharmony_ci	if (right_level == 0)
777862306a36Sopenharmony_ci		btrfs_item_key_to_cpu(right_path->nodes[right_level],
777962306a36Sopenharmony_ci				&right_key, right_path->slots[right_level]);
778062306a36Sopenharmony_ci	else
778162306a36Sopenharmony_ci		btrfs_node_key_to_cpu(right_path->nodes[right_level],
778262306a36Sopenharmony_ci				&right_key, right_path->slots[right_level]);
778362306a36Sopenharmony_ci
778462306a36Sopenharmony_ci	sctx->last_reloc_trans = fs_info->last_reloc_trans;
778562306a36Sopenharmony_ci
778662306a36Sopenharmony_ci	while (1) {
778762306a36Sopenharmony_ci		if (need_resched() ||
778862306a36Sopenharmony_ci		    rwsem_is_contended(&fs_info->commit_root_sem)) {
778962306a36Sopenharmony_ci			up_read(&fs_info->commit_root_sem);
779062306a36Sopenharmony_ci			cond_resched();
779162306a36Sopenharmony_ci			down_read(&fs_info->commit_root_sem);
779262306a36Sopenharmony_ci		}
779362306a36Sopenharmony_ci
779462306a36Sopenharmony_ci		if (fs_info->last_reloc_trans > sctx->last_reloc_trans) {
779562306a36Sopenharmony_ci			ret = restart_after_relocation(left_path, right_path,
779662306a36Sopenharmony_ci						       &left_key, &right_key,
779762306a36Sopenharmony_ci						       left_level, right_level,
779862306a36Sopenharmony_ci						       sctx);
779962306a36Sopenharmony_ci			if (ret < 0)
780062306a36Sopenharmony_ci				goto out_unlock;
780162306a36Sopenharmony_ci			sctx->last_reloc_trans = fs_info->last_reloc_trans;
780262306a36Sopenharmony_ci		}
780362306a36Sopenharmony_ci
780462306a36Sopenharmony_ci		if (advance_left && !left_end_reached) {
780562306a36Sopenharmony_ci			ret = tree_advance(left_path, &left_level,
780662306a36Sopenharmony_ci					left_root_level,
780762306a36Sopenharmony_ci					advance_left != ADVANCE_ONLY_NEXT,
780862306a36Sopenharmony_ci					&left_key, reada_min_gen);
780962306a36Sopenharmony_ci			if (ret == -1)
781062306a36Sopenharmony_ci				left_end_reached = ADVANCE;
781162306a36Sopenharmony_ci			else if (ret < 0)
781262306a36Sopenharmony_ci				goto out_unlock;
781362306a36Sopenharmony_ci			advance_left = 0;
781462306a36Sopenharmony_ci		}
781562306a36Sopenharmony_ci		if (advance_right && !right_end_reached) {
781662306a36Sopenharmony_ci			ret = tree_advance(right_path, &right_level,
781762306a36Sopenharmony_ci					right_root_level,
781862306a36Sopenharmony_ci					advance_right != ADVANCE_ONLY_NEXT,
781962306a36Sopenharmony_ci					&right_key, reada_min_gen);
782062306a36Sopenharmony_ci			if (ret == -1)
782162306a36Sopenharmony_ci				right_end_reached = ADVANCE;
782262306a36Sopenharmony_ci			else if (ret < 0)
782362306a36Sopenharmony_ci				goto out_unlock;
782462306a36Sopenharmony_ci			advance_right = 0;
782562306a36Sopenharmony_ci		}
782662306a36Sopenharmony_ci
782762306a36Sopenharmony_ci		if (left_end_reached && right_end_reached) {
782862306a36Sopenharmony_ci			ret = 0;
782962306a36Sopenharmony_ci			goto out_unlock;
783062306a36Sopenharmony_ci		} else if (left_end_reached) {
783162306a36Sopenharmony_ci			if (right_level == 0) {
783262306a36Sopenharmony_ci				up_read(&fs_info->commit_root_sem);
783362306a36Sopenharmony_ci				ret = changed_cb(left_path, right_path,
783462306a36Sopenharmony_ci						&right_key,
783562306a36Sopenharmony_ci						BTRFS_COMPARE_TREE_DELETED,
783662306a36Sopenharmony_ci						sctx);
783762306a36Sopenharmony_ci				if (ret < 0)
783862306a36Sopenharmony_ci					goto out;
783962306a36Sopenharmony_ci				down_read(&fs_info->commit_root_sem);
784062306a36Sopenharmony_ci			}
784162306a36Sopenharmony_ci			advance_right = ADVANCE;
784262306a36Sopenharmony_ci			continue;
784362306a36Sopenharmony_ci		} else if (right_end_reached) {
784462306a36Sopenharmony_ci			if (left_level == 0) {
784562306a36Sopenharmony_ci				up_read(&fs_info->commit_root_sem);
784662306a36Sopenharmony_ci				ret = changed_cb(left_path, right_path,
784762306a36Sopenharmony_ci						&left_key,
784862306a36Sopenharmony_ci						BTRFS_COMPARE_TREE_NEW,
784962306a36Sopenharmony_ci						sctx);
785062306a36Sopenharmony_ci				if (ret < 0)
785162306a36Sopenharmony_ci					goto out;
785262306a36Sopenharmony_ci				down_read(&fs_info->commit_root_sem);
785362306a36Sopenharmony_ci			}
785462306a36Sopenharmony_ci			advance_left = ADVANCE;
785562306a36Sopenharmony_ci			continue;
785662306a36Sopenharmony_ci		}
785762306a36Sopenharmony_ci
785862306a36Sopenharmony_ci		if (left_level == 0 && right_level == 0) {
785962306a36Sopenharmony_ci			up_read(&fs_info->commit_root_sem);
786062306a36Sopenharmony_ci			cmp = btrfs_comp_cpu_keys(&left_key, &right_key);
786162306a36Sopenharmony_ci			if (cmp < 0) {
786262306a36Sopenharmony_ci				ret = changed_cb(left_path, right_path,
786362306a36Sopenharmony_ci						&left_key,
786462306a36Sopenharmony_ci						BTRFS_COMPARE_TREE_NEW,
786562306a36Sopenharmony_ci						sctx);
786662306a36Sopenharmony_ci				advance_left = ADVANCE;
786762306a36Sopenharmony_ci			} else if (cmp > 0) {
786862306a36Sopenharmony_ci				ret = changed_cb(left_path, right_path,
786962306a36Sopenharmony_ci						&right_key,
787062306a36Sopenharmony_ci						BTRFS_COMPARE_TREE_DELETED,
787162306a36Sopenharmony_ci						sctx);
787262306a36Sopenharmony_ci				advance_right = ADVANCE;
787362306a36Sopenharmony_ci			} else {
787462306a36Sopenharmony_ci				enum btrfs_compare_tree_result result;
787562306a36Sopenharmony_ci
787662306a36Sopenharmony_ci				WARN_ON(!extent_buffer_uptodate(left_path->nodes[0]));
787762306a36Sopenharmony_ci				ret = tree_compare_item(left_path, right_path,
787862306a36Sopenharmony_ci							tmp_buf);
787962306a36Sopenharmony_ci				if (ret)
788062306a36Sopenharmony_ci					result = BTRFS_COMPARE_TREE_CHANGED;
788162306a36Sopenharmony_ci				else
788262306a36Sopenharmony_ci					result = BTRFS_COMPARE_TREE_SAME;
788362306a36Sopenharmony_ci				ret = changed_cb(left_path, right_path,
788462306a36Sopenharmony_ci						 &left_key, result, sctx);
788562306a36Sopenharmony_ci				advance_left = ADVANCE;
788662306a36Sopenharmony_ci				advance_right = ADVANCE;
788762306a36Sopenharmony_ci			}
788862306a36Sopenharmony_ci
788962306a36Sopenharmony_ci			if (ret < 0)
789062306a36Sopenharmony_ci				goto out;
789162306a36Sopenharmony_ci			down_read(&fs_info->commit_root_sem);
789262306a36Sopenharmony_ci		} else if (left_level == right_level) {
789362306a36Sopenharmony_ci			cmp = btrfs_comp_cpu_keys(&left_key, &right_key);
789462306a36Sopenharmony_ci			if (cmp < 0) {
789562306a36Sopenharmony_ci				advance_left = ADVANCE;
789662306a36Sopenharmony_ci			} else if (cmp > 0) {
789762306a36Sopenharmony_ci				advance_right = ADVANCE;
789862306a36Sopenharmony_ci			} else {
789962306a36Sopenharmony_ci				left_blockptr = btrfs_node_blockptr(
790062306a36Sopenharmony_ci						left_path->nodes[left_level],
790162306a36Sopenharmony_ci						left_path->slots[left_level]);
790262306a36Sopenharmony_ci				right_blockptr = btrfs_node_blockptr(
790362306a36Sopenharmony_ci						right_path->nodes[right_level],
790462306a36Sopenharmony_ci						right_path->slots[right_level]);
790562306a36Sopenharmony_ci				left_gen = btrfs_node_ptr_generation(
790662306a36Sopenharmony_ci						left_path->nodes[left_level],
790762306a36Sopenharmony_ci						left_path->slots[left_level]);
790862306a36Sopenharmony_ci				right_gen = btrfs_node_ptr_generation(
790962306a36Sopenharmony_ci						right_path->nodes[right_level],
791062306a36Sopenharmony_ci						right_path->slots[right_level]);
791162306a36Sopenharmony_ci				if (left_blockptr == right_blockptr &&
791262306a36Sopenharmony_ci				    left_gen == right_gen) {
791362306a36Sopenharmony_ci					/*
791462306a36Sopenharmony_ci					 * As we're on a shared block, don't
791562306a36Sopenharmony_ci					 * allow to go deeper.
791662306a36Sopenharmony_ci					 */
791762306a36Sopenharmony_ci					advance_left = ADVANCE_ONLY_NEXT;
791862306a36Sopenharmony_ci					advance_right = ADVANCE_ONLY_NEXT;
791962306a36Sopenharmony_ci				} else {
792062306a36Sopenharmony_ci					advance_left = ADVANCE;
792162306a36Sopenharmony_ci					advance_right = ADVANCE;
792262306a36Sopenharmony_ci				}
792362306a36Sopenharmony_ci			}
792462306a36Sopenharmony_ci		} else if (left_level < right_level) {
792562306a36Sopenharmony_ci			advance_right = ADVANCE;
792662306a36Sopenharmony_ci		} else {
792762306a36Sopenharmony_ci			advance_left = ADVANCE;
792862306a36Sopenharmony_ci		}
792962306a36Sopenharmony_ci	}
793062306a36Sopenharmony_ci
793162306a36Sopenharmony_ciout_unlock:
793262306a36Sopenharmony_ci	up_read(&fs_info->commit_root_sem);
793362306a36Sopenharmony_ciout:
793462306a36Sopenharmony_ci	btrfs_free_path(left_path);
793562306a36Sopenharmony_ci	btrfs_free_path(right_path);
793662306a36Sopenharmony_ci	kvfree(tmp_buf);
793762306a36Sopenharmony_ci	return ret;
793862306a36Sopenharmony_ci}
793962306a36Sopenharmony_ci
794062306a36Sopenharmony_cistatic int send_subvol(struct send_ctx *sctx)
794162306a36Sopenharmony_ci{
794262306a36Sopenharmony_ci	int ret;
794362306a36Sopenharmony_ci
794462306a36Sopenharmony_ci	if (!(sctx->flags & BTRFS_SEND_FLAG_OMIT_STREAM_HEADER)) {
794562306a36Sopenharmony_ci		ret = send_header(sctx);
794662306a36Sopenharmony_ci		if (ret < 0)
794762306a36Sopenharmony_ci			goto out;
794862306a36Sopenharmony_ci	}
794962306a36Sopenharmony_ci
795062306a36Sopenharmony_ci	ret = send_subvol_begin(sctx);
795162306a36Sopenharmony_ci	if (ret < 0)
795262306a36Sopenharmony_ci		goto out;
795362306a36Sopenharmony_ci
795462306a36Sopenharmony_ci	if (sctx->parent_root) {
795562306a36Sopenharmony_ci		ret = btrfs_compare_trees(sctx->send_root, sctx->parent_root, sctx);
795662306a36Sopenharmony_ci		if (ret < 0)
795762306a36Sopenharmony_ci			goto out;
795862306a36Sopenharmony_ci		ret = finish_inode_if_needed(sctx, 1);
795962306a36Sopenharmony_ci		if (ret < 0)
796062306a36Sopenharmony_ci			goto out;
796162306a36Sopenharmony_ci	} else {
796262306a36Sopenharmony_ci		ret = full_send_tree(sctx);
796362306a36Sopenharmony_ci		if (ret < 0)
796462306a36Sopenharmony_ci			goto out;
796562306a36Sopenharmony_ci	}
796662306a36Sopenharmony_ci
796762306a36Sopenharmony_ciout:
796862306a36Sopenharmony_ci	free_recorded_refs(sctx);
796962306a36Sopenharmony_ci	return ret;
797062306a36Sopenharmony_ci}
797162306a36Sopenharmony_ci
797262306a36Sopenharmony_ci/*
797362306a36Sopenharmony_ci * If orphan cleanup did remove any orphans from a root, it means the tree
797462306a36Sopenharmony_ci * was modified and therefore the commit root is not the same as the current
797562306a36Sopenharmony_ci * root anymore. This is a problem, because send uses the commit root and
797662306a36Sopenharmony_ci * therefore can see inode items that don't exist in the current root anymore,
797762306a36Sopenharmony_ci * and for example make calls to btrfs_iget, which will do tree lookups based
797862306a36Sopenharmony_ci * on the current root and not on the commit root. Those lookups will fail,
797962306a36Sopenharmony_ci * returning a -ESTALE error, and making send fail with that error. So make
798062306a36Sopenharmony_ci * sure a send does not see any orphans we have just removed, and that it will
798162306a36Sopenharmony_ci * see the same inodes regardless of whether a transaction commit happened
798262306a36Sopenharmony_ci * before it started (meaning that the commit root will be the same as the
798362306a36Sopenharmony_ci * current root) or not.
798462306a36Sopenharmony_ci */
798562306a36Sopenharmony_cistatic int ensure_commit_roots_uptodate(struct send_ctx *sctx)
798662306a36Sopenharmony_ci{
798762306a36Sopenharmony_ci	int i;
798862306a36Sopenharmony_ci	struct btrfs_trans_handle *trans = NULL;
798962306a36Sopenharmony_ci
799062306a36Sopenharmony_ciagain:
799162306a36Sopenharmony_ci	if (sctx->parent_root &&
799262306a36Sopenharmony_ci	    sctx->parent_root->node != sctx->parent_root->commit_root)
799362306a36Sopenharmony_ci		goto commit_trans;
799462306a36Sopenharmony_ci
799562306a36Sopenharmony_ci	for (i = 0; i < sctx->clone_roots_cnt; i++)
799662306a36Sopenharmony_ci		if (sctx->clone_roots[i].root->node !=
799762306a36Sopenharmony_ci		    sctx->clone_roots[i].root->commit_root)
799862306a36Sopenharmony_ci			goto commit_trans;
799962306a36Sopenharmony_ci
800062306a36Sopenharmony_ci	if (trans)
800162306a36Sopenharmony_ci		return btrfs_end_transaction(trans);
800262306a36Sopenharmony_ci
800362306a36Sopenharmony_ci	return 0;
800462306a36Sopenharmony_ci
800562306a36Sopenharmony_cicommit_trans:
800662306a36Sopenharmony_ci	/* Use any root, all fs roots will get their commit roots updated. */
800762306a36Sopenharmony_ci	if (!trans) {
800862306a36Sopenharmony_ci		trans = btrfs_join_transaction(sctx->send_root);
800962306a36Sopenharmony_ci		if (IS_ERR(trans))
801062306a36Sopenharmony_ci			return PTR_ERR(trans);
801162306a36Sopenharmony_ci		goto again;
801262306a36Sopenharmony_ci	}
801362306a36Sopenharmony_ci
801462306a36Sopenharmony_ci	return btrfs_commit_transaction(trans);
801562306a36Sopenharmony_ci}
801662306a36Sopenharmony_ci
801762306a36Sopenharmony_ci/*
801862306a36Sopenharmony_ci * Make sure any existing dellaloc is flushed for any root used by a send
801962306a36Sopenharmony_ci * operation so that we do not miss any data and we do not race with writeback
802062306a36Sopenharmony_ci * finishing and changing a tree while send is using the tree. This could
802162306a36Sopenharmony_ci * happen if a subvolume is in RW mode, has delalloc, is turned to RO mode and
802262306a36Sopenharmony_ci * a send operation then uses the subvolume.
802362306a36Sopenharmony_ci * After flushing delalloc ensure_commit_roots_uptodate() must be called.
802462306a36Sopenharmony_ci */
802562306a36Sopenharmony_cistatic int flush_delalloc_roots(struct send_ctx *sctx)
802662306a36Sopenharmony_ci{
802762306a36Sopenharmony_ci	struct btrfs_root *root = sctx->parent_root;
802862306a36Sopenharmony_ci	int ret;
802962306a36Sopenharmony_ci	int i;
803062306a36Sopenharmony_ci
803162306a36Sopenharmony_ci	if (root) {
803262306a36Sopenharmony_ci		ret = btrfs_start_delalloc_snapshot(root, false);
803362306a36Sopenharmony_ci		if (ret)
803462306a36Sopenharmony_ci			return ret;
803562306a36Sopenharmony_ci		btrfs_wait_ordered_extents(root, U64_MAX, 0, U64_MAX);
803662306a36Sopenharmony_ci	}
803762306a36Sopenharmony_ci
803862306a36Sopenharmony_ci	for (i = 0; i < sctx->clone_roots_cnt; i++) {
803962306a36Sopenharmony_ci		root = sctx->clone_roots[i].root;
804062306a36Sopenharmony_ci		ret = btrfs_start_delalloc_snapshot(root, false);
804162306a36Sopenharmony_ci		if (ret)
804262306a36Sopenharmony_ci			return ret;
804362306a36Sopenharmony_ci		btrfs_wait_ordered_extents(root, U64_MAX, 0, U64_MAX);
804462306a36Sopenharmony_ci	}
804562306a36Sopenharmony_ci
804662306a36Sopenharmony_ci	return 0;
804762306a36Sopenharmony_ci}
804862306a36Sopenharmony_ci
804962306a36Sopenharmony_cistatic void btrfs_root_dec_send_in_progress(struct btrfs_root* root)
805062306a36Sopenharmony_ci{
805162306a36Sopenharmony_ci	spin_lock(&root->root_item_lock);
805262306a36Sopenharmony_ci	root->send_in_progress--;
805362306a36Sopenharmony_ci	/*
805462306a36Sopenharmony_ci	 * Not much left to do, we don't know why it's unbalanced and
805562306a36Sopenharmony_ci	 * can't blindly reset it to 0.
805662306a36Sopenharmony_ci	 */
805762306a36Sopenharmony_ci	if (root->send_in_progress < 0)
805862306a36Sopenharmony_ci		btrfs_err(root->fs_info,
805962306a36Sopenharmony_ci			  "send_in_progress unbalanced %d root %llu",
806062306a36Sopenharmony_ci			  root->send_in_progress, root->root_key.objectid);
806162306a36Sopenharmony_ci	spin_unlock(&root->root_item_lock);
806262306a36Sopenharmony_ci}
806362306a36Sopenharmony_ci
806462306a36Sopenharmony_cistatic void dedupe_in_progress_warn(const struct btrfs_root *root)
806562306a36Sopenharmony_ci{
806662306a36Sopenharmony_ci	btrfs_warn_rl(root->fs_info,
806762306a36Sopenharmony_ci"cannot use root %llu for send while deduplications on it are in progress (%d in progress)",
806862306a36Sopenharmony_ci		      root->root_key.objectid, root->dedupe_in_progress);
806962306a36Sopenharmony_ci}
807062306a36Sopenharmony_ci
807162306a36Sopenharmony_cilong btrfs_ioctl_send(struct inode *inode, struct btrfs_ioctl_send_args *arg)
807262306a36Sopenharmony_ci{
807362306a36Sopenharmony_ci	int ret = 0;
807462306a36Sopenharmony_ci	struct btrfs_root *send_root = BTRFS_I(inode)->root;
807562306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = send_root->fs_info;
807662306a36Sopenharmony_ci	struct btrfs_root *clone_root;
807762306a36Sopenharmony_ci	struct send_ctx *sctx = NULL;
807862306a36Sopenharmony_ci	u32 i;
807962306a36Sopenharmony_ci	u64 *clone_sources_tmp = NULL;
808062306a36Sopenharmony_ci	int clone_sources_to_rollback = 0;
808162306a36Sopenharmony_ci	size_t alloc_size;
808262306a36Sopenharmony_ci	int sort_clone_roots = 0;
808362306a36Sopenharmony_ci	struct btrfs_lru_cache_entry *entry;
808462306a36Sopenharmony_ci	struct btrfs_lru_cache_entry *tmp;
808562306a36Sopenharmony_ci
808662306a36Sopenharmony_ci	if (!capable(CAP_SYS_ADMIN))
808762306a36Sopenharmony_ci		return -EPERM;
808862306a36Sopenharmony_ci
808962306a36Sopenharmony_ci	/*
809062306a36Sopenharmony_ci	 * The subvolume must remain read-only during send, protect against
809162306a36Sopenharmony_ci	 * making it RW. This also protects against deletion.
809262306a36Sopenharmony_ci	 */
809362306a36Sopenharmony_ci	spin_lock(&send_root->root_item_lock);
809462306a36Sopenharmony_ci	if (btrfs_root_readonly(send_root) && send_root->dedupe_in_progress) {
809562306a36Sopenharmony_ci		dedupe_in_progress_warn(send_root);
809662306a36Sopenharmony_ci		spin_unlock(&send_root->root_item_lock);
809762306a36Sopenharmony_ci		return -EAGAIN;
809862306a36Sopenharmony_ci	}
809962306a36Sopenharmony_ci	send_root->send_in_progress++;
810062306a36Sopenharmony_ci	spin_unlock(&send_root->root_item_lock);
810162306a36Sopenharmony_ci
810262306a36Sopenharmony_ci	/*
810362306a36Sopenharmony_ci	 * Userspace tools do the checks and warn the user if it's
810462306a36Sopenharmony_ci	 * not RO.
810562306a36Sopenharmony_ci	 */
810662306a36Sopenharmony_ci	if (!btrfs_root_readonly(send_root)) {
810762306a36Sopenharmony_ci		ret = -EPERM;
810862306a36Sopenharmony_ci		goto out;
810962306a36Sopenharmony_ci	}
811062306a36Sopenharmony_ci
811162306a36Sopenharmony_ci	/*
811262306a36Sopenharmony_ci	 * Check that we don't overflow at later allocations, we request
811362306a36Sopenharmony_ci	 * clone_sources_count + 1 items, and compare to unsigned long inside
811462306a36Sopenharmony_ci	 * access_ok. Also set an upper limit for allocation size so this can't
811562306a36Sopenharmony_ci	 * easily exhaust memory. Max number of clone sources is about 200K.
811662306a36Sopenharmony_ci	 */
811762306a36Sopenharmony_ci	if (arg->clone_sources_count > SZ_8M / sizeof(struct clone_root)) {
811862306a36Sopenharmony_ci		ret = -EINVAL;
811962306a36Sopenharmony_ci		goto out;
812062306a36Sopenharmony_ci	}
812162306a36Sopenharmony_ci
812262306a36Sopenharmony_ci	if (arg->flags & ~BTRFS_SEND_FLAG_MASK) {
812362306a36Sopenharmony_ci		ret = -EOPNOTSUPP;
812462306a36Sopenharmony_ci		goto out;
812562306a36Sopenharmony_ci	}
812662306a36Sopenharmony_ci
812762306a36Sopenharmony_ci	sctx = kzalloc(sizeof(struct send_ctx), GFP_KERNEL);
812862306a36Sopenharmony_ci	if (!sctx) {
812962306a36Sopenharmony_ci		ret = -ENOMEM;
813062306a36Sopenharmony_ci		goto out;
813162306a36Sopenharmony_ci	}
813262306a36Sopenharmony_ci
813362306a36Sopenharmony_ci	INIT_LIST_HEAD(&sctx->new_refs);
813462306a36Sopenharmony_ci	INIT_LIST_HEAD(&sctx->deleted_refs);
813562306a36Sopenharmony_ci
813662306a36Sopenharmony_ci	btrfs_lru_cache_init(&sctx->name_cache, SEND_MAX_NAME_CACHE_SIZE);
813762306a36Sopenharmony_ci	btrfs_lru_cache_init(&sctx->backref_cache, SEND_MAX_BACKREF_CACHE_SIZE);
813862306a36Sopenharmony_ci	btrfs_lru_cache_init(&sctx->dir_created_cache,
813962306a36Sopenharmony_ci			     SEND_MAX_DIR_CREATED_CACHE_SIZE);
814062306a36Sopenharmony_ci	/*
814162306a36Sopenharmony_ci	 * This cache is periodically trimmed to a fixed size elsewhere, see
814262306a36Sopenharmony_ci	 * cache_dir_utimes() and trim_dir_utimes_cache().
814362306a36Sopenharmony_ci	 */
814462306a36Sopenharmony_ci	btrfs_lru_cache_init(&sctx->dir_utimes_cache, 0);
814562306a36Sopenharmony_ci
814662306a36Sopenharmony_ci	sctx->pending_dir_moves = RB_ROOT;
814762306a36Sopenharmony_ci	sctx->waiting_dir_moves = RB_ROOT;
814862306a36Sopenharmony_ci	sctx->orphan_dirs = RB_ROOT;
814962306a36Sopenharmony_ci	sctx->rbtree_new_refs = RB_ROOT;
815062306a36Sopenharmony_ci	sctx->rbtree_deleted_refs = RB_ROOT;
815162306a36Sopenharmony_ci
815262306a36Sopenharmony_ci	sctx->flags = arg->flags;
815362306a36Sopenharmony_ci
815462306a36Sopenharmony_ci	if (arg->flags & BTRFS_SEND_FLAG_VERSION) {
815562306a36Sopenharmony_ci		if (arg->version > BTRFS_SEND_STREAM_VERSION) {
815662306a36Sopenharmony_ci			ret = -EPROTO;
815762306a36Sopenharmony_ci			goto out;
815862306a36Sopenharmony_ci		}
815962306a36Sopenharmony_ci		/* Zero means "use the highest version" */
816062306a36Sopenharmony_ci		sctx->proto = arg->version ?: BTRFS_SEND_STREAM_VERSION;
816162306a36Sopenharmony_ci	} else {
816262306a36Sopenharmony_ci		sctx->proto = 1;
816362306a36Sopenharmony_ci	}
816462306a36Sopenharmony_ci	if ((arg->flags & BTRFS_SEND_FLAG_COMPRESSED) && sctx->proto < 2) {
816562306a36Sopenharmony_ci		ret = -EINVAL;
816662306a36Sopenharmony_ci		goto out;
816762306a36Sopenharmony_ci	}
816862306a36Sopenharmony_ci
816962306a36Sopenharmony_ci	sctx->send_filp = fget(arg->send_fd);
817062306a36Sopenharmony_ci	if (!sctx->send_filp || !(sctx->send_filp->f_mode & FMODE_WRITE)) {
817162306a36Sopenharmony_ci		ret = -EBADF;
817262306a36Sopenharmony_ci		goto out;
817362306a36Sopenharmony_ci	}
817462306a36Sopenharmony_ci
817562306a36Sopenharmony_ci	sctx->send_root = send_root;
817662306a36Sopenharmony_ci	/*
817762306a36Sopenharmony_ci	 * Unlikely but possible, if the subvolume is marked for deletion but
817862306a36Sopenharmony_ci	 * is slow to remove the directory entry, send can still be started
817962306a36Sopenharmony_ci	 */
818062306a36Sopenharmony_ci	if (btrfs_root_dead(sctx->send_root)) {
818162306a36Sopenharmony_ci		ret = -EPERM;
818262306a36Sopenharmony_ci		goto out;
818362306a36Sopenharmony_ci	}
818462306a36Sopenharmony_ci
818562306a36Sopenharmony_ci	sctx->clone_roots_cnt = arg->clone_sources_count;
818662306a36Sopenharmony_ci
818762306a36Sopenharmony_ci	if (sctx->proto >= 2) {
818862306a36Sopenharmony_ci		u32 send_buf_num_pages;
818962306a36Sopenharmony_ci
819062306a36Sopenharmony_ci		sctx->send_max_size = BTRFS_SEND_BUF_SIZE_V2;
819162306a36Sopenharmony_ci		sctx->send_buf = vmalloc(sctx->send_max_size);
819262306a36Sopenharmony_ci		if (!sctx->send_buf) {
819362306a36Sopenharmony_ci			ret = -ENOMEM;
819462306a36Sopenharmony_ci			goto out;
819562306a36Sopenharmony_ci		}
819662306a36Sopenharmony_ci		send_buf_num_pages = sctx->send_max_size >> PAGE_SHIFT;
819762306a36Sopenharmony_ci		sctx->send_buf_pages = kcalloc(send_buf_num_pages,
819862306a36Sopenharmony_ci					       sizeof(*sctx->send_buf_pages),
819962306a36Sopenharmony_ci					       GFP_KERNEL);
820062306a36Sopenharmony_ci		if (!sctx->send_buf_pages) {
820162306a36Sopenharmony_ci			ret = -ENOMEM;
820262306a36Sopenharmony_ci			goto out;
820362306a36Sopenharmony_ci		}
820462306a36Sopenharmony_ci		for (i = 0; i < send_buf_num_pages; i++) {
820562306a36Sopenharmony_ci			sctx->send_buf_pages[i] =
820662306a36Sopenharmony_ci				vmalloc_to_page(sctx->send_buf + (i << PAGE_SHIFT));
820762306a36Sopenharmony_ci		}
820862306a36Sopenharmony_ci	} else {
820962306a36Sopenharmony_ci		sctx->send_max_size = BTRFS_SEND_BUF_SIZE_V1;
821062306a36Sopenharmony_ci		sctx->send_buf = kvmalloc(sctx->send_max_size, GFP_KERNEL);
821162306a36Sopenharmony_ci	}
821262306a36Sopenharmony_ci	if (!sctx->send_buf) {
821362306a36Sopenharmony_ci		ret = -ENOMEM;
821462306a36Sopenharmony_ci		goto out;
821562306a36Sopenharmony_ci	}
821662306a36Sopenharmony_ci
821762306a36Sopenharmony_ci	sctx->clone_roots = kvcalloc(sizeof(*sctx->clone_roots),
821862306a36Sopenharmony_ci				     arg->clone_sources_count + 1,
821962306a36Sopenharmony_ci				     GFP_KERNEL);
822062306a36Sopenharmony_ci	if (!sctx->clone_roots) {
822162306a36Sopenharmony_ci		ret = -ENOMEM;
822262306a36Sopenharmony_ci		goto out;
822362306a36Sopenharmony_ci	}
822462306a36Sopenharmony_ci
822562306a36Sopenharmony_ci	alloc_size = array_size(sizeof(*arg->clone_sources),
822662306a36Sopenharmony_ci				arg->clone_sources_count);
822762306a36Sopenharmony_ci
822862306a36Sopenharmony_ci	if (arg->clone_sources_count) {
822962306a36Sopenharmony_ci		clone_sources_tmp = kvmalloc(alloc_size, GFP_KERNEL);
823062306a36Sopenharmony_ci		if (!clone_sources_tmp) {
823162306a36Sopenharmony_ci			ret = -ENOMEM;
823262306a36Sopenharmony_ci			goto out;
823362306a36Sopenharmony_ci		}
823462306a36Sopenharmony_ci
823562306a36Sopenharmony_ci		ret = copy_from_user(clone_sources_tmp, arg->clone_sources,
823662306a36Sopenharmony_ci				alloc_size);
823762306a36Sopenharmony_ci		if (ret) {
823862306a36Sopenharmony_ci			ret = -EFAULT;
823962306a36Sopenharmony_ci			goto out;
824062306a36Sopenharmony_ci		}
824162306a36Sopenharmony_ci
824262306a36Sopenharmony_ci		for (i = 0; i < arg->clone_sources_count; i++) {
824362306a36Sopenharmony_ci			clone_root = btrfs_get_fs_root(fs_info,
824462306a36Sopenharmony_ci						clone_sources_tmp[i], true);
824562306a36Sopenharmony_ci			if (IS_ERR(clone_root)) {
824662306a36Sopenharmony_ci				ret = PTR_ERR(clone_root);
824762306a36Sopenharmony_ci				goto out;
824862306a36Sopenharmony_ci			}
824962306a36Sopenharmony_ci			spin_lock(&clone_root->root_item_lock);
825062306a36Sopenharmony_ci			if (!btrfs_root_readonly(clone_root) ||
825162306a36Sopenharmony_ci			    btrfs_root_dead(clone_root)) {
825262306a36Sopenharmony_ci				spin_unlock(&clone_root->root_item_lock);
825362306a36Sopenharmony_ci				btrfs_put_root(clone_root);
825462306a36Sopenharmony_ci				ret = -EPERM;
825562306a36Sopenharmony_ci				goto out;
825662306a36Sopenharmony_ci			}
825762306a36Sopenharmony_ci			if (clone_root->dedupe_in_progress) {
825862306a36Sopenharmony_ci				dedupe_in_progress_warn(clone_root);
825962306a36Sopenharmony_ci				spin_unlock(&clone_root->root_item_lock);
826062306a36Sopenharmony_ci				btrfs_put_root(clone_root);
826162306a36Sopenharmony_ci				ret = -EAGAIN;
826262306a36Sopenharmony_ci				goto out;
826362306a36Sopenharmony_ci			}
826462306a36Sopenharmony_ci			clone_root->send_in_progress++;
826562306a36Sopenharmony_ci			spin_unlock(&clone_root->root_item_lock);
826662306a36Sopenharmony_ci
826762306a36Sopenharmony_ci			sctx->clone_roots[i].root = clone_root;
826862306a36Sopenharmony_ci			clone_sources_to_rollback = i + 1;
826962306a36Sopenharmony_ci		}
827062306a36Sopenharmony_ci		kvfree(clone_sources_tmp);
827162306a36Sopenharmony_ci		clone_sources_tmp = NULL;
827262306a36Sopenharmony_ci	}
827362306a36Sopenharmony_ci
827462306a36Sopenharmony_ci	if (arg->parent_root) {
827562306a36Sopenharmony_ci		sctx->parent_root = btrfs_get_fs_root(fs_info, arg->parent_root,
827662306a36Sopenharmony_ci						      true);
827762306a36Sopenharmony_ci		if (IS_ERR(sctx->parent_root)) {
827862306a36Sopenharmony_ci			ret = PTR_ERR(sctx->parent_root);
827962306a36Sopenharmony_ci			goto out;
828062306a36Sopenharmony_ci		}
828162306a36Sopenharmony_ci
828262306a36Sopenharmony_ci		spin_lock(&sctx->parent_root->root_item_lock);
828362306a36Sopenharmony_ci		sctx->parent_root->send_in_progress++;
828462306a36Sopenharmony_ci		if (!btrfs_root_readonly(sctx->parent_root) ||
828562306a36Sopenharmony_ci				btrfs_root_dead(sctx->parent_root)) {
828662306a36Sopenharmony_ci			spin_unlock(&sctx->parent_root->root_item_lock);
828762306a36Sopenharmony_ci			ret = -EPERM;
828862306a36Sopenharmony_ci			goto out;
828962306a36Sopenharmony_ci		}
829062306a36Sopenharmony_ci		if (sctx->parent_root->dedupe_in_progress) {
829162306a36Sopenharmony_ci			dedupe_in_progress_warn(sctx->parent_root);
829262306a36Sopenharmony_ci			spin_unlock(&sctx->parent_root->root_item_lock);
829362306a36Sopenharmony_ci			ret = -EAGAIN;
829462306a36Sopenharmony_ci			goto out;
829562306a36Sopenharmony_ci		}
829662306a36Sopenharmony_ci		spin_unlock(&sctx->parent_root->root_item_lock);
829762306a36Sopenharmony_ci	}
829862306a36Sopenharmony_ci
829962306a36Sopenharmony_ci	/*
830062306a36Sopenharmony_ci	 * Clones from send_root are allowed, but only if the clone source
830162306a36Sopenharmony_ci	 * is behind the current send position. This is checked while searching
830262306a36Sopenharmony_ci	 * for possible clone sources.
830362306a36Sopenharmony_ci	 */
830462306a36Sopenharmony_ci	sctx->clone_roots[sctx->clone_roots_cnt++].root =
830562306a36Sopenharmony_ci		btrfs_grab_root(sctx->send_root);
830662306a36Sopenharmony_ci
830762306a36Sopenharmony_ci	/* We do a bsearch later */
830862306a36Sopenharmony_ci	sort(sctx->clone_roots, sctx->clone_roots_cnt,
830962306a36Sopenharmony_ci			sizeof(*sctx->clone_roots), __clone_root_cmp_sort,
831062306a36Sopenharmony_ci			NULL);
831162306a36Sopenharmony_ci	sort_clone_roots = 1;
831262306a36Sopenharmony_ci
831362306a36Sopenharmony_ci	ret = flush_delalloc_roots(sctx);
831462306a36Sopenharmony_ci	if (ret)
831562306a36Sopenharmony_ci		goto out;
831662306a36Sopenharmony_ci
831762306a36Sopenharmony_ci	ret = ensure_commit_roots_uptodate(sctx);
831862306a36Sopenharmony_ci	if (ret)
831962306a36Sopenharmony_ci		goto out;
832062306a36Sopenharmony_ci
832162306a36Sopenharmony_ci	ret = send_subvol(sctx);
832262306a36Sopenharmony_ci	if (ret < 0)
832362306a36Sopenharmony_ci		goto out;
832462306a36Sopenharmony_ci
832562306a36Sopenharmony_ci	btrfs_lru_cache_for_each_entry_safe(&sctx->dir_utimes_cache, entry, tmp) {
832662306a36Sopenharmony_ci		ret = send_utimes(sctx, entry->key, entry->gen);
832762306a36Sopenharmony_ci		if (ret < 0)
832862306a36Sopenharmony_ci			goto out;
832962306a36Sopenharmony_ci		btrfs_lru_cache_remove(&sctx->dir_utimes_cache, entry);
833062306a36Sopenharmony_ci	}
833162306a36Sopenharmony_ci
833262306a36Sopenharmony_ci	if (!(sctx->flags & BTRFS_SEND_FLAG_OMIT_END_CMD)) {
833362306a36Sopenharmony_ci		ret = begin_cmd(sctx, BTRFS_SEND_C_END);
833462306a36Sopenharmony_ci		if (ret < 0)
833562306a36Sopenharmony_ci			goto out;
833662306a36Sopenharmony_ci		ret = send_cmd(sctx);
833762306a36Sopenharmony_ci		if (ret < 0)
833862306a36Sopenharmony_ci			goto out;
833962306a36Sopenharmony_ci	}
834062306a36Sopenharmony_ci
834162306a36Sopenharmony_ciout:
834262306a36Sopenharmony_ci	WARN_ON(sctx && !ret && !RB_EMPTY_ROOT(&sctx->pending_dir_moves));
834362306a36Sopenharmony_ci	while (sctx && !RB_EMPTY_ROOT(&sctx->pending_dir_moves)) {
834462306a36Sopenharmony_ci		struct rb_node *n;
834562306a36Sopenharmony_ci		struct pending_dir_move *pm;
834662306a36Sopenharmony_ci
834762306a36Sopenharmony_ci		n = rb_first(&sctx->pending_dir_moves);
834862306a36Sopenharmony_ci		pm = rb_entry(n, struct pending_dir_move, node);
834962306a36Sopenharmony_ci		while (!list_empty(&pm->list)) {
835062306a36Sopenharmony_ci			struct pending_dir_move *pm2;
835162306a36Sopenharmony_ci
835262306a36Sopenharmony_ci			pm2 = list_first_entry(&pm->list,
835362306a36Sopenharmony_ci					       struct pending_dir_move, list);
835462306a36Sopenharmony_ci			free_pending_move(sctx, pm2);
835562306a36Sopenharmony_ci		}
835662306a36Sopenharmony_ci		free_pending_move(sctx, pm);
835762306a36Sopenharmony_ci	}
835862306a36Sopenharmony_ci
835962306a36Sopenharmony_ci	WARN_ON(sctx && !ret && !RB_EMPTY_ROOT(&sctx->waiting_dir_moves));
836062306a36Sopenharmony_ci	while (sctx && !RB_EMPTY_ROOT(&sctx->waiting_dir_moves)) {
836162306a36Sopenharmony_ci		struct rb_node *n;
836262306a36Sopenharmony_ci		struct waiting_dir_move *dm;
836362306a36Sopenharmony_ci
836462306a36Sopenharmony_ci		n = rb_first(&sctx->waiting_dir_moves);
836562306a36Sopenharmony_ci		dm = rb_entry(n, struct waiting_dir_move, node);
836662306a36Sopenharmony_ci		rb_erase(&dm->node, &sctx->waiting_dir_moves);
836762306a36Sopenharmony_ci		kfree(dm);
836862306a36Sopenharmony_ci	}
836962306a36Sopenharmony_ci
837062306a36Sopenharmony_ci	WARN_ON(sctx && !ret && !RB_EMPTY_ROOT(&sctx->orphan_dirs));
837162306a36Sopenharmony_ci	while (sctx && !RB_EMPTY_ROOT(&sctx->orphan_dirs)) {
837262306a36Sopenharmony_ci		struct rb_node *n;
837362306a36Sopenharmony_ci		struct orphan_dir_info *odi;
837462306a36Sopenharmony_ci
837562306a36Sopenharmony_ci		n = rb_first(&sctx->orphan_dirs);
837662306a36Sopenharmony_ci		odi = rb_entry(n, struct orphan_dir_info, node);
837762306a36Sopenharmony_ci		free_orphan_dir_info(sctx, odi);
837862306a36Sopenharmony_ci	}
837962306a36Sopenharmony_ci
838062306a36Sopenharmony_ci	if (sort_clone_roots) {
838162306a36Sopenharmony_ci		for (i = 0; i < sctx->clone_roots_cnt; i++) {
838262306a36Sopenharmony_ci			btrfs_root_dec_send_in_progress(
838362306a36Sopenharmony_ci					sctx->clone_roots[i].root);
838462306a36Sopenharmony_ci			btrfs_put_root(sctx->clone_roots[i].root);
838562306a36Sopenharmony_ci		}
838662306a36Sopenharmony_ci	} else {
838762306a36Sopenharmony_ci		for (i = 0; sctx && i < clone_sources_to_rollback; i++) {
838862306a36Sopenharmony_ci			btrfs_root_dec_send_in_progress(
838962306a36Sopenharmony_ci					sctx->clone_roots[i].root);
839062306a36Sopenharmony_ci			btrfs_put_root(sctx->clone_roots[i].root);
839162306a36Sopenharmony_ci		}
839262306a36Sopenharmony_ci
839362306a36Sopenharmony_ci		btrfs_root_dec_send_in_progress(send_root);
839462306a36Sopenharmony_ci	}
839562306a36Sopenharmony_ci	if (sctx && !IS_ERR_OR_NULL(sctx->parent_root)) {
839662306a36Sopenharmony_ci		btrfs_root_dec_send_in_progress(sctx->parent_root);
839762306a36Sopenharmony_ci		btrfs_put_root(sctx->parent_root);
839862306a36Sopenharmony_ci	}
839962306a36Sopenharmony_ci
840062306a36Sopenharmony_ci	kvfree(clone_sources_tmp);
840162306a36Sopenharmony_ci
840262306a36Sopenharmony_ci	if (sctx) {
840362306a36Sopenharmony_ci		if (sctx->send_filp)
840462306a36Sopenharmony_ci			fput(sctx->send_filp);
840562306a36Sopenharmony_ci
840662306a36Sopenharmony_ci		kvfree(sctx->clone_roots);
840762306a36Sopenharmony_ci		kfree(sctx->send_buf_pages);
840862306a36Sopenharmony_ci		kvfree(sctx->send_buf);
840962306a36Sopenharmony_ci		kvfree(sctx->verity_descriptor);
841062306a36Sopenharmony_ci
841162306a36Sopenharmony_ci		close_current_inode(sctx);
841262306a36Sopenharmony_ci
841362306a36Sopenharmony_ci		btrfs_lru_cache_clear(&sctx->name_cache);
841462306a36Sopenharmony_ci		btrfs_lru_cache_clear(&sctx->backref_cache);
841562306a36Sopenharmony_ci		btrfs_lru_cache_clear(&sctx->dir_created_cache);
841662306a36Sopenharmony_ci		btrfs_lru_cache_clear(&sctx->dir_utimes_cache);
841762306a36Sopenharmony_ci
841862306a36Sopenharmony_ci		kfree(sctx);
841962306a36Sopenharmony_ci	}
842062306a36Sopenharmony_ci
842162306a36Sopenharmony_ci	return ret;
842262306a36Sopenharmony_ci}
8423