int librbd::RBDClient::write(PoolCtx *ctx, ImageCtx *ictx, off_t off, size_t len, const char *buf)
{
+ if (!len)
+ return 0;
+
int r, total_write = 0;
uint64_t start_block = get_block_num(&ictx->header, off);
- uint64_t end_block = get_block_num(&ictx->header, off + len);
+ uint64_t end_block = get_block_num(&ictx->header, off + len - 1);
uint64_t block_size = get_block_size(&ictx->header);
uint64_t left = len;
if ((uint64_t)r != write_len)
return -EIO;
total_write += write_len;
+ left -= write_len;
}
return total_write;
}
ret = write(fd, buf, len);
if (ret < 0)
return -errno;
+
+ cerr << "writing " << len << " bytes at ofs " << ofs << std::endl;
return 0;
}
return r;
r = rbd.read_iterate(image, 0, info.size, export_read_cb, (void *)&fd);
-
- close(fd);
if (r < 0)
return r;
if (r < 0)
return r;
+ close(fd);
+
return 0;
}
cerr << "failed to open image" << std::endl;
return r;
}
-
+ fsync(fd); /* flush it first, otherwise extents information might not have been flushed yet */
fiemap = read_fiemap(fd);
+ if (fiemap && !fiemap->fm_mapped_extents) {
+ cerr << "empty fiemap!" << std::endl;
+ free(fiemap);
+ fiemap = NULL;
+ }
if (!fiemap) {
fiemap = (struct fiemap *)malloc(sizeof(struct fiemap) + sizeof(struct fiemap_extent));
if (!fiemap) {
cerr << "rbd import file_pos=" << file_pos << " extent_len=" << extent_len << std::endl;
#define READ_BLOCK_LEN (4 * 1024 * 1024)
- uint64_t left = extent_len;
+ uint64_t left = end_ofs - file_pos;
while (left) {
uint64_t cur_seg = (left < READ_BLOCK_LEN ? left : READ_BLOCK_LEN);
while (cur_seg) {
bufferptr p(cur_seg);
cerr << "reading " << cur_seg << " bytes at offset " << file_pos << std::endl;
ssize_t rval = TEMP_FAILURE_RETRY(::pread(fd, p.c_str(), cur_seg, file_pos));
- if (ret < 0) {
+ if (rval < 0) {
r = -errno;
cerr << "error reading file: " << cpp_strerror(r) << std::endl;
goto done;
}
len = rval
+ if (!len) {
+ r = 0;
+ goto done;
+ }
bufferlist bl;
bl.append(p);
-
r = rbd.write(image, file_pos, len, bl);
if (r < 0) {
cerr << "error writing to image block" << std::endl;