]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: cannot clone all image-metas if we have more than 64 key/value pairs
authorPCzhangPC <pengcheng.zhang@easystack.cn>
Fri, 20 Oct 2017 06:21:09 +0000 (14:21 +0800)
committerJason Dillaman <dillaman@redhat.com>
Tue, 3 Apr 2018 23:28:50 +0000 (19:28 -0400)
Signed-off-by: PCzhangPC <pengcheng.zhang@easystack.cn>
(cherry picked from commit ccc56384032be7f6bd48e28b6825b3ce589c7cf7)

Conflicts:
src/librbd/image/CloneRequest.h/cc: logic exists in internal.cc

src/librbd/internal.cc

index 52e3dd9192e5ce8d42ffc3a5303cf3195963077e..8496545826b43b47c7f968f776d88eb7e05cafbc 100644 (file)
@@ -1529,6 +1529,8 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
     int partial_r;
     librbd::NoOpProgressContext no_op;
     ImageCtx *c_imctx = NULL;
+    std::string last_metadata_key;
+    const size_t max_metadata_keys = 64;
     map<string, bufferlist> pairs;
     parent_spec pspec(p_imctx->md_ctx.get_id(), p_imctx->id, p_imctx->snap_id);
 
@@ -1622,17 +1624,27 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
       goto err_remove_child;
     }
 
-    r = cls_client::metadata_list(&p_imctx->md_ctx, p_imctx->header_oid, "", 0,
-                                  &pairs);
-    if (r < 0 && r != -EOPNOTSUPP && r != -EIO) {
-      lderr(cct) << "couldn't list metadata: " << cpp_strerror(r) << dendl;
-      goto err_remove_child;
-    } else if (r == 0 && !pairs.empty()) {
+    while (true) {
+      r = cls_client::metadata_list(&p_imctx->md_ctx, p_imctx->header_oid,
+                                    last_metadata_key, max_metadata_keys,
+                                    &pairs);
+      if (r == -EOPNOTSUPP || r == -EIO) {
+        break;
+      } else if (r < 0) {
+        lderr(cct) << "couldn't list metadata: " << cpp_strerror(r) << dendl;
+        goto err_remove_child;
+      }
+
       r = cls_client::metadata_set(&c_ioctx, c_imctx->header_oid, pairs);
       if (r < 0) {
         lderr(cct) << "couldn't set metadata: " << cpp_strerror(r) << dendl;
         goto err_remove_child;
       }
+
+      if (pairs.size() < max_metadata_keys) {
+        break;
+      }
+      last_metadata_key = pairs.rbegin()->first;
     }
 
     ldout(cct, 2) << "done." << dendl;