From: Jason Dillaman Date: Tue, 24 Mar 2015 17:20:32 +0000 (-0400) Subject: librbd: add diff_iterate2 to API X-Git-Tag: v9.0.1~55^2~27 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6d5b969d4206208e91ca807b09aac75f2f428393;p=ceph.git librbd: add diff_iterate2 to API 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 --- diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h index 6a755b5d6b3..7157eaf766d 100644 --- a/src/include/rbd/librbd.h +++ b/src/include/rbd/librbd.h @@ -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); /* diff --git a/src/include/rbd/librbd.hpp b/src/include/rbd/librbd.hpp index ea81b8fed51..cf8b2e7b4e7 100644 --- a/src/include/rbd/librbd.hpp +++ b/src/include/rbd/librbd.hpp @@ -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); diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index ac219ad3a7c..188cddcecdb 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -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 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::iterator q = p->second.begin(); + q != p->second.end(); ++q) { + cb(off + q->offset, q->length, end_exists, arg); + } + continue; + } for (vector::iterator q = p->second.begin(); q != p->second.end(); ++q) { ldout(ictx->cct, 20) << "diff_iterate object " << p->first diff --git a/src/librbd/internal.h b/src/librbd/internal.h index 9f71f55da26..37f565e4524 100644 --- a/src/librbd/internal.h +++ b/src/librbd/internal.h @@ -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); diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index 5a2518e8585..ea6e2a6c0ea 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -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; } diff --git a/src/tracing/librbd.tp b/src/tracing/librbd.tp index b7d104591ce..c88a4f5bcdc 100644 --- a/src/tracing/librbd.tp +++ b/src/tracing/librbd.tp @@ -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) ) )