From 9951868fc33f0469cd4135fadebb5a8d2b4b55dd Mon Sep 17 00:00:00 2001 From: Yin Congmin Date: Wed, 29 Sep 2021 13:47:17 +0800 Subject: [PATCH] librbd/cache/pwl: cancel advance dispatch of external flush request For external flush request, it new syncpoint after passing guardedrequest and before dispatch. Then dispatch bypass deferred queue But the last write request may still in the deferred queue. It don't dispatch and not associated with any syncpoint. The external flush request will bypass the previous write request in deferred queue now. This does not conform to the semantics of external flush requests. External flush request should strictly follow the order of dispath. But for internal flush request, it will be dispatched after all write request which associated with previous syncpoint, persisted in cache. C_gather guarantee it. It is necessary to distinguish between external and internal flush requests. Internal flush can and should be dispatched in advance bypass deferred queue. At the same time, the order of external requests needs to be kept unchanged. So cancel advance dispatch of external flush request. Fixes: https://tracker.ceph.com/issues/52599 Signed-off-by: Yin Congmin --- src/librbd/cache/pwl/AbstractWriteLog.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librbd/cache/pwl/AbstractWriteLog.cc b/src/librbd/cache/pwl/AbstractWriteLog.cc index c01d2d411f9..bfc605285f2 100644 --- a/src/librbd/cache/pwl/AbstractWriteLog.cc +++ b/src/librbd/cache/pwl/AbstractWriteLog.cc @@ -1440,8 +1440,9 @@ void AbstractWriteLog::alloc_and_dispatch_io_req(C_BlockIORequestT *req) std::lock_guard locker(m_lock); dispatch_here = m_deferred_ios.empty(); // Only flush req's total_bytes is the max uint64 - if ((req->image_extents_summary.total_bytes == - std::numeric_limits::max())) { + if (req->image_extents_summary.total_bytes == + std::numeric_limits::max() && + static_cast(req)->internal == true) { dispatch_here = true; } } -- 2.39.5