From: Yehuda Sadeh Date: Sat, 29 Jan 2011 01:07:53 +0000 (-0800) Subject: rbd: fix misc problems X-Git-Tag: v0.25~143^2~39 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0d8bcb14e940c8d219e25d80aa8a32abe85149b5;p=ceph.git rbd: fix misc problems --- diff --git a/src/common/fiemap.cc b/src/common/fiemap.cc index 23e614f69177..933d78bc186d 100644 --- a/src/common/fiemap.cc +++ b/src/common/fiemap.cc @@ -59,6 +59,11 @@ struct fiemap *read_fiemap(int fd) goto done_err; } + if (!fiemap->fm_mapped_extents) { + free(fiemap); + return NULL; + } + /* Read in the extents */ extents_size = sizeof(struct fiemap_extent) * (fiemap->fm_mapped_extents); diff --git a/src/librbd.cc b/src/librbd.cc index 026e6d6cad26..f0a36e3651a8 100644 --- a/src/librbd.cc +++ b/src/librbd.cc @@ -942,9 +942,12 @@ int librbd::RBDClient::read(PoolCtx *ctx, ImageCtx *ictx, off_t ofs, size_t len, 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; @@ -960,6 +963,7 @@ int librbd::RBDClient::write(PoolCtx *ctx, ImageCtx *ictx, off_t off, size_t len if ((uint64_t)r != write_len) return -EIO; total_write += write_len; + left -= write_len; } return total_write; } diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc index 5d344355027e..635c04f4b9f9 100644 --- a/src/os/FileStore.cc +++ b/src/os/FileStore.cc @@ -419,6 +419,8 @@ static int do_fiemap(int fd, off_t start, size_t len, struct fiemap **pfiemap) fiemap->fm_start = start; fiemap->fm_length = len; + fsync(fd); /* flush extents to disk if needed */ + if (ioctl(fd, FS_IOC_FIEMAP, fiemap) < 0) { ret = -errno; goto done_err; diff --git a/src/rbd.cc b/src/rbd.cc index 08c10f64cb43..01aa04eddf04 100644 --- a/src/rbd.cc +++ b/src/rbd.cc @@ -371,6 +371,8 @@ static int export_read_cb(off_t ofs, size_t len, const char *buf, void *arg) ret = write(fd, buf, len); if (ret < 0) return -errno; + + cerr << "writing " << len << " bytes at ofs " << ofs << std::endl; return 0; } @@ -387,8 +389,6 @@ static int do_export(librbd::image_t image, const char *path) return r; r = rbd.read_iterate(image, 0, info.size, export_read_cb, (void *)&fd); - - close(fd); if (r < 0) return r; @@ -396,6 +396,8 @@ static int do_export(librbd::image_t image, const char *path) if (r < 0) return r; + close(fd); + return 0; } @@ -500,8 +502,13 @@ static int do_import(librados::pool_t pool, const char *imgname, int *order, con 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) { @@ -544,22 +551,25 @@ static int do_import(librados::pool_t pool, const char *imgname, int *order, con 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;