case SnapshotRollbackRequest<I>::STATE_ROLLBACK_OBJECTS:
os << "ROLLBACK_OBJECTS";
break;
+ case SnapshotRollbackRequest<I>::STATE_REFRESH_OBJECT_MAP:
+ os << "REFRESH_OBJECT_MAP";
+ break;
case SnapshotRollbackRequest<I>::STATE_INVALIDATE_CACHE:
os << "INVALIDATE_CACHE";
break;
uint64_t snap_size,
ProgressContext &prog_ctx)
: Request<I>(image_ctx, on_finish), m_snap_name(snap_name),
- m_snap_id(snap_id), m_snap_size(snap_size), m_prog_ctx(prog_ctx) {
+ m_snap_id(snap_id), m_snap_size(snap_size), m_prog_ctx(prog_ctx),
+ m_object_map(nullptr) {
+}
+
+template <typename I>
+SnapshotRollbackRequest<I>::~SnapshotRollbackRequest() {
+ delete m_object_map;
}
template <typename I>
send_rollback_objects();
break;
case STATE_ROLLBACK_OBJECTS:
+ finished = send_refresh_object_map();
+ break;
+ case STATE_REFRESH_OBJECT_MAP:
finished = send_invalidate_cache();
break;
case STATE_INVALIDATE_CACHE:
throttle->start_ops(image_ctx.concurrent_management_ops);
}
+template <typename I>
+bool SnapshotRollbackRequest<I>::send_refresh_object_map() {
+ I &image_ctx = this->m_image_ctx;
+ assert(image_ctx.owner_lock.is_locked());
+
+ if (image_ctx.object_map == nullptr) {
+ return send_invalidate_cache();
+ }
+
+ CephContext *cct = image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << dendl;
+ m_state = STATE_REFRESH_OBJECT_MAP;
+
+ m_object_map = image_ctx.create_object_map(CEPH_NOSNAP);
+
+ image_ctx.owner_lock.put_read();
+ Context *ctx = this->create_callback_context();
+ m_object_map->open(ctx);
+ image_ctx.owner_lock.get_read();
+
+ return false;
+}
+
template <typename I>
bool SnapshotRollbackRequest<I>::send_invalidate_cache() {
I &image_ctx = this->m_image_ctx;
assert(image_ctx.owner_lock.is_locked());
+ apply();
+
if (image_ctx.object_cacher == NULL) {
return true;
}
return false;
}
+template <typename I>
+void SnapshotRollbackRequest<I>::apply() {
+ I &image_ctx = this->m_image_ctx;
+
+ assert(image_ctx.owner_lock.is_locked());
+ RWLock::WLocker snap_locker(image_ctx.snap_lock);
+ if (image_ctx.object_map != nullptr) {
+ std::swap(m_object_map, image_ctx.object_map);
+ }
+}
+
} // namespace operation
} // namespace librbd
#define CEPH_LIBRBD_OPERATION_SNAPSHOT_ROLLBACK_REQUEST_H
#include "librbd/operation/Request.h"
+#include "librbd/ImageCtx.h"
#include "librbd/internal.h"
#include <string>
* . . . . > STATE_ROLLBACK_OBJECT_MAP
* . |
* . v
- * . . . . > STATE_ROLLBACK_OBJECTS . . .
- * | .
- * v .
- * STATE_INVALIDATE_CACHE .
- * | .
- * v .
- * <finish> < . . . . . . . .
+ * . . . . > STATE_ROLLBACK_OBJECTS . . . . . . . . . . .
+ * | .
+ * v .
+ * STATE_REFRESH_OBJECT_MAP (skip if object .
+ * | map disabled) .
+ * v .
+ * STATE_INVALIDATE_CACHE .
+ * | .
+ * v .
+ * <finish> < . . . . . . . . . . . . . . . .
*
* @endverbatim
*
STATE_RESIZE_IMAGE,
STATE_ROLLBACK_OBJECT_MAP,
STATE_ROLLBACK_OBJECTS,
+ STATE_REFRESH_OBJECT_MAP,
STATE_INVALIDATE_CACHE
};
SnapshotRollbackRequest(ImageCtxT &image_ctx, Context *on_finish,
const std::string &snap_name, uint64_t snap_id,
uint64_t snap_size, ProgressContext &prog_ctx);
+ virtual ~SnapshotRollbackRequest();
protected:
virtual void send_op();
NoOpProgressContext m_no_op_prog_ctx;
State m_state;
+ decltype(ImageCtxT::object_map) m_object_map;
+
void send_resize_image();
void send_rollback_object_map();
void send_rollback_objects();
+ bool send_refresh_object_map();
bool send_invalidate_cache();
+ void apply();
};
} // namespace operation