[lustre-devel] [PATCH 01/27] lustre: llite: fix the wrong beyond read end calculation
James Simmons <[email protected]> Mon, 17 Apr 2023 09:46:57 -0400
| Newsgroups | org.lustre.lists.lustre-devel |
|---|---|
| Message-ID | <[email protected]> |
From: Qian Yingjin <[email protected]> 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: c9f68ebdc6 ("lustre: llite: check read page past requested") WC-bug-id: https://jira.whamcloud.com/browse/LU-16579 Lustre-commit: ae356dc325877bd13 ("LU-16579 llite: fix the wrong beyond read end calculation") Signed-off-by: Qian Yingjin <[email protected]> Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/50065 Reviewed-by: Andreas Dilger <[email protected]> Reviewed-by: Patrick Farrell <[email protected]> Reviewed-by: Oleg Drokin <[email protected]> Signed-off-by: James Simmons <[email protected]> --- fs/lustre/llite/llite_internal.h | 3 +-- fs/lustre/llite/rw.c | 11 +++-------- fs/lustre/llite/vvp_io.c | 6 ++---- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/fs/lustre/llite/llite_internal.h b/fs/lustre/llite/llite_internal.h index 72de8f7..d8eee75 100644 --- a/fs/lustre/llite/llite_internal.h +++ b/fs/lustre/llite/llite_internal.h @@ -1375,8 +1375,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/fs/lustre/llite/rw.c b/fs/lustre/llite/rw.c index d285ae1..0c73258 100644 --- a/fs/lustre/llite/rw.c +++ b/fs/lustre/llite/rw.c @@ -1863,9 +1863,7 @@ int ll_readpage(struct file *file, struct page *vmpage) struct cl_read_ahead ra = { 0 }; struct ll_cl_context *lcc; struct cl_io *io = NULL; - struct iov_iter *iter; struct cl_page *page; - struct kiocb *iocb; int result; if (OBD_FAIL_PRECHECK(OBD_FAIL_LLITE_READPAGE_PAUSE)) { @@ -1974,11 +1972,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: @@ -2004,7 +1999,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/fs/lustre/llite/vvp_io.c b/fs/lustre/llite/vvp_io.c index 561ce66..50c2872 100644 --- a/fs/lustre/llite/vvp_io.c +++ b/fs/lustre/llite/vvp_io.c @@ -871,10 +871,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); out: -- 1.8.3.1 _______________________________________________ lustre-devel mailing list [email protected] http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org