Re: [PATCH] ufs: free the buffer head container in ubh_bforget

Luis Henriques <[email protected]>
Newsgroups gmane.linux.kernel.stable,gmane.linux.file-systems,gmane.linux.kernel
Message-ID <[email protected]>
On Sat, Aug 01 2026, Ali Ahmet Memis wrote:

> ubh_bforget() forgets the buffer heads referenced by a struct
> ufs_buffer_head but never frees the container itself, unlike its
> sibling ubh_brelse() which calls kfree() on the way out. The only
> caller, free_full_branch(), allocates the container through ubh_bread()
> while releasing an indirect block during truncate, so every fully
> removed indirect block leaks one ufs_buffer_head. Truncating or
> unlinking a large file then leaks one allocation per indirect block,
> which kmemleak reports with a free_full_branch, ufs_truncate_blocks,
> ufs_evict_inode backtrace.
>
> Free the container after forgetting its buffers, mirroring ubh_brelse().
>
> Luis Henriques posted a fix for this leak in 2018, but it was never
> applied while fs/ufs had no active maintainer, and the leak is still
> present.

It's been a while, and I don't even remember why I was running xfstests
against this filesystem :-)

But the fix still looks OK.  My original patch also dropped the 'if', but
that's just a minor detail.  I don't know who's using this ufs driver
these days -- each BSD has it's own thing, and it's likely to be risky to
mount a filesystem in rw mode.

Cheers,
-- 
Luís


> Link: https://lore.kernel.org/all/[email protected]/
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Cc: [email protected]
> Signed-off-by: Ali Ahmet Memis <[email protected]>
> ---
>  fs/ufs/util.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/fs/ufs/util.c b/fs/ufs/util.c
> index dff6f7461..3c65fbef6 100644
> --- a/fs/ufs/util.c
> +++ b/fs/ufs/util.c
> @@ -117,8 +117,10 @@ void ubh_bforget (struct ufs_buffer_head * ubh)
>  	unsigned i;
>  	if (!ubh) 
>  		return;
> -	for ( i = 0; i < ubh->count; i++ ) if ( ubh->bh[i] ) 
> -		bforget (ubh->bh[i]);
> +	for (i = 0; i < ubh->count; i++)
> +		if (ubh->bh[i])
> +			bforget(ubh->bh[i]);
> +	kfree(ubh);
>  }
>   
>  int ubh_buffer_dirty (struct ufs_buffer_head * ubh)
> -- 
> 2.54.0
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.