librbd/LibrbdAdminSocketHook.cc \
librbd/LibrbdWriteback.cc \
librbd/ObjectMap.cc \
+ librbd/object_map/InvalidateRequest.cc \
librbd/object_map/Request.cc \
librbd/object_map/ResizeRequest.cc \
librbd/object_map/UpdateRequest.cc \
librbd/SnapInfo.h \
librbd/TaskFinisher.h \
librbd/WatchNotifyTypes.h \
+ librbd/object_map/InvalidateRequest.h \
librbd/object_map/Request.h \
librbd/object_map/ResizeRequest.h \
librbd/object_map/UpdateRequest.h \
#include "librbd/ImageCtx.h"
#include "librbd/ImageWatcher.h"
#include "librbd/internal.h"
+#include "librbd/object_map/InvalidateRequest.h"
#include "librbd/object_map/ResizeRequest.h"
#include "librbd/object_map/UpdateRequest.h"
#include "common/dout.h"
return;
}
- flags = RBD_FLAG_OBJECT_MAP_INVALID;
- if ((m_image_ctx.features & RBD_FEATURE_FAST_DIFF) != 0) {
- flags |= RBD_FLAG_FAST_DIFF_INVALID;
- }
-
- CephContext *cct = m_image_ctx.cct;
- lderr(cct) << &m_image_ctx << " invalidating object map" << dendl;
- int r = m_image_ctx.update_flags(snap_id, flags, true);
- if (r < 0) {
- lderr(cct) << "failed to invalidate in-memory object map: "
- << cpp_strerror(r) << dendl;
- return;
- }
-
- // do not update on-disk flags if not image owner
- if (m_image_ctx.image_watcher == NULL ||
- (m_image_ctx.image_watcher->is_lock_supported(m_image_ctx.snap_lock) &&
- !m_image_ctx.image_watcher->is_lock_owner())) {
- return;
- }
+ // TODO remove once all methods are async
+ C_SaferCond cond_ctx;
+ object_map::InvalidateRequest *req = new object_map::InvalidateRequest(
+ m_image_ctx, m_snap_id, force, &cond_ctx);
+ req->send();
- librados::ObjectWriteOperation op;
- if (snap_id == CEPH_NOSNAP && !force) {
- m_image_ctx.image_watcher->assert_header_locked(&op);
- }
- cls_client::set_flags(&op, snap_id, flags, flags);
-
- r = m_image_ctx.md_ctx.operate(m_image_ctx.header_oid, &op);
- if (r == -EBUSY) {
- ldout(cct, 5) << "skipping on-disk object map invalidation: "
- << "image not locked by client" << dendl;
- } else if (r < 0) {
- lderr(cct) << "failed to invalidate on-disk object map: " << cpp_strerror(r)
- << dendl;
- }
+ cond_ctx.wait();
}
} // namespace librbd
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "librbd/object_map/InvalidateRequest.h"
+#include "common/dout.h"
+#include "common/errno.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageWatcher.h"
+
+#define dout_subsys ceph_subsys_rbd
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::object_map::InvalidateRequest: "
+
+namespace librbd {
+namespace object_map {
+
+void InvalidateRequest::send() {
+ assert(m_image_ctx.snap_lock.is_wlocked());
+
+ uint64_t snap_flags;
+ int r = m_image_ctx.get_flags(m_snap_id, &snap_flags);
+ if (r < 0 || ((snap_flags & RBD_FLAG_OBJECT_MAP_INVALID) != 0)) {
+ async_complete(r);
+ return;
+ }
+
+ CephContext *cct = m_image_ctx.cct;
+ lderr(cct) << this << " invalidating object map in-memory" << dendl;
+
+ // update in-memory flags
+ uint64_t flags = RBD_FLAG_OBJECT_MAP_INVALID;
+ if ((m_image_ctx.features & RBD_FEATURE_FAST_DIFF) != 0) {
+ flags |= RBD_FLAG_FAST_DIFF_INVALID;
+ }
+
+ r = m_image_ctx.update_flags(m_snap_id, flags, true);
+ if (r < 0) {
+ async_complete(r);
+ }
+
+ // do not update on-disk flags if not image owner
+ if (m_image_ctx.image_watcher == NULL ||
+ (m_image_ctx.image_watcher->is_lock_supported(m_image_ctx.snap_lock) &&
+ !m_image_ctx.image_watcher->is_lock_owner())) {
+ async_complete(0);
+ return;
+ }
+
+ lderr(cct) << this << " invalidating object map on-disk" << dendl;
+ librados::ObjectWriteOperation op;
+ if (m_snap_id == CEPH_NOSNAP && !m_force) {
+ m_image_ctx.image_watcher->assert_header_locked(&op);
+ }
+ cls_client::set_flags(&op, m_snap_id, flags, flags);
+
+ librados::AioCompletion *rados_completion = create_callback_completion();
+ r = m_image_ctx.md_ctx.aio_operate(m_image_ctx.header_oid, rados_completion,
+ &op);
+ assert(r == 0);
+ rados_completion->release();
+}
+
+bool InvalidateRequest::should_complete(int r) {
+ CephContext *cct = m_image_ctx.cct;
+ lderr(cct) << this << " " << __func__ << ": r=" << r << dendl;
+ return true;
+}
+
+} // namespace object_map
+} // namespace librbd
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_OBJECT_MAP_INVALIDATE_REQUEST_H
+#define CEPH_LIBRBD_OBJECT_MAP_INVALIDATE_REQUEST_H
+
+#include "include/int_types.h"
+#include "librbd/AsyncRequest.h"
+
+class Context;
+
+namespace librbd {
+
+class ImageCtx;
+
+namespace object_map {
+
+class InvalidateRequest : public AsyncRequest<> {
+public:
+ InvalidateRequest(ImageCtx &image_ctx, uint64_t snap_id, bool force,
+ Context *on_finish)
+ : AsyncRequest(image_ctx, on_finish), m_snap_id(snap_id), m_force(force) {
+ }
+
+ virtual void send();
+
+protected:
+ virtual bool should_complete(int r);
+ virtual int filter_return_code(int r) const {
+ // never propagate an error back to the caller
+ return 0;
+ }
+
+private:
+ uint64_t m_snap_id;
+ bool m_force;
+
+};
+
+} // namespace object_map
+} // namespace librbd
+
+#endif // CEPH_LIBRBD_OBJECT_MAP_INVALIDATE_REQUEST_H
#include "common/RWLock.h"
#include "librbd/ImageCtx.h"
#include "librbd/ImageWatcher.h"
+#include "librbd/object_map/InvalidateRequest.h"
#define dout_subsys ceph_subsys_rbd
#undef dout_prefix
return true;
}
- CephContext *cct = m_image_ctx.cct;
- RWLock::WLocker snap_locker(m_image_ctx.snap_lock);
-
- // requests shouldn't be running while using snapshots
- assert(m_image_ctx.snap_id == CEPH_NOSNAP);
-
- uint64_t flags = RBD_FLAG_OBJECT_MAP_INVALID;
- if ((m_image_ctx.features & RBD_FEATURE_FAST_DIFF) != 0) {
- flags |= RBD_FLAG_FAST_DIFF_INVALID;
- }
-
- lderr(cct) << &m_image_ctx << " invalidating object map" << dendl;
m_state = STATE_INVALIDATE;
- m_image_ctx.flags |= flags;
- librados::ObjectWriteOperation op;
- cls_client::set_flags(&op, CEPH_NOSNAP, flags, flags);
-
- librados::AioCompletion *rados_completion = create_callback_completion();
- int r = m_image_ctx.md_ctx.aio_operate(m_image_ctx.header_oid,
- rados_completion, &op);
- assert(r == 0);
- rados_completion->release();
+ RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
+ RWLock::WLocker snap_locker(m_image_ctx.snap_lock);
+ InvalidateRequest *req = new InvalidateRequest(m_image_ctx, m_snap_id, true,
+ create_callback_context());
+ req->send();
return false;
}