From: Ilya Dryomov Date: Mon, 15 Aug 2022 07:44:09 +0000 (+0200) Subject: librbd/cache/pwl: adjust compare-and-write compare substringing X-Git-Tag: v17.2.6~440^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c4c4f7e763beeaf9d234d00ea198629e078ab1d5;p=ceph.git librbd/cache/pwl: adjust compare-and-write compare substringing cmp_bl can no longer be shorter than read_bl (i.e. image extent). This is caught very early at the API level, see commit af96e6dae3f4 ("librbd: make C++ cmp&write semantics equal to C API"). However, cmp_bl can still be longer than read_bl and in that case it should be capped by the image extent length. Signed-off-by: Ilya Dryomov (cherry picked from commit 35f3ccb68714f18cc1ff78278fdd5216590cc9bf) --- diff --git a/src/librbd/cache/pwl/AbstractWriteLog.cc b/src/librbd/cache/pwl/AbstractWriteLog.cc index 580726ddffc6..713fc3caf083 100644 --- a/src/librbd/cache/pwl/AbstractWriteLog.cc +++ b/src/librbd/cache/pwl/AbstractWriteLog.cc @@ -1068,12 +1068,11 @@ void AbstractWriteLog::compare_and_write(Extents &&image_extents, << "cw_req=" << cw_req << dendl; /* Compare read_bl to cmp_bl to determine if this will produce a write */ - buffer::list aligned_read_bl; - if (cw_req->cmp_bl.length() < cw_req->read_bl.length()) { - aligned_read_bl.substr_of(cw_req->read_bl, 0, cw_req->cmp_bl.length()); - } - if (cw_req->cmp_bl.contents_equal(cw_req->read_bl) || - cw_req->cmp_bl.contents_equal(aligned_read_bl)) { + ceph_assert(cw_req->read_bl.length() <= cw_req->cmp_bl.length()); + ceph_assert(cw_req->read_bl.length() == cw_req->image_extents_summary.total_bytes); + bufferlist sub_cmp_bl; + sub_cmp_bl.substr_of(cw_req->cmp_bl, 0, cw_req->read_bl.length()); + if (sub_cmp_bl.contents_equal(cw_req->read_bl)) { /* Compare phase succeeds. Begin write */ ldout(m_image_ctx.cct, 5) << " cw_req=" << cw_req << " compare matched" << dendl; cw_req->compare_succeeded = true; @@ -1087,8 +1086,8 @@ void AbstractWriteLog::compare_and_write(Extents &&image_extents, ldout(m_image_ctx.cct, 15) << " cw_req=" << cw_req << " compare failed" << dendl; /* Bufferlist doesn't tell us where they differed, so we'll have to determine that here */ uint64_t bl_index = 0; - for (bl_index = 0; bl_index < cw_req->cmp_bl.length(); bl_index++) { - if (cw_req->cmp_bl[bl_index] != cw_req->read_bl[bl_index]) { + for (bl_index = 0; bl_index < sub_cmp_bl.length(); bl_index++) { + if (sub_cmp_bl[bl_index] != cw_req->read_bl[bl_index]) { ldout(m_image_ctx.cct, 15) << " cw_req=" << cw_req << " mismatch at " << bl_index << dendl; break; }