]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: fix misc problems
authorYehuda Sadeh <yehuda.sadeh@dreamhost.com>
Sat, 29 Jan 2011 01:07:53 +0000 (17:07 -0800)
committerYehuda Sadeh <yehuda.sadeh@dreamhost.com>
Mon, 7 Feb 2011 23:13:01 +0000 (15:13 -0800)
src/common/fiemap.cc
src/librbd.cc
src/os/FileStore.cc
src/rbd.cc

index 23e614f691770fd35f28f4435eaf9bee060ec43d..933d78bc186d4f74c6cf0e218a8916014fadeb15 100644 (file)
@@ -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);
 
index 026e6d6cad26fc141ed758f7174d652bcc5b75b7..f0a36e3651a81f126d6290cf0fba09b5023d1a22 100644 (file)
@@ -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;
 }
index 5d344355027e1f2438f6c082c5461215807e9bc4..635c04f4b9f92111854d0bc246f57243a82f504c 100644 (file)
@@ -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;
index 08c10f64cb430859c896e7bf259130efa17c0cdc..01aa04eddf0475d005365d10e151555192581f0d 100644 (file)
@@ -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;