]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: call user completion after incrementing perfcounters
authorJosh Durgin <josh.durgin@inktank.com>
Fri, 27 Dec 2013 01:38:52 +0000 (17:38 -0800)
committerJosh Durgin <josh.durgin@inktank.com>
Mon, 30 Dec 2013 17:16:38 +0000 (09:16 -0800)
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 <josh.durgin@inktank.com>
(cherry picked from commit 4cea7895da7331b84d8c6079851fdc0ff2f4afb1)

src/librbd/AioCompletion.h

index 899586d51a7a985203f45b549ded6cf25cef1664..9f9389d0a96d8b189245000e3e4b9a4aadf54269 100644 (file)
@@ -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();
     }