]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: reimplement copy using read_iterate
authorSage Weil <sage@newdream.net>
Mon, 22 Aug 2011 23:53:45 +0000 (16:53 -0700)
committerSage Weil <sage@newdream.net>
Mon, 22 Aug 2011 23:53:55 +0000 (16:53 -0700)
Ah, so much simpler!

Signed-off-by: Sage Weil <sage@newdream.net>
src/librbd.cc

index f0e35505b1511ae7ff6d6e2e90181202d6092656..2c2ef94384a378f27b2a71aa24a7e06214000994 100644 (file)
@@ -1012,20 +1012,19 @@ int snap_rollback(ImageCtx *ictx, const char *snap_name)
   return 0;
 }
 
+int do_copy_extent(uint64_t offset, size_t len, const char *buf, void *destictx)
+{
+  if (buf)
+    return write((ImageCtx *)destictx, offset, len, buf);
+  else
+    return 0;  /* do nothing for holes */
+}
+
 int copy(ImageCtx& ictx, IoCtx& dest_md_ctx, const char *destname)
 {
   CephContext *cct = dest_md_ctx.cct();
 
-  uint64_t src_size;
-  if (ictx.snapname.length()) {
-    map<std::string,SnapInfo>::iterator p = ictx.snaps_by_name.find(ictx.snapname);
-    assert(p != ictx.snaps_by_name.end());
-    src_size = p->second.size;
-  } else {
-    src_size = ictx.header.image_size;
-  }
-
-  uint64_t numseg = get_max_block(src_size, ictx.header.options.order);
+  uint64_t src_size = ictx.get_image_size();
 
   int order = ictx.header.options.order;
   int r = create(dest_md_ctx, destname, src_size, &order);
@@ -1041,40 +1040,7 @@ int copy(ImageCtx& ictx, IoCtx& dest_md_ctx, const char *destname)
     return r;
   }
 
-  uint64_t block_size = get_block_size(ictx.header);
-
-  for (uint64_t i = 0; i < numseg; i++) {
-    bufferlist bl;
-    string oid = get_block_oid(ictx.header, i);
-    map<uint64_t, uint64_t> m;
-    r = ictx.data_ctx.sparse_read(oid, m, bl, block_size, 0);
-    if (r < 0 && r == -ENOENT)
-      r = 0;
-    if (r < 0)
-      goto done;
-
-    uint64_t blpos = 0;
-    for (map<uint64_t, uint64_t>::iterator iter = m.begin(); iter != m.end(); ++iter) {
-      ldout(cct, 0) << " " << i << " " <<  iter->first << "~" << iter->second << dendl;
-      uint64_t extent_ofs = iter->first;
-      size_t extent_len = iter->second;
-      bufferlist wrbl;
-      if (blpos + extent_len > bl.length()) {
-       lderr(cct) << "data error!" << dendl;
-       r = -EIO;
-       goto done;
-      }
-      bl.copy(blpos, extent_len, wrbl);
-      blpos += extent_len;
-      r = write(destictx, i * block_size + extent_ofs, extent_len, wrbl.c_str());
-      if (r < 0)
-       goto done;
-    }
-    ldout(cct, 0) << i + 1 << "/" << numseg << " objects copied" << dendl;
-  }
-  r = 0;
-
- done:
+  r = read_iterate(&ictx, 0, src_size, do_copy_extent, destictx);
   close_image(destictx);
   return r;
 }