AsyncFlattenObjectContext(AsyncObjectThrottle &throttle, ImageCtx *image_ctx,
uint64_t object_size, ::SnapContext snapc,
uint64_t object_no)
- : C_AsyncObjectThrottle(throttle), m_image_ctx(*image_ctx),
- m_object_size(object_size), m_snapc(snapc), m_object_no(object_no)
+ : C_AsyncObjectThrottle(throttle, *image_ctx), m_object_size(object_size),
+ m_snapc(snapc), m_object_no(object_no)
{
}
}
private:
- ImageCtx &m_image_ctx;
uint64_t m_object_size;
::SnapContext m_snapc;
uint64_t m_object_no;
boost::lambda::_1, &m_image_ctx, m_object_size, m_snapc,
boost::lambda::_2));
AsyncObjectThrottle *throttle = new AsyncObjectThrottle(
- *this, context_factory, create_callback_context(), m_prog_ctx, 0,
- m_overlap_objects);
+ this, m_image_ctx, context_factory, create_callback_context(), m_prog_ctx,
+ 0, m_overlap_objects);
throttle->start_ops(cct->_conf->rbd_concurrent_management_ops);
}
// vim: ts=8 sw=2 smarttab
#include "librbd/AsyncObjectThrottle.h"
#include "include/rbd/librbd.hpp"
+#include "common/RWLock.h"
#include "librbd/AsyncRequest.h"
+#include "librbd/ImageCtx.h"
#include "librbd/internal.h"
namespace librbd
{
-AsyncObjectThrottle::AsyncObjectThrottle(const AsyncRequest& async_request,
+void C_AsyncObjectThrottle::finish(int r) {
+ RWLock::RLocker l(m_image_ctx.owner_lock);
+ m_finisher.finish_op(r);
+}
+
+AsyncObjectThrottle::AsyncObjectThrottle(const AsyncRequest* async_request,
+ ImageCtx &image_ctx,
const ContextFactory& context_factory,
Context *ctx, ProgressContext &prog_ctx,
uint64_t object_no,
uint64_t end_object_no)
: m_lock(unique_lock_name("librbd::AsyncThrottle::m_lock", this)),
- m_async_request(async_request), m_context_factory(context_factory),
- m_ctx(ctx), m_prog_ctx(prog_ctx), m_object_no(object_no),
- m_end_object_no(end_object_no), m_current_ops(0), m_ret(0)
+ m_async_request(async_request), m_image_ctx(image_ctx),
+ m_context_factory(context_factory), m_ctx(ctx), m_prog_ctx(prog_ctx),
+ m_object_no(object_no), m_end_object_no(end_object_no), m_current_ops(0),
+ m_ret(0)
{
}
void AsyncObjectThrottle::start_ops(uint64_t max_concurrent) {
+ assert(m_image_ctx.owner_lock.is_locked());
bool complete;
{
Mutex::Locker l(m_lock);
}
void AsyncObjectThrottle::finish_op(int r) {
+ assert(m_image_ctx.owner_lock.is_locked());
bool complete;
{
Mutex::Locker l(m_lock);
void AsyncObjectThrottle::start_next_op() {
bool done = false;
while (!done) {
- if (m_async_request.is_canceled() && m_ret == 0) {
+ if (m_async_request->is_canceled() && m_ret == 0) {
// allow in-flight ops to complete, but don't start new ops
m_ret = -ERESTART;
return;
{
class AsyncRequest;
class ProgressContext;
+struct ImageCtx;
class AsyncObjectThrottleFinisher {
public:
class C_AsyncObjectThrottle : public Context {
public:
- C_AsyncObjectThrottle(AsyncObjectThrottleFinisher &finisher)
- : m_finisher(finisher)
+ C_AsyncObjectThrottle(AsyncObjectThrottleFinisher &finisher,
+ ImageCtx &image_ctx)
+ : m_image_ctx(image_ctx), m_finisher(finisher)
{
}
- virtual void finish(int r)
- {
- m_finisher.finish_op(r);
- }
-
virtual int send() = 0;
+protected:
+ ImageCtx &m_image_ctx;
+
+ virtual void finish(int r);
+
private:
AsyncObjectThrottleFinisher &m_finisher;
};
typedef boost::function<C_AsyncObjectThrottle*(AsyncObjectThrottle&,
uint64_t)> ContextFactory;
- AsyncObjectThrottle(const AsyncRequest &async_request,
+ AsyncObjectThrottle(const AsyncRequest *async_request, ImageCtx &image_ctx,
const ContextFactory& context_factory, Context *ctx,
ProgressContext &prog_ctx, uint64_t object_no,
uint64_t end_object_no);
private:
Mutex m_lock;
- const AsyncRequest &m_async_request;
+ const AsyncRequest *m_async_request;
+ ImageCtx &m_image_ctx;
ContextFactory m_context_factory;
Context *m_ctx;
ProgressContext &m_prog_ctx;
public:
AsyncTrimObjectContext(AsyncObjectThrottle &throttle, ImageCtx *image_ctx,
uint64_t object_no)
- : C_AsyncObjectThrottle(throttle), m_image_ctx(*image_ctx),
- m_object_no(object_no)
+ : C_AsyncObjectThrottle(throttle, *image_ctx), m_object_no(object_no)
{
}
}
private:
- ImageCtx &m_image_ctx;
uint64_t m_object_no;
};
boost::lambda::bind(boost::lambda::new_ptr<AsyncTrimObjectContext>(),
boost::lambda::_1, &m_image_ctx, boost::lambda::_2));
AsyncObjectThrottle *throttle = new AsyncObjectThrottle(
- *this, context_factory, ctx, m_prog_ctx, m_delete_start, m_num_objects);
+ this, m_image_ctx, context_factory, ctx, m_prog_ctx, m_delete_start,
+ m_num_objects);
throttle->start_ops(cct->_conf->rbd_concurrent_management_ops);
}