]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: call user completion after incrementing perfcounters 1000/head
authorJosh Durgin <josh.durgin@inktank.com>
Fri, 27 Dec 2013 01:38:52 +0000 (17:38 -0800)
committerJosh Durgin <josh.durgin@inktank.com>
Fri, 27 Dec 2013 01:40:34 +0000 (17:40 -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>
src/librbd/AioCompletion.h

index c67a44fa50eef5940cb003970097d34bc022b782..aaccefef9fceec64bcc60b70115bede92582904f 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();
     }