Message ID | 20240123131204.1166101-2-xiubli@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | libceph: fix sparse-read failure bug | expand |
On Tue, 2024-01-23 at 21:12 +0800, xiubli@redhat.com wrote: > From: Xiubo Li <xiubli@redhat.com> > > Once this happens that means there have bugs. > > URL: https://tracker.ceph.com/issues/63586 > Signed-off-by: Xiubo Li <xiubli@redhat.com> > --- > net/ceph/osd_client.c | 13 +++++++++++-- > 1 file changed, 11 insertions(+), 2 deletions(-) > > diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c > index 9be80d01c1dc..6beab9be51e2 100644 > --- a/net/ceph/osd_client.c > +++ b/net/ceph/osd_client.c > @@ -5857,8 +5857,8 @@ static int osd_sparse_read(struct ceph_connection *con, > struct ceph_osd *o = con->private; > struct ceph_sparse_read *sr = &o->o_sparse_read; > u32 count = sr->sr_count; > - u64 eoff, elen; > - int ret; > + u64 eoff, elen, len = 0; > + int i, ret; > > switch (sr->sr_state) { > case CEPH_SPARSE_READ_HDR: > @@ -5909,6 +5909,13 @@ static int osd_sparse_read(struct ceph_connection *con, > /* Convert sr_datalen to host-endian */ > sr->sr_datalen = le32_to_cpu((__force __le32)sr->sr_datalen); > sr->sr_state = CEPH_SPARSE_READ_DATA; > + for (i = 0; i < count; i++) > + len += sr->sr_extent[i].len; > + if (sr->sr_datalen != len) { > + pr_warn_ratelimited("data len %u != extent len %llu\n", > + sr->sr_datalen, len); > + return -EREMOTEIO; > + } > fallthrough; > case CEPH_SPARSE_READ_DATA: > if (sr->sr_index >= count) { > @@ -5919,6 +5926,8 @@ static int osd_sparse_read(struct ceph_connection *con, > eoff = sr->sr_extent[sr->sr_index].off; > elen = sr->sr_extent[sr->sr_index].len; > > + sr->sr_datalen -= elen; > + > dout("[%d] ext %d off 0x%llx len 0x%llx\n", > o->o_osd, sr->sr_index, eoff, elen); > Reviewed-by: Jeff Layton <jlayton@kernel.org>
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 9be80d01c1dc..6beab9be51e2 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -5857,8 +5857,8 @@ static int osd_sparse_read(struct ceph_connection *con, struct ceph_osd *o = con->private; struct ceph_sparse_read *sr = &o->o_sparse_read; u32 count = sr->sr_count; - u64 eoff, elen; - int ret; + u64 eoff, elen, len = 0; + int i, ret; switch (sr->sr_state) { case CEPH_SPARSE_READ_HDR: @@ -5909,6 +5909,13 @@ static int osd_sparse_read(struct ceph_connection *con, /* Convert sr_datalen to host-endian */ sr->sr_datalen = le32_to_cpu((__force __le32)sr->sr_datalen); sr->sr_state = CEPH_SPARSE_READ_DATA; + for (i = 0; i < count; i++) + len += sr->sr_extent[i].len; + if (sr->sr_datalen != len) { + pr_warn_ratelimited("data len %u != extent len %llu\n", + sr->sr_datalen, len); + return -EREMOTEIO; + } fallthrough; case CEPH_SPARSE_READ_DATA: if (sr->sr_index >= count) { @@ -5919,6 +5926,8 @@ static int osd_sparse_read(struct ceph_connection *con, eoff = sr->sr_extent[sr->sr_index].off; elen = sr->sr_extent[sr->sr_index].len; + sr->sr_datalen -= elen; + dout("[%d] ext %d off 0x%llx len 0x%llx\n", o->o_osd, sr->sr_index, eoff, elen);