mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 23:13:01 +02:00
ext4: Make sure BH_New bit is cleared in ->write_end handler
Currently we clear BH_New bit in case of error and also in the standard
ext4_write_end() handler (in block_commit_write()). However
ext4_journalled_write_end() misses this clearing and thus we are leaving
stale BH_New bits behind. Generally ext4_block_write_begin() clears
these bits before any harm can be done but in case blocksize < pagesize
and we hit some error when processing a page with these stale bits,
we'll try to zero buffers with these stale BH_New bits and jbd2 will
complain (as buffers were not prepared for writing in this transaction).
Fix the problem by clearing BH_New bits in ext4_journalled_write_end()
and WARN if ext4_block_write_begin() sees stale BH_New bits.
Reported-by: Baolin Liu <liubaolin12138@163.com>
Reported-by: Zhi Long <longzhi@sangfor.com.cn>
Fixes: 3910b513fc
("ext4: persist the new uptodate buffers in ext4_journalled_zero_new_buffers")
Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20250709084831.23876-2-jack@suse.cz
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
c678bdc998
commit
91b8ca8b26
|
@ -612,6 +612,7 @@ retry:
|
|||
} else
|
||||
ret = ext4_block_write_begin(handle, folio, from, to,
|
||||
ext4_get_block);
|
||||
clear_buffer_new(folio_buffers(folio));
|
||||
|
||||
if (!ret && ext4_should_journal_data(inode)) {
|
||||
ret = ext4_walk_page_buffers(handle, inode,
|
||||
|
@ -891,6 +892,7 @@ static int ext4_da_convert_inline_data_to_extent(struct address_space *mapping,
|
|||
return ret;
|
||||
}
|
||||
|
||||
clear_buffer_new(folio_buffers(folio));
|
||||
folio_mark_dirty(folio);
|
||||
folio_mark_uptodate(folio);
|
||||
ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
|
||||
|
|
|
@ -1189,7 +1189,7 @@ int ext4_block_write_begin(handle_t *handle, struct folio *folio,
|
|||
}
|
||||
continue;
|
||||
}
|
||||
if (buffer_new(bh))
|
||||
if (WARN_ON_ONCE(buffer_new(bh)))
|
||||
clear_buffer_new(bh);
|
||||
if (!buffer_mapped(bh)) {
|
||||
WARN_ON(bh->b_size != blocksize);
|
||||
|
@ -1417,6 +1417,7 @@ static int write_end_fn(handle_t *handle, struct inode *inode,
|
|||
ret = ext4_dirty_journalled_data(handle, bh);
|
||||
clear_buffer_meta(bh);
|
||||
clear_buffer_prio(bh);
|
||||
clear_buffer_new(bh);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user