If a snapshot is created out-of-band, the next IO will result in the
cache being flushed. If pending writeback data performs a copy-on-write,
the read from the parent will be blocked.
Fixes: #15032
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit
f9e5ae80e3b0799b5a7e1d3f93b2d85a4baff20f)
void C_CacheRead::complete(int r) {
if (!m_enqueued) {
// cache_lock creates a lock ordering issue -- so re-execute this context
- // outside the cache_lock
+ // outside the cache_lock. use the writeback handler's dedicated thread
+ // to avoid blocking a dependent operation
m_enqueued = true;
- m_image_ctx.op_work_queue->queue(this, r);
+ m_image_ctx.writeback_handler->queue(this, r);
return;
}
Context::complete(r);
delete m_finisher;
}
+ void LibrbdWriteback::queue(Context *ctx, int r) {
+ m_finisher->queue(ctx, r);
+ }
+
void LibrbdWriteback::read(const object_t& oid, uint64_t object_no,
const object_locator_t& oloc,
uint64_t off, uint64_t len, snapid_t snapid,
{
if (!m_ictx->object_map.object_may_exist(object_no)) {
- m_finisher->queue(req, -ENOENT);
+ queue(req, -ENOENT);
return;
}
}
LibrbdWriteback(ImageCtx *ictx, Mutex& lock);
virtual ~LibrbdWriteback();
+ void queue(Context *ctx, int r);
+
// Note that oloc, trunc_size, and trunc_seq are ignored
virtual void read(const object_t& oid, uint64_t object_no,
const object_locator_t& oloc, uint64_t off, uint64_t len,