OPTION(rados_mon_op_timeout, OPT_DOUBLE, 0) // how many seconds to wait for a response from the monitor before returning an error from a rados operation. 0 means on limit.
OPTION(rados_osd_op_timeout, OPT_DOUBLE, 0) // how many seconds to wait for a response from osds before returning an error from a rados operation. 0 means no limit.
+OPTION(rbd_op_threads, OPT_INT, 1)
+OPTION(rbd_op_thread_timeout, OPT_INT, 60)
OPTION(rbd_cache, OPT_BOOL, false) // whether to enable caching (writeback unless rbd_cache_max_dirty is 0)
OPTION(rbd_cache_writethrough_until_flush, OPT_BOOL, false) // whether to make writeback caching writethrough until flush is called, to be sure the user of librbd will send flushs so that writeback is safe
OPTION(rbd_cache_size, OPT_LONGLONG, 32<<20) // cache size in bytes
#include "common/dout.h"
#include "common/errno.h"
#include "common/perf_counters.h"
+#include "common/WorkQueue.h"
#include "librbd/internal.h"
#include "librbd/WatchCtx.h"
using librados::IoCtx;
namespace librbd {
+
+namespace {
+
+class ThreadPoolSingleton : public ThreadPool {
+public:
+ ThreadPoolSingleton(CephContext *cct)
+ : ThreadPool(cct, "librbd::thread_pool", cct->_conf->rbd_op_threads,
+ "rbd_op_threads") {
+ start();
+ }
+ virtual ~ThreadPoolSingleton() {
+ stop();
+ }
+};
+
+} // anonymous namespace
+
ImageCtx::ImageCtx(const string &image_name, const string &image_id,
const char *snap, IoCtx& p, bool ro)
: cct((CephContext*)p.cct()),
id(image_id), parent(NULL),
stripe_unit(0), stripe_count(0),
object_cacher(NULL), writeback_handler(NULL), object_set(NULL),
- pending_aio(0)
+ pending_aio(0), aio_work_queue(NULL)
{
md_ctx.dup(p);
data_ctx.dup(p);
object_set->return_enoent = true;
object_cacher->start();
}
+
+ ThreadPoolSingleton *thread_pool_singleton;
+ cct->lookup_or_create_singleton_object<ThreadPoolSingleton>(
+ thread_pool_singleton, "librbd::thread_pool");
+ aio_work_queue = new ContextWQ("librbd::aio_work_queue",
+ cct->_conf->rbd_op_thread_timeout,
+ thread_pool_singleton);
}
ImageCtx::~ImageCtx() {
object_set = NULL;
}
delete[] format_string;
+
+ delete aio_work_queue;
}
int ImageCtx::init() {
#include "common/dout.h"
#include "common/errno.h"
#include "common/Throttle.h"
+#include "common/WorkQueue.h"
#include "cls/lock/cls_lock_client.h"
#include "include/stringify.h"
void close_image(ImageCtx *ictx)
{
ldout(ictx->cct, 20) << "close_image " << ictx << dendl;
+
+ ictx->aio_work_queue->drain();
+
if (ictx->object_cacher) {
ictx->shutdown_cache(); // implicitly flushes
} else {