From 2f25bfeaaff7a9a4914aa55fac6d14c6a3f84d2f Mon Sep 17 00:00:00 2001 From: Josh Durgin Date: Thu, 26 Dec 2013 17:38:52 -0800 Subject: [PATCH] librbd: call user completion after incrementing perfcounters The perfcounters (and the ictx) are only valid while the image is still open. If the librbd user gets the callback for its last I/O, then closes the image, the ictx and its perfcounters will be invalid. If the AioCompletion object is has not run the rest of its complete() method yet, it will access these now-invalid addresses, possibly leading to a crash. The AioCompletion object is independent of the ictx and does not access it again after incrementing perfcounters, so avoid this race by calling the user's callback after this step. The AioCompletion object will be cleaned up by the rest of complete_request(), independent of the ImageCtx. Fixes: #5426 Backport: dumpling, emperor Signed-off-by: Josh Durgin (cherry picked from commit 4cea7895da7331b84d8c6079851fdc0ff2f4afb1) --- src/librbd/AioCompletion.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librbd/AioCompletion.h b/src/librbd/AioCompletion.h index 899586d51a7a9..9f9389d0a96d8 100644 --- a/src/librbd/AioCompletion.h +++ b/src/librbd/AioCompletion.h @@ -101,9 +101,6 @@ namespace librbd { utime_t elapsed; assert(lock.is_locked()); elapsed = ceph_clock_now(ictx->cct) - start_time; - if (complete_cb) { - complete_cb(rbd_comp, complete_arg); - } switch (aio_type) { case AIO_TYPE_READ: ictx->perfcounter->tinc(l_librbd_aio_rd_latency, elapsed); break; @@ -117,6 +114,9 @@ namespace librbd { lderr(ictx->cct) << "completed invalid aio_type: " << aio_type << dendl; break; } + if (complete_cb) { + complete_cb(rbd_comp, complete_arg); + } done = true; cond.Signal(); } -- 2.39.5