trace_endpoint.copy_name(pname);
perf_start(pname);
+ assert(image_watcher == NULL);
+ image_watcher = new ImageWatcher<>(*this);
+ }
+
+ void ImageCtx::init_cache() {
if (cache) {
Mutex::Locker l(cache_lock);
ldout(cct, 20) << "enabling caching..." << dendl;
<< " max_dirty_age="
<< cache_max_dirty_age << dendl;
- object_cacher = new ObjectCacher(cct, pname, *writeback_handler, cache_lock,
- NULL, NULL,
- cache_size,
+ object_cacher = new ObjectCacher(cct, perfcounter->get_name(),
+ *writeback_handler, cache_lock, NULL,
+ NULL, cache_size,
10, /* reset this in init */
init_max_dirty,
cache_target_dirty,
}
void ImageCtx::register_watch(Context *on_finish) {
- assert(image_watcher == NULL);
- image_watcher = new ImageWatcher<>(*this);
+ assert(image_watcher != NULL);
image_watcher->register_watch(on_finish);
}
namespace librbd {
namespace image {
-namespace {
-
-static uint64_t MAX_METADATA_ITEMS = 128;
-
-}
-
using util::create_context_callback;
using util::create_rados_callback;
OpenRequest<I>::OpenRequest(I *image_ctx, bool skip_open_parent,
Context *on_finish)
: m_image_ctx(image_ctx), m_skip_open_parent_image(skip_open_parent),
- m_on_finish(on_finish), m_error_result(0),
- m_last_metadata_key(ImageCtx::METADATA_CONF_PREFIX) {
+ m_on_finish(on_finish), m_error_result(0) {
}
template <typename I>
m_image_ctx->header_oid = util::old_header_name(m_image_ctx->name);
m_image_ctx->apply_metadata({}, true);
- send_register_watch();
+ send_refresh();
}
return nullptr;
}
}
m_image_ctx->init_layout();
- send_v2_apply_metadata();
+ send_refresh();
return nullptr;
}
template <typename I>
-void OpenRequest<I>::send_v2_apply_metadata() {
- CephContext *cct = m_image_ctx->cct;
- ldout(cct, 10) << this << " " << __func__ << ": "
- << "start_key=" << m_last_metadata_key << dendl;
+void OpenRequest<I>::send_refresh() {
+ m_image_ctx->init();
- librados::ObjectReadOperation op;
- cls_client::metadata_list_start(&op, m_last_metadata_key, MAX_METADATA_ITEMS);
+ CephContext *cct = m_image_ctx->cct;
+ ldout(cct, 10) << this << " " << __func__ << dendl;
using klass = OpenRequest<I>;
- librados::AioCompletion *comp =
- create_rados_callback<klass, &klass::handle_v2_apply_metadata>(this);
- m_out_bl.clear();
- m_image_ctx->md_ctx.aio_operate(m_image_ctx->header_oid, comp, &op,
- &m_out_bl);
- comp->release();
+ RefreshRequest<I> *req = RefreshRequest<I>::create(
+ *m_image_ctx, false, m_skip_open_parent_image,
+ create_context_callback<klass, &klass::handle_refresh>(this));
+ req->send();
}
template <typename I>
-Context *OpenRequest<I>::handle_v2_apply_metadata(int *result) {
+Context *OpenRequest<I>::handle_refresh(int *result) {
CephContext *cct = m_image_ctx->cct;
- ldout(cct, 10) << this << " " << __func__ << ": r=" << *result << dendl;
-
- std::map<std::string, bufferlist> metadata;
- if (*result == 0) {
- bufferlist::iterator it = m_out_bl.begin();
- *result = cls_client::metadata_list_finish(&it, &metadata);
- }
+ ldout(cct, 10) << __func__ << ": r=" << *result << dendl;
- if (*result == -EOPNOTSUPP || *result == -EIO) {
- ldout(cct, 10) << "config metadata not supported by OSD" << dendl;
- } else if (*result < 0) {
- lderr(cct) << "failed to retrieve metadata: " << cpp_strerror(*result)
+ if (*result < 0) {
+ lderr(cct) << "failed to refresh image: " << cpp_strerror(*result)
<< dendl;
send_close_image(*result);
return nullptr;
}
- if (!metadata.empty()) {
- m_metadata.insert(metadata.begin(), metadata.end());
- m_last_metadata_key = metadata.rbegin()->first;
- if (boost::starts_with(m_last_metadata_key,
- ImageCtx::METADATA_CONF_PREFIX)) {
- send_v2_apply_metadata();
- return nullptr;
- }
- }
-
- m_image_ctx->apply_metadata(m_metadata, true);
-
- send_register_watch();
- return nullptr;
+ m_image_ctx->init_cache();
+ return send_register_watch(result);
}
template <typename I>
-void OpenRequest<I>::send_register_watch() {
- m_image_ctx->init();
-
+Context *OpenRequest<I>::send_register_watch(int *result) {
if (m_image_ctx->read_only) {
- send_refresh();
- return;
+ return send_set_snap(result);
}
CephContext *cct = m_image_ctx->cct;
Context *ctx = create_context_callback<
klass, &klass::handle_register_watch>(this);
m_image_ctx->register_watch(ctx);
+ return nullptr;
}
template <typename I>
lderr(cct) << "failed to register watch: " << cpp_strerror(*result)
<< dendl;
send_close_image(*result);
- } else {
- send_refresh();
- }
- return nullptr;
-}
-
-template <typename I>
-void OpenRequest<I>::send_refresh() {
- CephContext *cct = m_image_ctx->cct;
- ldout(cct, 10) << this << " " << __func__ << dendl;
-
- using klass = OpenRequest<I>;
- RefreshRequest<I> *req = RefreshRequest<I>::create(
- *m_image_ctx, false, m_skip_open_parent_image,
- create_context_callback<klass, &klass::handle_refresh>(this));
- req->send();
-}
-
-template <typename I>
-Context *OpenRequest<I>::handle_refresh(int *result) {
- CephContext *cct = m_image_ctx->cct;
- ldout(cct, 10) << __func__ << ": r=" << *result << dendl;
-
- if (*result < 0) {
- lderr(cct) << "failed to refresh image: " << cpp_strerror(*result)
- << dendl;
- send_close_image(*result);
return nullptr;
- } else {
- return send_set_snap(result);
}
+
+ return send_set_snap(result);
}
template <typename I>
* V2_GET_CREATE_TIMESTAMP |
* | |
* v |
- * V2_GET_DATA_POOL |
- * | |
- * v |
- * /---> V2_APPLY_METADATA -------------> REGISTER_WATCH (skip if
- * | | | read-only)
- * \---------/ v
- * REFRESH
+ * V2_GET_DATA_POOL --------------> REFRESH
* |
* v
+ * REGISTER_WATCH (skip if
+ * | read-only)
+ * v
* SET_SNAP (skip if no snap)
* |
* v
bufferlist m_out_bl;
int m_error_result;
- std::string m_last_metadata_key;
- std::map<std::string, bufferlist> m_metadata;
-
void send_v1_detect_header();
Context *handle_v1_detect_header(int *result);
void send_v2_get_data_pool();
Context *handle_v2_get_data_pool(int *result);
- void send_v2_apply_metadata();
- Context *handle_v2_apply_metadata(int *result);
-
- void send_register_watch();
- Context *handle_register_watch(int *result);
-
void send_refresh();
Context *handle_refresh(int *result);
+ Context *send_register_watch(int *result);
+ Context *handle_register_watch(int *result);
+
Context *send_set_snap(int *result);
Context *handle_set_snap(int *result);