#include "include/types.h"
#include "include/buffer_fwd.h"
+#include "include/rbd_types.h"
#include "common/Formatter.h"
-#include "librbd/parent_types.h"
#include "cls/rbd/cls_rbd_types.h"
/// information about our parent image, if any
std::map<rados::cls::lock::locker_id_t,
rados::cls::lock::locker_info_t> *lockers,
bool *exclusive_lock, std::string *lock_tag,
- ::SnapContext *snapc, parent_info *parent) {
+ ::SnapContext *snapc, ParentInfo *parent) {
assert(size);
assert(features);
assert(incompatible_features);
bool *exclusive_lock,
string *lock_tag,
::SnapContext *snapc,
- parent_info *parent)
+ ParentInfo *parent)
{
librados::ObjectReadOperation op;
get_mutable_metadata_start(&op, read_only);
}
int get_parent(librados::IoCtx *ioctx, const std::string &oid,
- snapid_t snap_id, parent_spec *pspec,
+ snapid_t snap_id, ParentSpec *pspec,
uint64_t *parent_overlap)
{
bufferlist inbl, outbl;
}
int set_parent(librados::IoCtx *ioctx, const std::string &oid,
- parent_spec pspec, uint64_t parent_overlap)
+ const ParentSpec &pspec, uint64_t parent_overlap)
{
librados::ObjectWriteOperation op;
set_parent(&op, pspec, parent_overlap);
}
void set_parent(librados::ObjectWriteOperation *op,
- parent_spec pspec, uint64_t parent_overlap) {
+ const ParentSpec &pspec, uint64_t parent_overlap) {
bufferlist in_bl;
::encode(pspec.pool_id, in_bl);
::encode(pspec.image_id, in_bl);
}
int add_child(librados::IoCtx *ioctx, const std::string &oid,
- parent_spec pspec, const std::string &c_imageid)
+ const ParentSpec &pspec, const std::string &c_imageid)
{
bufferlist in, out;
::encode(pspec.pool_id, in);
}
void remove_child(librados::ObjectWriteOperation *op,
- parent_spec pspec, const std::string &c_imageid)
+ const ParentSpec &pspec, const std::string &c_imageid)
{
bufferlist in;
::encode(pspec.pool_id, in);
}
int remove_child(librados::IoCtx *ioctx, const std::string &oid,
- parent_spec pspec, const std::string &c_imageid)
+ const ParentSpec &pspec, const std::string &c_imageid)
{
librados::ObjectWriteOperation op;
remove_child(&op, pspec, c_imageid);
}
void get_children_start(librados::ObjectReadOperation *op,
- const parent_spec &pspec) {
+ const ParentSpec &pspec) {
bufferlist in_bl;
::encode(pspec.pool_id, in_bl);
::encode(pspec.image_id, in_bl);
}
int get_children(librados::IoCtx *ioctx, const std::string &oid,
- parent_spec pspec, set<string>& children)
+ const ParentSpec &pspec, set<string>& children)
{
librados::ObjectReadOperation op;
get_children_start(&op, pspec);
const std::vector<snapid_t> &ids,
std::vector<string> *names,
std::vector<uint64_t> *sizes,
- std::vector<parent_info> *parents,
+ std::vector<ParentInfo> *parents,
std::vector<uint8_t> *protection_statuses)
{
names->resize(ids.size());
const std::vector<snapid_t> &ids,
std::vector<string> *names,
std::vector<uint64_t> *sizes,
- std::vector<parent_info> *parents,
+ std::vector<ParentInfo> *parents,
std::vector<uint8_t> *protection_statuses)
{
librados::ObjectReadOperation op;
#include "common/snap_types.h"
#include "include/rados/librados.hpp"
#include "include/types.h"
-#include "librbd/parent_types.h"
+#include "librbd/Types.h"
#include <string>
#include <vector>
std::map<rados::cls::lock::locker_id_t,
rados::cls::lock::locker_info_t> *lockers,
bool *exclusive_lock, std::string *lock_tag,
- ::SnapContext *snapc, parent_info *parent);
+ ::SnapContext *snapc, ParentInfo *parent);
int get_mutable_metadata(librados::IoCtx *ioctx, const std::string &oid,
bool read_only, uint64_t *size, uint64_t *features,
uint64_t *incompatible_features,
bool *exclusive_lock,
std::string *lock_tag,
::SnapContext *snapc,
- parent_info *parent);
+ ParentInfo *parent);
// low-level interface (mainly for testing)
void create_image(librados::ObjectWriteOperation *op, uint64_t size,
uint64_t size);
void set_size(librados::ObjectWriteOperation *op, uint64_t size);
int get_parent(librados::IoCtx *ioctx, const std::string &oid,
- snapid_t snap_id, parent_spec *pspec,
+ snapid_t snap_id, ParentSpec *pspec,
uint64_t *parent_overlap);
int set_parent(librados::IoCtx *ioctx, const std::string &oid,
- parent_spec pspec, uint64_t parent_overlap);
+ const ParentSpec &pspec, uint64_t parent_overlap);
void set_parent(librados::ObjectWriteOperation *op,
- parent_spec pspec, uint64_t parent_overlap);
+ const ParentSpec &pspec, uint64_t parent_overlap);
void get_flags_start(librados::ObjectReadOperation *op,
const std::vector<snapid_t> &snap_ids);
int get_flags_finish(bufferlist::iterator *it, uint64_t *flags,
int remove_parent(librados::IoCtx *ioctx, const std::string &oid);
void remove_parent(librados::ObjectWriteOperation *op);
int add_child(librados::IoCtx *ioctx, const std::string &oid,
- parent_spec pspec, const std::string &c_imageid);
+ const ParentSpec &pspec, const std::string &c_imageid);
void remove_child(librados::ObjectWriteOperation *op,
- parent_spec pspec, const std::string &c_imageid);
+ const ParentSpec &pspec, const std::string &c_imageid);
int remove_child(librados::IoCtx *ioctx, const std::string &oid,
- parent_spec pspec, const std::string &c_imageid);
+ const ParentSpec &pspec, const std::string &c_imageid);
void get_children_start(librados::ObjectReadOperation *op,
- const parent_spec &pspec);
+ const ParentSpec &pspec);
int get_children_finish(bufferlist::iterator *it,
std::set<string> *children);
int get_children(librados::IoCtx *ioctx, const std::string &oid,
- parent_spec pspec, set<string>& children);
+ const ParentSpec &pspec, set<string>& children);
void snapshot_add(librados::ObjectWriteOperation *op, snapid_t snap_id,
const std::string &snap_name,
const cls::rbd::SnapshotNamespace &snap_namespace);
const std::vector<snapid_t> &ids,
std::vector<string> *names,
std::vector<uint64_t> *sizes,
- std::vector<parent_info> *parents,
+ std::vector<ParentInfo> *parents,
std::vector<uint8_t> *protection_statuses);
void snapshot_timestamp_list_start(librados::ObjectReadOperation *op,
const std::vector<snapid_t> &ids);
const std::vector<snapid_t> &ids,
std::vector<string> *names,
std::vector<uint64_t> *sizes,
- std::vector<parent_info> *parents,
+ std::vector<ParentInfo> *parents,
std::vector<uint8_t> *protection_statuses);
void snapshot_namespace_list_start(librados::ObjectReadOperation *op,
struct rbd_obj_snap_ondisk snaps[0];
} __attribute__((packed));
+enum {
+ RBD_PROTECTION_STATUS_UNPROTECTED = 0,
+ RBD_PROTECTION_STATUS_UNPROTECTING = 1,
+ RBD_PROTECTION_STATUS_PROTECTED = 2,
+ RBD_PROTECTION_STATUS_LAST = 3
+};
+
#endif
}
int ImageCtx::get_parent_spec(snap_t in_snap_id,
- parent_spec *out_pspec) const
+ ParentSpec *out_pspec) const
{
const SnapInfo *info = get_snap_info(in_snap_id);
if (info) {
void ImageCtx::add_snap(string in_snap_name,
cls::rbd::SnapshotNamespace in_snap_namespace,
snap_t id, uint64_t in_size,
- parent_info parent, uint8_t protection_status,
+ const ParentInfo &parent, uint8_t protection_status,
uint64_t flags, utime_t timestamp)
{
assert(snap_lock.is_wlocked());
return 0;
}
- const parent_info* ImageCtx::get_parent_info(snap_t in_snap_id) const
+ const ParentInfo* ImageCtx::get_parent_info(snap_t in_snap_id) const
{
assert(snap_lock.is_locked());
assert(parent_lock.is_locked());
int64_t ImageCtx::get_parent_pool_id(snap_t in_snap_id) const
{
- const parent_info *info = get_parent_info(in_snap_id);
+ const ParentInfo *info = get_parent_info(in_snap_id);
if (info)
return info->spec.pool_id;
return -1;
string ImageCtx::get_parent_image_id(snap_t in_snap_id) const
{
- const parent_info *info = get_parent_info(in_snap_id);
+ const ParentInfo *info = get_parent_info(in_snap_id);
if (info)
return info->spec.image_id;
return "";
uint64_t ImageCtx::get_parent_snap_id(snap_t in_snap_id) const
{
- const parent_info *info = get_parent_info(in_snap_id);
+ const ParentInfo *info = get_parent_info(in_snap_id);
if (info)
return info->spec.snap_id;
return CEPH_NOSNAP;
int ImageCtx::get_parent_overlap(snap_t in_snap_id, uint64_t *overlap) const
{
assert(snap_lock.is_locked());
- const parent_info *info = get_parent_info(in_snap_id);
+ const ParentInfo *info = get_parent_info(in_snap_id);
if (info) {
*overlap = info->overlap;
return 0;
#include "cls/rbd/cls_rbd_types.h"
#include "cls/rbd/cls_rbd_client.h"
#include "librbd/AsyncRequest.h"
-#include "librbd/SnapInfo.h"
-#include "librbd/parent_types.h"
+#include "librbd/Types.h"
class CephContext;
class ContextWQ;
char *format_string;
std::string header_oid;
std::string id; // only used for new-format images
- parent_info parent_md;
+ ParentInfo parent_md;
ImageCtx *parent;
cls::rbd::GroupSpec group_spec;
uint64_t stripe_unit, stripe_count;
int get_snap_namespace(librados::snap_t in_snap_id,
cls::rbd::SnapshotNamespace *out_snap_namespace) const;
int get_parent_spec(librados::snap_t in_snap_id,
- parent_spec *pspec) const;
+ ParentSpec *pspec) const;
int is_snap_protected(librados::snap_t in_snap_id,
bool *is_protected) const;
int is_snap_unprotected(librados::snap_t in_snap_id,
void add_snap(std::string in_snap_name,
cls::rbd::SnapshotNamespace in_snap_namespace,
librados::snap_t id,
- uint64_t in_size, parent_info parent,
+ uint64_t in_size, const ParentInfo &parent,
uint8_t protection_status, uint64_t flags, utime_t timestamp);
void rm_snap(std::string in_snap_name, librados::snap_t id);
uint64_t get_image_size(librados::snap_t in_snap_id) const;
bool test_flags(uint64_t test_flags, const RWLock &in_snap_lock) const;
int update_flags(librados::snap_t in_snap_id, uint64_t flag, bool enabled);
- const parent_info* get_parent_info(librados::snap_t in_snap_id) const;
+ const ParentInfo* get_parent_info(librados::snap_t in_snap_id) const;
int64_t get_parent_pool_id(librados::snap_t in_snap_id) const;
std::string get_parent_image_id(librados::snap_t in_snap_id) const;
uint64_t get_parent_snap_id(librados::snap_t in_snap_id) const;
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-#ifndef CEPH_LIBRBD_SNAPINFO_H
-#define CEPH_LIBRBD_SNAPINFO_H
-
-#include "cls/rbd/cls_rbd_types.h"
-#include "include/int_types.h"
-
-#include "librbd/parent_types.h"
-
-namespace librbd {
-
- struct SnapInfo {
- std::string name;
- cls::rbd::SnapshotNamespace snap_namespace;
- uint64_t size;
- parent_info parent;
- uint8_t protection_status;
- uint64_t flags;
- utime_t timestamp;
- SnapInfo(std::string _name, const cls::rbd::SnapshotNamespace &_snap_namespace,
- uint64_t _size, parent_info _parent,
- uint8_t _protection_status, uint64_t _flags, utime_t _timestamp)
- : name(_name), snap_namespace(_snap_namespace), size(_size), parent(_parent),
- protection_status(_protection_status), flags(_flags), timestamp(_timestamp) {}
- };
-}
-
-#endif
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef LIBRBD_TYPES_H
+#define LIBRBD_TYPES_H
+
+#include "include/types.h"
+#include "cls/rbd/cls_rbd_types.h"
+#include <string>
+
+namespace librbd {
+
+/** @brief Unique identification of a parent in clone relationship.
+ * Cloning an image creates a child image that keeps a reference
+ * to its parent. This allows copy-on-write images. */
+struct ParentSpec {
+ int64_t pool_id;
+ std::string image_id;
+ snapid_t snap_id;
+
+ ParentSpec() : pool_id(-1), snap_id(CEPH_NOSNAP) {
+ }
+ ParentSpec(int64_t pool_id, std::string image_id, snapid_t snap_id)
+ : pool_id(pool_id), image_id(image_id), snap_id(snap_id) {
+ }
+
+ bool operator==(const ParentSpec &other) {
+ return ((this->pool_id == other.pool_id) &&
+ (this->image_id == other.image_id) &&
+ (this->snap_id == other.snap_id));
+ }
+ bool operator!=(const ParentSpec &other) {
+ return !(*this == other);
+ }
+};
+
+/// Full information about an image's parent.
+struct ParentInfo {
+ /// Identification of the parent.
+ ParentSpec spec;
+
+ /** @brief Where the portion of data shared with the child image ends.
+ * Since images can be resized multiple times, the portion of data shared
+ * with the child image is not necessarily min(parent size, child size).
+ * If the child image is first shrunk and then enlarged, the common portion
+ * will be shorter. */
+ uint64_t overlap;
+
+ ParentInfo() : overlap(0) {
+ }
+};
+
+struct SnapInfo {
+ std::string name;
+ cls::rbd::SnapshotNamespace snap_namespace;
+ uint64_t size;
+ ParentInfo parent;
+ uint8_t protection_status;
+ uint64_t flags;
+ utime_t timestamp;
+ SnapInfo(std::string _name,
+ const cls::rbd::SnapshotNamespace &_snap_namespace,
+ uint64_t _size, const ParentInfo &_parent,
+ uint8_t _protection_status, uint64_t _flags, utime_t _timestamp)
+ : name(_name), snap_namespace(_snap_namespace), size(_size),
+ parent(_parent), protection_status(_protection_status), flags(_flags),
+ timestamp(_timestamp) {
+ }
+};
+
+} // namespace librbd
+
+#endif // LIBRBD_TYPES_H
template <typename I>
RefreshParentRequest<I>::RefreshParentRequest(I &child_image_ctx,
- const parent_info &parent_md,
+ const ParentInfo &parent_md,
Context *on_finish)
: m_child_image_ctx(child_image_ctx), m_parent_md(parent_md),
m_on_finish(on_finish), m_parent_image_ctx(nullptr),
template <typename I>
bool RefreshParentRequest<I>::is_refresh_required(I &child_image_ctx,
- const parent_info &parent_md) {
+ const ParentInfo &parent_md) {
assert(child_image_ctx.snap_lock.is_locked());
assert(child_image_ctx.parent_lock.is_locked());
return (is_open_required(child_image_ctx, parent_md) ||
template <typename I>
bool RefreshParentRequest<I>::is_close_required(I &child_image_ctx,
- const parent_info &parent_md) {
+ const ParentInfo &parent_md) {
return (child_image_ctx.parent != nullptr &&
(parent_md.spec.pool_id == -1 || parent_md.overlap == 0));
}
template <typename I>
bool RefreshParentRequest<I>::is_open_required(I &child_image_ctx,
- const parent_info &parent_md) {
+ const ParentInfo &parent_md) {
return (parent_md.spec.pool_id > -1 && parent_md.overlap > 0 &&
(child_image_ctx.parent == nullptr ||
child_image_ctx.parent->md_ctx.get_id() != parent_md.spec.pool_id ||
#define CEPH_LIBRBD_IMAGE_REFRESH_PARENT_REQUEST_H
#include "include/int_types.h"
-#include "librbd/parent_types.h"
+#include "librbd/Types.h"
class Context;
class RefreshParentRequest {
public:
static RefreshParentRequest *create(ImageCtxT &child_image_ctx,
- const parent_info &parent_md,
+ const ParentInfo &parent_md,
Context *on_finish) {
return new RefreshParentRequest(child_image_ctx, parent_md, on_finish);
}
static bool is_refresh_required(ImageCtxT &child_image_ctx,
- const parent_info &parent_md);
+ const ParentInfo &parent_md);
void send();
void apply();
* @endverbatim
*/
- RefreshParentRequest(ImageCtxT &child_image_ctx, const parent_info &parent_md,
+ RefreshParentRequest(ImageCtxT &child_image_ctx, const ParentInfo &parent_md,
Context *on_finish);
ImageCtxT &m_child_image_ctx;
- parent_info m_parent_md;
+ ParentInfo m_parent_md;
Context *m_on_finish;
ImageCtxT *m_parent_image_ctx;
int m_error_result;
static bool is_close_required(ImageCtxT &child_image_ctx,
- const parent_info &parent_md);
+ const ParentInfo &parent_md);
static bool is_open_required(ImageCtxT &child_image_ctx,
- const parent_info &parent_md);
+ const ParentInfo &parent_md);
void send_open_parent();
Context *handle_open_parent(int *result);
RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
RWLock::RLocker parent_locker(m_image_ctx.parent_lock);
- parent_info parent_md;
+ ParentInfo parent_md;
int r = get_parent_info(m_image_ctx.snap_id, &parent_md);
if (!m_skip_open_parent_image && (r < 0 ||
RefreshParentRequest<I>::is_refresh_required(m_image_ctx, parent_md))) {
uint8_t protection_status = m_image_ctx.old_format ?
static_cast<uint8_t>(RBD_PROTECTION_STATUS_UNPROTECTED) :
m_snap_protection[i];
- parent_info parent;
+ ParentInfo parent;
if (!m_image_ctx.old_format) {
parent = m_snap_parents[i];
}
template <typename I>
int RefreshRequest<I>::get_parent_info(uint64_t snap_id,
- parent_info *parent_md) {
+ ParentInfo *parent_md) {
if (snap_id == CEPH_NOSNAP) {
*parent_md = m_parent_md;
return 0;
#include "common/snap_types.h"
#include "cls/lock/cls_lock_types.h"
#include "librbd/ImageCtx.h"
-#include "librbd/parent_types.h"
+#include "librbd/Types.h"
#include <string>
#include <vector>
uint64_t m_incompatible_features;
uint64_t m_flags;
std::string m_object_prefix;
- parent_info m_parent_md;
+ ParentInfo m_parent_md;
cls::rbd::GroupSpec m_group_spec;
::SnapContext m_snapc;
std::vector<std::string> m_snap_names;
std::vector<cls::rbd::SnapshotNamespace> m_snap_namespaces;
std::vector<uint64_t> m_snap_sizes;
- std::vector<parent_info> m_snap_parents;
+ std::vector<ParentInfo> m_snap_parents;
std::vector<uint8_t> m_snap_protection;
std::vector<uint64_t> m_snap_flags;
std::vector<utime_t> m_snap_timestamps;
}
void apply();
- int get_parent_info(uint64_t snap_id, parent_info *parent_md);
+ int get_parent_info(uint64_t snap_id, ParentInfo *parent_md);
};
} // namespace image
ldout(m_cct, 20) << dendl;
m_image_ctx->parent_lock.get_read();
- parent_info parent_info = m_image_ctx->parent_md;
+ ParentInfo parent_info = m_image_ctx->parent_md;
m_image_ctx->parent_lock.put_read();
librados::ObjectWriteOperation op;
Context *SetSnapRequest<I>::send_refresh_parent(int *result) {
CephContext *cct = m_image_ctx.cct;
- parent_info parent_md;
+ ParentInfo parent_md;
bool refresh_parent;
{
RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
RWLock::RLocker parent_locker(m_image_ctx.parent_lock);
- const parent_info *parent_info = m_image_ctx.get_parent_info(m_snap_id);
+ const ParentInfo *parent_info = m_image_ctx.get_parent_info(m_snap_id);
if (parent_info == nullptr) {
*result = -ENOENT;
lderr(cct) << "failed to retrieve snapshot parent info" << dendl;
#include "librbd/MirroringWatcher.h"
#include "librbd/ObjectMap.h"
#include "librbd/Operations.h"
-#include "librbd/parent_types.h"
+#include "librbd/Types.h"
#include "librbd/Utils.h"
#include "librbd/exclusive_lock/AutomaticPolicy.h"
#include "librbd/exclusive_lock/StandardPolicy.h"
RWLock::RLocker l(ictx->snap_lock);
snap_t snap_id = ictx->get_snap_id(snap_name);
- parent_spec parent_spec(ictx->md_ctx.get_id(), ictx->id, snap_id);
+ ParentSpec parent_spec(ictx->md_ctx.get_id(), ictx->id, snap_id);
map< pair<int64_t, string>, set<string> > image_info;
int r = list_children_info(ictx, parent_spec, image_info);
if ((imctx->features & RBD_FEATURE_DEEP_FLATTEN) == 0 &&
!imctx->snaps.empty()) {
imctx->parent_lock.get_read();
- parent_info parent_info = imctx->parent_md;
+ ParentInfo parent_info = imctx->parent_md;
imctx->parent_lock.put_read();
r = cls_client::remove_child(&imctx->md_ctx, RBD_CHILDREN,
ldout(cct, 20) << "children list " << ictx->name << dendl;
RWLock::RLocker l(ictx->snap_lock);
- parent_spec parent_spec(ictx->md_ctx.get_id(), ictx->id, ictx->snap_id);
+ ParentSpec parent_spec(ictx->md_ctx.get_id(), ictx->id, ictx->snap_id);
map< pair<int64_t, string>, set<string> > image_info;
int r = list_children_info(ictx, parent_spec, image_info);
return 0;
}
- int list_children_info(ImageCtx *ictx, librbd::parent_spec parent_spec,
+ int list_children_info(ImageCtx *ictx, const ParentSpec &parent_spec,
map< pair<int64_t, string >, set<string> >& image_info)
{
CephContext *cct = ictx->cct;
librbd::NoOpProgressContext no_op;
ImageCtx *c_imctx = NULL;
map<string, bufferlist> pairs;
- parent_spec pspec(p_imctx->md_ctx.get_id(), p_imctx->id, p_imctx->snap_id);
+ ParentSpec pspec(p_imctx->md_ctx.get_id(), p_imctx->id, p_imctx->snap_id);
if (p_imctx->old_format) {
lderr(cct) << "parent image must be in new format" << dendl;
return -ENOENT;
}
- parent_spec parent_spec;
+ ParentSpec parent_spec;
if (ictx->snap_id == CEPH_NOSNAP) {
parent_spec = ictx->parent_md.spec;
RWLock::RLocker l(ictx->snap_lock);
map<librados::snap_t, SnapInfo> snap_info = ictx->snap_info;
for (auto &info : snap_info) {
- librbd::parent_spec parent_spec(ictx->md_ctx.get_id(), ictx->id, info.first);
+ ParentSpec parent_spec(ictx->md_ctx.get_id(), ictx->id, info.first);
map< pair<int64_t, string>, set<string> > image_info;
r = list_children_info(ictx, parent_spec, image_info);
#include "include/buffer_fwd.h"
#include "include/rbd/librbd.hpp"
#include "include/rbd_types.h"
-#include "librbd/parent_types.h"
#include "cls/rbd/cls_rbd_types.h"
#include "common/WorkQueue.h"
+#include "librbd/Types.h"
enum {
l_librbd_first = 26000,
int list(librados::IoCtx& io_ctx, std::vector<std::string>& names);
int list_children(ImageCtx *ictx,
std::set<std::pair<std::string, std::string> > & names);
- int list_children_info(ImageCtx *ictx, librbd::parent_spec parent_spec,
+ int list_children_info(ImageCtx *ictx, const ParentSpec &parent_spec,
std::map<std::pair<int64_t, std::string >, std::set<std::string> >& image_info);
int create(librados::IoCtx& io_ctx, const char *imgname, uint64_t size,
int *order);
#define CEPH_LIBRBD_OPERATION_FLATTEN_REQUEST_H
#include "librbd/operation/Request.h"
-#include "librbd/parent_types.h"
#include "common/snap_types.h"
+#include "librbd/Types.h"
namespace librbd {
ProgressContext &m_prog_ctx;
State m_state;
- parent_spec m_parent_spec;
+ ParentSpec m_parent_spec;
bool m_ignore_enoent;
bool send_update_header();
#define CEPH_LIBRBD_OPERATION_SNAPSHOT_CREATE_REQUEST_H
#include "cls/rbd/cls_rbd_types.h"
+#include "librbd/Types.h"
#include "librbd/operation/Request.h"
-#include "librbd/parent_types.h"
#include <string>
class Context;
uint64_t m_snap_id;
uint64_t m_size;
- parent_info m_parent_info;
+ ParentInfo m_parent_info;
void send_suspend_requests();
Context *handle_suspend_requests(int *result);
RWLock::RLocker snap_locker(image_ctx.snap_lock);
RWLock::RLocker parent_locker(image_ctx.parent_lock);
- parent_spec our_pspec;
+ ParentSpec our_pspec;
int r = image_ctx.get_parent_spec(m_snap_id, &our_pspec);
if (r < 0) {
if (r == -ENOENT) {
}
template <typename I>
-int SnapshotRemoveRequest<I>::scan_for_parents(parent_spec &pspec) {
+int SnapshotRemoveRequest<I>::scan_for_parents(ParentSpec &pspec) {
I &image_ctx = this->m_image_ctx;
assert(image_ctx.snap_lock.is_locked());
assert(image_ctx.parent_lock.is_locked());
#define CEPH_LIBRBD_OPERATION_SNAPSHOT_REMOVE_REQUEST_H
#include "librbd/operation/Request.h"
-#include "librbd/parent_types.h"
+#include "librbd/Types.h"
#include <string>
class Context;
void send_release_snap_id();
void remove_snap_context();
- int scan_for_parents(parent_spec &pspec);
+ int scan_for_parents(ParentSpec &pspec);
};
#include "librbd/AsyncObjectThrottle.h"
#include "librbd/ImageCtx.h"
#include "librbd/internal.h"
-#include "librbd/parent_types.h"
+#include "librbd/Types.h"
#include "librbd/Utils.h"
#include <list>
#include <set>
class C_ScanPoolChildren : public C_AsyncObjectThrottle<I> {
public:
C_ScanPoolChildren(AsyncObjectThrottle<I> &throttle, I *image_ctx,
- const parent_spec &pspec, const Pools &pools,
+ const ParentSpec &pspec, const Pools &pools,
size_t pool_idx)
: C_AsyncObjectThrottle<I>(throttle, *image_ctx), m_pspec(pspec),
m_pool(pools[pool_idx]) {
}
private:
- parent_spec m_pspec;
+ ParentSpec m_pspec;
Pool m_pool;
IoCtx m_pool_ioctx;
std::list<Pool> pool_list;
rados.pool_list2(pool_list);
- parent_spec pspec(image_ctx.md_ctx.get_id(), image_ctx.id, m_snap_id);
+ ParentSpec pspec(image_ctx.md_ctx.get_id(), image_ctx.id, m_snap_id);
Pools pools(pool_list.begin(), pool_list.end());
Context *ctx = this->create_callback_context();
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-#ifndef CEPH_LIBRBD_PARENT_TYPES_H
-#define CEPH_LIBRBD_PARENT_TYPES_H
-
-#include "include/int_types.h"
-#include "include/types.h"
-#include <string>
-
-namespace librbd {
- /** @brief Unique identification of a parent in clone relationship.
- * Cloning an image creates a child image that keeps a reference
- * to its parent. This allows copy-on-write images. */
- struct parent_spec {
- int64_t pool_id;
- std::string image_id;
- snapid_t snap_id;
- parent_spec() : pool_id(-1), snap_id(CEPH_NOSNAP) {}
- parent_spec(int64_t pool_id, std::string image_id, snapid_t snap_id) :
- pool_id(pool_id), image_id(image_id), snap_id(snap_id) {}
- bool operator==(const parent_spec &other) {
- return ((this->pool_id == other.pool_id) &&
- (this->image_id == other.image_id) &&
- (this->snap_id == other.snap_id));
- }
- bool operator!=(const parent_spec &other) {
- return !(*this == other);
- }
- };
-
- /// Full information about an image's parent.
- struct parent_info {
- /// Identification of the parent.
- parent_spec spec;
-
- /** @brief Where the portion of data shared with the child image ends.
- * Since images can be resized multiple times, the portion of data shared
- * with the child image is not necessarily min(parent size, child size).
- * If the child image is first shrunk and then enlarged, the common portion
- * will be shorter. */
- uint64_t overlap;
-
- parent_info() : overlap(0) {}
- };
-}
-
-enum {
- RBD_PROTECTION_STATUS_UNPROTECTED = 0,
- RBD_PROTECTION_STATUS_UNPROTECTING = 1,
- RBD_PROTECTION_STATUS_PROTECTED = 2,
- RBD_PROTECTION_STATUS_LAST = 3
-};
-
-#endif
+++ /dev/null
-
-#ifndef LIBRBD_TYPE_H
-#define LIBRBD_TYPE_H
-
-#include <errno.h>
-
-#endif
using namespace std;
using namespace librbd::cls_client;
-using ::librbd::parent_info;
-using ::librbd::parent_spec;
+using ::librbd::ParentInfo;
+using ::librbd::ParentSpec;
static int snapshot_add(librados::IoCtx *ioctx, const std::string &oid,
uint64_t snap_id, const std::string &snap_name) {
snapid_t snapid(10);
string parent_image = "parent_id";
set<string>children;
- parent_spec pspec(ioctx.get_id(), parent_image, snapid);
+ ParentSpec pspec(ioctx.get_id(), parent_image, snapid);
// nonexistent children cannot be listed or removed
ASSERT_EQ(-ENOENT, get_children(&ioctx, oid, pspec, children));
ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
string oid = get_temp_image_name();
- parent_spec pspec;
+ ParentSpec pspec;
uint64_t size;
ASSERT_EQ(-ENOENT, get_parent(&ioctx, "doesnotexist", CEPH_NOSNAP, &pspec, &size));
ASSERT_STREQ("", pspec.image_id.c_str());
ASSERT_EQ(pspec.snap_id, CEPH_NOSNAP);
ASSERT_EQ(size, 0ULL);
- pspec = parent_spec(-1, "parent", 3);
- ASSERT_EQ(-ENOEXEC, set_parent(&ioctx, "old", parent_spec(-1, "parent", 3), 10<<20));
+ pspec = ParentSpec(-1, "parent", 3);
+ ASSERT_EQ(-ENOEXEC, set_parent(&ioctx, "old", ParentSpec(-1, "parent", 3), 10<<20));
ASSERT_EQ(-ENOEXEC, remove_parent(&ioctx, "old"));
// new image will work
ASSERT_EQ(0, get_parent(&ioctx, oid, 123, &pspec, &size));
ASSERT_EQ(-1, pspec.pool_id);
- ASSERT_EQ(-EINVAL, set_parent(&ioctx, oid, parent_spec(-1, "parent", 3), 10<<20));
- ASSERT_EQ(-EINVAL, set_parent(&ioctx, oid, parent_spec(1, "", 3), 10<<20));
- ASSERT_EQ(-EINVAL, set_parent(&ioctx, oid, parent_spec(1, "parent", CEPH_NOSNAP), 10<<20));
- ASSERT_EQ(-EINVAL, set_parent(&ioctx, oid, parent_spec(1, "parent", 3), 0));
+ ASSERT_EQ(-EINVAL, set_parent(&ioctx, oid, ParentSpec(-1, "parent", 3), 10<<20));
+ ASSERT_EQ(-EINVAL, set_parent(&ioctx, oid, ParentSpec(1, "", 3), 10<<20));
+ ASSERT_EQ(-EINVAL, set_parent(&ioctx, oid, ParentSpec(1, "parent", CEPH_NOSNAP), 10<<20));
+ ASSERT_EQ(-EINVAL, set_parent(&ioctx, oid, ParentSpec(1, "parent", 3), 0));
- pspec = parent_spec(1, "parent", 3);
+ pspec = ParentSpec(1, "parent", 3);
ASSERT_EQ(0, set_parent(&ioctx, oid, pspec, 10<<20));
ASSERT_EQ(-EEXIST, set_parent(&ioctx, oid, pspec, 10<<20));
- ASSERT_EQ(-EEXIST, set_parent(&ioctx, oid, parent_spec(2, "parent", 34), 10<<20));
+ ASSERT_EQ(-EEXIST, set_parent(&ioctx, oid, ParentSpec(2, "parent", 34), 10<<20));
ASSERT_EQ(0, get_parent(&ioctx, oid, CEPH_NOSNAP, &pspec, &size));
ASSERT_EQ(pspec.pool_id, 1);
ASSERT_EQ(-1, pspec.pool_id);
// snapshots
- ASSERT_EQ(0, set_parent(&ioctx, oid, parent_spec(1, "parent", 3), 10<<20));
+ ASSERT_EQ(0, set_parent(&ioctx, oid, ParentSpec(1, "parent", 3), 10<<20));
ASSERT_EQ(0, snapshot_add(&ioctx, oid, 10, "snap1"));
ASSERT_EQ(0, get_parent(&ioctx, oid, 10, &pspec, &size));
ASSERT_EQ(pspec.pool_id, 1);
ASSERT_EQ(size, 10ull<<20);
ASSERT_EQ(0, remove_parent(&ioctx, oid));
- ASSERT_EQ(0, set_parent(&ioctx, oid, parent_spec(4, "parent2", 6), 5<<20));
+ ASSERT_EQ(0, set_parent(&ioctx, oid, ParentSpec(4, "parent2", 6), 5<<20));
ASSERT_EQ(0, snapshot_add(&ioctx, oid, 11, "snap2"));
ASSERT_EQ(0, get_parent(&ioctx, oid, 10, &pspec, &size));
ASSERT_EQ(pspec.pool_id, 1);
ASSERT_EQ(-1, pspec.pool_id);
// make sure set_parent takes min of our size and parent's size
- ASSERT_EQ(0, set_parent(&ioctx, oid, parent_spec(1, "parent", 3), 1<<20));
+ ASSERT_EQ(0, set_parent(&ioctx, oid, ParentSpec(1, "parent", 3), 1<<20));
ASSERT_EQ(0, get_parent(&ioctx, oid, CEPH_NOSNAP, &pspec, &size));
ASSERT_EQ(pspec.pool_id, 1);
ASSERT_EQ(pspec.image_id, "parent");
ASSERT_EQ(size, 1ull<<20);
ASSERT_EQ(0, remove_parent(&ioctx, oid));
- ASSERT_EQ(0, set_parent(&ioctx, oid, parent_spec(1, "parent", 3), 100<<20));
+ ASSERT_EQ(0, set_parent(&ioctx, oid, ParentSpec(1, "parent", 3), 100<<20));
ASSERT_EQ(0, get_parent(&ioctx, oid, CEPH_NOSNAP, &pspec, &size));
ASSERT_EQ(pspec.pool_id, 1);
ASSERT_EQ(pspec.image_id, "parent");
ASSERT_EQ(0, remove_parent(&ioctx, oid));
// make sure resize adjust parent overlap
- ASSERT_EQ(0, set_parent(&ioctx, oid, parent_spec(1, "parent", 3), 10<<20));
+ ASSERT_EQ(0, set_parent(&ioctx, oid, ParentSpec(1, "parent", 3), 10<<20));
ASSERT_EQ(0, snapshot_add(&ioctx, oid, 14, "snap4"));
ASSERT_EQ(0, set_size(&ioctx, oid, 3 << 20));
ASSERT_EQ(0, create_image(&ioctx, oid, 33<<20, 22,
RBD_FEATURE_LAYERING | RBD_FEATURE_DEEP_FLATTEN,
"foo.", -1));
- ASSERT_EQ(0, set_parent(&ioctx, oid, parent_spec(1, "parent", 3), 100<<20));
+ ASSERT_EQ(0, set_parent(&ioctx, oid, ParentSpec(1, "parent", 3), 100<<20));
ASSERT_EQ(0, snapshot_add(&ioctx, oid, 1, "snap1"));
ASSERT_EQ(0, snapshot_add(&ioctx, oid, 2, "snap2"));
ASSERT_EQ(0, remove_parent(&ioctx, oid));
vector<cls::rbd::SnapshotNamespace> snap_namespaces;
vector<uint64_t> snap_sizes;
SnapContext snapc;
- vector<parent_info> parents;
+ vector<ParentInfo> parents;
vector<uint8_t> protection_status;
vector<utime_t> snap_timestamps;
bool exclusive_lock;
std::string lock_tag;
::SnapContext snapc;
- parent_info parent;
+ ParentInfo parent;
ASSERT_EQ(0, get_mutable_metadata(&ioctx, oid, true, &size, &features,
&incompatible_features, &lockers,
struct RefreshParentRequest<MockRefreshImageCtx> {
static RefreshParentRequest* s_instance;
static RefreshParentRequest* create(MockRefreshImageCtx &mock_image_ctx,
- const parent_info& parent_md,
+ const ParentInfo& parent_md,
Context *on_finish) {
assert(s_instance != nullptr);
s_instance->on_finish = on_finish;
return s_instance;
}
static bool is_refresh_required(MockRefreshImageCtx &mock_image_ctx,
- const parent_info& parent_md) {
+ const ParentInfo& parent_md) {
assert(s_instance != nullptr);
return s_instance->is_refresh_required();
}
MOCK_CONST_METHOD2(get_snap_namespace, int(librados::snap_t,
cls::rbd::SnapshotNamespace *out_snap_namespace));
MOCK_CONST_METHOD2(get_parent_spec, int(librados::snap_t in_snap_id,
- parent_spec *pspec));
+ ParentSpec *pspec));
MOCK_CONST_METHOD2(is_snap_protected, int(librados::snap_t in_snap_id,
bool *is_protected));
MOCK_METHOD8(add_snap, void(std::string in_snap_name,
cls::rbd::SnapshotNamespace in_snap_namespace,
librados::snap_t id,
- uint64_t in_size, parent_info parent,
+ uint64_t in_size, const ParentInfo &parent,
uint8_t protection_status, uint64_t flags, utime_t timestamp));
MOCK_METHOD2(rm_snap, void(std::string in_snap_name, librados::snap_t id));
std::string header_oid;
std::string id;
std::string name;
- parent_info parent_md;
+ ParentInfo parent_md;
char *format_string;
cls::rbd::GroupSpec group_spec;
if (r < 0) {
expect.WillOnce(Return(r));
} else {
- parent_spec &parent_spec = mock_image_ctx.snap_info.rbegin()->second.parent.spec;
+ ParentSpec &parent_spec = mock_image_ctx.snap_info.rbegin()->second.parent.spec;
expect.WillOnce(DoAll(SetArgPointee<1>(parent_spec),
Return(0)));
}
{
// hide the parent from the snapshot
RWLock::WLocker snap_locker(ictx2->snap_lock);
- ictx2->snap_info.begin()->second.parent = librbd::parent_info();
+ ictx2->snap_info.begin()->second.parent = librbd::ParentInfo();
}
librbd::io::ReadResult read_result{&read_bl};
{
// hide the parent from the snapshot
RWLock::WLocker snap_locker(ictx2->snap_lock);
- ictx2->snap_info.begin()->second.parent = librbd::parent_info();
+ ictx2->snap_info.begin()->second.parent = librbd::ParentInfo();
}
librbd::io::ReadResult read_result{&read_bl};
const std::string &snap_name,
const cls::rbd::SnapshotNamespace &snap_namespace,
uint64_t size,
- const librbd::parent_spec &parent_spec,
+ const librbd::ParentSpec &parent_spec,
uint64_t parent_overlap,
Context *on_finish) {
assert(s_instance != nullptr);
const std::string &snap_name,
const cls::rbd::SnapshotNamespace &snap_namespace,
uint64_t size,
- const librbd::parent_spec &spec,
+ const librbd::ParentSpec &spec,
uint64_t parent_overlap,
Context *on_finish) {
return new MockSnapshotCreateRequest(&mock_local_image_ctx, snap_name, snap_namespace, size,
#include "include/int_types.h"
#include "include/types.h"
#include "include/rados/librados.hpp"
-#include "librbd/parent_types.h"
+#include "librbd/Types.h"
#include <string>
class Context;
librados::IoCtx m_remote_parent_io_ctx;
ImageCtxT *m_remote_parent_image_ctx = nullptr;
- librbd::parent_spec m_remote_parent_spec;
+ librbd::ParentSpec m_remote_parent_spec;
librados::IoCtx m_local_parent_io_ctx;
ImageCtxT *m_local_parent_image_ctx = nullptr;
- librbd::parent_spec m_local_parent_spec;
+ librbd::ParentSpec m_local_parent_spec;
bufferlist m_out_bl;
std::string m_parent_global_image_id;
template <typename I>
void SnapshotCopyRequest<I>::send() {
- librbd::parent_spec remote_parent_spec;
+ librbd::ParentSpec remote_parent_spec;
int r = validate_parent(m_remote_image_ctx, &remote_parent_spec);
if (r < 0) {
derr << ": remote image parent spec mismatch" << dendl;
uint64_t size = snap_info_it->second.size;
m_snap_namespace = snap_info_it->second.snap_namespace;
- librbd::parent_spec parent_spec;
+ librbd::ParentSpec parent_spec;
uint64_t parent_overlap = 0;
if (snap_info_it->second.parent.spec.pool_id != -1) {
parent_spec = m_local_parent_spec;
template <typename I>
int SnapshotCopyRequest<I>::validate_parent(I *image_ctx,
- librbd::parent_spec *spec) {
+ librbd::ParentSpec *spec) {
RWLock::RLocker owner_locker(image_ctx->owner_lock);
RWLock::RLocker snap_locker(image_ctx->snap_lock);
#include "include/rados/librados.hpp"
#include "common/snap_types.h"
#include "librbd/ImageCtx.h"
-#include "librbd/parent_types.h"
+#include "librbd/Types.h"
#include "librbd/journal/TypeTraits.h"
#include "tools/rbd_mirror/BaseRequest.h"
#include <map>
std::string m_snap_name;
cls::rbd::SnapshotNamespace m_snap_namespace;
- librbd::parent_spec m_local_parent_spec;
+ librbd::ParentSpec m_local_parent_spec;
Mutex m_lock;
bool m_canceled = false;
void compute_snap_map();
- int validate_parent(ImageCtxT *image_ctx, librbd::parent_spec *spec);
+ int validate_parent(ImageCtxT *image_ctx, librbd::ParentSpec *spec);
};
const std::string &snap_name,
const cls::rbd::SnapshotNamespace &snap_namespace,
uint64_t size,
- const librbd::parent_spec &spec,
+ const librbd::ParentSpec &spec,
uint64_t parent_overlap,
Context *on_finish)
: m_local_image_ctx(local_image_ctx), m_snap_name(snap_name),
#include "include/rados/librados.hpp"
#include "common/snap_types.h"
#include "librbd/ImageCtx.h"
-#include "librbd/parent_types.h"
+#include "librbd/Types.h"
#include "librbd/journal/TypeTraits.h"
#include <map>
#include <set>
const std::string &snap_name,
const cls::rbd::SnapshotNamespace &snap_namespace,
uint64_t size,
- const librbd::parent_spec &parent_spec,
+ const librbd::ParentSpec &parent_spec,
uint64_t parent_overlap,
Context *on_finish) {
return new SnapshotCreateRequest(local_image_ctx, snap_name, snap_namespace, size,
const std::string &snap_name,
const cls::rbd::SnapshotNamespace &snap_namespace,
uint64_t size,
- const librbd::parent_spec &parent_spec,
+ const librbd::ParentSpec &parent_spec,
uint64_t parent_overlap, Context *on_finish);
void send();
std::string m_snap_name;
cls::rbd::SnapshotNamespace m_snap_namespace;
uint64_t m_size;
- librbd::parent_spec m_parent_spec;
+ librbd::ParentSpec m_parent_spec;
uint64_t m_parent_overlap;
Context *m_on_finish;