linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH e2fsprogs] libext2fs: fix orphan file size > kernel limit with large blocksize
@ 2025-11-12 12:21 libaokun
  2025-11-12 18:36 ` Darrick J. Wong
  0 siblings, 1 reply; 5+ messages in thread
From: libaokun @ 2025-11-12 12:21 UTC (permalink / raw)
  To: linux-ext4; +Cc: tytso, adilger.kernel, jack, yangerkun, libaokun1, libaokun

From: Baokun Li <libaokun1@huawei.com>

Kernel commit 0a6ce20c1564 ("ext4: verify orphan file size is not too big")
limits the maximum supported orphan file size to 8 << 20.

However, in e2fsprogs, the orphan file size is set to 32–512 filesystem
blocks when creating a filesystem.

With 64k block size, formatting an ext4 fs >32G gives an orphan file bigger
than the kernel allows, so mount prints an error and fails:

    EXT4-fs (vdb): orphan file too big: 8650752
    EXT4-fs (vdb): mount failed

Therefore, synchronize the kernel change to e2fsprogs to avoid creating
orphan files larger than the kernel limit.

Signed-off-by: Baokun Li <libaokun1@huawei.com>
---
 lib/ext2fs/ext2fs.h |  2 ++
 lib/ext2fs/orphan.c | 12 +++++++-----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index bb2170b7..d9df007c 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -1819,6 +1819,8 @@ errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io);
 errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io);
 
 /* orphan.c */
+#define EXT4_MAX_ORPHAN_FILE_SIZE	8 << 20
+#define EXT4_DEFAULT_ORPHAN_FILE_SIZE	2 << 20
 extern errcode_t ext2fs_create_orphan_file(ext2_filsys fs, blk_t num_blocks);
 extern errcode_t ext2fs_truncate_orphan_file(ext2_filsys fs);
 extern e2_blkcnt_t ext2fs_default_orphan_file_blocks(ext2_filsys fs);
diff --git a/lib/ext2fs/orphan.c b/lib/ext2fs/orphan.c
index 14ac3569..40b1c5c7 100644
--- a/lib/ext2fs/orphan.c
+++ b/lib/ext2fs/orphan.c
@@ -164,6 +164,8 @@ errcode_t ext2fs_create_orphan_file(ext2_filsys fs, blk_t num_blocks)
 	memset(zerobuf, 0, fs->blocksize);
 	ob_tail = ext2fs_orphan_block_tail(fs, buf);
 	ob_tail->ob_magic = ext2fs_cpu_to_le32(EXT4_ORPHAN_BLOCK_MAGIC);
+	if (num_blocks * fs->blocksize > EXT4_MAX_ORPHAN_FILE_SIZE)
+		num_blocks = EXT4_MAX_ORPHAN_FILE_SIZE / fs->blocksize;
 	oi.num_blocks = num_blocks;
 	oi.alloc_blocks = 0;
 	oi.last_blk = 0;
@@ -216,18 +218,18 @@ out:
 
 /*
  * Find reasonable size for orphan file. We choose orphan file size to be
- * between 32 and 512 filesystem blocks and not more than 1/4096 of the
- * filesystem unless it is really small.
+ * between 32 filesystem blocks and EXT4_DEFAULT_ORPHAN_FILE_SIZE, and not
+ * more than 1/fs->blocksize of the filesystem unless it is really small.
  */
 e2_blkcnt_t ext2fs_default_orphan_file_blocks(ext2_filsys fs)
 {
 	__u64 num_blocks = ext2fs_blocks_count(fs->super);
-	e2_blkcnt_t blks = 512;
+	e2_blkcnt_t blks = EXT4_DEFAULT_ORPHAN_FILE_SIZE / fs->blocksize;
 
 	if (num_blocks < 128 * 1024)
 		blks = 32;
-	else if (num_blocks < 2 * 1024 * 1024)
-		blks = num_blocks / 4096;
+	else if (num_blocks < EXT4_DEFAULT_ORPHAN_FILE_SIZE)
+		blks = num_blocks / fs->blocksize;
 	return (blks + EXT2FS_CLUSTER_MASK(fs)) & ~EXT2FS_CLUSTER_MASK(fs);
 }
 
-- 
2.46.1


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

* Re: [PATCH e2fsprogs] libext2fs: fix orphan file size > kernel limit with large blocksize
  2025-11-12 12:21 [PATCH e2fsprogs] libext2fs: fix orphan file size > kernel limit with large blocksize libaokun
@ 2025-11-12 18:36 ` Darrick J. Wong
  2025-11-12 19:55   ` Jan Kara
  2025-11-13  2:55   ` Baokun Li
  0 siblings, 2 replies; 5+ messages in thread
From: Darrick J. Wong @ 2025-11-12 18:36 UTC (permalink / raw)
  To: libaokun; +Cc: linux-ext4, tytso, adilger.kernel, jack, yangerkun, libaokun1

On Wed, Nov 12, 2025 at 08:21:57PM +0800, libaokun@huaweicloud.com wrote:
> From: Baokun Li <libaokun1@huawei.com>
> 
> Kernel commit 0a6ce20c1564 ("ext4: verify orphan file size is not too big")
> limits the maximum supported orphan file size to 8 << 20.
> 
> However, in e2fsprogs, the orphan file size is set to 32–512 filesystem
> blocks when creating a filesystem.
> 
> With 64k block size, formatting an ext4 fs >32G gives an orphan file bigger
> than the kernel allows, so mount prints an error and fails:
> 
>     EXT4-fs (vdb): orphan file too big: 8650752
>     EXT4-fs (vdb): mount failed
> 
> Therefore, synchronize the kernel change to e2fsprogs to avoid creating
> orphan files larger than the kernel limit.
> 
> Signed-off-by: Baokun Li <libaokun1@huawei.com>
> ---
>  lib/ext2fs/ext2fs.h |  2 ++
>  lib/ext2fs/orphan.c | 12 +++++++-----
>  2 files changed, 9 insertions(+), 5 deletions(-)
> 
> diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
> index bb2170b7..d9df007c 100644
> --- a/lib/ext2fs/ext2fs.h
> +++ b/lib/ext2fs/ext2fs.h
> @@ -1819,6 +1819,8 @@ errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io);
>  errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io);
>  
>  /* orphan.c */
> +#define EXT4_MAX_ORPHAN_FILE_SIZE	8 << 20
> +#define EXT4_DEFAULT_ORPHAN_FILE_SIZE	2 << 20

These #defines ought to have parentheses guarding the expression for
good hygiene.  Also, if this is an artifact of the ondisk format, then
shouldn't it be in ext2_fs.h?  and fs/ext4/ext4.h?

>  extern errcode_t ext2fs_create_orphan_file(ext2_filsys fs, blk_t num_blocks);
>  extern errcode_t ext2fs_truncate_orphan_file(ext2_filsys fs);
>  extern e2_blkcnt_t ext2fs_default_orphan_file_blocks(ext2_filsys fs);
> diff --git a/lib/ext2fs/orphan.c b/lib/ext2fs/orphan.c
> index 14ac3569..40b1c5c7 100644
> --- a/lib/ext2fs/orphan.c
> +++ b/lib/ext2fs/orphan.c
> @@ -164,6 +164,8 @@ errcode_t ext2fs_create_orphan_file(ext2_filsys fs, blk_t num_blocks)
>  	memset(zerobuf, 0, fs->blocksize);
>  	ob_tail = ext2fs_orphan_block_tail(fs, buf);
>  	ob_tail->ob_magic = ext2fs_cpu_to_le32(EXT4_ORPHAN_BLOCK_MAGIC);
> +	if (num_blocks * fs->blocksize > EXT4_MAX_ORPHAN_FILE_SIZE)
> +		num_blocks = EXT4_MAX_ORPHAN_FILE_SIZE / fs->blocksize;
>  	oi.num_blocks = num_blocks;
>  	oi.alloc_blocks = 0;
>  	oi.last_blk = 0;
> @@ -216,18 +218,18 @@ out:
>  
>  /*
>   * Find reasonable size for orphan file. We choose orphan file size to be
> - * between 32 and 512 filesystem blocks and not more than 1/4096 of the
> - * filesystem unless it is really small.
> + * between 32 filesystem blocks and EXT4_DEFAULT_ORPHAN_FILE_SIZE, and not
> + * more than 1/fs->blocksize of the filesystem unless it is really small.
>   */
>  e2_blkcnt_t ext2fs_default_orphan_file_blocks(ext2_filsys fs)
>  {
>  	__u64 num_blocks = ext2fs_blocks_count(fs->super);
> -	e2_blkcnt_t blks = 512;
> +	e2_blkcnt_t blks = EXT4_DEFAULT_ORPHAN_FILE_SIZE / fs->blocksize;
>  
>  	if (num_blocks < 128 * 1024)
>  		blks = 32;
> -	else if (num_blocks < 2 * 1024 * 1024)
> -		blks = num_blocks / 4096;
> +	else if (num_blocks < EXT4_DEFAULT_ORPHAN_FILE_SIZE)
> +		blks = num_blocks / fs->blocksize;

If the number of blocks in the filesystem is less than the default
orphan file size in bytes?  I don't understand that logic, particularly
because EXT4_DEFAULT_ORPHAN_FILE_SIZE == 2<<20 == 2097152 == 2 * 1024 *
1024.

--D

>  	return (blks + EXT2FS_CLUSTER_MASK(fs)) & ~EXT2FS_CLUSTER_MASK(fs);
>  }
>  
> -- 
> 2.46.1
> 
> 

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

* Re: [PATCH e2fsprogs] libext2fs: fix orphan file size > kernel limit with large blocksize
  2025-11-12 18:36 ` Darrick J. Wong
@ 2025-11-12 19:55   ` Jan Kara
  2025-11-13  3:02     ` Baokun Li
  2025-11-13  2:55   ` Baokun Li
  1 sibling, 1 reply; 5+ messages in thread
From: Jan Kara @ 2025-11-12 19:55 UTC (permalink / raw)
  To: Darrick J. Wong
  Cc: libaokun, linux-ext4, tytso, adilger.kernel, jack, yangerkun,
	libaokun1

On Wed 12-11-25 10:36:09, Darrick J. Wong wrote:
> On Wed, Nov 12, 2025 at 08:21:57PM +0800, libaokun@huaweicloud.com wrote:
> > From: Baokun Li <libaokun1@huawei.com>
> > 
> > Kernel commit 0a6ce20c1564 ("ext4: verify orphan file size is not too big")
> > limits the maximum supported orphan file size to 8 << 20.
> > 
> > However, in e2fsprogs, the orphan file size is set to 32–512 filesystem
> > blocks when creating a filesystem.
> > 
> > With 64k block size, formatting an ext4 fs >32G gives an orphan file bigger
> > than the kernel allows, so mount prints an error and fails:
> > 
> >     EXT4-fs (vdb): orphan file too big: 8650752
> >     EXT4-fs (vdb): mount failed
> > 
> > Therefore, synchronize the kernel change to e2fsprogs to avoid creating
> > orphan files larger than the kernel limit.
> > 
> > Signed-off-by: Baokun Li <libaokun1@huawei.com>
...
> >  /*
> >   * Find reasonable size for orphan file. We choose orphan file size to be
> > - * between 32 and 512 filesystem blocks and not more than 1/4096 of the
> > - * filesystem unless it is really small.
> > + * between 32 filesystem blocks and EXT4_DEFAULT_ORPHAN_FILE_SIZE, and not
> > + * more than 1/fs->blocksize of the filesystem unless it is really small.
> >   */
> >  e2_blkcnt_t ext2fs_default_orphan_file_blocks(ext2_filsys fs)
> >  {
> >  	__u64 num_blocks = ext2fs_blocks_count(fs->super);
> > -	e2_blkcnt_t blks = 512;
> > +	e2_blkcnt_t blks = EXT4_DEFAULT_ORPHAN_FILE_SIZE / fs->blocksize;
> >  
> >  	if (num_blocks < 128 * 1024)
> >  		blks = 32;
> > -	else if (num_blocks < 2 * 1024 * 1024)
> > -		blks = num_blocks / 4096;
> > +	else if (num_blocks < EXT4_DEFAULT_ORPHAN_FILE_SIZE)
> > +		blks = num_blocks / fs->blocksize;
> 
> If the number of blocks in the filesystem is less than the default
> orphan file size in bytes?  I don't understand that logic, particularly
> because EXT4_DEFAULT_ORPHAN_FILE_SIZE == 2<<20 == 2097152 == 2 * 1024 *
> 1024.

Yeah, these were just more or less ad hoc constants picked by me to make
sure orphan file doesn't consume too much space and they are unrelated to
the constant I've picked in the kernel limiting orphan file size. And I
agree making sure blks isn't larger than EXT4_DEFAULT_ORPHAN_FILE_SIZE
makes sense but otherwise I don't think we need to change anything here.

								Honza

-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

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

* Re: [PATCH e2fsprogs] libext2fs: fix orphan file size > kernel limit with large blocksize
  2025-11-12 18:36 ` Darrick J. Wong
  2025-11-12 19:55   ` Jan Kara
@ 2025-11-13  2:55   ` Baokun Li
  1 sibling, 0 replies; 5+ messages in thread
From: Baokun Li @ 2025-11-13  2:55 UTC (permalink / raw)
  To: Darrick J. Wong, libaokun
  Cc: linux-ext4, tytso, adilger.kernel, jack, yangerkun

On 2025-11-13 02:36, Darrick J. Wong wrote:
> On Wed, Nov 12, 2025 at 08:21:57PM +0800, libaokun@huaweicloud.com wrote:
>> From: Baokun Li <libaokun1@huawei.com>
>>
>> Kernel commit 0a6ce20c1564 ("ext4: verify orphan file size is not too big")
>> limits the maximum supported orphan file size to 8 << 20.
>>
>> However, in e2fsprogs, the orphan file size is set to 32–512 filesystem
>> blocks when creating a filesystem.
>>
>> With 64k block size, formatting an ext4 fs >32G gives an orphan file bigger
>> than the kernel allows, so mount prints an error and fails:
>>
>>     EXT4-fs (vdb): orphan file too big: 8650752
>>     EXT4-fs (vdb): mount failed
>>
>> Therefore, synchronize the kernel change to e2fsprogs to avoid creating
>> orphan files larger than the kernel limit.
>>
>> Signed-off-by: Baokun Li <libaokun1@huawei.com>
>> ---
>>  lib/ext2fs/ext2fs.h |  2 ++
>>  lib/ext2fs/orphan.c | 12 +++++++-----
>>  2 files changed, 9 insertions(+), 5 deletions(-)
>>
>> diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
>> index bb2170b7..d9df007c 100644
>> --- a/lib/ext2fs/ext2fs.h
>> +++ b/lib/ext2fs/ext2fs.h
>> @@ -1819,6 +1819,8 @@ errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io);
>>  errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io);
>>  
>>  /* orphan.c */
>> +#define EXT4_MAX_ORPHAN_FILE_SIZE	8 << 20
>> +#define EXT4_DEFAULT_ORPHAN_FILE_SIZE	2 << 20
> These #defines ought to have parentheses guarding the expression for
> good hygiene.  

Okay, the next version will add it.

> Also, if this is an artifact of the ondisk format, then
> shouldn't it be in ext2_fs.h?  and fs/ext4/ext4.h?

Since it is only used in the two functions ext2fs_create_orphan_file
and ext2fs_default_orphan_file_blocks, I defined it here.

>
>>  extern errcode_t ext2fs_create_orphan_file(ext2_filsys fs, blk_t num_blocks);
>>  extern errcode_t ext2fs_truncate_orphan_file(ext2_filsys fs);
>>  extern e2_blkcnt_t ext2fs_default_orphan_file_blocks(ext2_filsys fs);
>> diff --git a/lib/ext2fs/orphan.c b/lib/ext2fs/orphan.c
>> index 14ac3569..40b1c5c7 100644
>> --- a/lib/ext2fs/orphan.c
>> +++ b/lib/ext2fs/orphan.c
>> @@ -164,6 +164,8 @@ errcode_t ext2fs_create_orphan_file(ext2_filsys fs, blk_t num_blocks)
>>  	memset(zerobuf, 0, fs->blocksize);
>>  	ob_tail = ext2fs_orphan_block_tail(fs, buf);
>>  	ob_tail->ob_magic = ext2fs_cpu_to_le32(EXT4_ORPHAN_BLOCK_MAGIC);
>> +	if (num_blocks * fs->blocksize > EXT4_MAX_ORPHAN_FILE_SIZE)
>> +		num_blocks = EXT4_MAX_ORPHAN_FILE_SIZE / fs->blocksize;
>>  	oi.num_blocks = num_blocks;
>>  	oi.alloc_blocks = 0;
>>  	oi.last_blk = 0;
>> @@ -216,18 +218,18 @@ out:
>>  
>>  /*
>>   * Find reasonable size for orphan file. We choose orphan file size to be
>> - * between 32 and 512 filesystem blocks and not more than 1/4096 of the
>> - * filesystem unless it is really small.
>> + * between 32 filesystem blocks and EXT4_DEFAULT_ORPHAN_FILE_SIZE, and not
>> + * more than 1/fs->blocksize of the filesystem unless it is really small.
>>   */
>>  e2_blkcnt_t ext2fs_default_orphan_file_blocks(ext2_filsys fs)
>>  {
>>  	__u64 num_blocks = ext2fs_blocks_count(fs->super);
>> -	e2_blkcnt_t blks = 512;
>> +	e2_blkcnt_t blks = EXT4_DEFAULT_ORPHAN_FILE_SIZE / fs->blocksize;
>>  
>>  	if (num_blocks < 128 * 1024)
>>  		blks = 32;
>> -	else if (num_blocks < 2 * 1024 * 1024)
>> -		blks = num_blocks / 4096;
>> +	else if (num_blocks < EXT4_DEFAULT_ORPHAN_FILE_SIZE)
>> +		blks = num_blocks / fs->blocksize;
> If the number of blocks in the filesystem is less than the default
> orphan file size in bytes?  I don't understand that logic, particularly
> because EXT4_DEFAULT_ORPHAN_FILE_SIZE == 2<<20 == 2097152 == 2 * 1024 *
> 1024.

If the number of blocks in the filesystem is less than the default
orphan file size in bytes, mke2fs will fail.

However, this situation never actually occurs, because when the filesystem
has fewer than 2048 blocks, mke2fs does not enable the journal, and the
orphan file is only supported once the journal is enabled.


Cheers,
Baokun

>
> --D
>
>>  	return (blks + EXT2FS_CLUSTER_MASK(fs)) & ~EXT2FS_CLUSTER_MASK(fs);
>>  }
>>  
>> -- 
>> 2.46.1
>>
>>


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

* Re: [PATCH e2fsprogs] libext2fs: fix orphan file size > kernel limit with large blocksize
  2025-11-12 19:55   ` Jan Kara
@ 2025-11-13  3:02     ` Baokun Li
  0 siblings, 0 replies; 5+ messages in thread
From: Baokun Li @ 2025-11-13  3:02 UTC (permalink / raw)
  To: Jan Kara, Darrick J. Wong
  Cc: libaokun, linux-ext4, tytso, adilger.kernel, yangerkun, Baokun Li

On 2025-11-13 03:55, Jan Kara wrote:
> On Wed 12-11-25 10:36:09, Darrick J. Wong wrote:
>> On Wed, Nov 12, 2025 at 08:21:57PM +0800, libaokun@huaweicloud.com wrote:
>>> From: Baokun Li <libaokun1@huawei.com>
>>>
>>> Kernel commit 0a6ce20c1564 ("ext4: verify orphan file size is not too big")
>>> limits the maximum supported orphan file size to 8 << 20.
>>>
>>> However, in e2fsprogs, the orphan file size is set to 32–512 filesystem
>>> blocks when creating a filesystem.
>>>
>>> With 64k block size, formatting an ext4 fs >32G gives an orphan file bigger
>>> than the kernel allows, so mount prints an error and fails:
>>>
>>>     EXT4-fs (vdb): orphan file too big: 8650752
>>>     EXT4-fs (vdb): mount failed
>>>
>>> Therefore, synchronize the kernel change to e2fsprogs to avoid creating
>>> orphan files larger than the kernel limit.
>>>
>>> Signed-off-by: Baokun Li <libaokun1@huawei.com>
> ...
>>>  /*
>>>   * Find reasonable size for orphan file. We choose orphan file size to be
>>> - * between 32 and 512 filesystem blocks and not more than 1/4096 of the
>>> - * filesystem unless it is really small.
>>> + * between 32 filesystem blocks and EXT4_DEFAULT_ORPHAN_FILE_SIZE, and not
>>> + * more than 1/fs->blocksize of the filesystem unless it is really small.
>>>   */
>>>  e2_blkcnt_t ext2fs_default_orphan_file_blocks(ext2_filsys fs)
>>>  {
>>>  	__u64 num_blocks = ext2fs_blocks_count(fs->super);
>>> -	e2_blkcnt_t blks = 512;
>>> +	e2_blkcnt_t blks = EXT4_DEFAULT_ORPHAN_FILE_SIZE / fs->blocksize;
>>>  
>>>  	if (num_blocks < 128 * 1024)
>>>  		blks = 32;
>>> -	else if (num_blocks < 2 * 1024 * 1024)
>>> -		blks = num_blocks / 4096;
>>> +	else if (num_blocks < EXT4_DEFAULT_ORPHAN_FILE_SIZE)
>>> +		blks = num_blocks / fs->blocksize;
>> If the number of blocks in the filesystem is less than the default
>> orphan file size in bytes?  I don't understand that logic, particularly
>> because EXT4_DEFAULT_ORPHAN_FILE_SIZE == 2<<20 == 2097152 == 2 * 1024 *
>> 1024.
> Yeah, these were just more or less ad hoc constants picked by me to make
> sure orphan file doesn't consume too much space and they are unrelated to
> the constant I've picked in the kernel limiting orphan file size. And I
> agree making sure blks isn't larger than EXT4_DEFAULT_ORPHAN_FILE_SIZE
> makes sense but otherwise I don't think we need to change anything here.
>
> 								Honza
>
Okay, in the next version I will revert the changes in
ext2fs_default_orphan_file_blocks(), keep only the check
in ext2fs_create_orphan_file(), and add some comments.


Cheers,
Baokun


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

end of thread, other threads:[~2025-11-13  3:02 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-12 12:21 [PATCH e2fsprogs] libext2fs: fix orphan file size > kernel limit with large blocksize libaokun
2025-11-12 18:36 ` Darrick J. Wong
2025-11-12 19:55   ` Jan Kara
2025-11-13  3:02     ` Baokun Li
2025-11-13  2:55   ` Baokun Li

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).