public inbox for linux-btrfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] btrfs: fix an on-stack path leak and migrate to auto-release for on-stack paths
@ 2025-11-25  8:19 Qu Wenruo
  2025-11-25  8:19 ` [PATCH 1/2] btrfs: fix a potential path leak in print_data_reloc_error() Qu Wenruo
  2025-11-25  8:19 ` [PATCH 2/2] btrfs: introduce BTRFS_PATH_AUTO_RELEASE() helper Qu Wenruo
  0 siblings, 2 replies; 6+ messages in thread
From: Qu Wenruo @ 2025-11-25  8:19 UTC (permalink / raw)
  To: linux-btrfs

I thought patch "btrfs: make sure extent and csum paths are always released in
scrub_raid56_parity_stripe()" has already taught us that tag based
manual cleanup is never reliable, now there is another similar bug in
print_data_reloc_error().

This time it is harder to expose, as we always imply if the function
returned an error, they should do the proper cleanup.
But extent_to_logical() does not follow that assumption.

The first patch is the minimal fix for backport, the second patch is
going to solve the problem by using auto-release for all on-stack btrfs
paths.

Qu Wenruo (2):
  btrfs: fix a potential path leak in print_data_reloc_error()
  btrfs: introduce BTRFS_PATH_AUTO_RELEASE() helper

 fs/btrfs/ctree.h  |  5 +++++
 fs/btrfs/defrag.c |  5 +----
 fs/btrfs/inode.c  |  5 +----
 fs/btrfs/scrub.c  | 18 ++++++------------
 4 files changed, 13 insertions(+), 20 deletions(-)

-- 
2.52.0


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

* [PATCH 1/2] btrfs: fix a potential path leak in print_data_reloc_error()
  2025-11-25  8:19 [PATCH 0/2] btrfs: fix an on-stack path leak and migrate to auto-release for on-stack paths Qu Wenruo
@ 2025-11-25  8:19 ` Qu Wenruo
  2025-11-25  8:19 ` [PATCH 2/2] btrfs: introduce BTRFS_PATH_AUTO_RELEASE() helper Qu Wenruo
  1 sibling, 0 replies; 6+ messages in thread
From: Qu Wenruo @ 2025-11-25  8:19 UTC (permalink / raw)
  To: linux-btrfs

Inside print_data_reloc_error(), if extent_from_logical() failed we
return immediately.

However there are the following cases where extent_from_logical() can
return error but still holds a path:

- btrfs_search_slot() returned 0

- No backref item found in extent tree

- No @flags_ret provided
  This is not possible in this call site though.

So for the above two cases, we can return without releasing the path,
causing extent buffer leaks.

Fixes: b9a9a85059cd ("btrfs: output affected files when relocation fails")
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/inode.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3cf30abcdb08..46b5d29f7e29 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -255,6 +255,7 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off
 	if (ret < 0) {
 		btrfs_err_rl(fs_info, "failed to lookup extent item for logical %llu: %d",
 			     logical, ret);
+		btrfs_release_path(&path);
 		return;
 	}
 	eb = path.nodes[0];
-- 
2.52.0


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

* [PATCH 2/2] btrfs: introduce BTRFS_PATH_AUTO_RELEASE() helper
  2025-11-25  8:19 [PATCH 0/2] btrfs: fix an on-stack path leak and migrate to auto-release for on-stack paths Qu Wenruo
  2025-11-25  8:19 ` [PATCH 1/2] btrfs: fix a potential path leak in print_data_reloc_error() Qu Wenruo
@ 2025-11-25  8:19 ` Qu Wenruo
  2025-11-25 12:26   ` David Sterba
  1 sibling, 1 reply; 6+ messages in thread
From: Qu Wenruo @ 2025-11-25  8:19 UTC (permalink / raw)
  To: linux-btrfs

There are already several bugs with on-stack btrfs_path involved, even
it is already a little safer than btrfs_path pointers (only leaks the
extent buffers, not the btrfs_path structure itself)

- Patch "btrfs: make sure extent and csum paths are always released in
  scrub_raid56_parity_stripe()"
  Which is going into v6.19 release cycle.

- Patch "btrfs: fix a potential path leak in print_datA_reloc_error()"
  The previous patch in the series.

Thus there is a real need to apply auto release for those on-stack paths.

This patch introduces a new macro, BTRFS_PATH_AUTO_RELEASE(), which
defines one on-stack btrfs_path structure, initialize it all to 0, then
call btrfs_release_path() on it when exiting the scope.

This will applies to all 3 on-stack path usages:

- defrag_get_extent() in defrag.c

- print_data_reloc_error() in inode.c

- scrub_radi56_parity_stripe() in scrub.c

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/ctree.h  |  5 +++++
 fs/btrfs/defrag.c |  5 +----
 fs/btrfs/inode.c  |  6 +-----
 fs/btrfs/scrub.c  | 18 ++++++------------
 4 files changed, 13 insertions(+), 21 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 692370fc07b2..4ab27673bd9c 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -85,6 +85,10 @@ struct btrfs_path {
 #define BTRFS_PATH_AUTO_FREE(path_name)					\
 	struct btrfs_path *path_name __free(btrfs_free_path) = NULL
 
+/* This defines an on-stack path that will be auto released exiting the scope. */
+#define BTRFS_PATH_AUTO_RELEASE(path_name)					\
+	struct btrfs_path path_name __free(btrfs_release_path) = { 0 }
+
 /*
  * The state of btrfs root
  */
@@ -601,6 +605,7 @@ void btrfs_release_path(struct btrfs_path *p);
 struct btrfs_path *btrfs_alloc_path(void);
 void btrfs_free_path(struct btrfs_path *p);
 DEFINE_FREE(btrfs_free_path, struct btrfs_path *, btrfs_free_path(_T))
+DEFINE_FREE(btrfs_release_path, struct btrfs_path, btrfs_release_path(&_T))
 
 int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 		   struct btrfs_path *path, int slot, int nr);
diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c
index 2e3c011d410a..02a2e7736da0 100644
--- a/fs/btrfs/defrag.c
+++ b/fs/btrfs/defrag.c
@@ -610,7 +610,7 @@ static struct extent_map *defrag_get_extent(struct btrfs_inode *inode,
 {
 	struct btrfs_root *root = inode->root;
 	struct btrfs_file_extent_item *fi;
-	struct btrfs_path path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(path);
 	struct extent_map *em;
 	struct btrfs_key key;
 	u64 ino = btrfs_ino(inode);
@@ -721,16 +721,13 @@ static struct extent_map *defrag_get_extent(struct btrfs_inode *inode,
 		if (ret > 0)
 			goto not_found;
 	}
-	btrfs_release_path(&path);
 	return em;
 
 not_found:
-	btrfs_release_path(&path);
 	btrfs_free_extent_map(em);
 	return NULL;
 
 err:
-	btrfs_release_path(&path);
 	btrfs_free_extent_map(em);
 	return ERR_PTR(ret);
 }
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 46b5d29f7e29..eaf6179692b3 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -217,7 +217,7 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off
 				   int mirror_num)
 {
 	struct btrfs_fs_info *fs_info = inode->root->fs_info;
-	struct btrfs_path path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(path);
 	struct btrfs_key found_key = { 0 };
 	struct extent_buffer *eb;
 	struct btrfs_extent_item *ei;
@@ -255,7 +255,6 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off
 	if (ret < 0) {
 		btrfs_err_rl(fs_info, "failed to lookup extent item for logical %llu: %d",
 			     logical, ret);
-		btrfs_release_path(&path);
 		return;
 	}
 	eb = path.nodes[0];
@@ -285,13 +284,10 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off
 				(ref_level ? "node" : "leaf"),
 				ref_level, ref_root);
 		}
-		btrfs_release_path(&path);
 	} else {
 		struct btrfs_backref_walk_ctx ctx = { 0 };
 		struct data_reloc_warn reloc_warn = { 0 };
 
-		btrfs_release_path(&path);
-
 		ctx.bytenr = found_key.objectid;
 		ctx.extent_item_pos = logical - found_key.objectid;
 		ctx.fs_info = fs_info;
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 41ead4a929b0..de09cfeb3bf1 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -2173,8 +2173,8 @@ static int scrub_raid56_parity_stripe(struct scrub_ctx *sctx,
 				      u64 full_stripe_start)
 {
 	struct btrfs_fs_info *fs_info = sctx->fs_info;
-	struct btrfs_path extent_path = { 0 };
-	struct btrfs_path csum_path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(extent_path);
+	BTRFS_PATH_AUTO_RELEASE(csum_path);
 	struct scrub_stripe *stripe;
 	bool all_empty = true;
 	const int data_stripes = nr_data_stripes(map);
@@ -2226,7 +2226,7 @@ static int scrub_raid56_parity_stripe(struct scrub_ctx *sctx,
 				full_stripe_start + btrfs_stripe_nr_to_offset(i),
 				BTRFS_STRIPE_LEN, stripe);
 		if (ret < 0)
-			goto out;
+			return ret;
 		/*
 		 * No extent in this data stripe, need to manually mark them
 		 * initialized to make later read submission happy.
@@ -2248,10 +2248,8 @@ static int scrub_raid56_parity_stripe(struct scrub_ctx *sctx,
 			break;
 		}
 	}
-	if (all_empty) {
-		ret = 0;
-		goto out;
-	}
+	if (all_empty)
+		return 0;
 
 	for (int i = 0; i < data_stripes; i++) {
 		stripe = &sctx->raid56_data_stripes[i];
@@ -2292,8 +2290,7 @@ static int scrub_raid56_parity_stripe(struct scrub_ctx *sctx,
 "scrub: unrepaired sectors detected, full stripe %llu data stripe %u errors %*pbl",
 				  full_stripe_start, i, stripe->nr_sectors,
 				  &error);
-			ret = -EIO;
-			goto out;
+			return ret;
 		}
 		bitmap_or(&extent_bitmap, &extent_bitmap, &has_extent,
 			  stripe->nr_sectors);
@@ -2302,9 +2299,6 @@ static int scrub_raid56_parity_stripe(struct scrub_ctx *sctx,
 	/* Now we can check and regenerate the P/Q stripe. */
 	ret = scrub_raid56_cached_parity(sctx, scrub_dev, map, full_stripe_start,
 					 &extent_bitmap);
-out:
-	btrfs_release_path(&extent_path);
-	btrfs_release_path(&csum_path);
 	return ret;
 }
 
-- 
2.52.0


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

* Re: [PATCH 2/2] btrfs: introduce BTRFS_PATH_AUTO_RELEASE() helper
  2025-11-25  8:19 ` [PATCH 2/2] btrfs: introduce BTRFS_PATH_AUTO_RELEASE() helper Qu Wenruo
@ 2025-11-25 12:26   ` David Sterba
  2025-11-25 14:51     ` David Sterba
  0 siblings, 1 reply; 6+ messages in thread
From: David Sterba @ 2025-11-25 12:26 UTC (permalink / raw)
  To: Qu Wenruo; +Cc: linux-btrfs

On Tue, Nov 25, 2025 at 06:49:57PM +1030, Qu Wenruo wrote:
> There are already several bugs with on-stack btrfs_path involved, even
> it is already a little safer than btrfs_path pointers (only leaks the
> extent buffers, not the btrfs_path structure itself)
> 
> - Patch "btrfs: make sure extent and csum paths are always released in
>   scrub_raid56_parity_stripe()"
>   Which is going into v6.19 release cycle.
> 
> - Patch "btrfs: fix a potential path leak in print_datA_reloc_error()"
>   The previous patch in the series.
> 
> Thus there is a real need to apply auto release for those on-stack paths.
> 
> This patch introduces a new macro, BTRFS_PATH_AUTO_RELEASE(), which
> defines one on-stack btrfs_path structure, initialize it all to 0, then
> call btrfs_release_path() on it when exiting the scope.

Ok this makes sense. Similar to the path freeing, there should be almost
no code following the expected place of freeing/releasing. If the path
is locked then delaying the cleanup holds the locks. There are relese
calls that will act as an unlock so they should stay, one example below.

Otherwise the hint for auto freeing/releasing is "right before return".

> --- a/fs/btrfs/inode.c
> +++ b/fs/btrfs/inode.c
> @@ -217,7 +217,7 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off
>  				   int mirror_num)
>  {
>  	struct btrfs_fs_info *fs_info = inode->root->fs_info;
> -	struct btrfs_path path = { 0 };
> +	BTRFS_PATH_AUTO_RELEASE(path);
>  	struct btrfs_key found_key = { 0 };
>  	struct extent_buffer *eb;
>  	struct btrfs_extent_item *ei;
> @@ -255,7 +255,6 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off
>  	if (ret < 0) {
>  		btrfs_err_rl(fs_info, "failed to lookup extent item for logical %llu: %d",
>  			     logical, ret);
> -		btrfs_release_path(&path);
>  		return;
>  	}
>  	eb = path.nodes[0];
> @@ -285,13 +284,10 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off
>  				(ref_level ? "node" : "leaf"),
>  				ref_level, ref_root);
>  		}
> -		btrfs_release_path(&path);
>  	} else {
>  		struct btrfs_backref_walk_ctx ctx = { 0 };
>  		struct data_reloc_warn reloc_warn = { 0 };
>  
> -		btrfs_release_path(&path);

The path should be released here because there's iterate_extent_inodes()
which can potentially take long due to the iteration.

> -
>  		ctx.bytenr = found_key.objectid;
>  		ctx.extent_item_pos = logical - found_key.objectid;
>  		ctx.fs_info = fs_info;

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

* Re: [PATCH 2/2] btrfs: introduce BTRFS_PATH_AUTO_RELEASE() helper
  2025-11-25 12:26   ` David Sterba
@ 2025-11-25 14:51     ` David Sterba
  2025-11-25 21:15       ` Qu Wenruo
  0 siblings, 1 reply; 6+ messages in thread
From: David Sterba @ 2025-11-25 14:51 UTC (permalink / raw)
  To: David Sterba; +Cc: Qu Wenruo, linux-btrfs

On Tue, Nov 25, 2025 at 01:26:06PM +0100, David Sterba wrote:
> On Tue, Nov 25, 2025 at 06:49:57PM +1030, Qu Wenruo wrote:
> > There are already several bugs with on-stack btrfs_path involved, even
> > it is already a little safer than btrfs_path pointers (only leaks the
> > extent buffers, not the btrfs_path structure itself)
> > 
> > - Patch "btrfs: make sure extent and csum paths are always released in
> >   scrub_raid56_parity_stripe()"
> >   Which is going into v6.19 release cycle.
> > 
> > - Patch "btrfs: fix a potential path leak in print_datA_reloc_error()"
> >   The previous patch in the series.
> > 
> > Thus there is a real need to apply auto release for those on-stack paths.
> > 
> > This patch introduces a new macro, BTRFS_PATH_AUTO_RELEASE(), which
> > defines one on-stack btrfs_path structure, initialize it all to 0, then
> > call btrfs_release_path() on it when exiting the scope.
> 
> Ok this makes sense. Similar to the path freeing, there should be almost
> no code following the expected place of freeing/releasing. If the path
> is locked then delaying the cleanup holds the locks. There are relese
> calls that will act as an unlock so they should stay, one example below.

One example where a path release (either direct or from inside path
free) is crucial is e110f8911ddb ("btrfs: fix lockdep splat and
potential deadlock after failure running delayed items"). So removing
them from the middle of code should be careful.

> Otherwise the hint for auto freeing/releasing is "right before return".

With the above let me refine that a bit: use auto path
release/free before the 'return' when there's no code that depends on
the path and related extent buffers, or the remainging code is lighweight.

> > --- a/fs/btrfs/inode.c
> > +++ b/fs/btrfs/inode.c
> > @@ -217,7 +217,7 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off
> >  				   int mirror_num)
> >  {
> >  	struct btrfs_fs_info *fs_info = inode->root->fs_info;
> > -	struct btrfs_path path = { 0 };
> > +	BTRFS_PATH_AUTO_RELEASE(path);
> >  	struct btrfs_key found_key = { 0 };
> >  	struct extent_buffer *eb;
> >  	struct btrfs_extent_item *ei;
> > @@ -255,7 +255,6 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off
> >  	if (ret < 0) {
> >  		btrfs_err_rl(fs_info, "failed to lookup extent item for logical %llu: %d",
> >  			     logical, ret);
> > -		btrfs_release_path(&path);
> >  		return;
> >  	}
> >  	eb = path.nodes[0];
> > @@ -285,13 +284,10 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off
> >  				(ref_level ? "node" : "leaf"),
> >  				ref_level, ref_root);
> >  		}
> > -		btrfs_release_path(&path);
> >  	} else {
> >  		struct btrfs_backref_walk_ctx ctx = { 0 };
> >  		struct data_reloc_warn reloc_warn = { 0 };
> >  
> > -		btrfs_release_path(&path);
> 
> The path should be released here because there's iterate_extent_inodes()
> which can potentially take long due to the iteration.

It would be good to add a comment why the release is there, especially
when the function is using the auto release so it's not considered a
mistake.

In many other cases no comment is needed as the general rule is to free
the path right after it's not needed.

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

* Re: [PATCH 2/2] btrfs: introduce BTRFS_PATH_AUTO_RELEASE() helper
  2025-11-25 14:51     ` David Sterba
@ 2025-11-25 21:15       ` Qu Wenruo
  0 siblings, 0 replies; 6+ messages in thread
From: Qu Wenruo @ 2025-11-25 21:15 UTC (permalink / raw)
  To: dsterba; +Cc: Qu Wenruo, linux-btrfs



在 2025/11/26 01:21, David Sterba 写道:
> On Tue, Nov 25, 2025 at 01:26:06PM +0100, David Sterba wrote:
>> On Tue, Nov 25, 2025 at 06:49:57PM +1030, Qu Wenruo wrote:
>>> There are already several bugs with on-stack btrfs_path involved, even
>>> it is already a little safer than btrfs_path pointers (only leaks the
>>> extent buffers, not the btrfs_path structure itself)
>>>
>>> - Patch "btrfs: make sure extent and csum paths are always released in
>>>    scrub_raid56_parity_stripe()"
>>>    Which is going into v6.19 release cycle.
>>>
>>> - Patch "btrfs: fix a potential path leak in print_datA_reloc_error()"
>>>    The previous patch in the series.
>>>
>>> Thus there is a real need to apply auto release for those on-stack paths.
>>>
>>> This patch introduces a new macro, BTRFS_PATH_AUTO_RELEASE(), which
>>> defines one on-stack btrfs_path structure, initialize it all to 0, then
>>> call btrfs_release_path() on it when exiting the scope.
>>
>> Ok this makes sense. Similar to the path freeing, there should be almost
>> no code following the expected place of freeing/releasing. If the path
>> is locked then delaying the cleanup holds the locks. There are relese
>> calls that will act as an unlock so they should stay, one example below.

Yeah, I missed a location where the early release has its meanings.

Thankfully the auto-release here (not auto-free) is safe against any 
existing manual release.

So we should treat the auto-release usage as an extra safenet, and be 
more carefully removing the existing manual release.

> 
> One example where a path release (either direct or from inside path
> free) is crucial is e110f8911ddb ("btrfs: fix lockdep splat and
> potential deadlock after failure running delayed items"). So removing
> them from the middle of code should be careful.
> 
>> Otherwise the hint for auto freeing/releasing is "right before return".
> 
> With the above let me refine that a bit: use auto path
> release/free before the 'return' when there's no code that depends on
> the path and related extent buffers, or the remainging code is lighweight.

I'd say the hint should be, use it everywhere unless required otherwise, 
and review if the existing release can be safely removed.
At least for this AUTO_RELEASE behavior.

Unlike AUTO_FREE, we can mix auto-release and existing release safely,
while we can not mix the existing freeing code with auto-free, as the 
existing code won't re-set the path pointer to NULL after freeing, can 
lead to double freeing.


But the current objective of RAII and scope-based auto-cleanup are just 
to ensure we never miss a release.
There will be some quirks as you exposed and the auto-free problem I 
mentioned, but at least it would be easier to review than catching the 
original missing release/free.


For the long run I hope we can refine our structure lifespan design to 
be better, so it can be better suited for something like this (ignore 
the ret_guard() naming, and put aside your hate against RAII):

	ret_guard(btrfs_new_path, path = btrfs_search_slot_new_path())
	{
		/*
		 * Where the lifespan of the path is only inside the
		 * the code block, and get auto-freed exiting the scope.
		 */
		do_something(path);
	}
	if (IS_ERR(path)) {
		/* Error handling, no @path involved. */
	}

Although this is against our current error-handling-first coding style, 
and not all callsites should be replaced (e.g. callsites using 
pre-allocated path).

Thanks,
Qu


> 
>>> --- a/fs/btrfs/inode.c
>>> +++ b/fs/btrfs/inode.c
>>> @@ -217,7 +217,7 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off
>>>   				   int mirror_num)
>>>   {
>>>   	struct btrfs_fs_info *fs_info = inode->root->fs_info;
>>> -	struct btrfs_path path = { 0 };
>>> +	BTRFS_PATH_AUTO_RELEASE(path);
>>>   	struct btrfs_key found_key = { 0 };
>>>   	struct extent_buffer *eb;
>>>   	struct btrfs_extent_item *ei;
>>> @@ -255,7 +255,6 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off
>>>   	if (ret < 0) {
>>>   		btrfs_err_rl(fs_info, "failed to lookup extent item for logical %llu: %d",
>>>   			     logical, ret);
>>> -		btrfs_release_path(&path);
>>>   		return;
>>>   	}
>>>   	eb = path.nodes[0];
>>> @@ -285,13 +284,10 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off
>>>   				(ref_level ? "node" : "leaf"),
>>>   				ref_level, ref_root);
>>>   		}
>>> -		btrfs_release_path(&path);
>>>   	} else {
>>>   		struct btrfs_backref_walk_ctx ctx = { 0 };
>>>   		struct data_reloc_warn reloc_warn = { 0 };
>>>   
>>> -		btrfs_release_path(&path);
>>
>> The path should be released here because there's iterate_extent_inodes()
>> which can potentially take long due to the iteration.
> 
> It would be good to add a comment why the release is there, especially
> when the function is using the auto release so it's not considered a
> mistake.
> 
> In many other cases no comment is needed as the general rule is to free
> the path right after it's not needed.
> 


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

end of thread, other threads:[~2025-11-25 21:15 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-25  8:19 [PATCH 0/2] btrfs: fix an on-stack path leak and migrate to auto-release for on-stack paths Qu Wenruo
2025-11-25  8:19 ` [PATCH 1/2] btrfs: fix a potential path leak in print_data_reloc_error() Qu Wenruo
2025-11-25  8:19 ` [PATCH 2/2] btrfs: introduce BTRFS_PATH_AUTO_RELEASE() helper Qu Wenruo
2025-11-25 12:26   ` David Sterba
2025-11-25 14:51     ` David Sterba
2025-11-25 21:15       ` Qu Wenruo

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