From: NeilBrown neilb@suse.de
mainline inclusion from mainline-v5.18-rc1 commit a64239d0ef345208d8c15d7841a028a43a34c068 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9L9NO CVE: CVE-2024-27034
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
As congestion is no longer tracked, congestion_wait() is effectively equivalent to io_schedule_timeout().
So introduce f2fs_io_schedule_timeout() which sets TASK_UNINTERRUPTIBLE and call that instead.
Link: https://lkml.kernel.org/r/164549983744.9187.6425865370954230902.stgit@noble.... Signed-off-by: NeilBrown neilb@suse.de Cc: Anna Schumaker Anna.Schumaker@Netapp.com Cc: Chao Yu chao@kernel.org Cc: Darrick J. Wong djwong@kernel.org Cc: Ilya Dryomov idryomov@gmail.com Cc: Jaegeuk Kim jaegeuk@kernel.org Cc: Jan Kara jack@suse.cz Cc: Jeff Layton jlayton@kernel.org Cc: Jens Axboe axboe@kernel.dk Cc: Lars Ellenberg lars.ellenberg@linbit.com Cc: Miklos Szeredi miklos@szeredi.hu Cc: Paolo Valente paolo.valente@linaro.org Cc: Philipp Reisner philipp.reisner@linbit.com Cc: Ryusuke Konishi konishi.ryusuke@gmail.com Cc: Trond Myklebust trond.myklebust@hammerspace.com Cc: Wu Fengguang fengguang.wu@intel.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Yifan Qiao qiaoyifan4@huawei.com --- fs/f2fs/f2fs.h | 6 ++++++ fs/f2fs/compress.c | 4 +--- fs/f2fs/data.c | 3 +-- fs/f2fs/segment.c | 8 +++----- fs/f2fs/super.c | 6 ++---- 5 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 26f12d9f7776..fdfb13285291 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -4155,6 +4155,12 @@ static inline void f2fs_truncate_meta_inode_pages(struct f2fs_sb_info *sbi, F2FS_BLK_END_BYTES((loff_t)(blkaddr + cnt - 1))); }
+static inline void f2fs_io_schedule_timeout(long timeout) +{ + set_current_state(TASK_UNINTERRUPTIBLE); + io_schedule_timeout(timeout); +} + #define EFSBADCRC EBADMSG /* Bad CRC detected */ #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index c99f1cc5c449..17223e75bd64 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -1418,9 +1418,7 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc, if (IS_NOQUOTA(cc->inode)) return 0; ret = 0; - cond_resched(); - congestion_wait(BLK_RW_ASYNC, - DEFAULT_IO_TIMEOUT); + f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT); goto retry_write; } return ret; diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index c0c30a32fd59..38efd3237463 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -3152,8 +3152,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping, } else if (ret == -EAGAIN) { ret = 0; if (wbc->sync_mode == WB_SYNC_ALL) { - cond_resched(); - congestion_wait(BLK_RW_ASYNC, + f2fs_io_schedule_timeout( DEFAULT_IO_TIMEOUT); goto retry_write; } diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index c5c011ee0429..428ad5b718c8 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -313,8 +313,7 @@ void f2fs_drop_inmem_pages_all(struct f2fs_sb_info *sbi, bool gc_failure) skip: iput(inode); } - congestion_wait(BLK_RW_ASYNC, DEFAULT_IO_TIMEOUT); - cond_resched(); + f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT); if (gc_failure) { if (++looped >= count) return; @@ -785,8 +784,7 @@ int f2fs_flush_device_cache(struct f2fs_sb_info *sbi) do { ret = __submit_flush_wait(sbi, FDEV(i).bdev); if (ret) - congestion_wait(BLK_RW_ASYNC, - DEFAULT_IO_TIMEOUT); + f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT); } while (ret && --count);
if (ret) { @@ -3068,7 +3066,7 @@ static unsigned int __issue_discard_cmd_range(struct f2fs_sb_info *sbi, blk_finish_plug(&plug); mutex_unlock(&dcc->cmd_lock); trimmed += __wait_all_discard_cmd(sbi, NULL); - congestion_wait(BLK_RW_ASYNC, DEFAULT_IO_TIMEOUT); + f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT); goto next; } skip: diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 9a74d60f61db..6a214366970c 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1808,8 +1808,7 @@ static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi) /* we should flush all the data to keep data consistency */ do { sync_inodes_sb(sbi->sb); - cond_resched(); - congestion_wait(BLK_RW_ASYNC, DEFAULT_IO_TIMEOUT); + f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT); } while (get_pages(sbi, F2FS_DIRTY_DATA) && retry--);
if (unlikely(retry < 0)) @@ -2099,8 +2098,7 @@ static ssize_t f2fs_quota_write(struct super_block *sb, int type, &page, &fsdata); if (unlikely(err)) { if (err == -ENOMEM) { - congestion_wait(BLK_RW_ASYNC, - DEFAULT_IO_TIMEOUT); + f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT); goto retry; } set_sbi_flag(F2FS_SB(sb), SBI_QUOTA_NEED_REPAIR);