From e050b91c6c471d3576eba3bbf4f3c31aef644e3f Mon Sep 17 00:00:00 2001 From: Bobi Jam Date: Fri, 13 Jan 2023 12:36:01 +0800 Subject: [PATCH] LU-16468 llite: protect layout before read IO going It's possible that the before the read IO, file_read_confine_iter() ->lov_attr_get() to get proper kms (known minimum size of the file), and lov_attr_get() presumes that it's called under ongoing IO, which protected the layout from changing, while it's not in this case. Signed-off-by: Bobi Jam Change-Id: I1b36ec6e158331e63e8026ee2b986d5a7e3cb6dc Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/49622 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Mikhail Pershin Reviewed-by: Yang Sheng Reviewed-by: Oleg Drokin --- lustre/llite/file.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/lustre/llite/file.c b/lustre/llite/file.c index d33f115..f7b852a 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -2038,20 +2038,36 @@ ll_do_fast_read(struct kiocb *iocb, struct iov_iter *iter) static int file_read_confine_iter(struct lu_env *env, struct kiocb *iocb, struct iov_iter *to) { + struct cl_io *io; struct cl_attr *attr = vvp_env_thread_attr(env); struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); struct ll_inode_info *lli = ll_i2info(inode); + struct cl_object *obj = lli->lli_clob; loff_t read_end = iocb->ki_pos + iov_iter_count(to); loff_t kms; loff_t size; - int rc; + int rc = 0; + + ENTRY; + + if (!obj) + RETURN(rc); + + io = vvp_env_thread_io(env); + io->ci_obj = obj; + rc = cl_io_init(env, io, CIT_MISC, obj); + if (rc < 0) + GOTO(fini_io, rc); cl_object_attr_lock(lli->lli_clob); rc = cl_object_attr_get(env, lli->lli_clob, attr); cl_object_attr_unlock(lli->lli_clob); - if (rc != 0) - return rc; + +fini_io: + cl_io_fini(env, io); + if (rc < 0) + RETURN(rc); kms = attr->cat_kms; /* if read beyond end-of-file, adjust read count */ @@ -2068,14 +2084,14 @@ static int file_read_confine_iter(struct lu_env *env, struct kiocb *iocb, iocb->ki_pos, read_end, kms, size); if (iocb->ki_pos >= size) - return 1; + RETURN(1); if (read_end > size) iov_iter_truncate(to, size - iocb->ki_pos); } } - return rc; + RETURN(rc); } /* -- 1.8.3.1