| From a2b0b205d125f27cddfb4f7280e39affdaf46686 Mon Sep 17 00:00:00 2001 |
| From: Ye Bin <yebin10@huawei.com> |
| Date: Mon, 21 Mar 2022 22:44:38 +0800 |
| Subject: ext4: fix symlink file size not match to file content |
| |
| From: Ye Bin <yebin10@huawei.com> |
| |
| commit a2b0b205d125f27cddfb4f7280e39affdaf46686 upstream. |
| |
| We got issue as follows: |
| [home]# fsck.ext4 -fn ram0yb |
| e2fsck 1.45.6 (20-Mar-2020) |
| Pass 1: Checking inodes, blocks, and sizes |
| Pass 2: Checking directory structure |
| Symlink /p3/d14/d1a/l3d (inode #3494) is invalid. |
| Clear? no |
| Entry 'l3d' in /p3/d14/d1a (3383) has an incorrect filetype (was 7, should be 0). |
| Fix? no |
| |
| As the symlink file size does not match the file content. If the writeback |
| of the symlink data block failed, ext4_finish_bio() handles the end of IO. |
| However this function fails to mark the buffer with BH_write_io_error and |
| so when unmount does journal checkpoint it cannot detect the writeback |
| error and will cleanup the journal. Thus we've lost the correct data in the |
| journal area. To solve this issue, mark the buffer as BH_write_io_error in |
| ext4_finish_bio(). |
| |
| Cc: stable@kernel.org |
| Signed-off-by: Ye Bin <yebin10@huawei.com> |
| Reviewed-by: Jan Kara <jack@suse.cz> |
| Link: https://lore.kernel.org/r/20220321144438.201685-1-yebin10@huawei.com |
| Signed-off-by: Theodore Ts'o <tytso@mit.edu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| fs/ext4/page-io.c | 4 +++- |
| 1 file changed, 3 insertions(+), 1 deletion(-) |
| |
| --- a/fs/ext4/page-io.c |
| +++ b/fs/ext4/page-io.c |
| @@ -100,8 +100,10 @@ static void ext4_finish_bio(struct bio * |
| continue; |
| } |
| clear_buffer_async_write(bh); |
| - if (bio->bi_status) |
| + if (bio->bi_status) { |
| + set_buffer_write_io_error(bh); |
| buffer_io_error(bh); |
| + } |
| } while ((bh = bh->b_this_page) != head); |
| bit_spin_unlock(BH_Uptodate_Lock, &head->b_state); |
| local_irq_restore(flags); |