]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: add diff_iterate2 to API
authorJason Dillaman <dillaman@redhat.com>
Tue, 24 Mar 2015 17:20:32 +0000 (13:20 -0400)
committerJason Dillaman <dillaman@redhat.com>
Mon, 13 Apr 2015 01:17:32 +0000 (21:17 -0400)
New diff_iterate API supports skipping parent images and reporting
the object extents for an object that has been modified. The latter
will be helpful in providing an optimized diff method that can use
the object map to quickly compute object diffs between snapshots.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/include/rbd/librbd.h
src/include/rbd/librbd.hpp
src/librbd/internal.cc
src/librbd/internal.h
src/librbd/librbd.cc
src/tracing/librbd.tp

index 6a755b5d6b37e3cdde6a9935f5d13ca7cfdb329f..7157eaf766d181ded688e70fc909c15dc812d544 100644 (file)
@@ -389,6 +389,8 @@ CEPH_RBD_API int rbd_read_iterate2(rbd_image_t image, uint64_t ofs, uint64_t len
  * @param fromsnapname start snapshot name, or NULL
  * @param ofs start offset
  * @param len len in bytes of region to report on
+ * @param include_parent 1 if full history diff should include parent
+ * @param whole_object 1 if diff extents should cover whole object
  * @param cb callback to call for each allocated region
  * @param arg argument to pass to the callback
  * @returns 0 on success, or negative error code on error
@@ -398,6 +400,12 @@ CEPH_RBD_API int rbd_diff_iterate(rbd_image_t image,
                                  uint64_t ofs, uint64_t len,
                                  int (*cb)(uint64_t, size_t, int, void *),
                                   void *arg);
+CEPH_RBD_API int rbd_diff_iterate2(rbd_image_t image,
+                                  const char *fromsnapname,
+                                  uint64_t ofs, uint64_t len,
+                                   uint8_t include_parent, uint8_t whole_object,
+                                  int (*cb)(uint64_t, size_t, int, void *),
+                                   void *arg);
 CEPH_RBD_API ssize_t rbd_write(rbd_image_t image, uint64_t ofs, size_t len,
                                const char *buf);
 /*
index ea81b8fed51a1d9cac4b1a9a4e7b26dc006a4f6b..cf8b2e7b4e72a2cf9d3ca84e41c7d7ee78c1f494 100644 (file)
@@ -187,6 +187,8 @@ public:
    * @param fromsnapname start snapshot name, or NULL
    * @param ofs start offset
    * @param len len in bytes of region to report on
+   * @param include_parent true if full history diff should include parent
+   * @param whole_object 1 if diff extents should cover whole object
    * @param cb callback to call for each allocated region
    * @param arg argument to pass to the callback
    * @returns 0 on success, or negative error code on error
@@ -194,6 +196,11 @@ public:
   int diff_iterate(const char *fromsnapname,
                   uint64_t ofs, uint64_t len,
                   int (*cb)(uint64_t, size_t, int, void *), void *arg);
+  int diff_iterate2(const char *fromsnapname,
+                   uint64_t ofs, uint64_t len,
+                    bool include_parent, bool whole_object,
+                   int (*cb)(uint64_t, size_t, int, void *), void *arg);
+
   ssize_t write(uint64_t ofs, size_t len, ceph::bufferlist& bl);
   /* @parmam op_flags see librados.h constants beginning with LIBRADOS_OP_FLAG */
   ssize_t write2(uint64_t ofs, size_t len, ceph::bufferlist& bl, int op_flags);
index ac219ad3a7c58af02d3293460e20ad0f48ce21fa..188cddcecdbc784af758158d9bb5a0303343f75a 100644 (file)
@@ -2997,10 +2997,9 @@ reprotect_and_return_err:
   }
 
 
-  int diff_iterate(ImageCtx *ictx, const char *fromsnapname,
-                  uint64_t off, uint64_t len,
-                  int (*cb)(uint64_t, size_t, int, void *),
-                  void *arg)
+  int diff_iterate(ImageCtx *ictx, const char *fromsnapname, uint64_t off,
+                   uint64_t len, bool include_parent, bool whole_object,
+                  int (*cb)(uint64_t, size_t, int, void *), void *arg)
   {
     utime_t start_time, elapsed;
 
@@ -3057,7 +3056,7 @@ reprotect_and_return_err:
 
     // check parent overlap only if we are comparing to the beginning of time
     interval_set<uint64_t> parent_diff;
-    if (from_snap_id == 0) {
+    if (include_parent && from_snap_id == 0) {
       RWLock::RLocker l(ictx->snap_lock);
       RWLock::RLocker l2(ictx->parent_lock);
       uint64_t overlap = end_size;
@@ -3065,7 +3064,8 @@ reprotect_and_return_err:
       r = 0;
       if (ictx->parent && overlap > 0) {
        ldout(ictx->cct, 10) << " first getting parent diff" << dendl;
-       r = diff_iterate(ictx->parent, NULL, 0, overlap, simple_diff_cb, &parent_diff);
+       r = diff_iterate(ictx->parent, NULL, 0, overlap, include_parent,
+                         whole_object, simple_diff_cb, &parent_diff);
       }
       if (r < 0)
        return r;
@@ -3121,8 +3121,16 @@ reprotect_and_return_err:
                           end_snap_id,
                           &diff, &end_exists);
        ldout(ictx->cct, 20) << "  diff " << diff << " end_exists=" << end_exists << dendl;
-       if (diff.empty())
+       if (diff.empty()) {
          continue;
+        } else if (whole_object) {
+          // provide the full object extents to the callback
+          for (vector<ObjectExtent>::iterator q = p->second.begin();
+               q != p->second.end(); ++q) {
+            cb(off + q->offset, q->length, end_exists, arg);
+          }
+          continue;
+        }
 
        for (vector<ObjectExtent>::iterator q = p->second.begin(); q != p->second.end(); ++q) {
          ldout(ictx->cct, 20) << "diff_iterate object " << p->first
index 9f71f55da26cc5f9176ca95ce3801e943c71ab17..37f565e4524360bbc276986a496b529357b2cd99 100644 (file)
@@ -184,8 +184,8 @@ namespace librbd {
   int64_t read_iterate(ImageCtx *ictx, uint64_t off, uint64_t len,
                       int (*cb)(uint64_t, size_t, const char *, void *),
                       void *arg);
-  int diff_iterate(ImageCtx *ictx, const char *fromsnapname,
-                  uint64_t off, uint64_t len,
+  int diff_iterate(ImageCtx *ictx, const char *fromsnapname, uint64_t off,
+                   uint64_t len, bool include_parent, bool whole_object,
                   int (*cb)(uint64_t, size_t, int, void *),
                   void *arg);
   ssize_t read(ImageCtx *ictx, uint64_t off, size_t len, char *buf, int op_flags);
index 5a2518e858598fd629947a03d89b51a10b8f073d..ea6e2a6c0eaa36485398a973e939bd145cf8de3b 100644 (file)
@@ -673,8 +673,25 @@ namespace librbd {
                          void *arg)
   {
     ImageCtx *ictx = (ImageCtx *)ctx;
-    tracepoint(librbd, diff_iterate_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, fromsnapname, ofs, len);
-    int r = librbd::diff_iterate(ictx, fromsnapname, ofs, len, cb, arg);
+    tracepoint(librbd, diff_iterate_enter, ictx, ictx->name.c_str(),
+               ictx->snap_name.c_str(), ictx->read_only, fromsnapname, ofs, len,
+               true, true);
+    int r = librbd::diff_iterate(ictx, fromsnapname, ofs, len, true, false, cb,
+                                 arg);
+    tracepoint(librbd, diff_iterate_exit, r);
+    return r;
+  }
+
+  int Image::diff_iterate2(const char *fromsnapname, uint64_t ofs, uint64_t len,
+                           bool include_parent, bool whole_object,
+                           int (*cb)(uint64_t, size_t, int, void *), void *arg)
+  {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    tracepoint(librbd, diff_iterate_enter, ictx, ictx->name.c_str(),
+              ictx->snap_name.c_str(), ictx->read_only, fromsnapname, ofs, len,
+              include_parent, whole_object);
+    int r = librbd::diff_iterate(ictx, fromsnapname, ofs, len, include_parent,
+                                whole_object, cb, arg);
     tracepoint(librbd, diff_iterate_exit, r);
     return r;
   }
@@ -1638,8 +1655,27 @@ extern "C" int rbd_diff_iterate(rbd_image_t image,
                                void *arg)
 {
   librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
-  tracepoint(librbd, diff_iterate_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, fromsnapname, ofs, len);
-  int r = librbd::diff_iterate(ictx, fromsnapname, ofs, len, cb, arg);
+  tracepoint(librbd, diff_iterate_enter, ictx, ictx->name.c_str(),
+             ictx->snap_name.c_str(), ictx->read_only, fromsnapname, ofs, len,
+             true, true);
+  int r = librbd::diff_iterate(ictx, fromsnapname, ofs, len, true, false, cb,
+                               arg);
+  tracepoint(librbd, diff_iterate_exit, r);
+  return r;
+}
+
+extern "C" int rbd_diff_iterate2(rbd_image_t image, const char *fromsnapname,
+                                uint64_t ofs, uint64_t len,
+                                uint8_t include_parent, uint8_t whole_object,
+                                int (*cb)(uint64_t, size_t, int, void *),
+                                void *arg)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  tracepoint(librbd, diff_iterate_enter, ictx, ictx->name.c_str(),
+            ictx->snap_name.c_str(), ictx->read_only, fromsnapname, ofs, len,
+            include_parent != 0, whole_object != 0);
+  int r = librbd::diff_iterate(ictx, fromsnapname, ofs, len, include_parent,
+                              whole_object, cb, arg);
   tracepoint(librbd, diff_iterate_exit, r);
   return r;
 }
index b7d104591ce986f0c086bdb72a779b3f22f1c059..c88a4f5bcdcadf9646c722f9732b2d931743e40b 100644 (file)
@@ -1287,7 +1287,9 @@ TRACEPOINT_EVENT(librbd, diff_iterate_enter,
         char, read_only,
         const char*, from_snap_name,
         uint64_t, offset,
-        uint64_t, length),
+        uint64_t, length,
+        char, include_parent,
+        char, whole_object),
     TP_FIELDS(
         ctf_integer_hex(void*, imagectx, imagectx)
         ctf_string(name, name)
@@ -1296,6 +1298,8 @@ TRACEPOINT_EVENT(librbd, diff_iterate_enter,
         ctf_string(from_snap_name, from_snap_name)
         ctf_integer(uint64_t, offset, offset)
         ctf_integer(uint64_t, length, length)
+        ctf_integer(char, include_parent, include_parent)
+        ctf_integer(char, whole_object, whole_object)
     )
 )