From: Jason Dillaman Date: Thu, 30 Apr 2015 19:41:59 +0000 (-0400) Subject: librbd: AsyncObjectThrottle should always hold owner_lock X-Git-Tag: v0.94.4~77^2~15 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=9249ab7dacd43e7a546656b99013a595381fd5fd;p=ceph.git librbd: AsyncObjectThrottle should always hold owner_lock Signed-off-by: Jason Dillaman (cherry picked from commit c352bcdc0f63eea55677fe3c3b5f0c61347c0db3) --- diff --git a/src/librbd/AsyncFlattenRequest.cc b/src/librbd/AsyncFlattenRequest.cc index ebaf511ca29f..1d6d6cf696b1 100644 --- a/src/librbd/AsyncFlattenRequest.cc +++ b/src/librbd/AsyncFlattenRequest.cc @@ -23,8 +23,8 @@ public: 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) { } @@ -76,7 +76,6 @@ public: } private: - ImageCtx &m_image_ctx; uint64_t m_object_size; ::SnapContext m_snapc; uint64_t m_object_no; @@ -121,8 +120,8 @@ void AsyncFlattenRequest::send() { 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); } diff --git a/src/librbd/AsyncObjectThrottle.cc b/src/librbd/AsyncObjectThrottle.cc index 85cfec8e0db1..2c7ccd10d68d 100644 --- a/src/librbd/AsyncObjectThrottle.cc +++ b/src/librbd/AsyncObjectThrottle.cc @@ -2,25 +2,35 @@ // 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); @@ -39,6 +49,7 @@ void AsyncObjectThrottle::start_ops(uint64_t max_concurrent) { } void AsyncObjectThrottle::finish_op(int r) { + assert(m_image_ctx.owner_lock.is_locked()); bool complete; { Mutex::Locker l(m_lock); @@ -59,7 +70,7 @@ void AsyncObjectThrottle::finish_op(int r) { 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; diff --git a/src/librbd/AsyncObjectThrottle.h b/src/librbd/AsyncObjectThrottle.h index 83d69d8c773c..f7f254fb4461 100644 --- a/src/librbd/AsyncObjectThrottle.h +++ b/src/librbd/AsyncObjectThrottle.h @@ -13,6 +13,7 @@ namespace librbd { class AsyncRequest; class ProgressContext; +struct ImageCtx; class AsyncObjectThrottleFinisher { public: @@ -22,18 +23,19 @@ 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; }; @@ -43,7 +45,7 @@ public: typedef boost::function 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); @@ -53,7 +55,8 @@ public: 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; diff --git a/src/librbd/AsyncTrimRequest.cc b/src/librbd/AsyncTrimRequest.cc index af325f612f57..1a52c317f291 100644 --- a/src/librbd/AsyncTrimRequest.cc +++ b/src/librbd/AsyncTrimRequest.cc @@ -28,8 +28,7 @@ class AsyncTrimObjectContext : public C_AsyncObjectThrottle { 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) { } @@ -56,7 +55,6 @@ public: } private: - ImageCtx &m_image_ctx; uint64_t m_object_no; }; @@ -150,7 +148,8 @@ void AsyncTrimRequest::send_remove_objects() { boost::lambda::bind(boost::lambda::new_ptr(), 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); }