namespace librbd {
ObjectMap::ObjectMap(ImageCtx &image_ctx)
- : m_image_ctx(image_ctx), m_enabled(false)
+ : m_image_ctx(image_ctx), m_snap_id(CEPH_NOSNAP), m_enabled(false)
{
}
{
assert(m_image_ctx.snap_lock.is_wlocked());
RWLock::WLocker l(m_image_ctx.object_map_lock);
+ m_snap_id = snap_id;
if ((m_image_ctx.features & RBD_FEATURE_OBJECT_MAP) == 0 ||
(m_image_ctx.snap_id == snap_id && !m_image_ctx.snap_exists)) {
invalidate(snap_id);
librados::ObjectWriteOperation op;
- rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", "");
+ if (snap_id == CEPH_NOSNAP) {
+ rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "",
+ "");
+ }
op.truncate(0);
cls_client::object_map_resize(&op, num_objs, OBJECT_NONEXISTENT);
// correct the size issue so future IO can keep the object map in sync
librados::ObjectWriteOperation op;
- rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", "");
+ if (snap_id == CEPH_NOSNAP) {
+ rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "",
+ "");
+ }
cls_client::object_map_resize(&op, num_objs, OBJECT_NONEXISTENT);
r = m_image_ctx.md_ctx.operate(oid, &op);
Context *on_finish) {
assert(m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP));
assert(m_image_ctx.owner_lock.is_locked());
- assert(m_image_ctx.image_watcher->is_lock_owner());
+ assert(!m_image_ctx.image_watcher->is_lock_supported() ||
+ m_image_ctx.image_watcher->is_lock_owner());
ResizeRequest *req = new ResizeRequest(
- m_image_ctx, new_size, default_object_state, on_finish);
+ m_image_ctx, m_snap_id, new_size, default_object_state, on_finish);
req->send();
}
{
assert(m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP));
assert(m_image_ctx.owner_lock.is_locked());
- assert(m_image_ctx.image_watcher->is_lock_owner());
+ assert(!m_image_ctx.image_watcher->is_lock_supported() ||
+ m_image_ctx.image_watcher->is_lock_owner());
assert(m_image_ctx.object_map_lock.is_wlocked());
assert(start_object_no < end_object_no);
++object_no) {
if ((!current_state || m_object_map[object_no] == *current_state) &&
m_object_map[object_no] != new_state) {
- UpdateRequest *req = new UpdateRequest(m_image_ctx, start_object_no,
- end_object_no, new_state,
- current_state, on_finish);
+ UpdateRequest *req = new UpdateRequest(m_image_ctx, m_snap_id,
+ start_object_no, end_object_no,
+ new_state, current_state,
+ on_finish);
req->send();
return true;
}
<< m_num_objs << dendl;
librados::ObjectWriteOperation op;
- rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", "");
+ if (m_snap_id == CEPH_NOSNAP) {
+ rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", "");
+ }
cls_client::object_map_resize(&op, m_num_objs, m_default_object_state);
librados::AioCompletion *rados_completion = create_callback_completion();
- std::string oid(object_map_name(m_image_ctx.id, CEPH_NOSNAP));
+ std::string oid(object_map_name(m_image_ctx.id, m_snap_id));
int r = m_image_ctx.md_ctx.aio_operate(oid, rados_completion, &op);
assert(r == 0);
rados_completion->release();
}
librados::ObjectWriteOperation op;
- rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", "");
+ if (m_snap_id == CEPH_NOSNAP) {
+ rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", "");
+ }
cls_client::object_map_update(&op, m_start_object_no, m_end_object_no,
m_new_state, m_current_state);
librados::AioCompletion *rados_completion = create_callback_completion();
- std::string oid(object_map_name(m_image_ctx.id, CEPH_NOSNAP));
+ std::string oid(object_map_name(m_image_ctx.id, m_snap_id));
int r = m_image_ctx.md_ctx.aio_operate(oid, rados_completion, &op);
assert(r == 0);
rados_completion->release();
class Request : public AsyncRequest {
public:
- Request(ImageCtx &image_ctx, Context *on_finish)
- : AsyncRequest(image_ctx, on_finish), m_state(STATE_REQUEST)
+ Request(ImageCtx &image_ctx, uint64_t snap_id, Context *on_finish)
+ : AsyncRequest(image_ctx, on_finish), m_snap_id(snap_id),
+ m_state(STATE_REQUEST)
{
}
protected:
+ const uint64_t m_snap_id;
+
virtual bool should_complete(int r);
virtual void finish(ObjectMap *object_map) = 0;
-
private:
/**
* <start> ---> STATE_REQUEST ---> <finish>
State m_state;
bool invalidate();
- };
+ };
class ResizeRequest : public Request {
public:
- ResizeRequest(ImageCtx &image_ctx, uint64_t new_size,
+ ResizeRequest(ImageCtx &image_ctx, uint64_t snap_id, uint64_t new_size,
uint8_t default_object_state, Context *on_finish)
- : Request(image_ctx, on_finish), m_num_objs(0), m_new_size(new_size),
- m_default_object_state(default_object_state)
+ : Request(image_ctx, snap_id, on_finish), m_num_objs(0),
+ m_new_size(new_size), m_default_object_state(default_object_state)
{
}
class UpdateRequest : public Request {
public:
- UpdateRequest(ImageCtx &image_ctx, uint64_t start_object_no,
- uint64_t end_object_no, uint8_t new_state,
+ UpdateRequest(ImageCtx &image_ctx, uint64_t snap_id,
+ uint64_t start_object_no, uint64_t end_object_no,
+ uint8_t new_state,
const boost::optional<uint8_t> ¤t_state,
Context *on_finish)
- : Request(image_ctx, on_finish), m_start_object_no(start_object_no),
- m_end_object_no(end_object_no), m_new_state(new_state),
- m_current_state(current_state)
+ : Request(image_ctx, snap_id, on_finish),
+ m_start_object_no(start_object_no), m_end_object_no(end_object_no),
+ m_new_state(new_state), m_current_state(current_state)
{
}
ImageCtx &m_image_ctx;
ceph::BitVector<2> m_object_map;
+ uint64_t m_snap_id;
bool m_enabled;
void invalidate(uint64_t snap_id);