* @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
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);
/*
* @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
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);
}
- 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;
// 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;
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;
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
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);
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;
}
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;
}
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)
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)
)
)