public inbox for linux-btrfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Leo Martins <loemra.dev@gmail.com>
To: Leo Martins <loemra.dev@gmail.com>
Cc: linux-btrfs@vger.kernel.org, kernel-team@fb.com, fstests@vger.kernel.org
Subject: Re: [PATCH] generic/747: handle ENOSPC gracefully during write/delete cycles
Date: Tue, 24 Mar 2026 16:39:43 -0700	[thread overview]
Message-ID: <20260324234010.590043-1-loemra.dev@gmail.com> (raw)
In-Reply-To: <efcb3c8470bf099534fec1c1745780eba445e111.1774394322.git.loemra.dev@gmail.com>

On Tue, 24 Mar 2026 16:33:26 -0700 Leo Martins <loemra.dev@gmail.com> wrote:

Forgot to CC fstests mailing list.

> generic/747 consistently fails on btrfs in my fstests setup, with an
> ~88% failure rate across multiple runs on kernels ranging from v6.9 to
> v7.0-rc5. This is not a regression but a pre-existing issue since the
> test was added.
> 
> The test fills a filesystem to 95% then does mixed write/delete cycles,
> using statfs to decide whether to write or delete. However, statfs
> f_bavail may overestimate the actual available space. On btrfs, the
> statfs implementation documents its estimate as "a close approximation"
> (fs/btrfs/super.c). At high fill levels the discrepancy between what
> statfs reports and what the filesystem can actually allocate becomes
> significant, causing dd to hit ENOSPC even though statfs indicated
> there was room.
> 
> This is not a filesystem bug. The filesystem correctly rejects the
> write when it cannot reserve space. The test's purpose is to stress
> garbage collection through write/delete churn, not to validate space
> accounting.
> 
> Handle ENOSPC by cleaning up the partial file and making room:
> 
> In _direct_fillup: break out of the fill loop (we're full enough).
> In _mixed_write_delete: delete a file to free space and retry. If
> writes fail 10 consecutive times, _fail the test as that indicates a
> real filesystem issue rather than a transient statfs discrepancy.
> 
> Redirect dd stderr to seqres.full so errors are preserved for
> debugging without polluting the expected output.
> 
> Signed-off-by: Leo Martins <loemra.dev@gmail.com>
> ---
>  tests/generic/747 | 28 +++++++++++++++++++---------
>  1 file changed, 19 insertions(+), 9 deletions(-)
> 
> diff --git a/tests/generic/747 b/tests/generic/747
> index 44834186..35de3ccb 100755
> --- a/tests/generic/747
> +++ b/tests/generic/747
> @@ -35,11 +35,7 @@ _create_file() {
>  
>  	POSIXLY_CORRECT=yes dd if=/dev/zero of=${file_name} \
>  		bs=${bs} count=$(( $file_sz / ${bs} )) \
> -		status=none $dd_extra  2>&1
> -
> -	if [ $? -ne 0 ]; then
> -		_fail "Failed writing $file_name"
> -	fi
> +		status=none $dd_extra  2>>$seqres.full
>  }
>  
>  _total_M() {
> @@ -69,7 +65,10 @@ _direct_fillup () {
>  	while [ $(_used_percent) -lt $fill_percent ]; do
>  		local fsz=$(_get_random_fsz)
>  
> -		_create_file $testseq $fsz "oflag=direct conv=fsync"
> +		if ! _create_file $testseq $fsz "oflag=direct conv=fsync"; then
> +			rm ${SCRATCH_MNT}/data_${testseq}
> +			break
> +		fi
>  		testseq=$((${testseq} + 1))
>  	done
>  }
> @@ -79,14 +78,25 @@ _mixed_write_delete() {
>  	local total_M=$(_total_M)
>  	local to_write_M=$(( ${overwrite_percentage} * ${total_M} / 100 ))
>  	local written_M=0
> +	local enospc_retries=0
> +	local max_enospc_retries=10
>  
>  	while [ $written_M -lt $to_write_M ]; do
>  		if [ $(_used_percent) -lt $fill_percent ]; then
>  			local fsz=$(_get_random_fsz)
>  
> -			_create_file $testseq $fsz "$dd_extra"
> -			written_M=$((${written_M} + ${fsz}/${M}))
> -			testseq=$((${testseq} + 1))
> +			if ! _create_file $testseq $fsz "$dd_extra"; then
> +				rm ${SCRATCH_MNT}/data_${testseq}
> +				_delete_random_file
> +				enospc_retries=$((enospc_retries + 1))
> +				if [ $enospc_retries -ge $max_enospc_retries ]; then
> +					_fail "failed to write after $max_enospc_retries consecutive ENOSPC attempts"
> +				fi
> +			else
> +				written_M=$((${written_M} + ${fsz}/${M}))
> +				testseq=$((${testseq} + 1))
> +				enospc_retries=0
> +			fi
>  		else
>  			_delete_random_file
>  		fi
> -- 
> 2.52.0

  reply	other threads:[~2026-03-24 23:40 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-24 23:33 [PATCH] generic/747: handle ENOSPC gracefully during write/delete cycles Leo Martins
2026-03-24 23:39 ` Leo Martins [this message]
2026-03-25  5:50   ` Christoph Hellwig
2026-03-25  6:23 ` Qu Wenruo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260324234010.590043-1-loemra.dev@gmail.com \
    --to=loemra.dev@gmail.com \
    --cc=fstests@vger.kernel.org \
    --cc=kernel-team@fb.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox