Re: [PATCH -next v5 27/32] ext4: clear DISKSIZE_GROW_PENDING on truncate or error

Zhang Yi <[email protected]>
Newsgroups org.kernel.vger.linux-ext4,dev.linux.lists.sashiko-reviews
Message-ID <[email protected]>
On 8/14/2026 6:31 PM, [email protected] wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [High] The EXT4_STATE_DISKSIZE_GROW_PENDING inode state bit is never set anywhere in the codebase. As a result, the entire deferred disksize update mechanism introduced in this patch series is non-functional.
> - [Medium] The DISKSIZE_GROW_PENDING state is not cleared for linked inodes (i_nlink > 0) during eviction, leading to a WARN_ON_ONCE in ext4_destroy_inode() on forced shutdown.
> --
> 
> --- Patch [27]: [PATCH -next v5 27/32] ext4: clear DISKSIZE_GROW_PENDING on truncate or error ---
> commit a9d36fc1a5b406105120b9e8fd8d91b4a9fe12f0
> Author: Zhang Yi <[email protected]>
> 
> ext4: clear DISKSIZE_GROW_PENDING on truncate or error
> 
> The disksize-grow-pending state is set when a zeroed EOF block is queued
> for writeback and cleared by the ioend completion path once writeback
> finishes. This patch clears the disksize-grow-pending state on discard,
> inode eviction, filesystem emergency state, or truncate to avoid blocking
> writebacks and preventing warnings in ext4_destroy_inode().
> 
>> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
>> index 056937e278594..a1dfb70127ca8 100644
>> --- a/fs/ext4/inode.c
>> +++ b/fs/ext4/inode.c
>> @@ -273,6 +273,8 @@ void ext4_evict_inode(struct inode *inode)
>>   
>>   	if (ext4_should_order_data(inode))
>>   		ext4_begin_ordered_truncate(inode, 0);
>> +	if (ext4_inode_buffered_iomap(inode))
>> +		ext4_iomap_clear_disksize_pending(inode);
> 
> [Severity: Medium]
> If a filesystem is forcibly shut down (e.g., via EXT4_IOC_SHUTDOWN without
> logging an error that sets EXT4_ERROR_FS) and then unmounted, dirty linked
> inodes will be evicted.
> 
> Looking earlier in ext4_evict_inode(), if inode->i_nlink is > 0, the code
> jumps to the no_delete label, completely bypassing this cleanup:
> 
> 	if (inode->i_nlink) {
> 		...
> 		goto no_delete;
> 	}
> 
> Will this cause the newly added WARN_ON_ONCE in ext4_destroy_inode() to
> trigger for linked inodes since they bypass this state clearing?
> 

Yes, this is right. A linked inode evicted after a forced shutdown
bypasses it and would hit the WARN_ON_ONCE in ext4_destroy_inode(). So
I'd tightened the WARN_ON_ONCE guard in ext4_destroy_inode() to skip the
check when the filesystem is in an error or emergency state, since the
pending block may not have been written back in those cases. Besides,
drop the emergency-state cleanup added to ext4_iomap_writepages()
because it becomes unnecessary.

Thanks,
Yi.


>>   	truncate_inode_pages_final(&inode->i_data);
>>   
>>   	/*
> 
> [ ... ]
> 
>> @@ -6741,7 +6759,18 @@ static int ext4_truncate_down(struct inode *inode, loff_t oldsize,
>>   	start_lblk = newsize > 0 ? (newsize - 1) >> inode->i_blkbits : 0;
>>   	ext4_fc_track_range(handle, inode, start_lblk, EXT_MAX_BLOCKS - 1);
>>   
>> -	ext4_set_inode_size(inode, newsize);
>> +	down_write(&EXT4_I(inode)->i_data_sem);
>> +	/*
>> +	 * Truncate the zeroed EOF block invalidates the pending disksize
>> +	 * update, so clear the disksize-grow-pending state.
>> +	 */
>> +	if (ext4_test_inode_state(inode, EXT4_STATE_DISKSIZE_GROW_PENDING) &&
>> +	    (newsize <= EXT4_I(inode)->i_disksize))
>> +		ext4_iomap_clear_disksize_pending(inode);
> 
> [Severity: High]
> Is the EXT4_STATE_DISKSIZE_GROW_PENDING bit ever set anywhere in the
> codebase?
> 
> A search of the tree indicates the literal EXT4_STATE_DISKSIZE_GROW_PENDING
> is only ever read or cleared, never set via ext4_set_inode_state() or
> similar.
> 
> There is a TODO comment in ext4_block_zero_eof() indicating that this state
> should be set:
> 
> 	/*
> 	 * TODO: In the iomap path, handle this by tracking the ordered
> 	 * range and updating i_disksize to i_size after the zeroed data
> 	 * has been written back.
> 	 */
> 
> If the bit is never actually set, won't this entire deferred disksize update
> mechanism be non-functional, leaving the filesystem vulnerable to the stale
> data exposure this patchset was intended to fix?
> 
>> +
>> +	i_size_write(inode, newsize);
>> +	__ext4_set_i_disksize(inode, newsize);
>> +	up_write(&EXT4_I(inode)->i_data_sem);
>>   
>>   	ret = ext4_mark_inode_dirty(handle, inode);
>>   	ext4_journal_stop(handle);
>
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.