public inbox for linux-btrfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] block: reject zero length in bio_add_page()
@ 2026-03-13  2:25 Qu Wenruo
  2026-03-16 16:29 ` Christoph Hellwig
  0 siblings, 1 reply; 3+ messages in thread
From: Qu Wenruo @ 2026-03-13  2:25 UTC (permalink / raw)
  To: linux-btrfs, linux-block

[BUG]
I caused a regression in btrfs where an incorrect check leads to
a bio_add_folio() call with a zero length.

Then btrfs goes through the error handling, including:
- Freeing the folio
- Freeing every folio inside that bio

But that can lead VM_BUG_ON() on the last folio.

[CAUSE]
When calling bio_add_folio()/bio_add_page() with zero length, the folio
can still be added to the bio as long as there is a free bvec slot or
can be merged with previous folio/page.

Then bio_add_page() return @len, which is 0.

Normally this means an addition failure, but this time the folio is
already queued into the folio.

This can easily confuse the caller, as for normal failure cases both the
folio and bio should be cleaned up.
But since the bio has the last folio queued in already, this leads to
double folio freeing.

[FIX]
I do not think anyone should call bio_add_folio()/bio_add_page() with zero
length, but idiots like me can still show up.

So add an extra WARN_ON_ONCE() check for zero length and rejects it
early to avoid double freeing.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 block/bio.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/block/bio.c b/block/bio.c
index d80d5d26804e..6048d9382fec 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1064,6 +1064,8 @@ int bio_add_page(struct bio *bio, struct page *page,
 {
 	if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
 		return 0;
+	if (WARN_ON_ONCE(len == 0))
+		return 0;
 	if (bio->bi_iter.bi_size > BIO_MAX_SIZE - len)
 		return 0;
 
-- 
2.53.0


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

* Re: [PATCH] block: reject zero length in bio_add_page()
  2026-03-13  2:25 [PATCH] block: reject zero length in bio_add_page() Qu Wenruo
@ 2026-03-16 16:29 ` Christoph Hellwig
  2026-03-16 20:44   ` Qu Wenruo
  0 siblings, 1 reply; 3+ messages in thread
From: Christoph Hellwig @ 2026-03-16 16:29 UTC (permalink / raw)
  To: Qu Wenruo; +Cc: linux-btrfs, linux-block

I'm a bit worried about adding more an more checks, but this seems like
an actually useful one.

On Fri, Mar 13, 2026 at 12:55:55PM +1030, Qu Wenruo wrote:
> [BUG]

However this [TAG] style commit message is a bit weird.  Can you 
rewrite it like a normal kernel commit message?


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

* Re: [PATCH] block: reject zero length in bio_add_page()
  2026-03-16 16:29 ` Christoph Hellwig
@ 2026-03-16 20:44   ` Qu Wenruo
  0 siblings, 0 replies; 3+ messages in thread
From: Qu Wenruo @ 2026-03-16 20:44 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-btrfs, linux-block



在 2026/3/17 02:59, Christoph Hellwig 写道:
> I'm a bit worried about adding more an more checks, but this seems like
> an actually useful one.
> 
> On Fri, Mar 13, 2026 at 12:55:55PM +1030, Qu Wenruo wrote:
>> [BUG]
> 
> However this [TAG] style commit message is a bit weird.  Can you
> rewrite it like a normal kernel commit message?
> 

Sure, I'll check the history commits of block layer and follow them.

I thought the usual chapter splits of BUG/CAUSE/FIX would make it clear 
to read, but if it's not following the subsystem's requirement, I can 
definitely change it.

Thanks,
Qu

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

end of thread, other threads:[~2026-03-16 20:44 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-13  2:25 [PATCH] block: reject zero length in bio_add_page() Qu Wenruo
2026-03-16 16:29 ` Christoph Hellwig
2026-03-16 20:44   ` Qu Wenruo

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