public inbox for linux-btrfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send
@ 2025-02-19 11:43 fdmanana
  2025-02-19 11:43 ` [PATCH 01/26] btrfs: send: remove duplicated logic from fs_path_reset() fdmanana
                   ` (26 more replies)
  0 siblings, 27 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

This eleminates repeated path allocations and computations for send when
processing the current inode. The bulk of this is done in patches 24/26
and 25/26, while the remainder are cleanups and simplifications, some of
them to simplify the actual work related to avoiding the repeated path
allocations and computations.

A test, and its result, is described in the change log of patch 25/26.

Filipe Manana (26):
  btrfs: send: remove duplicated logic from fs_path_reset()
  btrfs: send: make fs_path_len() inline and constify its argument
  btrfs: send: always use fs_path_len() to determine a path's length
  btrfs: send: simplify return logic from fs_path_prepare_for_add()
  btrfs: send: simplify return logic from fs_path_add()
  btrfs: send: implement fs_path_add_path() using fs_path_add()
  btrfs: send: simplify return logic from fs_path_add_from_extent_buffer()
  btrfs: send: return -ENAMETOOLONG when attempting a path that is too long
  btrfs: send: simplify return logic from __get_cur_name_and_parent()
  btrfs: send: simplify return logic from is_inode_existent()
  btrfs: send: simplify return logic from get_cur_inode_state()
  btrfs: send: factor out common logic when sending xattrs
  btrfs: send: only use booleans variables at process_recorded_refs()
  btrfs: send: add and use helper to rename current inode when processing refs
  btrfs: send: simplify return logic from send_remove_xattr()
  btrfs: send: simplify return logic from record_new_ref_if_needed()
  btrfs: send: simplify return logic from record_deleted_ref_if_needed()
  btrfs: send: simplify return logic from record_new_ref()
  btrfs: send: simplify return logic from record_deleted_ref()
  btrfs: send: simplify return logic from record_changed_ref()
  btrfs: send: remove unnecessary return variable from process_new_xattr()
  btrfs: send: simplify return logic from process_changed_xattr()
  btrfs: send: simplify return logic from send_verity()
  btrfs: send: keep the current inode's path cached
  btrfs: send: avoid path allocation for the current inode when issuing commands
  btrfs: send: simplify return logic from send_set_xattr()

 fs/btrfs/send.c | 485 +++++++++++++++++++++++-------------------------
 1 file changed, 232 insertions(+), 253 deletions(-)

-- 
2.45.2


^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH 01/26] btrfs: send: remove duplicated logic from fs_path_reset()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 02/26] btrfs: send: make fs_path_len() inline and constify its argument fdmanana
                   ` (25 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There's duplicated logic in both branches of the if statement, so move it
outside the branches.

This also reduces the object code size.

Before this change:

  $ size fs/btrfs/btrfs.ko
     text	   data	    bss	    dec	    hex	filename
  1746279	 163600	  16920	1926799	 1d668f	fs/btrfs/btrfs.ko

After this change:

  $ size fs/btrfs/btrfs.ko
     text	   data	    bss	    dec	    hex	filename
  1746047	 163592	  16920	1926559	 1d659f	fs/btrfs/btrfs.ko

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index d513f7fd5fe8..8de561fb1390 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -424,15 +424,13 @@ static int need_send_hole(struct send_ctx *sctx)
 
 static void fs_path_reset(struct fs_path *p)
 {
-	if (p->reversed) {
+	if (p->reversed)
 		p->start = p->buf + p->buf_len - 1;
-		p->end = p->start;
-		*p->start = 0;
-	} else {
+	else
 		p->start = p->buf;
-		p->end = p->start;
-		*p->start = 0;
-	}
+
+	p->end = p->start;
+	*p->start = 0;
 }
 
 static struct fs_path *fs_path_alloc(void)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 02/26] btrfs: send: make fs_path_len() inline and constify its argument
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
  2025-02-19 11:43 ` [PATCH 01/26] btrfs: send: remove duplicated logic from fs_path_reset() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 03/26] btrfs: send: always use fs_path_len() to determine a path's length fdmanana
                   ` (24 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

The helper function fs_path_len() is trivial and doesn't need to change
its path argument, so make it inline and constify the argument.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 8de561fb1390..4e998bf8d379 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -468,7 +468,7 @@ static void fs_path_free(struct fs_path *p)
 	kfree(p);
 }
 
-static int fs_path_len(struct fs_path *p)
+static inline int fs_path_len(const struct fs_path *p)
 {
 	return p->end - p->start;
 }
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 03/26] btrfs: send: always use fs_path_len() to determine a path's length
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
  2025-02-19 11:43 ` [PATCH 01/26] btrfs: send: remove duplicated logic from fs_path_reset() fdmanana
  2025-02-19 11:43 ` [PATCH 02/26] btrfs: send: make fs_path_len() inline and constify its argument fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 04/26] btrfs: send: simplify return logic from fs_path_prepare_for_add() fdmanana
                   ` (23 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

Several places are hardcoding the path length calculation instead of using
the helper fs_path_len() for that. Update all those places to instead use
fs_path_len().

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 4e998bf8d379..9f9885dc1e10 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -489,7 +489,7 @@ static int fs_path_ensure_buf(struct fs_path *p, int len)
 		return -ENOMEM;
 	}
 
-	path_len = p->end - p->start;
+	path_len = fs_path_len(p);
 	old_buf_len = p->buf_len;
 
 	/*
@@ -530,7 +530,7 @@ static int fs_path_prepare_for_add(struct fs_path *p, int name_len,
 	int ret;
 	int new_len;
 
-	new_len = p->end - p->start + name_len;
+	new_len = fs_path_len(p) + name_len;
 	if (p->start != p->end)
 		new_len++;
 	ret = fs_path_ensure_buf(p, new_len);
@@ -571,12 +571,13 @@ static int fs_path_add(struct fs_path *p, const char *name, int name_len)
 static int fs_path_add_path(struct fs_path *p, struct fs_path *p2)
 {
 	int ret;
+	const int p2_len = fs_path_len(p2);
 	char *prepared;
 
-	ret = fs_path_prepare_for_add(p, p2->end - p2->start, &prepared);
+	ret = fs_path_prepare_for_add(p, p2_len, &prepared);
 	if (ret < 0)
 		goto out;
-	memcpy(prepared, p2->start, p2->end - p2->start);
+	memcpy(prepared, p2->start, p2_len);
 
 out:
 	return ret;
@@ -616,7 +617,7 @@ static void fs_path_unreverse(struct fs_path *p)
 		return;
 
 	tmp = p->start;
-	len = p->end - p->start;
+	len = fs_path_len(p);
 	p->start = p->buf;
 	p->end = p->start + len;
 	memmove(p->start, tmp, len + 1);
@@ -737,7 +738,7 @@ static int tlv_put_btrfs_timespec(struct send_ctx *sctx, u16 attr,
 #define TLV_PUT_PATH(sctx, attrtype, p) \
 	do { \
 		ret = tlv_put_string(sctx, attrtype, p->start, \
-			p->end - p->start); \
+				     fs_path_len((p)));	       \
 		if (ret < 0) \
 			goto tlv_put_failure; \
 	} while(0)
@@ -2364,7 +2365,7 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
 	 * earlier. If yes, treat as orphan and return 1.
 	 */
 	ret = did_overwrite_ref(sctx, *parent_ino, *parent_gen, ino, gen,
-			dest->start, dest->end - dest->start);
+				dest->start, fs_path_len(dest));
 	if (ret < 0)
 		goto out;
 	if (ret) {
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 04/26] btrfs: send: simplify return logic from fs_path_prepare_for_add()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (2 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 03/26] btrfs: send: always use fs_path_len() to determine a path's length fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 05/26] btrfs: send: simplify return logic from fs_path_add() fdmanana
                   ` (22 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 9f9885dc1e10..535384028cb8 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -535,7 +535,7 @@ static int fs_path_prepare_for_add(struct fs_path *p, int name_len,
 		new_len++;
 	ret = fs_path_ensure_buf(p, new_len);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	if (p->reversed) {
 		if (p->start != p->end)
@@ -550,8 +550,7 @@ static int fs_path_prepare_for_add(struct fs_path *p, int name_len,
 		*p->end = 0;
 	}
 
-out:
-	return ret;
+	return 0;
 }
 
 static int fs_path_add(struct fs_path *p, const char *name, int name_len)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 05/26] btrfs: send: simplify return logic from fs_path_add()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (3 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 04/26] btrfs: send: simplify return logic from fs_path_prepare_for_add() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 06/26] btrfs: send: implement fs_path_add_path() using fs_path_add() fdmanana
                   ` (21 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 535384028cb8..2203745569e0 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -560,11 +560,10 @@ static int fs_path_add(struct fs_path *p, const char *name, int name_len)
 
 	ret = fs_path_prepare_for_add(p, name_len, &prepared);
 	if (ret < 0)
-		goto out;
+		return ret;
 	memcpy(prepared, name, name_len);
 
-out:
-	return ret;
+	return 0;
 }
 
 static int fs_path_add_path(struct fs_path *p, struct fs_path *p2)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 06/26] btrfs: send: implement fs_path_add_path() using fs_path_add()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (4 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 05/26] btrfs: send: simplify return logic from fs_path_add() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 07/26] btrfs: send: simplify return logic from fs_path_add_from_extent_buffer() fdmanana
                   ` (20 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

The helper fs_path_add_path() is basically a copy of fs_path_add() and it
can be made a wrapper around fs_path_add(). So do that and also make it
inline and constify its second argument.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 2203745569e0..7a75f1d963f9 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -566,19 +566,9 @@ static int fs_path_add(struct fs_path *p, const char *name, int name_len)
 	return 0;
 }
 
-static int fs_path_add_path(struct fs_path *p, struct fs_path *p2)
+static inline int fs_path_add_path(struct fs_path *p, const struct fs_path *p2)
 {
-	int ret;
-	const int p2_len = fs_path_len(p2);
-	char *prepared;
-
-	ret = fs_path_prepare_for_add(p, p2_len, &prepared);
-	if (ret < 0)
-		goto out;
-	memcpy(prepared, p2->start, p2_len);
-
-out:
-	return ret;
+	return fs_path_add(p, p2->start, fs_path_len(p2));
 }
 
 static int fs_path_add_from_extent_buffer(struct fs_path *p,
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 07/26] btrfs: send: simplify return logic from fs_path_add_from_extent_buffer()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (5 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 06/26] btrfs: send: implement fs_path_add_path() using fs_path_add() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 08/26] btrfs: send: return -ENAMETOOLONG when attempting a path that is too long fdmanana
                   ` (19 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 7a75f1d963f9..b9de1ab94367 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -580,12 +580,11 @@ static int fs_path_add_from_extent_buffer(struct fs_path *p,
 
 	ret = fs_path_prepare_for_add(p, len, &prepared);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	read_extent_buffer(eb, prepared, off, len);
 
-out:
-	return ret;
+	return 0;
 }
 
 static int fs_path_copy(struct fs_path *p, struct fs_path *from)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 08/26] btrfs: send: return -ENAMETOOLONG when attempting a path that is too long
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (6 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 07/26] btrfs: send: simplify return logic from fs_path_add_from_extent_buffer() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 09/26] btrfs: send: simplify return logic from __get_cur_name_and_parent() fdmanana
                   ` (18 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

When attempting to build a too long path we are currently returning
-ENOMEM, which is very odd and misleading. So update fs_path_ensure_buf()
to return -ENAMETOOLONG instead. Also, while at it, move the WARN_ON()
into the if statement's expression, as it makes it clear what is being
tested and also has the effect of adding 'unlikely' to the statement,
which allows the compiler to generate better code as this condition is
never expected to happen.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index b9de1ab94367..dcc1cf7d1dbd 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -484,10 +484,8 @@ static int fs_path_ensure_buf(struct fs_path *p, int len)
 	if (p->buf_len >= len)
 		return 0;
 
-	if (len > PATH_MAX) {
-		WARN_ON(1);
-		return -ENOMEM;
-	}
+	if (WARN_ON(len > PATH_MAX))
+		return -ENAMETOOLONG;
 
 	path_len = fs_path_len(p);
 	old_buf_len = p->buf_len;
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 09/26] btrfs: send: simplify return logic from __get_cur_name_and_parent()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (7 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 08/26] btrfs: send: return -ENAMETOOLONG when attempting a path that is too long fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 10/26] btrfs: send: simplify return logic from is_inode_existent() fdmanana
                   ` (17 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index dcc1cf7d1dbd..393c9ca5de90 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -2309,9 +2309,8 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
 			*parent_gen = nce->parent_gen;
 			ret = fs_path_add(dest, nce->name, nce->name_len);
 			if (ret < 0)
-				goto out;
-			ret = nce->ret;
-			goto out;
+				return ret;
+			return nce->ret;
 		}
 	}
 
@@ -2322,12 +2321,12 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
 	 */
 	ret = is_inode_existent(sctx, ino, gen, NULL, NULL);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	if (!ret) {
 		ret = gen_unique_name(sctx, ino, gen, dest);
 		if (ret < 0)
-			goto out;
+			return ret;
 		ret = 1;
 		goto out_cache;
 	}
@@ -2343,7 +2342,7 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
 		ret = get_first_ref(sctx->parent_root, ino,
 				    parent_ino, parent_gen, dest);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	/*
 	 * Check if the ref was overwritten by an inode's ref that was processed
@@ -2352,12 +2351,12 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
 	ret = did_overwrite_ref(sctx, *parent_ino, *parent_gen, ino, gen,
 				dest->start, fs_path_len(dest));
 	if (ret < 0)
-		goto out;
+		return ret;
 	if (ret) {
 		fs_path_reset(dest);
 		ret = gen_unique_name(sctx, ino, gen, dest);
 		if (ret < 0)
-			goto out;
+			return ret;
 		ret = 1;
 	}
 
@@ -2366,10 +2365,8 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
 	 * Store the result of the lookup in the name cache.
 	 */
 	nce = kmalloc(sizeof(*nce) + fs_path_len(dest), GFP_KERNEL);
-	if (!nce) {
-		ret = -ENOMEM;
-		goto out;
-	}
+	if (!nce)
+		return -ENOMEM;
 
 	nce->entry.key = ino;
 	nce->entry.gen = gen;
@@ -2387,10 +2384,9 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
 	nce_ret = btrfs_lru_cache_store(&sctx->name_cache, &nce->entry, GFP_KERNEL);
 	if (nce_ret < 0) {
 		kfree(nce);
-		ret = nce_ret;
+		return nce_ret;
 	}
 
-out:
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 10/26] btrfs: send: simplify return logic from is_inode_existent()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (8 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 09/26] btrfs: send: simplify return logic from __get_cur_name_and_parent() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 11/26] btrfs: send: simplify return logic from get_cur_inode_state() fdmanana
                   ` (16 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 393c9ca5de90..0a908e1066a6 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -1950,17 +1950,14 @@ static int is_inode_existent(struct send_ctx *sctx, u64 ino, u64 gen,
 
 	ret = get_cur_inode_state(sctx, ino, gen, send_gen, parent_gen);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	if (ret == inode_state_no_change ||
 	    ret == inode_state_did_create ||
 	    ret == inode_state_will_delete)
-		ret = 1;
-	else
-		ret = 0;
+		return 1;
 
-out:
-	return ret;
+	return 0;
 }
 
 /*
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 11/26] btrfs: send: simplify return logic from get_cur_inode_state()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (9 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 10/26] btrfs: send: simplify return logic from is_inode_existent() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 12/26] btrfs: send: factor out common logic when sending xattrs fdmanana
                   ` (15 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 0a908e1066a6..e0e24ac94aac 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -1880,7 +1880,7 @@ static int get_cur_inode_state(struct send_ctx *sctx, u64 ino, u64 gen,
 
 	ret = get_inode_info(sctx->send_root, ino, &info);
 	if (ret < 0 && ret != -ENOENT)
-		goto out;
+		return ret;
 	left_ret = (info.nlink == 0) ? -ENOENT : ret;
 	left_gen = info.gen;
 	if (send_gen)
@@ -1891,7 +1891,7 @@ static int get_cur_inode_state(struct send_ctx *sctx, u64 ino, u64 gen,
 	} else {
 		ret = get_inode_info(sctx->parent_root, ino, &info);
 		if (ret < 0 && ret != -ENOENT)
-			goto out;
+			return ret;
 		right_ret = (info.nlink == 0) ? -ENOENT : ret;
 		right_gen = info.gen;
 		if (parent_gen)
@@ -1936,7 +1936,6 @@ static int get_cur_inode_state(struct send_ctx *sctx, u64 ino, u64 gen,
 		ret = -ENOENT;
 	}
 
-out:
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 12/26] btrfs: send: factor out common logic when sending xattrs
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (10 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 11/26] btrfs: send: simplify return logic from get_cur_inode_state() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 13/26] btrfs: send: only use booleans variables at process_recorded_refs() fdmanana
                   ` (14 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

We always send xattrs for the current inode only and both callers of
send_set_xattr() pass a path for the current inode. So move the path
allocation and computation to send_set_xattr(), reducing duplicated
code. This also facilitates an upcoming patch.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 41 +++++++++++++++--------------------------
 1 file changed, 15 insertions(+), 26 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index e0e24ac94aac..3aa2877f8c80 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4844,11 +4844,19 @@ static int process_all_refs(struct send_ctx *sctx,
 }
 
 static int send_set_xattr(struct send_ctx *sctx,
-			  struct fs_path *path,
 			  const char *name, int name_len,
 			  const char *data, int data_len)
 {
-	int ret = 0;
+	struct fs_path *path;
+	int ret;
+
+	path = fs_path_alloc();
+	if (!path)
+		return -ENOMEM;
+
+	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, path);
+	if (ret < 0)
+		goto out;
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_SET_XATTR);
 	if (ret < 0)
@@ -4862,6 +4870,8 @@ static int send_set_xattr(struct send_ctx *sctx,
 
 tlv_put_failure:
 out:
+	fs_path_free(path);
+
 	return ret;
 }
 
@@ -4889,19 +4899,13 @@ static int __process_new_xattr(int num, struct btrfs_key *di_key,
 			       const char *name, int name_len, const char *data,
 			       int data_len, void *ctx)
 {
-	int ret;
 	struct send_ctx *sctx = ctx;
-	struct fs_path *p;
 	struct posix_acl_xattr_header dummy_acl;
 
 	/* Capabilities are emitted by finish_inode_if_needed */
 	if (!strncmp(name, XATTR_NAME_CAPS, name_len))
 		return 0;
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
-
 	/*
 	 * This hack is needed because empty acls are stored as zero byte
 	 * data in xattrs. Problem with that is, that receiving these zero byte
@@ -4918,15 +4922,7 @@ static int __process_new_xattr(int num, struct btrfs_key *di_key,
 		}
 	}
 
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-	if (ret < 0)
-		goto out;
-
-	ret = send_set_xattr(sctx, p, name, name_len, data, data_len);
-
-out:
-	fs_path_free(p);
-	return ret;
+	return send_set_xattr(sctx, name, name_len, data, data_len);
 }
 
 static int __process_deleted_xattr(int num, struct btrfs_key *di_key,
@@ -5803,7 +5799,6 @@ static int send_extent_data(struct send_ctx *sctx, struct btrfs_path *path,
  */
 static int send_capabilities(struct send_ctx *sctx)
 {
-	struct fs_path *fspath = NULL;
 	struct btrfs_path *path;
 	struct btrfs_dir_item *di;
 	struct extent_buffer *leaf;
@@ -5829,25 +5824,19 @@ static int send_capabilities(struct send_ctx *sctx)
 	leaf = path->nodes[0];
 	buf_len = btrfs_dir_data_len(leaf, di);
 
-	fspath = fs_path_alloc();
 	buf = kmalloc(buf_len, GFP_KERNEL);
-	if (!fspath || !buf) {
+	if (!buf) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath);
-	if (ret < 0)
-		goto out;
-
 	data_ptr = (unsigned long)(di + 1) + btrfs_dir_name_len(leaf, di);
 	read_extent_buffer(leaf, buf, data_ptr, buf_len);
 
-	ret = send_set_xattr(sctx, fspath, XATTR_NAME_CAPS,
+	ret = send_set_xattr(sctx, XATTR_NAME_CAPS,
 			strlen(XATTR_NAME_CAPS), buf, buf_len);
 out:
 	kfree(buf);
-	fs_path_free(fspath);
 	btrfs_free_path(path);
 	return ret;
 }
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 13/26] btrfs: send: only use booleans variables at process_recorded_refs()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (11 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 12/26] btrfs: send: factor out common logic when sending xattrs fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 14/26] btrfs: send: add and use helper to rename current inode when processing refs fdmanana
                   ` (13 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

We have several local variables at process_recorded_refs() that are used
as booleans, with some of them having a 'bool' type while two of them
having an 'int' type. Change this to make them all use the 'bool' type
which is more clear and to make everything more consistent.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 3aa2877f8c80..6e27a7d77b25 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4147,9 +4147,9 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
 	u64 ow_inode = 0;
 	u64 ow_gen;
 	u64 ow_mode;
-	int did_overwrite = 0;
-	int is_orphan = 0;
 	u64 last_dir_ino_rm = 0;
+	bool did_overwrite = false;
+	bool is_orphan = false;
 	bool can_rename = true;
 	bool orphanized_dir = false;
 	bool orphanized_ancestor = false;
@@ -4191,14 +4191,14 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
 		if (ret < 0)
 			goto out;
 		if (ret)
-			did_overwrite = 1;
+			did_overwrite = true;
 	}
 	if (sctx->cur_inode_new || did_overwrite) {
 		ret = gen_unique_name(sctx, sctx->cur_ino,
 				sctx->cur_inode_gen, valid_path);
 		if (ret < 0)
 			goto out;
-		is_orphan = 1;
+		is_orphan = true;
 	} else {
 		ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen,
 				valid_path);
@@ -4421,7 +4421,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
 			ret = send_rename(sctx, valid_path, cur->full_path);
 			if (ret < 0)
 				goto out;
-			is_orphan = 0;
+			is_orphan = false;
 			ret = fs_path_copy(valid_path, cur->full_path);
 			if (ret < 0)
 				goto out;
@@ -4482,7 +4482,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
 					sctx->cur_inode_gen, valid_path);
 			if (ret < 0)
 				goto out;
-			is_orphan = 1;
+			is_orphan = true;
 		}
 
 		list_for_each_entry(cur, &sctx->deleted_refs, list) {
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 14/26] btrfs: send: add and use helper to rename current inode when processing refs
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (12 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 13/26] btrfs: send: only use booleans variables at process_recorded_refs() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 15/26] btrfs: send: simplify return logic from send_remove_xattr() fdmanana
                   ` (12 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

Extract the logic to rename the current inode at process_recorded_refs()
into a helper function and use it, therefore removing duplicated logic
and making it easier for an upcoming patch by avoiding yet more duplicated
logic.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 6e27a7d77b25..653e0b9a94ca 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4133,6 +4133,19 @@ static int refresh_ref_path(struct send_ctx *sctx, struct recorded_ref *ref)
 	return ret;
 }
 
+static int rename_current_inode(struct send_ctx *sctx,
+				struct fs_path *current_path,
+				struct fs_path *new_path)
+{
+	int ret;
+
+	ret = send_rename(sctx, current_path, new_path);
+	if (ret < 0)
+		return ret;
+
+	return fs_path_copy(current_path, new_path);
+}
+
 /*
  * This does all the move/link/unlink/rmdir magic.
  */
@@ -4418,13 +4431,10 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
 		 * it depending on the inode mode.
 		 */
 		if (is_orphan && can_rename) {
-			ret = send_rename(sctx, valid_path, cur->full_path);
+			ret = rename_current_inode(sctx, valid_path, cur->full_path);
 			if (ret < 0)
 				goto out;
 			is_orphan = false;
-			ret = fs_path_copy(valid_path, cur->full_path);
-			if (ret < 0)
-				goto out;
 		} else if (can_rename) {
 			if (S_ISDIR(sctx->cur_inode_mode)) {
 				/*
@@ -4432,10 +4442,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
 				 * dirs, we always have one new and one deleted
 				 * ref. The deleted ref is ignored later.
 				 */
-				ret = send_rename(sctx, valid_path,
-						  cur->full_path);
-				if (!ret)
-					ret = fs_path_copy(valid_path,
+				ret = rename_current_inode(sctx, valid_path,
 							   cur->full_path);
 				if (ret < 0)
 					goto out;
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 15/26] btrfs: send: simplify return logic from send_remove_xattr()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (13 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 14/26] btrfs: send: add and use helper to rename current inode when processing refs fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 16/26] btrfs: send: simplify return logic from record_new_ref_if_needed() fdmanana
                   ` (11 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There's no need for the 'out' label as there are no resources to cleanup
in case of an error and we can directly return if begin_cmd() fails.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 653e0b9a94ca..5fd3deaf14d6 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4886,11 +4886,11 @@ static int send_remove_xattr(struct send_ctx *sctx,
 			  struct fs_path *path,
 			  const char *name, int name_len)
 {
-	int ret = 0;
+	int ret;
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_REMOVE_XATTR);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path);
 	TLV_PUT_STRING(sctx, BTRFS_SEND_A_XATTR_NAME, name, name_len);
@@ -4898,7 +4898,6 @@ static int send_remove_xattr(struct send_ctx *sctx,
 	ret = send_cmd(sctx);
 
 tlv_put_failure:
-out:
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 16/26] btrfs: send: simplify return logic from record_new_ref_if_needed()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (14 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 15/26] btrfs: send: simplify return logic from send_remove_xattr() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 17/26] btrfs: send: simplify return logic from record_deleted_ref_if_needed() fdmanana
                   ` (10 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
 make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 5fd3deaf14d6..96aa519e791a 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4683,7 +4683,7 @@ static int record_ref_in_tree(struct rb_root *root, struct list_head *refs,
 
 static int record_new_ref_if_needed(u64 dir, struct fs_path *name, void *ctx)
 {
-	int ret = 0;
+	int ret;
 	struct send_ctx *sctx = ctx;
 	struct rb_node *node = NULL;
 	struct recorded_ref data;
@@ -4692,7 +4692,7 @@ static int record_new_ref_if_needed(u64 dir, struct fs_path *name, void *ctx)
 
 	ret = get_inode_gen(sctx->send_root, dir, &dir_gen);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	data.dir = dir;
 	data.dir_gen = dir_gen;
@@ -4706,7 +4706,7 @@ static int record_new_ref_if_needed(u64 dir, struct fs_path *name, void *ctx)
 					 &sctx->new_refs, name, dir, dir_gen,
 					 sctx);
 	}
-out:
+
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 17/26] btrfs: send: simplify return logic from record_deleted_ref_if_needed()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (15 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 16/26] btrfs: send: simplify return logic from record_new_ref_if_needed() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 18/26] btrfs: send: simplify return logic from record_new_ref() fdmanana
                   ` (9 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 96aa519e791a..b715557ec720 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4712,7 +4712,7 @@ static int record_new_ref_if_needed(u64 dir, struct fs_path *name, void *ctx)
 
 static int record_deleted_ref_if_needed(u64 dir, struct fs_path *name, void *ctx)
 {
-	int ret = 0;
+	int ret;
 	struct send_ctx *sctx = ctx;
 	struct rb_node *node = NULL;
 	struct recorded_ref data;
@@ -4721,7 +4721,7 @@ static int record_deleted_ref_if_needed(u64 dir, struct fs_path *name, void *ctx
 
 	ret = get_inode_gen(sctx->parent_root, dir, &dir_gen);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	data.dir = dir;
 	data.dir_gen = dir_gen;
@@ -4735,7 +4735,7 @@ static int record_deleted_ref_if_needed(u64 dir, struct fs_path *name, void *ctx
 					 &sctx->deleted_refs, name, dir,
 					 dir_gen, sctx);
 	}
-out:
+
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 18/26] btrfs: send: simplify return logic from record_new_ref()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (16 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 17/26] btrfs: send: simplify return logic from record_deleted_ref_if_needed() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 19/26] btrfs: send: simplify return logic from record_deleted_ref() fdmanana
                   ` (8 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index b715557ec720..181a234e3a5e 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4746,11 +4746,9 @@ static int record_new_ref(struct send_ctx *sctx)
 	ret = iterate_inode_ref(sctx->send_root, sctx->left_path,
 				sctx->cmp_key, 0, record_new_ref_if_needed, sctx);
 	if (ret < 0)
-		goto out;
-	ret = 0;
+		return ret;
 
-out:
-	return ret;
+	return 0;
 }
 
 static int record_deleted_ref(struct send_ctx *sctx)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 19/26] btrfs: send: simplify return logic from record_deleted_ref()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (17 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 18/26] btrfs: send: simplify return logic from record_new_ref() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 20/26] btrfs: send: simplify return logic from record_changed_ref() fdmanana
                   ` (7 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 181a234e3a5e..6e171b504415 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4759,11 +4759,9 @@ static int record_deleted_ref(struct send_ctx *sctx)
 				sctx->cmp_key, 0, record_deleted_ref_if_needed,
 				sctx);
 	if (ret < 0)
-		goto out;
-	ret = 0;
+		return ret;
 
-out:
-	return ret;
+	return 0;
 }
 
 static int record_changed_ref(struct send_ctx *sctx)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 20/26] btrfs: send: simplify return logic from record_changed_ref()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (18 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 19/26] btrfs: send: simplify return logic from record_deleted_ref() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 21/26] btrfs: send: remove unnecessary return variable from process_new_xattr() fdmanana
                   ` (6 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 6e171b504415..01b8b570d6ed 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4766,20 +4766,18 @@ static int record_deleted_ref(struct send_ctx *sctx)
 
 static int record_changed_ref(struct send_ctx *sctx)
 {
-	int ret = 0;
+	int ret;
 
 	ret = iterate_inode_ref(sctx->send_root, sctx->left_path,
 			sctx->cmp_key, 0, record_new_ref_if_needed, sctx);
 	if (ret < 0)
-		goto out;
+		return ret;
 	ret = iterate_inode_ref(sctx->parent_root, sctx->right_path,
 			sctx->cmp_key, 0, record_deleted_ref_if_needed, sctx);
 	if (ret < 0)
-		goto out;
-	ret = 0;
+		return ret;
 
-out:
-	return ret;
+	return 0;
 }
 
 /*
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 21/26] btrfs: send: remove unnecessary return variable from process_new_xattr()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (19 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 20/26] btrfs: send: simplify return logic from record_changed_ref() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 22/26] btrfs: send: simplify return logic from process_changed_xattr() fdmanana
                   ` (5 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There's no need for the 'ret' variable, we can just return directly the
result of the call to iterate_dir_item().

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 01b8b570d6ed..e29b5a5ccdd6 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4950,12 +4950,8 @@ static int __process_deleted_xattr(int num, struct btrfs_key *di_key,
 
 static int process_new_xattr(struct send_ctx *sctx)
 {
-	int ret = 0;
-
-	ret = iterate_dir_item(sctx->send_root, sctx->left_path,
-			       __process_new_xattr, sctx);
-
-	return ret;
+	return iterate_dir_item(sctx->send_root, sctx->left_path,
+				__process_new_xattr, sctx);
 }
 
 static int process_deleted_xattr(struct send_ctx *sctx)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 22/26] btrfs: send: simplify return logic from process_changed_xattr()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (20 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 21/26] btrfs: send: remove unnecessary return variable from process_new_xattr() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 23/26] btrfs: send: simplify return logic from send_verity() fdmanana
                   ` (4 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index e29b5a5ccdd6..0cbc8b5b6fab 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -5067,17 +5067,15 @@ static int __process_changed_deleted_xattr(int num, struct btrfs_key *di_key,
 
 static int process_changed_xattr(struct send_ctx *sctx)
 {
-	int ret = 0;
+	int ret;
 
 	ret = iterate_dir_item(sctx->send_root, sctx->left_path,
 			__process_changed_new_xattr, sctx);
 	if (ret < 0)
-		goto out;
-	ret = iterate_dir_item(sctx->parent_root, sctx->right_path,
-			__process_changed_deleted_xattr, sctx);
+		return ret;
 
-out:
-	return ret;
+	return iterate_dir_item(sctx->parent_root, sctx->right_path,
+				__process_changed_deleted_xattr, sctx);
 }
 
 static int process_all_new_xattrs(struct send_ctx *sctx)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 23/26] btrfs: send: simplify return logic from send_verity()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (21 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 22/26] btrfs: send: simplify return logic from process_changed_xattr() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 24/26] btrfs: send: keep the current inode's path cached fdmanana
                   ` (3 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There's no need for the 'out' label as there are no resources to cleanup
in case of an error and we can directly return if begin_cmd() fails.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 0cbc8b5b6fab..f161e6a695bd 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -5122,7 +5122,7 @@ static int send_verity(struct send_ctx *sctx, struct fs_path *path,
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_ENABLE_VERITY);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path);
 	TLV_PUT_U8(sctx, BTRFS_SEND_A_VERITY_ALGORITHM,
@@ -5137,7 +5137,6 @@ static int send_verity(struct send_ctx *sctx, struct fs_path *path,
 	ret = send_cmd(sctx);
 
 tlv_put_failure:
-out:
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 24/26] btrfs: send: keep the current inode's path cached
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (22 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 23/26] btrfs: send: simplify return logic from send_verity() fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 25/26] btrfs: send: avoid path allocation for the current inode when issuing commands fdmanana
                   ` (2 subsequent siblings)
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

Whenever we need to send a command for the current inode, like sending
writes, xattr updates, truncates, utimes, etc, we compute the inode's
path each time, which implies doing some memory allocations and traversing
the inode hierarchy to extract the name of the inode and each ancestor
directory, and that implies doing lookups in the subvolume tree amongst
other operations.

Most of the time, by far, the current inode's path doesn't change while
we are processing it (like if we need to issue 100 write commands, the
path remains the same and it's pointless to compute it 100 times).

To avoid this keep the current inode's path cached in the send context
and invalidate it or update it whenever it's needed (after unlinks or
renames).

A performance test, and its results, is mentioned in the next patch in
the series (subject: "btrfs: send: avoid path allocation for the current
inode when issuing commands").

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 53 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 48 insertions(+), 5 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index f161e6a695bd..0d0f073a9945 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -177,6 +177,7 @@ struct send_ctx {
 	u64 cur_inode_rdev;
 	u64 cur_inode_last_extent;
 	u64 cur_inode_next_write_offset;
+	struct fs_path cur_inode_path;
 	bool cur_inode_new;
 	bool cur_inode_new_gen;
 	bool cur_inode_deleted;
@@ -433,6 +434,14 @@ static void fs_path_reset(struct fs_path *p)
 	*p->start = 0;
 }
 
+static void init_path(struct fs_path *p)
+{
+	p->reversed = 0;
+	p->buf = p->inline_buf;
+	p->buf_len = FS_PATH_INLINE_SIZE;
+	fs_path_reset(p);
+}
+
 static struct fs_path *fs_path_alloc(void)
 {
 	struct fs_path *p;
@@ -440,10 +449,7 @@ static struct fs_path *fs_path_alloc(void)
 	p = kmalloc(sizeof(*p), GFP_KERNEL);
 	if (!p)
 		return NULL;
-	p->reversed = 0;
-	p->buf = p->inline_buf;
-	p->buf_len = FS_PATH_INLINE_SIZE;
-	fs_path_reset(p);
+	init_path(p);
 	return p;
 }
 
@@ -609,6 +615,14 @@ static void fs_path_unreverse(struct fs_path *p)
 	p->reversed = 0;
 }
 
+static inline bool is_current_inode_path(const struct send_ctx *sctx,
+					 const struct fs_path *path)
+{
+	const struct fs_path *cur = &sctx->cur_inode_path;
+
+	return (strncmp(path->start, cur->start, fs_path_len(cur)) == 0);
+}
+
 static struct btrfs_path *alloc_path_for_send(void)
 {
 	struct btrfs_path *path;
@@ -2419,6 +2433,14 @@ static int get_cur_path(struct send_ctx *sctx, u64 ino, u64 gen,
 	u64 parent_inode = 0;
 	u64 parent_gen = 0;
 	int stop = 0;
+	const bool is_cur_inode = (ino == sctx->cur_ino && gen == sctx->cur_inode_gen);
+
+	if (is_cur_inode && fs_path_len(&sctx->cur_inode_path) > 0) {
+		if (dest != &sctx->cur_inode_path)
+			return fs_path_copy(dest, &sctx->cur_inode_path);
+
+		return 0;
+	}
 
 	name = fs_path_alloc();
 	if (!name) {
@@ -2470,8 +2492,12 @@ static int get_cur_path(struct send_ctx *sctx, u64 ino, u64 gen,
 
 out:
 	fs_path_free(name);
-	if (!ret)
+	if (!ret) {
 		fs_path_unreverse(dest);
+		if (is_cur_inode && dest != &sctx->cur_inode_path)
+			ret = fs_path_copy(&sctx->cur_inode_path, dest);
+	}
+
 	return ret;
 }
 
@@ -3081,6 +3107,11 @@ static int orphanize_inode(struct send_ctx *sctx, u64 ino, u64 gen,
 		goto out;
 
 	ret = send_rename(sctx, path, orphan);
+	if (ret < 0)
+		goto out;
+
+	if (ino == sctx->cur_ino && gen == sctx->cur_inode_gen)
+		ret = fs_path_copy(&sctx->cur_inode_path, orphan);
 
 out:
 	fs_path_free(orphan);
@@ -4143,6 +4174,10 @@ static int rename_current_inode(struct send_ctx *sctx,
 	if (ret < 0)
 		return ret;
 
+	ret = fs_path_copy(&sctx->cur_inode_path, new_path);
+	if (ret < 0)
+		return ret;
+
 	return fs_path_copy(current_path, new_path);
 }
 
@@ -4336,6 +4371,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
 				if (ret > 0) {
 					orphanized_ancestor = true;
 					fs_path_reset(valid_path);
+					fs_path_reset(&sctx->cur_inode_path);
 					ret = get_cur_path(sctx, sctx->cur_ino,
 							   sctx->cur_inode_gen,
 							   valid_path);
@@ -4535,6 +4571,8 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
 				ret = send_unlink(sctx, cur->full_path);
 				if (ret < 0)
 					goto out;
+				if (is_current_inode_path(sctx, cur->full_path))
+					fs_path_reset(&sctx->cur_inode_path);
 			}
 			ret = dup_ref(cur, &check_dirs);
 			if (ret < 0)
@@ -6855,6 +6893,7 @@ static int changed_inode(struct send_ctx *sctx,
 	sctx->cur_inode_last_extent = (u64)-1;
 	sctx->cur_inode_next_write_offset = 0;
 	sctx->ignore_cur_inode = false;
+	fs_path_reset(&sctx->cur_inode_path);
 
 	/*
 	 * Set send_progress to current inode. This will tell all get_cur_xxx
@@ -8130,6 +8169,7 @@ long btrfs_ioctl_send(struct btrfs_inode *inode, const struct btrfs_ioctl_send_a
 		goto out;
 	}
 
+	init_path(&sctx->cur_inode_path);
 	INIT_LIST_HEAD(&sctx->new_refs);
 	INIT_LIST_HEAD(&sctx->deleted_refs);
 
@@ -8406,6 +8446,9 @@ long btrfs_ioctl_send(struct btrfs_inode *inode, const struct btrfs_ioctl_send_a
 		btrfs_lru_cache_clear(&sctx->dir_created_cache);
 		btrfs_lru_cache_clear(&sctx->dir_utimes_cache);
 
+		if (sctx->cur_inode_path.buf != sctx->cur_inode_path.inline_buf)
+			kfree(sctx->cur_inode_path.buf);
+
 		kfree(sctx);
 	}
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 25/26] btrfs: send: avoid path allocation for the current inode when issuing commands
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (23 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 24/26] btrfs: send: keep the current inode's path cached fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-19 11:43 ` [PATCH 26/26] btrfs: send: simplify return logic from send_set_xattr() fdmanana
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

Whenever we issue a command we allocate a path and then compute it. For
the current inode this is not necessary since we have one preallocated
and computed in the send context structure, so we can use it instead
and avoid allocating and freeing a path.

For example if we have 100 extents to send (100 write commands) for a
file, we are allocating and freeing paths 100 times.

So improve on this by avoiding path allocation and freeing whenever a
command is for the current inode by using the current inode's path
stored in the send context structure.

A test was run before applying this patch and the previous one in the
series:

  "btrfs: send: keep the current inode's path cached"

The test script is the following:

  $ cat test.sh
  #!/bin/bash

  DEV=/dev/nullb0
  MNT=/mnt/nullb0

  mkfs.btrfs -f $DEV > /dev/null
  mount $DEV $MNT

  DIR="$MNT/one/two/three/four"
  FILE="$DIR/foobar"

  mkdir -p $DIR

  # Create some empty files to get a deeper btree and therefore make
  # path computations slower.
  for ((i = 1; i <= 30000; i++)); do
      echo -n > "$DIR/filler_$i"
  done

  for ((i = 0; i < 10000; i += 2)); do
     offset=$(( i * 4096 ))
     xfs_io -f -c "pwrite -S 0xab $offset 4K" $FILE > /dev/null
  done

  btrfs subvolume snapshot -r $MNT $MNT/snap

  start=$(date +%s%N)
  btrfs send -f /dev/null $MNT/snap
  end=$(date +%s%N)

  echo -e "\nsend took $(( (end - start) / 1000000 )) milliseconds"

  umount $MNT

Result before applying the 2 patches:  1121 milliseconds
Result after applying the 2 patches:    815 milliseconds  (-31.6%)

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 215 ++++++++++++++++++++++--------------------------
 1 file changed, 97 insertions(+), 118 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 0d0f073a9945..77cedde3b57b 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -2592,6 +2592,47 @@ static int send_subvol_begin(struct send_ctx *sctx)
 	return ret;
 }
 
+static struct fs_path *get_cur_inode_path(struct send_ctx *sctx)
+{
+	if (fs_path_len(&sctx->cur_inode_path) == 0) {
+		int ret;
+
+		ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen,
+				   &sctx->cur_inode_path);
+		if (ret < 0)
+			return ERR_PTR(ret);
+	}
+
+	return &sctx->cur_inode_path;
+}
+
+static struct fs_path *get_path_for_command(struct send_ctx *sctx, u64 ino, u64 gen)
+{
+	struct fs_path *path;
+	int ret;
+
+	if (ino == sctx->cur_ino && gen == sctx->cur_inode_gen)
+		return get_cur_inode_path(sctx);
+
+	path = fs_path_alloc();
+	if (!path)
+		return ERR_PTR(-ENOMEM);
+
+	ret = get_cur_path(sctx, ino, gen, path);
+	if (ret < 0) {
+		fs_path_free(path);
+		return ERR_PTR(ret);
+	}
+
+	return path;
+}
+
+static void free_path_for_command(const struct send_ctx *sctx, struct fs_path *path)
+{
+	if (path != &sctx->cur_inode_path)
+		fs_path_free(path);
+}
+
 static int send_truncate(struct send_ctx *sctx, u64 ino, u64 gen, u64 size)
 {
 	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
@@ -2600,17 +2641,14 @@ static int send_truncate(struct send_ctx *sctx, u64 ino, u64 gen, u64 size)
 
 	btrfs_debug(fs_info, "send_truncate %llu size=%llu", ino, size);
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
+	p = get_path_for_command(sctx, ino, gen);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_TRUNCATE);
 	if (ret < 0)
 		goto out;
 
-	ret = get_cur_path(sctx, ino, gen, p);
-	if (ret < 0)
-		goto out;
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_SIZE, size);
 
@@ -2618,7 +2656,7 @@ static int send_truncate(struct send_ctx *sctx, u64 ino, u64 gen, u64 size)
 
 tlv_put_failure:
 out:
-	fs_path_free(p);
+	free_path_for_command(sctx, p);
 	return ret;
 }
 
@@ -2630,17 +2668,14 @@ static int send_chmod(struct send_ctx *sctx, u64 ino, u64 gen, u64 mode)
 
 	btrfs_debug(fs_info, "send_chmod %llu mode=%llu", ino, mode);
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
+	p = get_path_for_command(sctx, ino, gen);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_CHMOD);
 	if (ret < 0)
 		goto out;
 
-	ret = get_cur_path(sctx, ino, gen, p);
-	if (ret < 0)
-		goto out;
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_MODE, mode & 07777);
 
@@ -2648,7 +2683,7 @@ static int send_chmod(struct send_ctx *sctx, u64 ino, u64 gen, u64 mode)
 
 tlv_put_failure:
 out:
-	fs_path_free(p);
+	free_path_for_command(sctx, p);
 	return ret;
 }
 
@@ -2663,17 +2698,14 @@ static int send_fileattr(struct send_ctx *sctx, u64 ino, u64 gen, u64 fileattr)
 
 	btrfs_debug(fs_info, "send_fileattr %llu fileattr=%llu", ino, fileattr);
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
+	p = get_path_for_command(sctx, ino, gen);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_FILEATTR);
 	if (ret < 0)
 		goto out;
 
-	ret = get_cur_path(sctx, ino, gen, p);
-	if (ret < 0)
-		goto out;
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILEATTR, fileattr);
 
@@ -2681,7 +2713,7 @@ static int send_fileattr(struct send_ctx *sctx, u64 ino, u64 gen, u64 fileattr)
 
 tlv_put_failure:
 out:
-	fs_path_free(p);
+	free_path_for_command(sctx, p);
 	return ret;
 }
 
@@ -2694,17 +2726,14 @@ static int send_chown(struct send_ctx *sctx, u64 ino, u64 gen, u64 uid, u64 gid)
 	btrfs_debug(fs_info, "send_chown %llu uid=%llu, gid=%llu",
 		    ino, uid, gid);
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
+	p = get_path_for_command(sctx, ino, gen);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_CHOWN);
 	if (ret < 0)
 		goto out;
 
-	ret = get_cur_path(sctx, ino, gen, p);
-	if (ret < 0)
-		goto out;
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_UID, uid);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_GID, gid);
@@ -2713,7 +2742,7 @@ static int send_chown(struct send_ctx *sctx, u64 ino, u64 gen, u64 uid, u64 gid)
 
 tlv_put_failure:
 out:
-	fs_path_free(p);
+	free_path_for_command(sctx, p);
 	return ret;
 }
 
@@ -2730,9 +2759,9 @@ static int send_utimes(struct send_ctx *sctx, u64 ino, u64 gen)
 
 	btrfs_debug(fs_info, "send_utimes %llu", ino);
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
+	p = get_path_for_command(sctx, ino, gen);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
 	path = alloc_path_for_send();
 	if (!path) {
@@ -2757,9 +2786,6 @@ static int send_utimes(struct send_ctx *sctx, u64 ino, u64 gen)
 	if (ret < 0)
 		goto out;
 
-	ret = get_cur_path(sctx, ino, gen, p);
-	if (ret < 0)
-		goto out;
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
 	TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_ATIME, eb, &ii->atime);
 	TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_MTIME, eb, &ii->mtime);
@@ -2771,7 +2797,7 @@ static int send_utimes(struct send_ctx *sctx, u64 ino, u64 gen)
 
 tlv_put_failure:
 out:
-	fs_path_free(p);
+	free_path_for_command(sctx, p);
 	btrfs_free_path(path);
 	return ret;
 }
@@ -4889,13 +4915,9 @@ static int send_set_xattr(struct send_ctx *sctx,
 	struct fs_path *path;
 	int ret;
 
-	path = fs_path_alloc();
-	if (!path)
-		return -ENOMEM;
-
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, path);
-	if (ret < 0)
-		goto out;
+	path = get_cur_inode_path(sctx);
+	if (IS_ERR(path))
+		return PTR_ERR(path);
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_SET_XATTR);
 	if (ret < 0)
@@ -4909,8 +4931,6 @@ static int send_set_xattr(struct send_ctx *sctx,
 
 tlv_put_failure:
 out:
-	fs_path_free(path);
-
 	return ret;
 }
 
@@ -4967,23 +4987,14 @@ static int __process_deleted_xattr(int num, struct btrfs_key *di_key,
 				   const char *name, int name_len,
 				   const char *data, int data_len, void *ctx)
 {
-	int ret;
 	struct send_ctx *sctx = ctx;
 	struct fs_path *p;
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
-
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-	if (ret < 0)
-		goto out;
-
-	ret = send_remove_xattr(sctx, p, name, name_len);
+	p = get_cur_inode_path(sctx);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
-out:
-	fs_path_free(p);
-	return ret;
+	return send_remove_xattr(sctx, p, name, name_len);
 }
 
 static int process_new_xattr(struct send_ctx *sctx)
@@ -5209,21 +5220,13 @@ static int process_verity(struct send_ctx *sctx)
 	if (ret < 0)
 		goto iput;
 
-	p = fs_path_alloc();
-	if (!p) {
-		ret = -ENOMEM;
+	p = get_cur_inode_path(sctx);
+	if (IS_ERR(p)) {
+		ret = PTR_ERR(p);
 		goto iput;
 	}
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-	if (ret < 0)
-		goto free_path;
 
 	ret = send_verity(sctx, p, sctx->verity_descriptor);
-	if (ret < 0)
-		goto free_path;
-
-free_path:
-	fs_path_free(p);
 iput:
 	iput(inode);
 	return ret;
@@ -5345,31 +5348,25 @@ static int send_write(struct send_ctx *sctx, u64 offset, u32 len)
 	int ret = 0;
 	struct fs_path *p;
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
-
 	btrfs_debug(fs_info, "send_write offset=%llu, len=%d", offset, len);
 
-	ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE);
-	if (ret < 0)
-		goto out;
+	p = get_cur_inode_path(sctx);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
+	ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
 	ret = put_file_data(sctx, offset, len);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	ret = send_cmd(sctx);
 
 tlv_put_failure:
-out:
-	fs_path_free(p);
 	return ret;
 }
 
@@ -5382,6 +5379,7 @@ static int send_clone(struct send_ctx *sctx,
 {
 	int ret = 0;
 	struct fs_path *p;
+	struct fs_path *cur_inode_path;
 	u64 gen;
 
 	btrfs_debug(sctx->send_root->fs_info,
@@ -5389,6 +5387,10 @@ static int send_clone(struct send_ctx *sctx,
 		    offset, len, btrfs_root_id(clone_root->root),
 		    clone_root->ino, clone_root->offset);
 
+	cur_inode_path = get_cur_inode_path(sctx);
+	if (IS_ERR(cur_inode_path))
+		return PTR_ERR(cur_inode_path);
+
 	p = fs_path_alloc();
 	if (!p)
 		return -ENOMEM;
@@ -5397,13 +5399,9 @@ static int send_clone(struct send_ctx *sctx,
 	if (ret < 0)
 		goto out;
 
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-	if (ret < 0)
-		goto out;
-
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_LEN, len);
-	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
+	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, cur_inode_path);
 
 	if (clone_root->root == sctx->send_root) {
 		ret = get_inode_gen(sctx->send_root, clone_root->ino, &gen);
@@ -5454,17 +5452,13 @@ static int send_update_extent(struct send_ctx *sctx,
 	int ret = 0;
 	struct fs_path *p;
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
+	p = get_cur_inode_path(sctx);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_UPDATE_EXTENT);
 	if (ret < 0)
-		goto out;
-
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-	if (ret < 0)
-		goto out;
+		return ret;
 
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
@@ -5473,8 +5467,6 @@ static int send_update_extent(struct send_ctx *sctx,
 	ret = send_cmd(sctx);
 
 tlv_put_failure:
-out:
-	fs_path_free(p);
 	return ret;
 }
 
@@ -5503,12 +5495,10 @@ static int send_hole(struct send_ctx *sctx, u64 end)
 	if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA)
 		return send_update_extent(sctx, offset, end - offset);
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-	if (ret < 0)
-		goto tlv_put_failure;
+	p = get_cur_inode_path(sctx);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
+
 	while (offset < end) {
 		u64 len = min(end - offset, read_size);
 
@@ -5529,7 +5519,6 @@ static int send_hole(struct send_ctx *sctx, u64 end)
 	}
 	sctx->cur_inode_next_write_offset = offset;
 tlv_put_failure:
-	fs_path_free(p);
 	return ret;
 }
 
@@ -5552,9 +5541,9 @@ static int send_encoded_inline_extent(struct send_ctx *sctx,
 	if (IS_ERR(inode))
 		return PTR_ERR(inode);
 
-	fspath = fs_path_alloc();
-	if (!fspath) {
-		ret = -ENOMEM;
+	fspath = get_cur_inode_path(sctx);
+	if (IS_ERR(fspath)) {
+		ret = PTR_ERR(fspath);
 		goto out;
 	}
 
@@ -5562,10 +5551,6 @@ static int send_encoded_inline_extent(struct send_ctx *sctx,
 	if (ret < 0)
 		goto out;
 
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath);
-	if (ret < 0)
-		goto out;
-
 	btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
 	ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item);
 	ram_bytes = btrfs_file_extent_ram_bytes(leaf, ei);
@@ -5594,7 +5579,6 @@ static int send_encoded_inline_extent(struct send_ctx *sctx,
 
 tlv_put_failure:
 out:
-	fs_path_free(fspath);
 	iput(inode);
 	return ret;
 }
@@ -5619,9 +5603,9 @@ static int send_encoded_extent(struct send_ctx *sctx, struct btrfs_path *path,
 	if (IS_ERR(inode))
 		return PTR_ERR(inode);
 
-	fspath = fs_path_alloc();
-	if (!fspath) {
-		ret = -ENOMEM;
+	fspath = get_cur_inode_path(sctx);
+	if (IS_ERR(fspath)) {
+		ret = PTR_ERR(fspath);
 		goto out;
 	}
 
@@ -5629,10 +5613,6 @@ static int send_encoded_extent(struct send_ctx *sctx, struct btrfs_path *path,
 	if (ret < 0)
 		goto out;
 
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath);
-	if (ret < 0)
-		goto out;
-
 	btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
 	ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item);
 	disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, ei);
@@ -5700,7 +5680,6 @@ static int send_encoded_extent(struct send_ctx *sctx, struct btrfs_path *path,
 
 tlv_put_failure:
 out:
-	fs_path_free(fspath);
 	iput(inode);
 	return ret;
 }
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 26/26] btrfs: send: simplify return logic from send_set_xattr()
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (24 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 25/26] btrfs: send: avoid path allocation for the current inode when issuing commands fdmanana
@ 2025-02-19 11:43 ` fdmanana
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
  26 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-19 11:43 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There's no longer any need for the 'out' label as there are no resources
to cleanup anymore in case of an error and we can directly return if
begin_cmd() fails.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 77cedde3b57b..644172f1cdb0 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4921,7 +4921,7 @@ static int send_set_xattr(struct send_ctx *sctx,
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_SET_XATTR);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path);
 	TLV_PUT_STRING(sctx, BTRFS_SEND_A_XATTR_NAME, name, name_len);
@@ -4930,7 +4930,6 @@ static int send_set_xattr(struct send_ctx *sctx,
 	ret = send_cmd(sctx);
 
 tlv_put_failure:
-out:
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send
  2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
                   ` (25 preceding siblings ...)
  2025-02-19 11:43 ` [PATCH 26/26] btrfs: send: simplify return logic from send_set_xattr() fdmanana
@ 2025-02-20 11:04 ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 01/30] btrfs: send: remove duplicated logic from fs_path_reset() fdmanana
                     ` (30 more replies)
  26 siblings, 31 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

This eleminates repeated path allocations and computations for send when
processing the current inode. The bulk of this is done in patches 28/30
and 29/30, while the remainder are cleanups and simplifications, some of
them to simplify the actual work related to avoiding the repeated path
allocations and computations.

A test, and its result, is described in the change log of patch 29/30.

V2: Add 4 missing patches (cleanups).

Filipe Manana (30):
  btrfs: send: remove duplicated logic from fs_path_reset()
  btrfs: send: make fs_path_len() inline and constify its argument
  btrfs: send: always use fs_path_len() to determine a path's length
  btrfs: send: simplify return logic from fs_path_prepare_for_add()
  btrfs: send: simplify return logic from fs_path_add()
  btrfs: send: implement fs_path_add_path() using fs_path_add()
  btrfs: send: simplify return logic from fs_path_add_from_extent_buffer()
  btrfs: send: return -ENAMETOOLONG when attempting a path that is too long
  btrfs: send: simplify return logic from __get_cur_name_and_parent()
  btrfs: send: simplify return logic from is_inode_existent()
  btrfs: send: simplify return logic from get_cur_inode_state()
  btrfs: send: factor out common logic when sending xattrs
  btrfs: send: only use booleans variables at process_recorded_refs()
  btrfs: send: add and use helper to rename current inode when processing refs
  btrfs: send: simplify return logic from send_remove_xattr()
  btrfs: send: simplify return logic from record_new_ref_if_needed()
  btrfs: send: simplify return logic from record_deleted_ref_if_needed()
  btrfs: send: simplify return logic from record_new_ref()
  btrfs: send: simplify return logic from record_deleted_ref()
  btrfs: send: simplify return logic from record_changed_ref()
  btrfs: send: remove unnecessary return variable from process_new_xattr()
  btrfs: send: simplify return logic from process_changed_xattr()
  btrfs: send: simplify return logic from send_verity()
  btrfs: send: simplify return logic from send_rename()
  btrfs: send: simplify return logic from send_link()
  btrfs: send: simplify return logic from send_unlink()
  btrfs: send: simplify return logic from send_rmdir()
  btrfs: send: keep the current inode's path cached
  btrfs: send: avoid path allocation for the current inode when issuing commands
  btrfs: send: simplify return logic from send_set_xattr()

 fs/btrfs/send.c | 497 +++++++++++++++++++++++-------------------------
 1 file changed, 236 insertions(+), 261 deletions(-)

-- 
2.45.2


^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH v2 01/30] btrfs: send: remove duplicated logic from fs_path_reset()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 02/30] btrfs: send: make fs_path_len() inline and constify its argument fdmanana
                     ` (29 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There's duplicated logic in both branches of the if statement, so move it
outside the branches.

This also reduces the object code size.

Before this change:

  $ size fs/btrfs/btrfs.ko
     text	   data	    bss	    dec	    hex	filename
  1746279	 163600	  16920	1926799	 1d668f	fs/btrfs/btrfs.ko

After this change:

  $ size fs/btrfs/btrfs.ko
     text	   data	    bss	    dec	    hex	filename
  1746047	 163592	  16920	1926559	 1d659f	fs/btrfs/btrfs.ko

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index d513f7fd5fe8..8de561fb1390 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -424,15 +424,13 @@ static int need_send_hole(struct send_ctx *sctx)
 
 static void fs_path_reset(struct fs_path *p)
 {
-	if (p->reversed) {
+	if (p->reversed)
 		p->start = p->buf + p->buf_len - 1;
-		p->end = p->start;
-		*p->start = 0;
-	} else {
+	else
 		p->start = p->buf;
-		p->end = p->start;
-		*p->start = 0;
-	}
+
+	p->end = p->start;
+	*p->start = 0;
 }
 
 static struct fs_path *fs_path_alloc(void)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 02/30] btrfs: send: make fs_path_len() inline and constify its argument
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
  2025-02-20 11:04   ` [PATCH v2 01/30] btrfs: send: remove duplicated logic from fs_path_reset() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 03/30] btrfs: send: always use fs_path_len() to determine a path's length fdmanana
                     ` (28 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

The helper function fs_path_len() is trivial and doesn't need to change
its path argument, so make it inline and constify the argument.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 8de561fb1390..4e998bf8d379 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -468,7 +468,7 @@ static void fs_path_free(struct fs_path *p)
 	kfree(p);
 }
 
-static int fs_path_len(struct fs_path *p)
+static inline int fs_path_len(const struct fs_path *p)
 {
 	return p->end - p->start;
 }
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 03/30] btrfs: send: always use fs_path_len() to determine a path's length
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
  2025-02-20 11:04   ` [PATCH v2 01/30] btrfs: send: remove duplicated logic from fs_path_reset() fdmanana
  2025-02-20 11:04   ` [PATCH v2 02/30] btrfs: send: make fs_path_len() inline and constify its argument fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 04/30] btrfs: send: simplify return logic from fs_path_prepare_for_add() fdmanana
                     ` (27 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

Several places are hardcoding the path length calculation instead of using
the helper fs_path_len() for that. Update all those places to instead use
fs_path_len().

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 4e998bf8d379..9f9885dc1e10 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -489,7 +489,7 @@ static int fs_path_ensure_buf(struct fs_path *p, int len)
 		return -ENOMEM;
 	}
 
-	path_len = p->end - p->start;
+	path_len = fs_path_len(p);
 	old_buf_len = p->buf_len;
 
 	/*
@@ -530,7 +530,7 @@ static int fs_path_prepare_for_add(struct fs_path *p, int name_len,
 	int ret;
 	int new_len;
 
-	new_len = p->end - p->start + name_len;
+	new_len = fs_path_len(p) + name_len;
 	if (p->start != p->end)
 		new_len++;
 	ret = fs_path_ensure_buf(p, new_len);
@@ -571,12 +571,13 @@ static int fs_path_add(struct fs_path *p, const char *name, int name_len)
 static int fs_path_add_path(struct fs_path *p, struct fs_path *p2)
 {
 	int ret;
+	const int p2_len = fs_path_len(p2);
 	char *prepared;
 
-	ret = fs_path_prepare_for_add(p, p2->end - p2->start, &prepared);
+	ret = fs_path_prepare_for_add(p, p2_len, &prepared);
 	if (ret < 0)
 		goto out;
-	memcpy(prepared, p2->start, p2->end - p2->start);
+	memcpy(prepared, p2->start, p2_len);
 
 out:
 	return ret;
@@ -616,7 +617,7 @@ static void fs_path_unreverse(struct fs_path *p)
 		return;
 
 	tmp = p->start;
-	len = p->end - p->start;
+	len = fs_path_len(p);
 	p->start = p->buf;
 	p->end = p->start + len;
 	memmove(p->start, tmp, len + 1);
@@ -737,7 +738,7 @@ static int tlv_put_btrfs_timespec(struct send_ctx *sctx, u16 attr,
 #define TLV_PUT_PATH(sctx, attrtype, p) \
 	do { \
 		ret = tlv_put_string(sctx, attrtype, p->start, \
-			p->end - p->start); \
+				     fs_path_len((p)));	       \
 		if (ret < 0) \
 			goto tlv_put_failure; \
 	} while(0)
@@ -2364,7 +2365,7 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
 	 * earlier. If yes, treat as orphan and return 1.
 	 */
 	ret = did_overwrite_ref(sctx, *parent_ino, *parent_gen, ino, gen,
-			dest->start, dest->end - dest->start);
+				dest->start, fs_path_len(dest));
 	if (ret < 0)
 		goto out;
 	if (ret) {
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 04/30] btrfs: send: simplify return logic from fs_path_prepare_for_add()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (2 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 03/30] btrfs: send: always use fs_path_len() to determine a path's length fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 05/30] btrfs: send: simplify return logic from fs_path_add() fdmanana
                     ` (26 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 9f9885dc1e10..535384028cb8 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -535,7 +535,7 @@ static int fs_path_prepare_for_add(struct fs_path *p, int name_len,
 		new_len++;
 	ret = fs_path_ensure_buf(p, new_len);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	if (p->reversed) {
 		if (p->start != p->end)
@@ -550,8 +550,7 @@ static int fs_path_prepare_for_add(struct fs_path *p, int name_len,
 		*p->end = 0;
 	}
 
-out:
-	return ret;
+	return 0;
 }
 
 static int fs_path_add(struct fs_path *p, const char *name, int name_len)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 05/30] btrfs: send: simplify return logic from fs_path_add()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (3 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 04/30] btrfs: send: simplify return logic from fs_path_prepare_for_add() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 06/30] btrfs: send: implement fs_path_add_path() using fs_path_add() fdmanana
                     ` (25 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 535384028cb8..2203745569e0 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -560,11 +560,10 @@ static int fs_path_add(struct fs_path *p, const char *name, int name_len)
 
 	ret = fs_path_prepare_for_add(p, name_len, &prepared);
 	if (ret < 0)
-		goto out;
+		return ret;
 	memcpy(prepared, name, name_len);
 
-out:
-	return ret;
+	return 0;
 }
 
 static int fs_path_add_path(struct fs_path *p, struct fs_path *p2)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 06/30] btrfs: send: implement fs_path_add_path() using fs_path_add()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (4 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 05/30] btrfs: send: simplify return logic from fs_path_add() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 07/30] btrfs: send: simplify return logic from fs_path_add_from_extent_buffer() fdmanana
                     ` (24 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

The helper fs_path_add_path() is basically a copy of fs_path_add() and it
can be made a wrapper around fs_path_add(). So do that and also make it
inline and constify its second argument.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 2203745569e0..7a75f1d963f9 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -566,19 +566,9 @@ static int fs_path_add(struct fs_path *p, const char *name, int name_len)
 	return 0;
 }
 
-static int fs_path_add_path(struct fs_path *p, struct fs_path *p2)
+static inline int fs_path_add_path(struct fs_path *p, const struct fs_path *p2)
 {
-	int ret;
-	const int p2_len = fs_path_len(p2);
-	char *prepared;
-
-	ret = fs_path_prepare_for_add(p, p2_len, &prepared);
-	if (ret < 0)
-		goto out;
-	memcpy(prepared, p2->start, p2_len);
-
-out:
-	return ret;
+	return fs_path_add(p, p2->start, fs_path_len(p2));
 }
 
 static int fs_path_add_from_extent_buffer(struct fs_path *p,
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 07/30] btrfs: send: simplify return logic from fs_path_add_from_extent_buffer()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (5 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 06/30] btrfs: send: implement fs_path_add_path() using fs_path_add() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 08/30] btrfs: send: return -ENAMETOOLONG when attempting a path that is too long fdmanana
                     ` (23 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 7a75f1d963f9..b9de1ab94367 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -580,12 +580,11 @@ static int fs_path_add_from_extent_buffer(struct fs_path *p,
 
 	ret = fs_path_prepare_for_add(p, len, &prepared);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	read_extent_buffer(eb, prepared, off, len);
 
-out:
-	return ret;
+	return 0;
 }
 
 static int fs_path_copy(struct fs_path *p, struct fs_path *from)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 08/30] btrfs: send: return -ENAMETOOLONG when attempting a path that is too long
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (6 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 07/30] btrfs: send: simplify return logic from fs_path_add_from_extent_buffer() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 09/30] btrfs: send: simplify return logic from __get_cur_name_and_parent() fdmanana
                     ` (22 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

When attempting to build a too long path we are currently returning
-ENOMEM, which is very odd and misleading. So update fs_path_ensure_buf()
to return -ENAMETOOLONG instead. Also, while at it, move the WARN_ON()
into the if statement's expression, as it makes it clear what is being
tested and also has the effect of adding 'unlikely' to the statement,
which allows the compiler to generate better code as this condition is
never expected to happen.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index b9de1ab94367..dcc1cf7d1dbd 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -484,10 +484,8 @@ static int fs_path_ensure_buf(struct fs_path *p, int len)
 	if (p->buf_len >= len)
 		return 0;
 
-	if (len > PATH_MAX) {
-		WARN_ON(1);
-		return -ENOMEM;
-	}
+	if (WARN_ON(len > PATH_MAX))
+		return -ENAMETOOLONG;
 
 	path_len = fs_path_len(p);
 	old_buf_len = p->buf_len;
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 09/30] btrfs: send: simplify return logic from __get_cur_name_and_parent()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (7 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 08/30] btrfs: send: return -ENAMETOOLONG when attempting a path that is too long fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 10/30] btrfs: send: simplify return logic from is_inode_existent() fdmanana
                     ` (21 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index dcc1cf7d1dbd..393c9ca5de90 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -2309,9 +2309,8 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
 			*parent_gen = nce->parent_gen;
 			ret = fs_path_add(dest, nce->name, nce->name_len);
 			if (ret < 0)
-				goto out;
-			ret = nce->ret;
-			goto out;
+				return ret;
+			return nce->ret;
 		}
 	}
 
@@ -2322,12 +2321,12 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
 	 */
 	ret = is_inode_existent(sctx, ino, gen, NULL, NULL);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	if (!ret) {
 		ret = gen_unique_name(sctx, ino, gen, dest);
 		if (ret < 0)
-			goto out;
+			return ret;
 		ret = 1;
 		goto out_cache;
 	}
@@ -2343,7 +2342,7 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
 		ret = get_first_ref(sctx->parent_root, ino,
 				    parent_ino, parent_gen, dest);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	/*
 	 * Check if the ref was overwritten by an inode's ref that was processed
@@ -2352,12 +2351,12 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
 	ret = did_overwrite_ref(sctx, *parent_ino, *parent_gen, ino, gen,
 				dest->start, fs_path_len(dest));
 	if (ret < 0)
-		goto out;
+		return ret;
 	if (ret) {
 		fs_path_reset(dest);
 		ret = gen_unique_name(sctx, ino, gen, dest);
 		if (ret < 0)
-			goto out;
+			return ret;
 		ret = 1;
 	}
 
@@ -2366,10 +2365,8 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
 	 * Store the result of the lookup in the name cache.
 	 */
 	nce = kmalloc(sizeof(*nce) + fs_path_len(dest), GFP_KERNEL);
-	if (!nce) {
-		ret = -ENOMEM;
-		goto out;
-	}
+	if (!nce)
+		return -ENOMEM;
 
 	nce->entry.key = ino;
 	nce->entry.gen = gen;
@@ -2387,10 +2384,9 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
 	nce_ret = btrfs_lru_cache_store(&sctx->name_cache, &nce->entry, GFP_KERNEL);
 	if (nce_ret < 0) {
 		kfree(nce);
-		ret = nce_ret;
+		return nce_ret;
 	}
 
-out:
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 10/30] btrfs: send: simplify return logic from is_inode_existent()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (8 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 09/30] btrfs: send: simplify return logic from __get_cur_name_and_parent() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 11/30] btrfs: send: simplify return logic from get_cur_inode_state() fdmanana
                     ` (20 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 393c9ca5de90..0a908e1066a6 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -1950,17 +1950,14 @@ static int is_inode_existent(struct send_ctx *sctx, u64 ino, u64 gen,
 
 	ret = get_cur_inode_state(sctx, ino, gen, send_gen, parent_gen);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	if (ret == inode_state_no_change ||
 	    ret == inode_state_did_create ||
 	    ret == inode_state_will_delete)
-		ret = 1;
-	else
-		ret = 0;
+		return 1;
 
-out:
-	return ret;
+	return 0;
 }
 
 /*
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 11/30] btrfs: send: simplify return logic from get_cur_inode_state()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (9 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 10/30] btrfs: send: simplify return logic from is_inode_existent() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 12/30] btrfs: send: factor out common logic when sending xattrs fdmanana
                     ` (19 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 0a908e1066a6..e0e24ac94aac 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -1880,7 +1880,7 @@ static int get_cur_inode_state(struct send_ctx *sctx, u64 ino, u64 gen,
 
 	ret = get_inode_info(sctx->send_root, ino, &info);
 	if (ret < 0 && ret != -ENOENT)
-		goto out;
+		return ret;
 	left_ret = (info.nlink == 0) ? -ENOENT : ret;
 	left_gen = info.gen;
 	if (send_gen)
@@ -1891,7 +1891,7 @@ static int get_cur_inode_state(struct send_ctx *sctx, u64 ino, u64 gen,
 	} else {
 		ret = get_inode_info(sctx->parent_root, ino, &info);
 		if (ret < 0 && ret != -ENOENT)
-			goto out;
+			return ret;
 		right_ret = (info.nlink == 0) ? -ENOENT : ret;
 		right_gen = info.gen;
 		if (parent_gen)
@@ -1936,7 +1936,6 @@ static int get_cur_inode_state(struct send_ctx *sctx, u64 ino, u64 gen,
 		ret = -ENOENT;
 	}
 
-out:
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 12/30] btrfs: send: factor out common logic when sending xattrs
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (10 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 11/30] btrfs: send: simplify return logic from get_cur_inode_state() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 13/30] btrfs: send: only use booleans variables at process_recorded_refs() fdmanana
                     ` (18 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

We always send xattrs for the current inode only and both callers of
send_set_xattr() pass a path for the current inode. So move the path
allocation and computation to send_set_xattr(), reducing duplicated
code. This also facilitates an upcoming patch.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 41 +++++++++++++++--------------------------
 1 file changed, 15 insertions(+), 26 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index e0e24ac94aac..3aa2877f8c80 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4844,11 +4844,19 @@ static int process_all_refs(struct send_ctx *sctx,
 }
 
 static int send_set_xattr(struct send_ctx *sctx,
-			  struct fs_path *path,
 			  const char *name, int name_len,
 			  const char *data, int data_len)
 {
-	int ret = 0;
+	struct fs_path *path;
+	int ret;
+
+	path = fs_path_alloc();
+	if (!path)
+		return -ENOMEM;
+
+	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, path);
+	if (ret < 0)
+		goto out;
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_SET_XATTR);
 	if (ret < 0)
@@ -4862,6 +4870,8 @@ static int send_set_xattr(struct send_ctx *sctx,
 
 tlv_put_failure:
 out:
+	fs_path_free(path);
+
 	return ret;
 }
 
@@ -4889,19 +4899,13 @@ static int __process_new_xattr(int num, struct btrfs_key *di_key,
 			       const char *name, int name_len, const char *data,
 			       int data_len, void *ctx)
 {
-	int ret;
 	struct send_ctx *sctx = ctx;
-	struct fs_path *p;
 	struct posix_acl_xattr_header dummy_acl;
 
 	/* Capabilities are emitted by finish_inode_if_needed */
 	if (!strncmp(name, XATTR_NAME_CAPS, name_len))
 		return 0;
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
-
 	/*
 	 * This hack is needed because empty acls are stored as zero byte
 	 * data in xattrs. Problem with that is, that receiving these zero byte
@@ -4918,15 +4922,7 @@ static int __process_new_xattr(int num, struct btrfs_key *di_key,
 		}
 	}
 
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-	if (ret < 0)
-		goto out;
-
-	ret = send_set_xattr(sctx, p, name, name_len, data, data_len);
-
-out:
-	fs_path_free(p);
-	return ret;
+	return send_set_xattr(sctx, name, name_len, data, data_len);
 }
 
 static int __process_deleted_xattr(int num, struct btrfs_key *di_key,
@@ -5803,7 +5799,6 @@ static int send_extent_data(struct send_ctx *sctx, struct btrfs_path *path,
  */
 static int send_capabilities(struct send_ctx *sctx)
 {
-	struct fs_path *fspath = NULL;
 	struct btrfs_path *path;
 	struct btrfs_dir_item *di;
 	struct extent_buffer *leaf;
@@ -5829,25 +5824,19 @@ static int send_capabilities(struct send_ctx *sctx)
 	leaf = path->nodes[0];
 	buf_len = btrfs_dir_data_len(leaf, di);
 
-	fspath = fs_path_alloc();
 	buf = kmalloc(buf_len, GFP_KERNEL);
-	if (!fspath || !buf) {
+	if (!buf) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath);
-	if (ret < 0)
-		goto out;
-
 	data_ptr = (unsigned long)(di + 1) + btrfs_dir_name_len(leaf, di);
 	read_extent_buffer(leaf, buf, data_ptr, buf_len);
 
-	ret = send_set_xattr(sctx, fspath, XATTR_NAME_CAPS,
+	ret = send_set_xattr(sctx, XATTR_NAME_CAPS,
 			strlen(XATTR_NAME_CAPS), buf, buf_len);
 out:
 	kfree(buf);
-	fs_path_free(fspath);
 	btrfs_free_path(path);
 	return ret;
 }
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 13/30] btrfs: send: only use booleans variables at process_recorded_refs()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (11 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 12/30] btrfs: send: factor out common logic when sending xattrs fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 14/30] btrfs: send: add and use helper to rename current inode when processing refs fdmanana
                     ` (17 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

We have several local variables at process_recorded_refs() that are used
as booleans, with some of them having a 'bool' type while two of them
having an 'int' type. Change this to make them all use the 'bool' type
which is more clear and to make everything more consistent.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 3aa2877f8c80..6e27a7d77b25 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4147,9 +4147,9 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
 	u64 ow_inode = 0;
 	u64 ow_gen;
 	u64 ow_mode;
-	int did_overwrite = 0;
-	int is_orphan = 0;
 	u64 last_dir_ino_rm = 0;
+	bool did_overwrite = false;
+	bool is_orphan = false;
 	bool can_rename = true;
 	bool orphanized_dir = false;
 	bool orphanized_ancestor = false;
@@ -4191,14 +4191,14 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
 		if (ret < 0)
 			goto out;
 		if (ret)
-			did_overwrite = 1;
+			did_overwrite = true;
 	}
 	if (sctx->cur_inode_new || did_overwrite) {
 		ret = gen_unique_name(sctx, sctx->cur_ino,
 				sctx->cur_inode_gen, valid_path);
 		if (ret < 0)
 			goto out;
-		is_orphan = 1;
+		is_orphan = true;
 	} else {
 		ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen,
 				valid_path);
@@ -4421,7 +4421,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
 			ret = send_rename(sctx, valid_path, cur->full_path);
 			if (ret < 0)
 				goto out;
-			is_orphan = 0;
+			is_orphan = false;
 			ret = fs_path_copy(valid_path, cur->full_path);
 			if (ret < 0)
 				goto out;
@@ -4482,7 +4482,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
 					sctx->cur_inode_gen, valid_path);
 			if (ret < 0)
 				goto out;
-			is_orphan = 1;
+			is_orphan = true;
 		}
 
 		list_for_each_entry(cur, &sctx->deleted_refs, list) {
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 14/30] btrfs: send: add and use helper to rename current inode when processing refs
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (12 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 13/30] btrfs: send: only use booleans variables at process_recorded_refs() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 15/30] btrfs: send: simplify return logic from send_remove_xattr() fdmanana
                     ` (16 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

Extract the logic to rename the current inode at process_recorded_refs()
into a helper function and use it, therefore removing duplicated logic
and making it easier for an upcoming patch by avoiding yet more duplicated
logic.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 6e27a7d77b25..653e0b9a94ca 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4133,6 +4133,19 @@ static int refresh_ref_path(struct send_ctx *sctx, struct recorded_ref *ref)
 	return ret;
 }
 
+static int rename_current_inode(struct send_ctx *sctx,
+				struct fs_path *current_path,
+				struct fs_path *new_path)
+{
+	int ret;
+
+	ret = send_rename(sctx, current_path, new_path);
+	if (ret < 0)
+		return ret;
+
+	return fs_path_copy(current_path, new_path);
+}
+
 /*
  * This does all the move/link/unlink/rmdir magic.
  */
@@ -4418,13 +4431,10 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
 		 * it depending on the inode mode.
 		 */
 		if (is_orphan && can_rename) {
-			ret = send_rename(sctx, valid_path, cur->full_path);
+			ret = rename_current_inode(sctx, valid_path, cur->full_path);
 			if (ret < 0)
 				goto out;
 			is_orphan = false;
-			ret = fs_path_copy(valid_path, cur->full_path);
-			if (ret < 0)
-				goto out;
 		} else if (can_rename) {
 			if (S_ISDIR(sctx->cur_inode_mode)) {
 				/*
@@ -4432,10 +4442,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
 				 * dirs, we always have one new and one deleted
 				 * ref. The deleted ref is ignored later.
 				 */
-				ret = send_rename(sctx, valid_path,
-						  cur->full_path);
-				if (!ret)
-					ret = fs_path_copy(valid_path,
+				ret = rename_current_inode(sctx, valid_path,
 							   cur->full_path);
 				if (ret < 0)
 					goto out;
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 15/30] btrfs: send: simplify return logic from send_remove_xattr()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (13 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 14/30] btrfs: send: add and use helper to rename current inode when processing refs fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 16/30] btrfs: send: simplify return logic from record_new_ref_if_needed() fdmanana
                     ` (15 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There's no need for the 'out' label as there are no resources to cleanup
in case of an error and we can directly return if begin_cmd() fails.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 653e0b9a94ca..5fd3deaf14d6 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4886,11 +4886,11 @@ static int send_remove_xattr(struct send_ctx *sctx,
 			  struct fs_path *path,
 			  const char *name, int name_len)
 {
-	int ret = 0;
+	int ret;
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_REMOVE_XATTR);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path);
 	TLV_PUT_STRING(sctx, BTRFS_SEND_A_XATTR_NAME, name, name_len);
@@ -4898,7 +4898,6 @@ static int send_remove_xattr(struct send_ctx *sctx,
 	ret = send_cmd(sctx);
 
 tlv_put_failure:
-out:
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 16/30] btrfs: send: simplify return logic from record_new_ref_if_needed()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (14 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 15/30] btrfs: send: simplify return logic from send_remove_xattr() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 17/30] btrfs: send: simplify return logic from record_deleted_ref_if_needed() fdmanana
                     ` (14 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
 make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 5fd3deaf14d6..96aa519e791a 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4683,7 +4683,7 @@ static int record_ref_in_tree(struct rb_root *root, struct list_head *refs,
 
 static int record_new_ref_if_needed(u64 dir, struct fs_path *name, void *ctx)
 {
-	int ret = 0;
+	int ret;
 	struct send_ctx *sctx = ctx;
 	struct rb_node *node = NULL;
 	struct recorded_ref data;
@@ -4692,7 +4692,7 @@ static int record_new_ref_if_needed(u64 dir, struct fs_path *name, void *ctx)
 
 	ret = get_inode_gen(sctx->send_root, dir, &dir_gen);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	data.dir = dir;
 	data.dir_gen = dir_gen;
@@ -4706,7 +4706,7 @@ static int record_new_ref_if_needed(u64 dir, struct fs_path *name, void *ctx)
 					 &sctx->new_refs, name, dir, dir_gen,
 					 sctx);
 	}
-out:
+
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 17/30] btrfs: send: simplify return logic from record_deleted_ref_if_needed()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (15 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 16/30] btrfs: send: simplify return logic from record_new_ref_if_needed() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 18/30] btrfs: send: simplify return logic from record_new_ref() fdmanana
                     ` (13 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 96aa519e791a..b715557ec720 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4712,7 +4712,7 @@ static int record_new_ref_if_needed(u64 dir, struct fs_path *name, void *ctx)
 
 static int record_deleted_ref_if_needed(u64 dir, struct fs_path *name, void *ctx)
 {
-	int ret = 0;
+	int ret;
 	struct send_ctx *sctx = ctx;
 	struct rb_node *node = NULL;
 	struct recorded_ref data;
@@ -4721,7 +4721,7 @@ static int record_deleted_ref_if_needed(u64 dir, struct fs_path *name, void *ctx
 
 	ret = get_inode_gen(sctx->parent_root, dir, &dir_gen);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	data.dir = dir;
 	data.dir_gen = dir_gen;
@@ -4735,7 +4735,7 @@ static int record_deleted_ref_if_needed(u64 dir, struct fs_path *name, void *ctx
 					 &sctx->deleted_refs, name, dir,
 					 dir_gen, sctx);
 	}
-out:
+
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 18/30] btrfs: send: simplify return logic from record_new_ref()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (16 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 17/30] btrfs: send: simplify return logic from record_deleted_ref_if_needed() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 19/30] btrfs: send: simplify return logic from record_deleted_ref() fdmanana
                     ` (12 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index b715557ec720..181a234e3a5e 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4746,11 +4746,9 @@ static int record_new_ref(struct send_ctx *sctx)
 	ret = iterate_inode_ref(sctx->send_root, sctx->left_path,
 				sctx->cmp_key, 0, record_new_ref_if_needed, sctx);
 	if (ret < 0)
-		goto out;
-	ret = 0;
+		return ret;
 
-out:
-	return ret;
+	return 0;
 }
 
 static int record_deleted_ref(struct send_ctx *sctx)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 19/30] btrfs: send: simplify return logic from record_deleted_ref()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (17 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 18/30] btrfs: send: simplify return logic from record_new_ref() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 20/30] btrfs: send: simplify return logic from record_changed_ref() fdmanana
                     ` (11 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 181a234e3a5e..6e171b504415 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4759,11 +4759,9 @@ static int record_deleted_ref(struct send_ctx *sctx)
 				sctx->cmp_key, 0, record_deleted_ref_if_needed,
 				sctx);
 	if (ret < 0)
-		goto out;
-	ret = 0;
+		return ret;
 
-out:
-	return ret;
+	return 0;
 }
 
 static int record_changed_ref(struct send_ctx *sctx)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 20/30] btrfs: send: simplify return logic from record_changed_ref()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (18 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 19/30] btrfs: send: simplify return logic from record_deleted_ref() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 21/30] btrfs: send: remove unnecessary return variable from process_new_xattr() fdmanana
                     ` (10 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 6e171b504415..01b8b570d6ed 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4766,20 +4766,18 @@ static int record_deleted_ref(struct send_ctx *sctx)
 
 static int record_changed_ref(struct send_ctx *sctx)
 {
-	int ret = 0;
+	int ret;
 
 	ret = iterate_inode_ref(sctx->send_root, sctx->left_path,
 			sctx->cmp_key, 0, record_new_ref_if_needed, sctx);
 	if (ret < 0)
-		goto out;
+		return ret;
 	ret = iterate_inode_ref(sctx->parent_root, sctx->right_path,
 			sctx->cmp_key, 0, record_deleted_ref_if_needed, sctx);
 	if (ret < 0)
-		goto out;
-	ret = 0;
+		return ret;
 
-out:
-	return ret;
+	return 0;
 }
 
 /*
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 21/30] btrfs: send: remove unnecessary return variable from process_new_xattr()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (19 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 20/30] btrfs: send: simplify return logic from record_changed_ref() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 22/30] btrfs: send: simplify return logic from process_changed_xattr() fdmanana
                     ` (9 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There's no need for the 'ret' variable, we can just return directly the
result of the call to iterate_dir_item().

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 01b8b570d6ed..e29b5a5ccdd6 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4950,12 +4950,8 @@ static int __process_deleted_xattr(int num, struct btrfs_key *di_key,
 
 static int process_new_xattr(struct send_ctx *sctx)
 {
-	int ret = 0;
-
-	ret = iterate_dir_item(sctx->send_root, sctx->left_path,
-			       __process_new_xattr, sctx);
-
-	return ret;
+	return iterate_dir_item(sctx->send_root, sctx->left_path,
+				__process_new_xattr, sctx);
 }
 
 static int process_deleted_xattr(struct send_ctx *sctx)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 22/30] btrfs: send: simplify return logic from process_changed_xattr()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (20 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 21/30] btrfs: send: remove unnecessary return variable from process_new_xattr() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 23/30] btrfs: send: simplify return logic from send_verity() fdmanana
                     ` (8 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index e29b5a5ccdd6..0cbc8b5b6fab 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -5067,17 +5067,15 @@ static int __process_changed_deleted_xattr(int num, struct btrfs_key *di_key,
 
 static int process_changed_xattr(struct send_ctx *sctx)
 {
-	int ret = 0;
+	int ret;
 
 	ret = iterate_dir_item(sctx->send_root, sctx->left_path,
 			__process_changed_new_xattr, sctx);
 	if (ret < 0)
-		goto out;
-	ret = iterate_dir_item(sctx->parent_root, sctx->right_path,
-			__process_changed_deleted_xattr, sctx);
+		return ret;
 
-out:
-	return ret;
+	return iterate_dir_item(sctx->parent_root, sctx->right_path,
+				__process_changed_deleted_xattr, sctx);
 }
 
 static int process_all_new_xattrs(struct send_ctx *sctx)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 23/30] btrfs: send: simplify return logic from send_verity()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (21 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 22/30] btrfs: send: simplify return logic from process_changed_xattr() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 24/30] btrfs: send: simplify return logic from send_rename() fdmanana
                     ` (7 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There's no need for the 'out' label as there are no resources to cleanup
in case of an error and we can directly return if begin_cmd() fails.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 0cbc8b5b6fab..f161e6a695bd 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -5122,7 +5122,7 @@ static int send_verity(struct send_ctx *sctx, struct fs_path *path,
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_ENABLE_VERITY);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path);
 	TLV_PUT_U8(sctx, BTRFS_SEND_A_VERITY_ALGORITHM,
@@ -5137,7 +5137,6 @@ static int send_verity(struct send_ctx *sctx, struct fs_path *path,
 	ret = send_cmd(sctx);
 
 tlv_put_failure:
-out:
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 24/30] btrfs: send: simplify return logic from send_rename()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (22 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 23/30] btrfs: send: simplify return logic from send_verity() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 25/30] btrfs: send: simplify return logic from send_link() fdmanana
                     ` (6 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index f161e6a695bd..d5c151651d07 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -809,7 +809,7 @@ static int send_rename(struct send_ctx *sctx,
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_RENAME);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, from);
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_TO, to);
@@ -817,7 +817,6 @@ static int send_rename(struct send_ctx *sctx,
 	ret = send_cmd(sctx);
 
 tlv_put_failure:
-out:
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 25/30] btrfs: send: simplify return logic from send_link()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (23 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 24/30] btrfs: send: simplify return logic from send_rename() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 26/30] btrfs: send: simplify return logic from send_unlink() fdmanana
                     ` (5 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index d5c151651d07..bda229c7084b 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -833,7 +833,7 @@ static int send_link(struct send_ctx *sctx,
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_LINK);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path);
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_LINK, lnk);
@@ -841,7 +841,6 @@ static int send_link(struct send_ctx *sctx,
 	ret = send_cmd(sctx);
 
 tlv_put_failure:
-out:
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 26/30] btrfs: send: simplify return logic from send_unlink()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (24 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 25/30] btrfs: send: simplify return logic from send_link() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 27/30] btrfs: send: simplify return logic from send_rmdir() fdmanana
                     ` (4 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index bda229c7084b..cbc9ca9db062 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -856,14 +856,13 @@ static int send_unlink(struct send_ctx *sctx, struct fs_path *path)
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_UNLINK);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path);
 
 	ret = send_cmd(sctx);
 
 tlv_put_failure:
-out:
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 27/30] btrfs: send: simplify return logic from send_rmdir()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (25 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 26/30] btrfs: send: simplify return logic from send_unlink() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 28/30] btrfs: send: keep the current inode's path cached fdmanana
                     ` (3 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index cbc9ca9db062..0c496270e10f 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -878,14 +878,13 @@ static int send_rmdir(struct send_ctx *sctx, struct fs_path *path)
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_RMDIR);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path);
 
 	ret = send_cmd(sctx);
 
 tlv_put_failure:
-out:
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 28/30] btrfs: send: keep the current inode's path cached
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (26 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 27/30] btrfs: send: simplify return logic from send_rmdir() fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 29/30] btrfs: send: avoid path allocation for the current inode when issuing commands fdmanana
                     ` (2 subsequent siblings)
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

Whenever we need to send a command for the current inode, like sending
writes, xattr updates, truncates, utimes, etc, we compute the inode's
path each time, which implies doing some memory allocations and traversing
the inode hierarchy to extract the name of the inode and each ancestor
directory, and that implies doing lookups in the subvolume tree amongst
other operations.

Most of the time, by far, the current inode's path doesn't change while
we are processing it (like if we need to issue 100 write commands, the
path remains the same and it's pointless to compute it 100 times).

To avoid this keep the current inode's path cached in the send context
and invalidate it or update it whenever it's needed (after unlinks or
renames).

A performance test, and its results, is mentioned in the next patch in
the series (subject: "btrfs: send: avoid path allocation for the current
inode when issuing commands").

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 53 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 48 insertions(+), 5 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 0c496270e10f..e811c9237e9e 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -177,6 +177,7 @@ struct send_ctx {
 	u64 cur_inode_rdev;
 	u64 cur_inode_last_extent;
 	u64 cur_inode_next_write_offset;
+	struct fs_path cur_inode_path;
 	bool cur_inode_new;
 	bool cur_inode_new_gen;
 	bool cur_inode_deleted;
@@ -433,6 +434,14 @@ static void fs_path_reset(struct fs_path *p)
 	*p->start = 0;
 }
 
+static void init_path(struct fs_path *p)
+{
+	p->reversed = 0;
+	p->buf = p->inline_buf;
+	p->buf_len = FS_PATH_INLINE_SIZE;
+	fs_path_reset(p);
+}
+
 static struct fs_path *fs_path_alloc(void)
 {
 	struct fs_path *p;
@@ -440,10 +449,7 @@ static struct fs_path *fs_path_alloc(void)
 	p = kmalloc(sizeof(*p), GFP_KERNEL);
 	if (!p)
 		return NULL;
-	p->reversed = 0;
-	p->buf = p->inline_buf;
-	p->buf_len = FS_PATH_INLINE_SIZE;
-	fs_path_reset(p);
+	init_path(p);
 	return p;
 }
 
@@ -609,6 +615,14 @@ static void fs_path_unreverse(struct fs_path *p)
 	p->reversed = 0;
 }
 
+static inline bool is_current_inode_path(const struct send_ctx *sctx,
+					 const struct fs_path *path)
+{
+	const struct fs_path *cur = &sctx->cur_inode_path;
+
+	return (strncmp(path->start, cur->start, fs_path_len(cur)) == 0);
+}
+
 static struct btrfs_path *alloc_path_for_send(void)
 {
 	struct btrfs_path *path;
@@ -2415,6 +2429,14 @@ static int get_cur_path(struct send_ctx *sctx, u64 ino, u64 gen,
 	u64 parent_inode = 0;
 	u64 parent_gen = 0;
 	int stop = 0;
+	const bool is_cur_inode = (ino == sctx->cur_ino && gen == sctx->cur_inode_gen);
+
+	if (is_cur_inode && fs_path_len(&sctx->cur_inode_path) > 0) {
+		if (dest != &sctx->cur_inode_path)
+			return fs_path_copy(dest, &sctx->cur_inode_path);
+
+		return 0;
+	}
 
 	name = fs_path_alloc();
 	if (!name) {
@@ -2466,8 +2488,12 @@ static int get_cur_path(struct send_ctx *sctx, u64 ino, u64 gen,
 
 out:
 	fs_path_free(name);
-	if (!ret)
+	if (!ret) {
 		fs_path_unreverse(dest);
+		if (is_cur_inode && dest != &sctx->cur_inode_path)
+			ret = fs_path_copy(&sctx->cur_inode_path, dest);
+	}
+
 	return ret;
 }
 
@@ -3077,6 +3103,11 @@ static int orphanize_inode(struct send_ctx *sctx, u64 ino, u64 gen,
 		goto out;
 
 	ret = send_rename(sctx, path, orphan);
+	if (ret < 0)
+		goto out;
+
+	if (ino == sctx->cur_ino && gen == sctx->cur_inode_gen)
+		ret = fs_path_copy(&sctx->cur_inode_path, orphan);
 
 out:
 	fs_path_free(orphan);
@@ -4139,6 +4170,10 @@ static int rename_current_inode(struct send_ctx *sctx,
 	if (ret < 0)
 		return ret;
 
+	ret = fs_path_copy(&sctx->cur_inode_path, new_path);
+	if (ret < 0)
+		return ret;
+
 	return fs_path_copy(current_path, new_path);
 }
 
@@ -4332,6 +4367,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
 				if (ret > 0) {
 					orphanized_ancestor = true;
 					fs_path_reset(valid_path);
+					fs_path_reset(&sctx->cur_inode_path);
 					ret = get_cur_path(sctx, sctx->cur_ino,
 							   sctx->cur_inode_gen,
 							   valid_path);
@@ -4531,6 +4567,8 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
 				ret = send_unlink(sctx, cur->full_path);
 				if (ret < 0)
 					goto out;
+				if (is_current_inode_path(sctx, cur->full_path))
+					fs_path_reset(&sctx->cur_inode_path);
 			}
 			ret = dup_ref(cur, &check_dirs);
 			if (ret < 0)
@@ -6851,6 +6889,7 @@ static int changed_inode(struct send_ctx *sctx,
 	sctx->cur_inode_last_extent = (u64)-1;
 	sctx->cur_inode_next_write_offset = 0;
 	sctx->ignore_cur_inode = false;
+	fs_path_reset(&sctx->cur_inode_path);
 
 	/*
 	 * Set send_progress to current inode. This will tell all get_cur_xxx
@@ -8126,6 +8165,7 @@ long btrfs_ioctl_send(struct btrfs_inode *inode, const struct btrfs_ioctl_send_a
 		goto out;
 	}
 
+	init_path(&sctx->cur_inode_path);
 	INIT_LIST_HEAD(&sctx->new_refs);
 	INIT_LIST_HEAD(&sctx->deleted_refs);
 
@@ -8402,6 +8442,9 @@ long btrfs_ioctl_send(struct btrfs_inode *inode, const struct btrfs_ioctl_send_a
 		btrfs_lru_cache_clear(&sctx->dir_created_cache);
 		btrfs_lru_cache_clear(&sctx->dir_utimes_cache);
 
+		if (sctx->cur_inode_path.buf != sctx->cur_inode_path.inline_buf)
+			kfree(sctx->cur_inode_path.buf);
+
 		kfree(sctx);
 	}
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 29/30] btrfs: send: avoid path allocation for the current inode when issuing commands
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (27 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 28/30] btrfs: send: keep the current inode's path cached fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 11:04   ` [PATCH v2 30/30] btrfs: send: simplify return logic from send_set_xattr() fdmanana
  2025-02-20 23:46   ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send David Sterba
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

Whenever we issue a command we allocate a path and then compute it. For
the current inode this is not necessary since we have one preallocated
and computed in the send context structure, so we can use it instead
and avoid allocating and freeing a path.

For example if we have 100 extents to send (100 write commands) for a
file, we are allocating and freeing paths 100 times.

So improve on this by avoiding path allocation and freeing whenever a
command is for the current inode by using the current inode's path
stored in the send context structure.

A test was run before applying this patch and the previous one in the
series:

  "btrfs: send: keep the current inode's path cached"

The test script is the following:

  $ cat test.sh
  #!/bin/bash

  DEV=/dev/nullb0
  MNT=/mnt/nullb0

  mkfs.btrfs -f $DEV > /dev/null
  mount $DEV $MNT

  DIR="$MNT/one/two/three/four"
  FILE="$DIR/foobar"

  mkdir -p $DIR

  # Create some empty files to get a deeper btree and therefore make
  # path computations slower.
  for ((i = 1; i <= 30000; i++)); do
      echo -n > "$DIR/filler_$i"
  done

  for ((i = 0; i < 10000; i += 2)); do
     offset=$(( i * 4096 ))
     xfs_io -f -c "pwrite -S 0xab $offset 4K" $FILE > /dev/null
  done

  btrfs subvolume snapshot -r $MNT $MNT/snap

  start=$(date +%s%N)
  btrfs send -f /dev/null $MNT/snap
  end=$(date +%s%N)

  echo -e "\nsend took $(( (end - start) / 1000000 )) milliseconds"

  umount $MNT

Result before applying the 2 patches:  1121 milliseconds
Result after applying the 2 patches:    815 milliseconds  (-31.6%)

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 215 ++++++++++++++++++++++--------------------------
 1 file changed, 97 insertions(+), 118 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index e811c9237e9e..2c1259068b76 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -2588,6 +2588,47 @@ static int send_subvol_begin(struct send_ctx *sctx)
 	return ret;
 }
 
+static struct fs_path *get_cur_inode_path(struct send_ctx *sctx)
+{
+	if (fs_path_len(&sctx->cur_inode_path) == 0) {
+		int ret;
+
+		ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen,
+				   &sctx->cur_inode_path);
+		if (ret < 0)
+			return ERR_PTR(ret);
+	}
+
+	return &sctx->cur_inode_path;
+}
+
+static struct fs_path *get_path_for_command(struct send_ctx *sctx, u64 ino, u64 gen)
+{
+	struct fs_path *path;
+	int ret;
+
+	if (ino == sctx->cur_ino && gen == sctx->cur_inode_gen)
+		return get_cur_inode_path(sctx);
+
+	path = fs_path_alloc();
+	if (!path)
+		return ERR_PTR(-ENOMEM);
+
+	ret = get_cur_path(sctx, ino, gen, path);
+	if (ret < 0) {
+		fs_path_free(path);
+		return ERR_PTR(ret);
+	}
+
+	return path;
+}
+
+static void free_path_for_command(const struct send_ctx *sctx, struct fs_path *path)
+{
+	if (path != &sctx->cur_inode_path)
+		fs_path_free(path);
+}
+
 static int send_truncate(struct send_ctx *sctx, u64 ino, u64 gen, u64 size)
 {
 	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
@@ -2596,17 +2637,14 @@ static int send_truncate(struct send_ctx *sctx, u64 ino, u64 gen, u64 size)
 
 	btrfs_debug(fs_info, "send_truncate %llu size=%llu", ino, size);
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
+	p = get_path_for_command(sctx, ino, gen);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_TRUNCATE);
 	if (ret < 0)
 		goto out;
 
-	ret = get_cur_path(sctx, ino, gen, p);
-	if (ret < 0)
-		goto out;
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_SIZE, size);
 
@@ -2614,7 +2652,7 @@ static int send_truncate(struct send_ctx *sctx, u64 ino, u64 gen, u64 size)
 
 tlv_put_failure:
 out:
-	fs_path_free(p);
+	free_path_for_command(sctx, p);
 	return ret;
 }
 
@@ -2626,17 +2664,14 @@ static int send_chmod(struct send_ctx *sctx, u64 ino, u64 gen, u64 mode)
 
 	btrfs_debug(fs_info, "send_chmod %llu mode=%llu", ino, mode);
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
+	p = get_path_for_command(sctx, ino, gen);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_CHMOD);
 	if (ret < 0)
 		goto out;
 
-	ret = get_cur_path(sctx, ino, gen, p);
-	if (ret < 0)
-		goto out;
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_MODE, mode & 07777);
 
@@ -2644,7 +2679,7 @@ static int send_chmod(struct send_ctx *sctx, u64 ino, u64 gen, u64 mode)
 
 tlv_put_failure:
 out:
-	fs_path_free(p);
+	free_path_for_command(sctx, p);
 	return ret;
 }
 
@@ -2659,17 +2694,14 @@ static int send_fileattr(struct send_ctx *sctx, u64 ino, u64 gen, u64 fileattr)
 
 	btrfs_debug(fs_info, "send_fileattr %llu fileattr=%llu", ino, fileattr);
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
+	p = get_path_for_command(sctx, ino, gen);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_FILEATTR);
 	if (ret < 0)
 		goto out;
 
-	ret = get_cur_path(sctx, ino, gen, p);
-	if (ret < 0)
-		goto out;
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILEATTR, fileattr);
 
@@ -2677,7 +2709,7 @@ static int send_fileattr(struct send_ctx *sctx, u64 ino, u64 gen, u64 fileattr)
 
 tlv_put_failure:
 out:
-	fs_path_free(p);
+	free_path_for_command(sctx, p);
 	return ret;
 }
 
@@ -2690,17 +2722,14 @@ static int send_chown(struct send_ctx *sctx, u64 ino, u64 gen, u64 uid, u64 gid)
 	btrfs_debug(fs_info, "send_chown %llu uid=%llu, gid=%llu",
 		    ino, uid, gid);
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
+	p = get_path_for_command(sctx, ino, gen);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_CHOWN);
 	if (ret < 0)
 		goto out;
 
-	ret = get_cur_path(sctx, ino, gen, p);
-	if (ret < 0)
-		goto out;
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_UID, uid);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_GID, gid);
@@ -2709,7 +2738,7 @@ static int send_chown(struct send_ctx *sctx, u64 ino, u64 gen, u64 uid, u64 gid)
 
 tlv_put_failure:
 out:
-	fs_path_free(p);
+	free_path_for_command(sctx, p);
 	return ret;
 }
 
@@ -2726,9 +2755,9 @@ static int send_utimes(struct send_ctx *sctx, u64 ino, u64 gen)
 
 	btrfs_debug(fs_info, "send_utimes %llu", ino);
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
+	p = get_path_for_command(sctx, ino, gen);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
 	path = alloc_path_for_send();
 	if (!path) {
@@ -2753,9 +2782,6 @@ static int send_utimes(struct send_ctx *sctx, u64 ino, u64 gen)
 	if (ret < 0)
 		goto out;
 
-	ret = get_cur_path(sctx, ino, gen, p);
-	if (ret < 0)
-		goto out;
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
 	TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_ATIME, eb, &ii->atime);
 	TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_MTIME, eb, &ii->mtime);
@@ -2767,7 +2793,7 @@ static int send_utimes(struct send_ctx *sctx, u64 ino, u64 gen)
 
 tlv_put_failure:
 out:
-	fs_path_free(p);
+	free_path_for_command(sctx, p);
 	btrfs_free_path(path);
 	return ret;
 }
@@ -4885,13 +4911,9 @@ static int send_set_xattr(struct send_ctx *sctx,
 	struct fs_path *path;
 	int ret;
 
-	path = fs_path_alloc();
-	if (!path)
-		return -ENOMEM;
-
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, path);
-	if (ret < 0)
-		goto out;
+	path = get_cur_inode_path(sctx);
+	if (IS_ERR(path))
+		return PTR_ERR(path);
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_SET_XATTR);
 	if (ret < 0)
@@ -4905,8 +4927,6 @@ static int send_set_xattr(struct send_ctx *sctx,
 
 tlv_put_failure:
 out:
-	fs_path_free(path);
-
 	return ret;
 }
 
@@ -4963,23 +4983,14 @@ static int __process_deleted_xattr(int num, struct btrfs_key *di_key,
 				   const char *name, int name_len,
 				   const char *data, int data_len, void *ctx)
 {
-	int ret;
 	struct send_ctx *sctx = ctx;
 	struct fs_path *p;
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
-
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-	if (ret < 0)
-		goto out;
-
-	ret = send_remove_xattr(sctx, p, name, name_len);
+	p = get_cur_inode_path(sctx);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
-out:
-	fs_path_free(p);
-	return ret;
+	return send_remove_xattr(sctx, p, name, name_len);
 }
 
 static int process_new_xattr(struct send_ctx *sctx)
@@ -5205,21 +5216,13 @@ static int process_verity(struct send_ctx *sctx)
 	if (ret < 0)
 		goto iput;
 
-	p = fs_path_alloc();
-	if (!p) {
-		ret = -ENOMEM;
+	p = get_cur_inode_path(sctx);
+	if (IS_ERR(p)) {
+		ret = PTR_ERR(p);
 		goto iput;
 	}
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-	if (ret < 0)
-		goto free_path;
 
 	ret = send_verity(sctx, p, sctx->verity_descriptor);
-	if (ret < 0)
-		goto free_path;
-
-free_path:
-	fs_path_free(p);
 iput:
 	iput(inode);
 	return ret;
@@ -5341,31 +5344,25 @@ static int send_write(struct send_ctx *sctx, u64 offset, u32 len)
 	int ret = 0;
 	struct fs_path *p;
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
-
 	btrfs_debug(fs_info, "send_write offset=%llu, len=%d", offset, len);
 
-	ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE);
-	if (ret < 0)
-		goto out;
+	p = get_cur_inode_path(sctx);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
+	ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
 	ret = put_file_data(sctx, offset, len);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	ret = send_cmd(sctx);
 
 tlv_put_failure:
-out:
-	fs_path_free(p);
 	return ret;
 }
 
@@ -5378,6 +5375,7 @@ static int send_clone(struct send_ctx *sctx,
 {
 	int ret = 0;
 	struct fs_path *p;
+	struct fs_path *cur_inode_path;
 	u64 gen;
 
 	btrfs_debug(sctx->send_root->fs_info,
@@ -5385,6 +5383,10 @@ static int send_clone(struct send_ctx *sctx,
 		    offset, len, btrfs_root_id(clone_root->root),
 		    clone_root->ino, clone_root->offset);
 
+	cur_inode_path = get_cur_inode_path(sctx);
+	if (IS_ERR(cur_inode_path))
+		return PTR_ERR(cur_inode_path);
+
 	p = fs_path_alloc();
 	if (!p)
 		return -ENOMEM;
@@ -5393,13 +5395,9 @@ static int send_clone(struct send_ctx *sctx,
 	if (ret < 0)
 		goto out;
 
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-	if (ret < 0)
-		goto out;
-
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_LEN, len);
-	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
+	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, cur_inode_path);
 
 	if (clone_root->root == sctx->send_root) {
 		ret = get_inode_gen(sctx->send_root, clone_root->ino, &gen);
@@ -5450,17 +5448,13 @@ static int send_update_extent(struct send_ctx *sctx,
 	int ret = 0;
 	struct fs_path *p;
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
+	p = get_cur_inode_path(sctx);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_UPDATE_EXTENT);
 	if (ret < 0)
-		goto out;
-
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-	if (ret < 0)
-		goto out;
+		return ret;
 
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
@@ -5469,8 +5463,6 @@ static int send_update_extent(struct send_ctx *sctx,
 	ret = send_cmd(sctx);
 
 tlv_put_failure:
-out:
-	fs_path_free(p);
 	return ret;
 }
 
@@ -5499,12 +5491,10 @@ static int send_hole(struct send_ctx *sctx, u64 end)
 	if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA)
 		return send_update_extent(sctx, offset, end - offset);
 
-	p = fs_path_alloc();
-	if (!p)
-		return -ENOMEM;
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-	if (ret < 0)
-		goto tlv_put_failure;
+	p = get_cur_inode_path(sctx);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
+
 	while (offset < end) {
 		u64 len = min(end - offset, read_size);
 
@@ -5525,7 +5515,6 @@ static int send_hole(struct send_ctx *sctx, u64 end)
 	}
 	sctx->cur_inode_next_write_offset = offset;
 tlv_put_failure:
-	fs_path_free(p);
 	return ret;
 }
 
@@ -5548,9 +5537,9 @@ static int send_encoded_inline_extent(struct send_ctx *sctx,
 	if (IS_ERR(inode))
 		return PTR_ERR(inode);
 
-	fspath = fs_path_alloc();
-	if (!fspath) {
-		ret = -ENOMEM;
+	fspath = get_cur_inode_path(sctx);
+	if (IS_ERR(fspath)) {
+		ret = PTR_ERR(fspath);
 		goto out;
 	}
 
@@ -5558,10 +5547,6 @@ static int send_encoded_inline_extent(struct send_ctx *sctx,
 	if (ret < 0)
 		goto out;
 
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath);
-	if (ret < 0)
-		goto out;
-
 	btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
 	ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item);
 	ram_bytes = btrfs_file_extent_ram_bytes(leaf, ei);
@@ -5590,7 +5575,6 @@ static int send_encoded_inline_extent(struct send_ctx *sctx,
 
 tlv_put_failure:
 out:
-	fs_path_free(fspath);
 	iput(inode);
 	return ret;
 }
@@ -5615,9 +5599,9 @@ static int send_encoded_extent(struct send_ctx *sctx, struct btrfs_path *path,
 	if (IS_ERR(inode))
 		return PTR_ERR(inode);
 
-	fspath = fs_path_alloc();
-	if (!fspath) {
-		ret = -ENOMEM;
+	fspath = get_cur_inode_path(sctx);
+	if (IS_ERR(fspath)) {
+		ret = PTR_ERR(fspath);
 		goto out;
 	}
 
@@ -5625,10 +5609,6 @@ static int send_encoded_extent(struct send_ctx *sctx, struct btrfs_path *path,
 	if (ret < 0)
 		goto out;
 
-	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath);
-	if (ret < 0)
-		goto out;
-
 	btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
 	ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item);
 	disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, ei);
@@ -5696,7 +5676,6 @@ static int send_encoded_extent(struct send_ctx *sctx, struct btrfs_path *path,
 
 tlv_put_failure:
 out:
-	fs_path_free(fspath);
 	iput(inode);
 	return ret;
 }
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH v2 30/30] btrfs: send: simplify return logic from send_set_xattr()
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (28 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 29/30] btrfs: send: avoid path allocation for the current inode when issuing commands fdmanana
@ 2025-02-20 11:04   ` fdmanana
  2025-02-20 23:46   ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send David Sterba
  30 siblings, 0 replies; 59+ messages in thread
From: fdmanana @ 2025-02-20 11:04 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

There's no longer any need for the 'out' label as there are no resources
to cleanup anymore in case of an error and we can directly return if
begin_cmd() fails.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 2c1259068b76..878b32331bc2 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4917,7 +4917,7 @@ static int send_set_xattr(struct send_ctx *sctx,
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_SET_XATTR);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, path);
 	TLV_PUT_STRING(sctx, BTRFS_SEND_A_XATTR_NAME, name, name_len);
@@ -4926,7 +4926,6 @@ static int send_set_xattr(struct send_ctx *sctx,
 	ret = send_cmd(sctx);
 
 tlv_put_failure:
-out:
 	return ret;
 }
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* Re: [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send
  2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
                     ` (29 preceding siblings ...)
  2025-02-20 11:04   ` [PATCH v2 30/30] btrfs: send: simplify return logic from send_set_xattr() fdmanana
@ 2025-02-20 23:46   ` David Sterba
  30 siblings, 0 replies; 59+ messages in thread
From: David Sterba @ 2025-02-20 23:46 UTC (permalink / raw)
  To: fdmanana; +Cc: linux-btrfs

On Thu, Feb 20, 2025 at 11:04:13AM +0000, fdmanana@kernel.org wrote:
> From: Filipe Manana <fdmanana@suse.com>
> 
> This eleminates repeated path allocations and computations for send when
> processing the current inode. The bulk of this is done in patches 28/30
> and 29/30, while the remainder are cleanups and simplifications, some of
> them to simplify the actual work related to avoiding the repeated path
> allocations and computations.
> 
> A test, and its result, is described in the change log of patch 29/30.
> 
> V2: Add 4 missing patches (cleanups).
> 
> Filipe Manana (30):
>   btrfs: send: remove duplicated logic from fs_path_reset()
>   btrfs: send: make fs_path_len() inline and constify its argument
>   btrfs: send: always use fs_path_len() to determine a path's length
>   btrfs: send: simplify return logic from fs_path_prepare_for_add()
>   btrfs: send: simplify return logic from fs_path_add()
>   btrfs: send: implement fs_path_add_path() using fs_path_add()
>   btrfs: send: simplify return logic from fs_path_add_from_extent_buffer()
>   btrfs: send: return -ENAMETOOLONG when attempting a path that is too long
>   btrfs: send: simplify return logic from __get_cur_name_and_parent()
>   btrfs: send: simplify return logic from is_inode_existent()
>   btrfs: send: simplify return logic from get_cur_inode_state()
>   btrfs: send: factor out common logic when sending xattrs
>   btrfs: send: only use booleans variables at process_recorded_refs()
>   btrfs: send: add and use helper to rename current inode when processing refs
>   btrfs: send: simplify return logic from send_remove_xattr()
>   btrfs: send: simplify return logic from record_new_ref_if_needed()
>   btrfs: send: simplify return logic from record_deleted_ref_if_needed()
>   btrfs: send: simplify return logic from record_new_ref()
>   btrfs: send: simplify return logic from record_deleted_ref()
>   btrfs: send: simplify return logic from record_changed_ref()
>   btrfs: send: remove unnecessary return variable from process_new_xattr()
>   btrfs: send: simplify return logic from process_changed_xattr()
>   btrfs: send: simplify return logic from send_verity()
>   btrfs: send: simplify return logic from send_rename()
>   btrfs: send: simplify return logic from send_link()
>   btrfs: send: simplify return logic from send_unlink()
>   btrfs: send: simplify return logic from send_rmdir()
>   btrfs: send: keep the current inode's path cached
>   btrfs: send: avoid path allocation for the current inode when issuing commands
>   btrfs: send: simplify return logic from send_set_xattr()

Reviewed-by: David Sterba <dsterba@suse.com>

^ permalink raw reply	[flat|nested] 59+ messages in thread

end of thread, other threads:[~2025-02-20 23:46 UTC | newest]

Thread overview: 59+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-19 11:43 [PATCH 00/26] btrfs: avoid repeated path computations and allocations for send fdmanana
2025-02-19 11:43 ` [PATCH 01/26] btrfs: send: remove duplicated logic from fs_path_reset() fdmanana
2025-02-19 11:43 ` [PATCH 02/26] btrfs: send: make fs_path_len() inline and constify its argument fdmanana
2025-02-19 11:43 ` [PATCH 03/26] btrfs: send: always use fs_path_len() to determine a path's length fdmanana
2025-02-19 11:43 ` [PATCH 04/26] btrfs: send: simplify return logic from fs_path_prepare_for_add() fdmanana
2025-02-19 11:43 ` [PATCH 05/26] btrfs: send: simplify return logic from fs_path_add() fdmanana
2025-02-19 11:43 ` [PATCH 06/26] btrfs: send: implement fs_path_add_path() using fs_path_add() fdmanana
2025-02-19 11:43 ` [PATCH 07/26] btrfs: send: simplify return logic from fs_path_add_from_extent_buffer() fdmanana
2025-02-19 11:43 ` [PATCH 08/26] btrfs: send: return -ENAMETOOLONG when attempting a path that is too long fdmanana
2025-02-19 11:43 ` [PATCH 09/26] btrfs: send: simplify return logic from __get_cur_name_and_parent() fdmanana
2025-02-19 11:43 ` [PATCH 10/26] btrfs: send: simplify return logic from is_inode_existent() fdmanana
2025-02-19 11:43 ` [PATCH 11/26] btrfs: send: simplify return logic from get_cur_inode_state() fdmanana
2025-02-19 11:43 ` [PATCH 12/26] btrfs: send: factor out common logic when sending xattrs fdmanana
2025-02-19 11:43 ` [PATCH 13/26] btrfs: send: only use booleans variables at process_recorded_refs() fdmanana
2025-02-19 11:43 ` [PATCH 14/26] btrfs: send: add and use helper to rename current inode when processing refs fdmanana
2025-02-19 11:43 ` [PATCH 15/26] btrfs: send: simplify return logic from send_remove_xattr() fdmanana
2025-02-19 11:43 ` [PATCH 16/26] btrfs: send: simplify return logic from record_new_ref_if_needed() fdmanana
2025-02-19 11:43 ` [PATCH 17/26] btrfs: send: simplify return logic from record_deleted_ref_if_needed() fdmanana
2025-02-19 11:43 ` [PATCH 18/26] btrfs: send: simplify return logic from record_new_ref() fdmanana
2025-02-19 11:43 ` [PATCH 19/26] btrfs: send: simplify return logic from record_deleted_ref() fdmanana
2025-02-19 11:43 ` [PATCH 20/26] btrfs: send: simplify return logic from record_changed_ref() fdmanana
2025-02-19 11:43 ` [PATCH 21/26] btrfs: send: remove unnecessary return variable from process_new_xattr() fdmanana
2025-02-19 11:43 ` [PATCH 22/26] btrfs: send: simplify return logic from process_changed_xattr() fdmanana
2025-02-19 11:43 ` [PATCH 23/26] btrfs: send: simplify return logic from send_verity() fdmanana
2025-02-19 11:43 ` [PATCH 24/26] btrfs: send: keep the current inode's path cached fdmanana
2025-02-19 11:43 ` [PATCH 25/26] btrfs: send: avoid path allocation for the current inode when issuing commands fdmanana
2025-02-19 11:43 ` [PATCH 26/26] btrfs: send: simplify return logic from send_set_xattr() fdmanana
2025-02-20 11:04 ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send fdmanana
2025-02-20 11:04   ` [PATCH v2 01/30] btrfs: send: remove duplicated logic from fs_path_reset() fdmanana
2025-02-20 11:04   ` [PATCH v2 02/30] btrfs: send: make fs_path_len() inline and constify its argument fdmanana
2025-02-20 11:04   ` [PATCH v2 03/30] btrfs: send: always use fs_path_len() to determine a path's length fdmanana
2025-02-20 11:04   ` [PATCH v2 04/30] btrfs: send: simplify return logic from fs_path_prepare_for_add() fdmanana
2025-02-20 11:04   ` [PATCH v2 05/30] btrfs: send: simplify return logic from fs_path_add() fdmanana
2025-02-20 11:04   ` [PATCH v2 06/30] btrfs: send: implement fs_path_add_path() using fs_path_add() fdmanana
2025-02-20 11:04   ` [PATCH v2 07/30] btrfs: send: simplify return logic from fs_path_add_from_extent_buffer() fdmanana
2025-02-20 11:04   ` [PATCH v2 08/30] btrfs: send: return -ENAMETOOLONG when attempting a path that is too long fdmanana
2025-02-20 11:04   ` [PATCH v2 09/30] btrfs: send: simplify return logic from __get_cur_name_and_parent() fdmanana
2025-02-20 11:04   ` [PATCH v2 10/30] btrfs: send: simplify return logic from is_inode_existent() fdmanana
2025-02-20 11:04   ` [PATCH v2 11/30] btrfs: send: simplify return logic from get_cur_inode_state() fdmanana
2025-02-20 11:04   ` [PATCH v2 12/30] btrfs: send: factor out common logic when sending xattrs fdmanana
2025-02-20 11:04   ` [PATCH v2 13/30] btrfs: send: only use booleans variables at process_recorded_refs() fdmanana
2025-02-20 11:04   ` [PATCH v2 14/30] btrfs: send: add and use helper to rename current inode when processing refs fdmanana
2025-02-20 11:04   ` [PATCH v2 15/30] btrfs: send: simplify return logic from send_remove_xattr() fdmanana
2025-02-20 11:04   ` [PATCH v2 16/30] btrfs: send: simplify return logic from record_new_ref_if_needed() fdmanana
2025-02-20 11:04   ` [PATCH v2 17/30] btrfs: send: simplify return logic from record_deleted_ref_if_needed() fdmanana
2025-02-20 11:04   ` [PATCH v2 18/30] btrfs: send: simplify return logic from record_new_ref() fdmanana
2025-02-20 11:04   ` [PATCH v2 19/30] btrfs: send: simplify return logic from record_deleted_ref() fdmanana
2025-02-20 11:04   ` [PATCH v2 20/30] btrfs: send: simplify return logic from record_changed_ref() fdmanana
2025-02-20 11:04   ` [PATCH v2 21/30] btrfs: send: remove unnecessary return variable from process_new_xattr() fdmanana
2025-02-20 11:04   ` [PATCH v2 22/30] btrfs: send: simplify return logic from process_changed_xattr() fdmanana
2025-02-20 11:04   ` [PATCH v2 23/30] btrfs: send: simplify return logic from send_verity() fdmanana
2025-02-20 11:04   ` [PATCH v2 24/30] btrfs: send: simplify return logic from send_rename() fdmanana
2025-02-20 11:04   ` [PATCH v2 25/30] btrfs: send: simplify return logic from send_link() fdmanana
2025-02-20 11:04   ` [PATCH v2 26/30] btrfs: send: simplify return logic from send_unlink() fdmanana
2025-02-20 11:04   ` [PATCH v2 27/30] btrfs: send: simplify return logic from send_rmdir() fdmanana
2025-02-20 11:04   ` [PATCH v2 28/30] btrfs: send: keep the current inode's path cached fdmanana
2025-02-20 11:04   ` [PATCH v2 29/30] btrfs: send: avoid path allocation for the current inode when issuing commands fdmanana
2025-02-20 11:04   ` [PATCH v2 30/30] btrfs: send: simplify return logic from send_set_xattr() fdmanana
2025-02-20 23:46   ` [PATCH v2 00/30] btrfs: avoid repeated path computations and allocations for send David Sterba

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox