From: Qian Yingjin Date: Mon, 20 Feb 2023 03:11:54 +0000 (-0500) Subject: LU-16579 llite: fix the wrong beyond read end calculation X-Git-Tag: 2.15.55~83 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=ae356dc325877bd130ad94acc5f3610898de8a8a;p=fs%2Flustre-release.git LU-16579 llite: fix the wrong beyond read end calculation During the test, we found a dead loop in the read path which retruns AOP_TRUNCATED_PAGE(0x8001) endless. The reason is that the calculation of the ending beyond offset is wrong: (iter->count + iocb->ki_pos). The ending beyond offset was supposed to be not changed during the read I/O loop for each page in buffered I/O mode. However, @iter->count is decreased with read bytes when finished the read of each page: @iter->count -= read_bytes. In this patch, we store the ending beyond page index in @lcc->lcc_end_index before call @generic_file_read_iter into a loop for each read page and solve this bug. Fixes: 2f8f38effa ("LU-16412 llite: check read page past requested") Signed-off-by: Qian Yingjin Change-Id: I5bb7ab82e5e2de8b9bd911798fb8ae65fc7c91af Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/50065 Reviewed-by: Andreas Dilger Reviewed-by: Patrick Farrell Reviewed-by: Oleg Drokin Tested-by: jenkins Tested-by: Maloo --- diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 89edc09..bf632d4 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -1395,8 +1395,7 @@ struct ll_cl_context { struct cl_io *lcc_io; struct cl_page *lcc_page; enum lcc_type lcc_type; - struct kiocb *lcc_iocb; - struct iov_iter *lcc_iter; + pgoff_t lcc_end_index; }; struct ll_thread_info { diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index 49f1688..bad0150 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -1858,13 +1858,11 @@ int ll_readpage(struct file *file, struct page *vmpage) struct inode *inode = file_inode(file); struct cl_object *clob = ll_i2info(inode)->lli_clob; struct ll_sb_info *sbi = ll_i2sbi(inode); - const struct lu_env *env = NULL; + const struct lu_env *env = NULL; struct cl_read_ahead ra = { 0 }; struct ll_cl_context *lcc; - struct cl_io *io = NULL; - struct iov_iter *iter; + struct cl_io *io = NULL; struct cl_page *page; - struct kiocb *iocb; int result; ENTRY; @@ -1970,11 +1968,8 @@ int ll_readpage(struct file *file, struct page *vmpage) } if (lcc && lcc->lcc_type != LCC_MMAP) { - iocb = lcc->lcc_iocb; - iter = lcc->lcc_iter; - - CDEBUG(D_VFSTRACE, "pgno:%ld, cnt:%ld, pos:%lld\n", - vmpage->index, iter->count, iocb->ki_pos); + CDEBUG(D_VFSTRACE, "pgno:%ld, beyond read end_index:%ld\n", + vmpage->index, lcc->lcc_end_index); /* * This handles a kernel bug introduced in kernel 5.12: @@ -2000,7 +1995,7 @@ int ll_readpage(struct file *file, struct page *vmpage) * This should never occur except in kernels with the bug * mentioned above. */ - if (cl_offset(clob, vmpage->index) >= iter->count + iocb->ki_pos) { + if (vmpage->index >= lcc->lcc_end_index) { result = cl_io_read_ahead(env, io, vmpage->index, &ra); if (result < 0 || vmpage->index > ra.cra_end_idx) { cl_read_ahead_release(env, &ra); diff --git a/lustre/llite/vvp_io.c b/lustre/llite/vvp_io.c index e19db59..7fa452e 100644 --- a/lustre/llite/vvp_io.c +++ b/lustre/llite/vvp_io.c @@ -889,10 +889,8 @@ static int vvp_io_read_start(const struct lu_env *env, iter = *vio->vui_iter; lcc = ll_cl_find(inode); - lcc->lcc_iter = &iter; - lcc->lcc_iocb = vio->vui_iocb; - CDEBUG(D_VFSTRACE, "cnt:%ld,iocb pos:%lld\n", lcc->lcc_iter->count, - lcc->lcc_iocb->ki_pos); + lcc->lcc_end_index = DIV_ROUND_UP(pos + iter.count, PAGE_SIZE); + CDEBUG(D_VFSTRACE, "count:%ld iocb pos:%lld\n", iter.count, pos); result = generic_file_read_iter(vio->vui_iocb, &iter);