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);
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;
}