]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: get rid of AIO_STATE_CALLBACK in AioCompletion 58591/head
authorIlya Dryomov <idryomov@gmail.com>
Mon, 15 Jul 2024 09:39:11 +0000 (11:39 +0200)
committerIlya Dryomov <idryomov@gmail.com>
Wed, 17 Jul 2024 08:13:53 +0000 (10:13 +0200)
After commit 002afa0fe375 ("librbd: avoid using lock within AIO
completion where possible"), the only method whose behavior would
change if AIO_STATE_CALLBACK is removed is is_complete() and it
actually needs fixing anyway: because of state != AIO_STATE_PENDING
test, is_complete() returns true both for AIO_STATE_CALLBACK and
AIO_STATE_COMPLETE, while wait_for_complete() still blocks on
AIO_STATE_CALLBACK and returns only on AIO_STATE_COMPLETE.  These
methods back public APIs, so this inconsistency is exposed to users.

If we move to setting state to AIO_STATE_COMPLETE at the top of
mark_complete_and_notify() (i.e. before event socket notification), the
transient state for callbacks can be eliminated entirely and the
inconsistency goes away.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
src/librbd/io/AioCompletion.cc
src/librbd/io/AioCompletion.h

index 7164d98c2594eddbb26af4e8da9b28dc14f40a21..5452edf5fd37d15e5a175cf2569a58b054583fd5 100644 (file)
@@ -97,7 +97,6 @@ void AioCompletion::complete() {
     }
   }
 
-  state = AIO_STATE_CALLBACK;
   if (complete_cb) {
     if (external_callback) {
       complete_external_callback();
@@ -238,7 +237,7 @@ void AioCompletion::complete_request(ssize_t r)
 
 bool AioCompletion::is_complete() {
   tracepoint(librbd, aio_is_complete_enter, this);
-  bool done = (this->state != AIO_STATE_PENDING);
+  bool done = (this->state == AIO_STATE_COMPLETE);
   tracepoint(librbd, aio_is_complete_exit, done);
   return done;
 }
@@ -263,13 +262,13 @@ void AioCompletion::complete_external_callback() {
 }
 
 void AioCompletion::mark_complete_and_notify() {
+  state = AIO_STATE_COMPLETE;
+
   if (ictx != nullptr && event_notify && ictx->event_socket.is_valid()) {
     ictx->event_socket_completions.push(this);
     ictx->event_socket.notify();
   }
 
-  state = AIO_STATE_COMPLETE;
-
   {
     std::unique_lock<std::mutex> locker(lock);
     cond.notify_all();
index 9afced7e2be95ac19dbc507e27ba63d2c2a5e50b..d98055878cd9aed452a4d285cfbb2e08ad5ca940 100644 (file)
@@ -40,7 +40,6 @@ namespace io {
 struct AioCompletion {
   typedef enum {
     AIO_STATE_PENDING = 0,
-    AIO_STATE_CALLBACK,
     AIO_STATE_COMPLETE,
   } aio_state_t;