On Thu, Feb 22, 2024 at 2:21 PM <xiubli@xxxxxxxxxx> wrote: > > From: Xiubo Li <xiubli@xxxxxxxxxx> > > If hits the EOF it will revise the return value to the i_size > instead of the real length read, but it will advance the offset > of iovc, then for the next try it may be incorrectly skipped. > > This will just skip advancing the iovc's offset more than i_size. > > URL: https://patchwork.kernel.org/project/ceph-devel/list/?series=819323 > Reported-by: Frank Hsiao 蕭法宣 <frankhsiao@xxxxxxxx> > Signed-off-by: Xiubo Li <xiubli@xxxxxxxxxx> > --- > fs/ceph/file.c | 18 ++++++++---------- > 1 file changed, 8 insertions(+), 10 deletions(-) > > diff --git a/fs/ceph/file.c b/fs/ceph/file.c > index 71d29571712d..2b2b07a0a61b 100644 > --- a/fs/ceph/file.c > +++ b/fs/ceph/file.c > @@ -1195,7 +1195,7 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos, > } > > idx = 0; > - left = ret > 0 ? ret : 0; > + left = ret > 0 ? umin(ret, i_size) : 0; Hi Xiubo, Can ret (i.e. the number of bytes actually read) be compared to i_size without taking the offset into account? How does this a handle a case where e.g. off = 20 ret = 10 i_size = 25 Did you intend the copy_page_to_iter() loop to go over 10 bytes and therefore advance the iovc ("to") by 10 instead of 5 bytes here? Thanks, Ilya