From: Yu Kuai yukuai3@huawei.com
hulk inclusion category: bugfix bugzilla: 186896, https://gitee.com/src-openeuler/kernel/issues/I5FRAP CVE: NA
--------------------------------
In filemap_read(), first page will not mark accessed if previous page is equal to the current page:
if (iocb->ki_pos >> PAGE_SHIFT != ra->prev_pos >> PAGE_SHIFT)) folio_mark_accessed(fbatch.folios[0]);
However, 'prev_pos' is set to 'ki_pos + copied' during last read, which means 'prev_pos' can be equal to 'ki_pos' in this read, thus previous page can be miscaculated.
Fix the problem by setting 'prev_pos' to the start offset of last read, so that 'prev_pos >> PAGE_SHIFT' will be previous page as expected.
Fixes: 06c0444290ce ("mm/filemap.c: generic_file_buffered_read() now uses find_get_pages_contig") Signed-off-by: Yu Kuai yukuai3@huawei.com Reviewed-by: Kefeng Wang wangkefeng.wang@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- mm/filemap.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/mm/filemap.c b/mm/filemap.c index 3958fc3280d8..9653c1e0faef 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2549,10 +2549,11 @@ ssize_t generic_file_buffered_read(struct kiocb *iocb, flush_dcache_page(pages[i]);
copied = copy_page_to_iter(pages[i], offset, bytes, iter); - - written += copied; - iocb->ki_pos += copied; - ra->prev_pos = iocb->ki_pos; + if (copied) { + ra->prev_pos = iocb->ki_pos; + written += copied; + iocb->ki_pos += copied; + }
if (copied < bytes) { error = -EFAULT;