]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd/migration/NBDStream: introduce from_nbd_errno()
authorIlya Dryomov <idryomov@gmail.com>
Mon, 2 Sep 2024 20:11:29 +0000 (22:11 +0200)
committerIlya Dryomov <idryomov@gmail.com>
Wed, 21 May 2025 15:27:16 +0000 (17:27 +0200)
Errors returned by nbd_get_errno() can't be used to complete Contexts
directly because a) these errors are positive while complete() in most
cases expects a negative error and b) nbd_get_errno() can return 0 even
after libnbd call fails (i.e. returns -1).

Introduce a helper with EIO as a default/fallback error.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
(cherry picked from commit 1b12f4603e5a5137e48b795565d7d807b73158ec)

src/librbd/migration/NBDStream.cc

index a1e8bcf57d24fe8bb5e444cd635ca625bc27a60b..2513f156efdbce19e887dddb50f998300c7b4549 100644 (file)
@@ -17,6 +17,14 @@ namespace {
 const std::string SERVER_KEY {"server"};
 const std::string PORT_KEY {"port"};
 
+int from_nbd_errno(int rc) {
+  // nbd_get_errno() needs a default/fallback error:
+  // "Even when a call returns an error, nbd_get_errno() might return 0.
+  // This does not mean there was no error. It means no additional errno
+  // information is available for this error."
+  return rc > 0 ? -rc : -EIO;
+}
+
 int extent_cb(void* data, const char* metacontext, uint64_t offset,
               uint32_t* entries, size_t nr_entries, int* error) {
   auto sparse_extents = reinterpret_cast<io::SparseExtents*>(data);
@@ -86,7 +94,7 @@ struct NBDStream<I>::ReadRequest {
       lderr(cct) << "pread " << byte_offset << "~" << byte_length << ": "
                  << nbd_get_error() << " (errno = " << rc << ")"
                  << dendl;
-      finish(rc);
+      finish(from_nbd_errno(rc));
       return;
     }
 
@@ -222,24 +230,28 @@ void NBDStream<I>::open(Context* on_finish) {
 
   m_nbd = nbd_create();
   if (m_nbd == nullptr) {
-    lderr(m_cct) << "failed to create nbd object '" << dendl;
-    on_finish->complete(-EINVAL);
+    rc = nbd_get_errno();
+    lderr(m_cct) << "create: " << nbd_get_error()
+                 << " (errno = " << rc << ")" << dendl;
+    on_finish->complete(from_nbd_errno(rc));
     return;
   }
 
   rc = nbd_add_meta_context(m_nbd, LIBNBD_CONTEXT_BASE_ALLOCATION);
   if (rc == -1) {
-    lderr(m_cct) << "failed to add nbd meta context '" << dendl;
-    on_finish->complete(-EINVAL);
+    rc = nbd_get_errno();
+    lderr(m_cct) << "add_meta_context: " << nbd_get_error()
+                 << " (errno = " << rc << ")" << dendl;
+    on_finish->complete(from_nbd_errno(rc));
     return;
   }
 
   rc = nbd_connect_tcp(m_nbd, m_server, m_port);
   if (rc == -1) {
     rc = nbd_get_errno();
-    lderr(m_cct) << "failed to connect to nbd server: " << nbd_get_error()
-                 << " (errno=" << rc << ")" << dendl;
-    on_finish->complete(rc);
+    lderr(m_cct) << "connect_tcp: " << nbd_get_error()
+                 << " (errno = " << rc << ")" << dendl;
+    on_finish->complete(from_nbd_errno(rc));
     return;
   }