return flags;
}
- int ImageCtx::snap_set(cls::rbd::SnapshotNamespace in_snap_namespace,
- string in_snap_name)
- {
+ int ImageCtx::snap_set(uint64_t in_snap_id) {
assert(snap_lock.is_wlocked());
- snap_t in_snap_id = get_snap_id(in_snap_namespace, in_snap_name);
- if (in_snap_id != CEPH_NOSNAP) {
+ auto it = snap_info.find(in_snap_id);
+ if (in_snap_id != CEPH_NOSNAP && it != snap_info.end()) {
snap_id = in_snap_id;
- snap_namespace = in_snap_namespace;
- snap_name = in_snap_name;
+ snap_namespace = it->second.snap_namespace;
+ snap_name = it->second.name;
snap_exists = true;
data_ctx.snap_set_read(snap_id);
return 0;
void perf_stop();
void set_read_flag(unsigned flag);
int get_read_flags(librados::snap_t snap_id);
- int snap_set(cls::rbd::SnapshotNamespace in_snap_namespace,
- std::string in_snap_name);
+ int snap_set(uint64_t snap_id);
void snap_unset();
librados::snap_t get_snap_id(const cls::rbd::SnapshotNamespace& in_snap_namespace,
const std::string& in_snap_name) const;
}
template <typename I>
-void ImageState<I>::snap_set(const cls::rbd::SnapshotNamespace &snap_namespace,
- const std::string &snap_name,
- Context *on_finish) {
+void ImageState<I>::snap_set(uint64_t snap_id, Context *on_finish) {
CephContext *cct = m_image_ctx->cct;
- ldout(cct, 20) << __func__ << ": snap_name=" << snap_name << dendl;
+ ldout(cct, 20) << __func__ << ": snap_id=" << snap_id << dendl;
Action action(ACTION_TYPE_SET_SNAP);
- action.snap_namespace = snap_namespace;
- action.snap_name = snap_name;
+ action.snap_id = snap_id;
m_lock.Lock();
execute_action_unlock(action, on_finish);
CephContext *cct = m_image_ctx->cct;
ldout(cct, 10) << this << " " << __func__ << ": "
- << "snap_name=" << action_contexts.first.snap_name << dendl;
+ << "snap_id=" << action_contexts.first.snap_id << dendl;
Context *ctx = create_async_context_callback(
*m_image_ctx, create_context_callback<
ImageState<I>, &ImageState<I>::handle_set_snap>(this));
image::SetSnapRequest<I> *req = image::SetSnapRequest<I>::create(
- *m_image_ctx, action_contexts.first.snap_namespace, action_contexts.first.snap_name, ctx);
+ *m_image_ctx, action_contexts.first.snap_id, ctx);
m_lock.Unlock();
req->send();
int refresh_if_required();
void refresh(Context *on_finish);
- void snap_set(const cls::rbd::SnapshotNamespace &snap_namespace,
- const std::string &snap_name,
- Context *on_finish);
+ void snap_set(uint64_t snap_id, Context *on_finish);
void prepare_lock(Context *on_ready);
void handle_prepare_lock_complete();
struct Action {
ActionType action_type;
uint64_t refresh_seq = 0;
- cls::rbd::SnapshotNamespace snap_namespace;
- std::string snap_name;
+ uint64_t snap_id = CEPH_NOSNAP;
Context *on_ready = nullptr;
Action(ActionType action_type) : action_type(action_type) {
case ACTION_TYPE_REFRESH:
return (refresh_seq == action.refresh_seq);
case ACTION_TYPE_SET_SNAP:
- return (snap_name == action.snap_name) && (snap_namespace == action.snap_namespace);
+ return (snap_id == action.snap_id);
case ACTION_TYPE_LOCK:
return false;
default:
}
return r;
}
- std::string snap_name;
- {
- RWLock::RLocker parent_snap_locker(src_parent_image_ctx->snap_lock);
- auto it = src_parent_image_ctx->snap_info.find(parent_spec.snap_id);
- if (it == src_parent_image_ctx->snap_info.end()) {
- return -ENOENT;
- }
- snap_name = it->second.name;
- }
C_SaferCond cond;
- src_parent_image_ctx->state->snap_set(cls::rbd::UserSnapshotNamespace(),
- snap_name, &cond);
+ src_parent_image_ctx->state->snap_set(parent_spec.snap_id, &cond);
r = cond.wait();
if (r < 0) {
if (r != -ENOENT) {
CephContext *cct = m_image_ctx->cct;
ldout(cct, 10) << this << " " << __func__ << dendl;
+ uint64_t snap_id = CEPH_NOSNAP;
+ {
+ RWLock::RLocker snap_locker(m_image_ctx->snap_lock);
+ snap_id = m_image_ctx->get_snap_id(m_image_ctx->snap_namespace,
+ m_image_ctx->snap_name);
+ }
+ if (snap_id == CEPH_NOSNAP) {
+ *result = -ENOENT;
+ return m_on_finish;
+ }
+
using klass = OpenRequest<I>;
SetSnapRequest<I> *req = SetSnapRequest<I>::create(
- *m_image_ctx, m_image_ctx->snap_namespace, m_image_ctx->snap_name,
+ *m_image_ctx, snap_id,
create_context_callback<klass, &klass::handle_set_snap>(this));
req->send();
return nullptr;
CephContext *cct = m_child_image_ctx.cct;
ldout(cct, 10) << this << " " << __func__ << dendl;
- cls::rbd::SnapshotNamespace snap_namespace;
- std::string snap_name;
- {
- RWLock::RLocker snap_locker(m_parent_image_ctx->snap_lock);
- const SnapInfo *info = m_parent_image_ctx->get_snap_info(m_parent_md.spec.snap_id);
- if (!info) {
- lderr(cct) << "failed to locate snapshot: Snapshot with this id not found" << dendl;
- send_complete(-ENOENT);
- return;
- }
- snap_namespace = info->snap_namespace;
- snap_name = info->name;
- }
-
using klass = RefreshParentRequest<I>;
Context *ctx = create_context_callback<
klass, &klass::handle_set_parent_snap, false>(this);
SetSnapRequest<I> *req = SetSnapRequest<I>::create(
- *m_parent_image_ctx, snap_namespace, snap_name, ctx);
+ *m_parent_image_ctx, m_parent_md.spec.snap_id, ctx);
req->send();
}
using util::create_context_callback;
template <typename I>
-SetSnapRequest<I>::SetSnapRequest(I &image_ctx, const cls::rbd::SnapshotNamespace& snap_namespace,
- const std::string &snap_name,
+SetSnapRequest<I>::SetSnapRequest(I &image_ctx, uint64_t snap_id,
Context *on_finish)
- : m_image_ctx(image_ctx), m_snap_namespace(snap_namespace),
- m_snap_name(snap_name), m_on_finish(on_finish),
- m_snap_id(CEPH_NOSNAP), m_exclusive_lock(nullptr), m_object_map(nullptr),
- m_refresh_parent(nullptr), m_writes_blocked(false) {
+ : m_image_ctx(image_ctx), m_snap_id(snap_id), m_on_finish(on_finish),
+ m_exclusive_lock(nullptr), m_object_map(nullptr), m_refresh_parent(nullptr),
+ m_writes_blocked(false) {
}
template <typename I>
template <typename I>
void SetSnapRequest<I>::send() {
- if (m_snap_name.empty()) {
+ if (m_snap_id == CEPH_NOSNAP) {
send_init_exclusive_lock();
} else {
send_block_writes();
{
RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
- m_snap_id = m_image_ctx.get_snap_id(m_snap_namespace, m_snap_name);
- if (m_snap_id == CEPH_NOSNAP) {
- ldout(cct, 5) << "failed to locate snapshot '" << m_snap_name << "'"
+ auto it = m_image_ctx.snap_info.find(m_snap_id);
+ if (it == m_image_ctx.snap_info.end()) {
+ ldout(cct, 5) << "failed to locate snapshot '" << m_snap_id << "'"
<< dendl;
*result = -ENOENT;
RWLock::WLocker parent_locker(m_image_ctx.parent_lock);
if (m_snap_id != CEPH_NOSNAP) {
assert(m_image_ctx.exclusive_lock == nullptr);
- int r = m_image_ctx.snap_set(m_snap_namespace, m_snap_name);
+ int r = m_image_ctx.snap_set(m_snap_id);
if (r < 0) {
return r;
}
template <typename ImageCtxT = ImageCtx>
class SetSnapRequest {
public:
- static SetSnapRequest *create(ImageCtxT &image_ctx,
- const cls::rbd::SnapshotNamespace& snap_namespace,
- const std::string &snap_name,
+ static SetSnapRequest *create(ImageCtxT &image_ctx, uint64_t snap_id,
Context *on_finish) {
- return new SetSnapRequest(image_ctx, snap_namespace, snap_name, on_finish);
+ return new SetSnapRequest(image_ctx, snap_id, on_finish);
}
~SetSnapRequest();
* @endverbatim
*/
- SetSnapRequest(ImageCtxT &image_ctx, const cls::rbd::SnapshotNamespace& snap_namespace,
- const std::string &snap_name,
- Context *on_finish);
+ SetSnapRequest(ImageCtxT &image_ctx, uint64_t snap_id, Context *on_finish);
ImageCtxT &m_image_ctx;
- cls::rbd::SnapshotNamespace m_snap_namespace;
- std::string m_snap_name;
+ uint64_t m_snap_id;
Context *m_on_finish;
- uint64_t m_snap_id;
ExclusiveLock<ImageCtxT> *m_exclusive_lock;
ObjectMap<ImageCtxT> *m_object_map;
RefreshParentRequest<ImageCtxT> *m_refresh_parent;
return r;
}
- int snap_set(ImageCtx *ictx, const cls::rbd::SnapshotNamespace &snap_namespace,
+ int snap_set(ImageCtx *ictx,
+ const cls::rbd::SnapshotNamespace &snap_namespace,
const char *snap_name)
{
ldout(ictx->cct, 20) << "snap_set " << ictx << " snap = "
// snapshot and the user is trying to fix that
ictx->state->refresh_if_required();
- C_SaferCond ctx;
+ uint64_t snap_id = CEPH_NOSNAP;
std::string name(snap_name == nullptr ? "" : snap_name);
- ictx->state->snap_set(snap_namespace, name, &ctx);
+ if (!name.empty()) {
+ RWLock::RLocker snap_locker(ictx->snap_lock);
+ snap_id = ictx->get_snap_id(cls::rbd::UserSnapshotNamespace{},
+ snap_name);
+ if (snap_id == CEPH_NOSNAP) {
+ return -ENOENT;
+ }
+ }
+ C_SaferCond ctx;
+ ictx->state->snap_set(snap_id, &ctx);
int r = ctx.wait();
if (r < 0) {
if (r != -ENOENT) {
ASSERT_EQ(0, image_ctx->operations->snap_protect(
cls::rbd::UserSnapshotNamespace{}, "snap"));
+ uint64_t snap_id = image_ctx->snap_ids[
+ {cls::rbd::UserSnapshotNamespace{}, "snap"}];
+ ASSERT_NE(CEPH_NOSNAP, snap_id);
+
C_SaferCond ctx;
- image_ctx->state->snap_set(cls::rbd::UserSnapshotNamespace{}, "snap",
- &ctx);
+ image_ctx->state->snap_set(snap_id, &ctx);
ASSERT_EQ(0, ctx.wait());
}
}
MOCK_METHOD0(close, int());
MOCK_METHOD1(close, void(Context*));
- MOCK_METHOD3(snap_set, void(const cls::rbd::SnapshotNamespace &, const std::string &, Context*));
+ MOCK_METHOD2(snap_set, void(uint64_t snap_id, Context*));
MOCK_METHOD1(prepare_lock, void(Context*));
MOCK_METHOD0(handle_prepare_lock_complete, void());
void expect_snap_set(librbd::MockTestImageCtx &mock_image_ctx,
const std::string &snap_name, int r) {
- EXPECT_CALL(*mock_image_ctx.state, snap_set(_, StrEq(snap_name), _))
- .WillOnce(WithArg<2>(Invoke([this, r](Context *on_finish) {
+ EXPECT_CALL(*mock_image_ctx.state, snap_set(_, _))
+ .WillOnce(Invoke([this, &mock_image_ctx, snap_name, r](uint64_t snap_id, Context *on_finish) {
+ RWLock::RLocker snap_locker(mock_image_ctx.snap_lock);
+ auto id = mock_image_ctx.image_ctx->get_snap_id(
+ cls::rbd::UserSnapshotNamespace{}, snap_name);
+ ASSERT_NE(snap_id, id);
m_threads->work_queue->queue(on_finish, r);
- })));
+ }));
}
void expect_clone_image(MockCloneRequest &mock_clone_request,
read_local_bl.append(std::string(object_size, '1'));
for (auto &snap_name : snap_names) {
+ uint64_t remote_snap_id;
+ {
+ RWLock::RLocker remote_snap_locker(m_remote_image_ctx->snap_lock);
+ remote_snap_id = m_remote_image_ctx->get_snap_id(
+ cls::rbd::UserSnapshotNamespace{}, snap_name);
+ }
+
uint64_t remote_size;
{
C_SaferCond ctx;
- m_remote_image_ctx->state->snap_set(cls::rbd::UserSnapshotNamespace(),
- snap_name,
- &ctx);
+ m_remote_image_ctx->state->snap_set(remote_snap_id, &ctx);
ASSERT_EQ(0, ctx.wait());
RWLock::RLocker remote_snap_locker(m_remote_image_ctx->snap_lock);
m_remote_image_ctx->snap_id);
}
+ uint64_t local_snap_id;
+ {
+ RWLock::RLocker snap_locker(m_local_image_ctx->snap_lock);
+ local_snap_id = m_local_image_ctx->get_snap_id(
+ cls::rbd::UserSnapshotNamespace{}, snap_name);
+ }
+
uint64_t local_size;
{
C_SaferCond ctx;
- m_local_image_ctx->state->snap_set(cls::rbd::UserSnapshotNamespace(),
- snap_name,
- &ctx);
+ m_local_image_ctx->state->snap_set(local_snap_id, &ctx);
ASSERT_EQ(0, ctx.wait());
RWLock::RLocker snap_locker(m_local_image_ctx->snap_lock);
.WillOnce(Return(123));
}
- void expect_snap_set(librbd::MockTestImageCtx &mock_image_ctx,
- const std::string &snap_name, int r) {
- EXPECT_CALL(*mock_image_ctx.state, snap_set(_, StrEq(snap_name), _))
- .WillOnce(WithArg<2>(Invoke([this, r](Context *on_finish) {
- m_threads->work_queue->queue(on_finish, r);
- })));
- }
-
void expect_notify_sync_request(MockInstanceWatcher &mock_instance_watcher,
const std::string &sync_id, int r) {
EXPECT_CALL(mock_instance_watcher, notify_sync_request(sync_id, _))
template <typename I>
void CreateImageRequest<I>::set_local_parent_snap() {
- dout(20) << dendl;
-
- {
- RWLock::RLocker remote_snap_locker(m_remote_parent_image_ctx->snap_lock);
- auto it = m_remote_parent_image_ctx->snap_info.find(
- m_remote_parent_spec.snap_id);
- if (it != m_remote_parent_image_ctx->snap_info.end()) {
- m_parent_snap_name = it->second.name;
- }
- }
-
- if (m_parent_snap_name.empty()) {
- m_ret_val = -ENOENT;
- close_local_parent_image();
- return;
- }
- dout(20) << ": parent_snap_name=" << m_parent_snap_name << dendl;
+ dout(20) << ": parent_snap_id=" << m_remote_parent_spec.snap_id << dendl;
Context *ctx = create_context_callback<
CreateImageRequest<I>,
&CreateImageRequest<I>::handle_set_local_parent_snap>(this);
- m_local_parent_image_ctx->state->snap_set(cls::rbd::UserSnapshotNamespace(),
- m_parent_snap_name,
+ m_local_parent_image_ctx->state->snap_set(m_remote_parent_spec.snap_id,
ctx);
}
void CreateImageRequest<I>::handle_set_local_parent_snap(int r) {
dout(20) << ": r=" << r << dendl;
if (r < 0) {
- derr << ": failed to set parent snapshot " << m_parent_snap_name
+ derr << ": failed to set parent snapshot " << m_remote_parent_spec.snap_id
<< ": " << cpp_strerror(r) << dendl;
m_ret_val = r;
close_local_parent_image();
bufferlist m_out_bl;
std::string m_parent_global_image_id;
std::string m_parent_pool_name;
- std::string m_parent_snap_name;
int m_ret_val = 0;
void create_image();