Skip to content

Commit 3006137

Browse files
lxbszSasha Levin
authored and
Sasha Levin
committedMar 26, 2024
ceph: stop copying to iter at EOF on sync reads
[ Upstream commit 1065da2 ] If EOF is encountered, ceph_sync_read() return value is adjusted down according to i_size, but the "to" iter is advanced by the actual number of bytes read. Then, when retrying, the remainder of the range may be skipped incorrectly. Ensure that the "to" iter is advanced only until EOF. [ idryomov: changelog ] Fixes: c3d8e0b ("ceph: return the real size read when it hits EOF") Reported-by: Frank Hsiao <frankhsiao@qnap.com> Signed-off-by: Xiubo Li <xiubli@redhat.com> Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Tested-by: Frank Hsiao <frankhsiao@qnap.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent a4cbcc4 commit 3006137

File tree

1 file changed

+13
-10
lines changed

1 file changed

+13
-10
lines changed
 

‎fs/ceph/file.c

+13-10
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,12 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos,
11081108
}
11091109

11101110
idx = 0;
1111-
left = ret > 0 ? ret : 0;
1111+
if (ret <= 0)
1112+
left = 0;
1113+
else if (off + ret > i_size)
1114+
left = i_size - off;
1115+
else
1116+
left = ret;
11121117
while (left > 0) {
11131118
size_t plen, copied;
11141119

@@ -1137,15 +1142,13 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos,
11371142
}
11381143

11391144
if (ret > 0) {
1140-
if (off > *ki_pos) {
1141-
if (off >= i_size) {
1142-
*retry_op = CHECK_EOF;
1143-
ret = i_size - *ki_pos;
1144-
*ki_pos = i_size;
1145-
} else {
1146-
ret = off - *ki_pos;
1147-
*ki_pos = off;
1148-
}
1145+
if (off >= i_size) {
1146+
*retry_op = CHECK_EOF;
1147+
ret = i_size - *ki_pos;
1148+
*ki_pos = i_size;
1149+
} else {
1150+
ret = off - *ki_pos;
1151+
*ki_pos = off;
11491152
}
11501153

11511154
if (last_objver)

0 commit comments

Comments
 (0)