mirror of
https://github.com/ceph/ceph
synced 2024-12-19 01:46:00 +00:00
librados_test_stub: support AIO snapshot context
AIO operations can be executed with a different snapshot context from the IoCtx. librbd takes advantage of this capability to perform a deep object copyup. Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
parent
9fd708b1a0
commit
12719478ad
@ -395,7 +395,8 @@ void IoCtx::dup(const IoCtx& rhs) {
|
|||||||
int IoCtx::exec(const std::string& oid, const char *cls, const char *method,
|
int IoCtx::exec(const std::string& oid, const char *cls, const char *method,
|
||||||
bufferlist& inbl, bufferlist& outbl) {
|
bufferlist& inbl, bufferlist& outbl) {
|
||||||
TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
|
TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
|
||||||
return ctx->exec(oid, *get_class_handler(), cls, method, inbl, &outbl);
|
return ctx->exec(oid, *get_class_handler(), cls, method, inbl, &outbl,
|
||||||
|
ctx->get_snap_context());
|
||||||
}
|
}
|
||||||
|
|
||||||
void IoCtx::from_rados_ioctx_t(rados_ioctx_t p, IoCtx &io) {
|
void IoCtx::from_rados_ioctx_t(rados_ioctx_t p, IoCtx &io) {
|
||||||
@ -548,12 +549,12 @@ int IoCtx::watch2(const std::string& o, uint64_t *handle,
|
|||||||
int IoCtx::write(const std::string& oid, bufferlist& bl, size_t len,
|
int IoCtx::write(const std::string& oid, bufferlist& bl, size_t len,
|
||||||
uint64_t off) {
|
uint64_t off) {
|
||||||
TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
|
TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
|
||||||
return ctx->write(oid, bl, len, off);
|
return ctx->write(oid, bl, len, off, ctx->get_snap_context());
|
||||||
}
|
}
|
||||||
|
|
||||||
int IoCtx::write_full(const std::string& oid, bufferlist& bl) {
|
int IoCtx::write_full(const std::string& oid, bufferlist& bl) {
|
||||||
TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
|
TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
|
||||||
return ctx->write_full(oid, bl);
|
return ctx->write_full(oid, bl, ctx->get_snap_context());
|
||||||
}
|
}
|
||||||
|
|
||||||
static int save_operation_result(int result, int *pval) {
|
static int save_operation_result(int result, int *pval) {
|
||||||
@ -587,7 +588,7 @@ void ObjectOperation::exec(const char *cls, const char *method,
|
|||||||
TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
|
TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
|
||||||
o->ops.push_back(boost::bind(&TestIoCtxImpl::exec, _1, _2,
|
o->ops.push_back(boost::bind(&TestIoCtxImpl::exec, _1, _2,
|
||||||
boost::ref(*get_class_handler()),
|
boost::ref(*get_class_handler()),
|
||||||
cls, method, inbl, _3));
|
cls, method, inbl, _3, _4));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectOperation::set_op_flags2(int flags) {
|
void ObjectOperation::set_op_flags2(int flags) {
|
||||||
@ -605,7 +606,7 @@ void ObjectReadOperation::list_snaps(snap_set_t *out_snaps, int *prval) {
|
|||||||
out_snaps);
|
out_snaps);
|
||||||
if (prval != NULL) {
|
if (prval != NULL) {
|
||||||
op = boost::bind(save_operation_result,
|
op = boost::bind(save_operation_result,
|
||||||
boost::bind(op, _1, _2, _3), prval);
|
boost::bind(op, _1, _2, _3, _4), prval);
|
||||||
}
|
}
|
||||||
o->ops.push_back(op);
|
o->ops.push_back(op);
|
||||||
}
|
}
|
||||||
@ -623,7 +624,7 @@ void ObjectReadOperation::read(size_t off, uint64_t len, bufferlist *pbl,
|
|||||||
|
|
||||||
if (prval != NULL) {
|
if (prval != NULL) {
|
||||||
op = boost::bind(save_operation_result,
|
op = boost::bind(save_operation_result,
|
||||||
boost::bind(op, _1, _2, _3), prval);
|
boost::bind(op, _1, _2, _3, _4), prval);
|
||||||
}
|
}
|
||||||
o->ops.push_back(op);
|
o->ops.push_back(op);
|
||||||
}
|
}
|
||||||
@ -642,7 +643,7 @@ void ObjectReadOperation::sparse_read(uint64_t off, uint64_t len,
|
|||||||
|
|
||||||
if (prval != NULL) {
|
if (prval != NULL) {
|
||||||
op = boost::bind(save_operation_result,
|
op = boost::bind(save_operation_result,
|
||||||
boost::bind(op, _1, _2, _3), prval);
|
boost::bind(op, _1, _2, _3, _4), prval);
|
||||||
}
|
}
|
||||||
o->ops.push_back(op);
|
o->ops.push_back(op);
|
||||||
}
|
}
|
||||||
@ -683,12 +684,12 @@ void ObjectWriteOperation::truncate(uint64_t off) {
|
|||||||
void ObjectWriteOperation::write(uint64_t off, const bufferlist& bl) {
|
void ObjectWriteOperation::write(uint64_t off, const bufferlist& bl) {
|
||||||
TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
|
TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
|
||||||
o->ops.push_back(boost::bind(&TestIoCtxImpl::write, _1, _2, bl, bl.length(),
|
o->ops.push_back(boost::bind(&TestIoCtxImpl::write, _1, _2, bl, bl.length(),
|
||||||
off));
|
off, _4));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectWriteOperation::write_full(const bufferlist& bl) {
|
void ObjectWriteOperation::write_full(const bufferlist& bl) {
|
||||||
TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
|
TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
|
||||||
o->ops.push_back(boost::bind(&TestIoCtxImpl::write_full, _1, _2, bl));
|
o->ops.push_back(boost::bind(&TestIoCtxImpl::write_full, _1, _2, bl, _4));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectWriteOperation::zero(uint64_t off, uint64_t len) {
|
void ObjectWriteOperation::zero(uint64_t off, uint64_t len) {
|
||||||
@ -990,13 +991,13 @@ int cls_cxx_write(cls_method_context_t hctx, int ofs, int len,
|
|||||||
bufferlist *inbl) {
|
bufferlist *inbl) {
|
||||||
librados::TestClassHandler::MethodContext *ctx =
|
librados::TestClassHandler::MethodContext *ctx =
|
||||||
reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
|
reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
|
||||||
return ctx->io_ctx_impl->write(ctx->oid, *inbl, len, ofs);
|
return ctx->io_ctx_impl->write(ctx->oid, *inbl, len, ofs, ctx->snapc);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cls_cxx_write_full(cls_method_context_t hctx, bufferlist *inbl) {
|
int cls_cxx_write_full(cls_method_context_t hctx, bufferlist *inbl) {
|
||||||
librados::TestClassHandler::MethodContext *ctx =
|
librados::TestClassHandler::MethodContext *ctx =
|
||||||
reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
|
reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
|
||||||
return ctx->io_ctx_impl->write_full(ctx->oid, *inbl);
|
return ctx->io_ctx_impl->write_full(ctx->oid, *inbl, ctx->snapc);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cls_log(int level, const char *format, ...) {
|
int cls_log(int level, const char *format, ...) {
|
||||||
|
@ -100,10 +100,12 @@ cls_method_cxx_call_t TestClassHandler::get_method(const std::string &cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
TestClassHandler::SharedMethodContext TestClassHandler::get_method_context(
|
TestClassHandler::SharedMethodContext TestClassHandler::get_method_context(
|
||||||
TestIoCtxImpl *io_ctx_impl, const std::string &oid) {
|
TestIoCtxImpl *io_ctx_impl, const std::string &oid,
|
||||||
|
const SnapContext &snapc) {
|
||||||
SharedMethodContext ctx(new MethodContext());
|
SharedMethodContext ctx(new MethodContext());
|
||||||
ctx->io_ctx_impl = io_ctx_impl;
|
ctx->io_ctx_impl = io_ctx_impl;
|
||||||
ctx->oid = oid;
|
ctx->oid = oid;
|
||||||
|
ctx->snapc = snapc;
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#define CEPH_TEST_CLASS_HANDLER_H
|
#define CEPH_TEST_CLASS_HANDLER_H
|
||||||
|
|
||||||
#include "objclass/objclass.h"
|
#include "objclass/objclass.h"
|
||||||
|
#include "common/snap_types.h"
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -24,6 +25,7 @@ public:
|
|||||||
struct MethodContext {
|
struct MethodContext {
|
||||||
TestIoCtxImpl *io_ctx_impl;
|
TestIoCtxImpl *io_ctx_impl;
|
||||||
std::string oid;
|
std::string oid;
|
||||||
|
SnapContext snapc;
|
||||||
};
|
};
|
||||||
typedef boost::shared_ptr<MethodContext> SharedMethodContext;
|
typedef boost::shared_ptr<MethodContext> SharedMethodContext;
|
||||||
|
|
||||||
@ -47,7 +49,8 @@ public:
|
|||||||
cls_method_cxx_call_t get_method(const std::string &cls,
|
cls_method_cxx_call_t get_method(const std::string &cls,
|
||||||
const std::string &method);
|
const std::string &method);
|
||||||
SharedMethodContext get_method_context(TestIoCtxImpl *io_ctx_impl,
|
SharedMethodContext get_method_context(TestIoCtxImpl *io_ctx_impl,
|
||||||
const std::string &oid);
|
const std::string &oid,
|
||||||
|
const SnapContext &snapc);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -88,11 +88,12 @@ void TestIoCtxImpl::aio_flush_async(AioCompletionImpl *c) {
|
|||||||
int TestIoCtxImpl::aio_operate(const std::string& oid, TestObjectOperationImpl &ops,
|
int TestIoCtxImpl::aio_operate(const std::string& oid, TestObjectOperationImpl &ops,
|
||||||
AioCompletionImpl *c, SnapContext *snap_context,
|
AioCompletionImpl *c, SnapContext *snap_context,
|
||||||
int flags) {
|
int flags) {
|
||||||
// TODO ignoring snap_context and flags for now
|
// TODO flags for now
|
||||||
ops.get();
|
ops.get();
|
||||||
m_client->add_aio_operation(oid, true, boost::bind(
|
m_client->add_aio_operation(oid, true, boost::bind(
|
||||||
&TestIoCtxImpl::execute_aio_operations, this, oid, &ops,
|
&TestIoCtxImpl::execute_aio_operations, this, oid, &ops,
|
||||||
reinterpret_cast<bufferlist*>(NULL)), c);
|
reinterpret_cast<bufferlist*>(NULL),
|
||||||
|
snap_context != NULL ? *snap_context : m_snapc), c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,20 +104,21 @@ int TestIoCtxImpl::aio_operate_read(const std::string& oid,
|
|||||||
// TODO ignoring flags for now
|
// TODO ignoring flags for now
|
||||||
ops.get();
|
ops.get();
|
||||||
m_client->add_aio_operation(oid, true, boost::bind(
|
m_client->add_aio_operation(oid, true, boost::bind(
|
||||||
&TestIoCtxImpl::execute_aio_operations, this, oid, &ops, pbl), c);
|
&TestIoCtxImpl::execute_aio_operations, this, oid, &ops, pbl, m_snapc), c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TestIoCtxImpl::exec(const std::string& oid, TestClassHandler &handler,
|
int TestIoCtxImpl::exec(const std::string& oid, TestClassHandler &handler,
|
||||||
const char *cls, const char *method,
|
const char *cls, const char *method,
|
||||||
bufferlist& inbl, bufferlist* outbl) {
|
bufferlist& inbl, bufferlist* outbl,
|
||||||
|
const SnapContext &snapc) {
|
||||||
cls_method_cxx_call_t call = handler.get_method(cls, method);
|
cls_method_cxx_call_t call = handler.get_method(cls, method);
|
||||||
if (call == NULL) {
|
if (call == NULL) {
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*call)(reinterpret_cast<cls_method_context_t>(
|
return (*call)(reinterpret_cast<cls_method_context_t>(
|
||||||
handler.get_method_context(this, oid).get()), &inbl, outbl);
|
handler.get_method_context(this, oid, snapc).get()), &inbl, outbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TestIoCtxImpl::list_watchers(const std::string& o,
|
int TestIoCtxImpl::list_watchers(const std::string& o,
|
||||||
@ -141,7 +143,7 @@ int TestIoCtxImpl::operate(const std::string& oid, TestObjectOperationImpl &ops)
|
|||||||
ops.get();
|
ops.get();
|
||||||
m_client->add_aio_operation(oid, false, boost::bind(
|
m_client->add_aio_operation(oid, false, boost::bind(
|
||||||
&TestIoCtxImpl::execute_aio_operations, this, oid, &ops,
|
&TestIoCtxImpl::execute_aio_operations, this, oid, &ops,
|
||||||
reinterpret_cast<bufferlist*>(NULL)), comp);
|
reinterpret_cast<bufferlist*>(NULL), m_snapc), comp);
|
||||||
|
|
||||||
comp->wait_for_safe();
|
comp->wait_for_safe();
|
||||||
int ret = comp->get_return_value();
|
int ret = comp->get_return_value();
|
||||||
@ -155,7 +157,8 @@ int TestIoCtxImpl::operate_read(const std::string& oid, TestObjectOperationImpl
|
|||||||
|
|
||||||
ops.get();
|
ops.get();
|
||||||
m_client->add_aio_operation(oid, false, boost::bind(
|
m_client->add_aio_operation(oid, false, boost::bind(
|
||||||
&TestIoCtxImpl::execute_aio_operations, this, oid, &ops, pbl), comp);
|
&TestIoCtxImpl::execute_aio_operations, this, oid, &ops, pbl,
|
||||||
|
m_snapc), comp);
|
||||||
|
|
||||||
comp->wait_for_complete();
|
comp->wait_for_complete();
|
||||||
int ret = comp->get_return_value();
|
int ret = comp->get_return_value();
|
||||||
@ -229,7 +232,7 @@ int TestIoCtxImpl::tmap_update(const std::string& oid, bufferlist& cmdbl) {
|
|||||||
bufferlist out;
|
bufferlist out;
|
||||||
::encode(tmap_header, out);
|
::encode(tmap_header, out);
|
||||||
::encode(tmap, out);
|
::encode(tmap, out);
|
||||||
r = write_full(oid, out);
|
r = write_full(oid, out, m_snapc);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,10 +247,12 @@ int TestIoCtxImpl::watch(const std::string& o, uint64_t *handle,
|
|||||||
|
|
||||||
int TestIoCtxImpl::execute_aio_operations(const std::string& oid,
|
int TestIoCtxImpl::execute_aio_operations(const std::string& oid,
|
||||||
TestObjectOperationImpl *ops,
|
TestObjectOperationImpl *ops,
|
||||||
bufferlist *pbl) {
|
bufferlist *pbl,
|
||||||
|
const SnapContext &snapc) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
for (ObjectOperations::iterator it = ops->ops.begin(); it != ops->ops.end(); ++it) {
|
for (ObjectOperations::iterator it = ops->ops.begin();
|
||||||
ret = (*it)(this, oid, pbl);
|
it != ops->ops.end(); ++it) {
|
||||||
|
ret = (*it)(this, oid, pbl, snapc);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,8 @@ class TestRadosClient;
|
|||||||
|
|
||||||
typedef boost::function<int(TestIoCtxImpl*,
|
typedef boost::function<int(TestIoCtxImpl*,
|
||||||
const std::string&,
|
const std::string&,
|
||||||
bufferlist *)> ObjectOperationTestImpl;
|
bufferlist *,
|
||||||
|
const SnapContext &)> ObjectOperationTestImpl;
|
||||||
typedef std::list<ObjectOperationTestImpl> ObjectOperations;
|
typedef std::list<ObjectOperationTestImpl> ObjectOperations;
|
||||||
|
|
||||||
struct TestObjectOperationImpl {
|
struct TestObjectOperationImpl {
|
||||||
@ -74,7 +75,8 @@ public:
|
|||||||
virtual int create(const std::string& oid, bool exclusive) = 0;
|
virtual int create(const std::string& oid, bool exclusive) = 0;
|
||||||
virtual int exec(const std::string& oid, TestClassHandler &handler,
|
virtual int exec(const std::string& oid, TestClassHandler &handler,
|
||||||
const char *cls, const char *method,
|
const char *cls, const char *method,
|
||||||
bufferlist& inbl, bufferlist* outbl);
|
bufferlist& inbl, bufferlist* outbl,
|
||||||
|
const SnapContext &snapc);
|
||||||
virtual int list_snaps(const std::string& o, snap_set_t *out_snaps) = 0;
|
virtual int list_snaps(const std::string& o, snap_set_t *out_snaps) = 0;
|
||||||
virtual int list_watchers(const std::string& o,
|
virtual int list_watchers(const std::string& o,
|
||||||
std::list<obj_watch_t> *out_watchers);
|
std::list<obj_watch_t> *out_watchers);
|
||||||
@ -117,8 +119,9 @@ public:
|
|||||||
virtual int watch(const std::string& o, uint64_t *handle,
|
virtual int watch(const std::string& o, uint64_t *handle,
|
||||||
librados::WatchCtx *ctx, librados::WatchCtx2 *ctx2);
|
librados::WatchCtx *ctx, librados::WatchCtx2 *ctx2);
|
||||||
virtual int write(const std::string& oid, bufferlist& bl, size_t len,
|
virtual int write(const std::string& oid, bufferlist& bl, size_t len,
|
||||||
uint64_t off) = 0;
|
uint64_t off, const SnapContext &snapc) = 0;
|
||||||
virtual int write_full(const std::string& oid, bufferlist& bl) = 0;
|
virtual int write_full(const std::string& oid, bufferlist& bl,
|
||||||
|
const SnapContext &snapc) = 0;
|
||||||
virtual int xattr_get(const std::string& oid,
|
virtual int xattr_get(const std::string& oid,
|
||||||
std::map<std::string, bufferlist>* attrset) = 0;
|
std::map<std::string, bufferlist>* attrset) = 0;
|
||||||
virtual int xattr_set(const std::string& oid, const std::string &name,
|
virtual int xattr_set(const std::string& oid, const std::string &name,
|
||||||
@ -129,8 +132,9 @@ protected:
|
|||||||
TestIoCtxImpl(const TestIoCtxImpl& rhs);
|
TestIoCtxImpl(const TestIoCtxImpl& rhs);
|
||||||
virtual ~TestIoCtxImpl();
|
virtual ~TestIoCtxImpl();
|
||||||
|
|
||||||
int execute_aio_operations(const std::string& oid, TestObjectOperationImpl *ops,
|
int execute_aio_operations(const std::string& oid,
|
||||||
bufferlist *pbl);
|
TestObjectOperationImpl *ops,
|
||||||
|
bufferlist *pbl, const SnapContext &snapc);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -45,7 +45,8 @@ int TestMemIoCtxImpl::aio_remove(const std::string& oid, AioCompletionImpl *c) {
|
|||||||
|
|
||||||
int TestMemIoCtxImpl::assert_exists(const std::string &oid) {
|
int TestMemIoCtxImpl::assert_exists(const std::string &oid) {
|
||||||
RWLock::RLocker l(m_pool->file_lock);
|
RWLock::RLocker l(m_pool->file_lock);
|
||||||
TestMemRadosClient::SharedFile file = get_file(oid, false);
|
TestMemRadosClient::SharedFile file = get_file(oid, false,
|
||||||
|
get_snap_context());
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
@ -58,7 +59,7 @@ int TestMemIoCtxImpl::create(const std::string& oid, bool exclusive) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RWLock::WLocker l(m_pool->file_lock);
|
RWLock::WLocker l(m_pool->file_lock);
|
||||||
get_file(oid, true);
|
get_file(oid, true, get_snap_context());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +141,7 @@ int TestMemIoCtxImpl::omap_get_vals(const std::string& oid,
|
|||||||
TestMemRadosClient::SharedFile file;
|
TestMemRadosClient::SharedFile file;
|
||||||
{
|
{
|
||||||
RWLock::RLocker l(m_pool->file_lock);
|
RWLock::RLocker l(m_pool->file_lock);
|
||||||
file = get_file(oid, false);
|
file = get_file(oid, false, get_snap_context());
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
@ -180,7 +181,7 @@ int TestMemIoCtxImpl::omap_rm_keys(const std::string& oid,
|
|||||||
TestMemRadosClient::SharedFile file;
|
TestMemRadosClient::SharedFile file;
|
||||||
{
|
{
|
||||||
RWLock::WLocker l(m_pool->file_lock);
|
RWLock::WLocker l(m_pool->file_lock);
|
||||||
file = get_file(oid, true);
|
file = get_file(oid, true, get_snap_context());
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
@ -203,7 +204,7 @@ int TestMemIoCtxImpl::omap_set(const std::string& oid,
|
|||||||
TestMemRadosClient::SharedFile file;
|
TestMemRadosClient::SharedFile file;
|
||||||
{
|
{
|
||||||
RWLock::WLocker l(m_pool->file_lock);
|
RWLock::WLocker l(m_pool->file_lock);
|
||||||
file = get_file(oid, true);
|
file = get_file(oid, true, get_snap_context());
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
@ -225,7 +226,7 @@ int TestMemIoCtxImpl::read(const std::string& oid, size_t len, uint64_t off,
|
|||||||
TestMemRadosClient::SharedFile file;
|
TestMemRadosClient::SharedFile file;
|
||||||
{
|
{
|
||||||
RWLock::RLocker l(m_pool->file_lock);
|
RWLock::RLocker l(m_pool->file_lock);
|
||||||
file = get_file(oid, false);
|
file = get_file(oid, false, get_snap_context());
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
@ -250,11 +251,12 @@ int TestMemIoCtxImpl::remove(const std::string& oid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RWLock::WLocker l(m_pool->file_lock);
|
RWLock::WLocker l(m_pool->file_lock);
|
||||||
TestMemRadosClient::SharedFile file = get_file(oid, false);
|
TestMemRadosClient::SharedFile file = get_file(oid, false,
|
||||||
|
get_snap_context());
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
file = get_file(oid, true);
|
file = get_file(oid, true, get_snap_context());
|
||||||
|
|
||||||
RWLock::WLocker l2(file->lock);
|
RWLock::WLocker l2(file->lock);
|
||||||
file->exists = false;
|
file->exists = false;
|
||||||
@ -340,7 +342,7 @@ int TestMemIoCtxImpl::sparse_read(const std::string& oid, uint64_t off,
|
|||||||
TestMemRadosClient::SharedFile file;
|
TestMemRadosClient::SharedFile file;
|
||||||
{
|
{
|
||||||
RWLock::RLocker l(m_pool->file_lock);
|
RWLock::RLocker l(m_pool->file_lock);
|
||||||
file = get_file(oid, false);
|
file = get_file(oid, false, get_snap_context());
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
@ -367,7 +369,7 @@ int TestMemIoCtxImpl::stat(const std::string& oid, uint64_t *psize,
|
|||||||
TestMemRadosClient::SharedFile file;
|
TestMemRadosClient::SharedFile file;
|
||||||
{
|
{
|
||||||
RWLock::RLocker l(m_pool->file_lock);
|
RWLock::RLocker l(m_pool->file_lock);
|
||||||
file = get_file(oid, false);
|
file = get_file(oid, false, get_snap_context());
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
@ -391,7 +393,7 @@ int TestMemIoCtxImpl::truncate(const std::string& oid, uint64_t size) {
|
|||||||
TestMemRadosClient::SharedFile file;
|
TestMemRadosClient::SharedFile file;
|
||||||
{
|
{
|
||||||
RWLock::WLocker l(m_pool->file_lock);
|
RWLock::WLocker l(m_pool->file_lock);
|
||||||
file = get_file(oid, true);
|
file = get_file(oid, true, get_snap_context());
|
||||||
}
|
}
|
||||||
|
|
||||||
RWLock::WLocker l(file->lock);
|
RWLock::WLocker l(file->lock);
|
||||||
@ -419,7 +421,7 @@ int TestMemIoCtxImpl::truncate(const std::string& oid, uint64_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int TestMemIoCtxImpl::write(const std::string& oid, bufferlist& bl, size_t len,
|
int TestMemIoCtxImpl::write(const std::string& oid, bufferlist& bl, size_t len,
|
||||||
uint64_t off) {
|
uint64_t off, const SnapContext &snapc) {
|
||||||
if (get_snap_read() != CEPH_NOSNAP) {
|
if (get_snap_read() != CEPH_NOSNAP) {
|
||||||
return -EROFS;
|
return -EROFS;
|
||||||
}
|
}
|
||||||
@ -427,7 +429,7 @@ int TestMemIoCtxImpl::write(const std::string& oid, bufferlist& bl, size_t len,
|
|||||||
TestMemRadosClient::SharedFile file;
|
TestMemRadosClient::SharedFile file;
|
||||||
{
|
{
|
||||||
RWLock::WLocker l(m_pool->file_lock);
|
RWLock::WLocker l(m_pool->file_lock);
|
||||||
file = get_file(oid, true);
|
file = get_file(oid, true, snapc);
|
||||||
}
|
}
|
||||||
|
|
||||||
RWLock::WLocker l(file->lock);
|
RWLock::WLocker l(file->lock);
|
||||||
@ -443,7 +445,8 @@ int TestMemIoCtxImpl::write(const std::string& oid, bufferlist& bl, size_t len,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TestMemIoCtxImpl::write_full(const std::string& oid, bufferlist& bl) {
|
int TestMemIoCtxImpl::write_full(const std::string& oid, bufferlist& bl,
|
||||||
|
const SnapContext &snapc) {
|
||||||
if (get_snap_read() != CEPH_NOSNAP) {
|
if (get_snap_read() != CEPH_NOSNAP) {
|
||||||
return -EROFS;
|
return -EROFS;
|
||||||
}
|
}
|
||||||
@ -451,7 +454,7 @@ int TestMemIoCtxImpl::write_full(const std::string& oid, bufferlist& bl) {
|
|||||||
TestMemRadosClient::SharedFile file;
|
TestMemRadosClient::SharedFile file;
|
||||||
{
|
{
|
||||||
RWLock::WLocker l(m_pool->file_lock);
|
RWLock::WLocker l(m_pool->file_lock);
|
||||||
file = get_file(oid, true);
|
file = get_file(oid, true, snapc);
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
@ -494,11 +497,11 @@ int TestMemIoCtxImpl::zero(const std::string& oid, uint64_t off, uint64_t len) {
|
|||||||
TestMemRadosClient::SharedFile file;
|
TestMemRadosClient::SharedFile file;
|
||||||
{
|
{
|
||||||
RWLock::WLocker l(m_pool->file_lock);
|
RWLock::WLocker l(m_pool->file_lock);
|
||||||
file = get_file(oid, false);
|
file = get_file(oid, false, get_snap_context());
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
file = get_file(oid, true);
|
file = get_file(oid, true, get_snap_context());
|
||||||
|
|
||||||
RWLock::RLocker l2(file->lock);
|
RWLock::RLocker l2(file->lock);
|
||||||
if (len > 0 && off + len >= file->data.length()) {
|
if (len > 0 && off + len >= file->data.length()) {
|
||||||
@ -512,7 +515,7 @@ int TestMemIoCtxImpl::zero(const std::string& oid, uint64_t off, uint64_t len) {
|
|||||||
|
|
||||||
bufferlist bl;
|
bufferlist bl;
|
||||||
bl.append_zero(len);
|
bl.append_zero(len);
|
||||||
return write(oid, bl, len, off);
|
return write(oid, bl, len, off, get_snap_context());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestMemIoCtxImpl::append_clone(bufferlist& src, bufferlist* dest) {
|
void TestMemIoCtxImpl::append_clone(bufferlist& src, bufferlist* dest) {
|
||||||
@ -544,7 +547,7 @@ void TestMemIoCtxImpl::ensure_minimum_length(size_t len, bufferlist *bl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TestMemRadosClient::SharedFile TestMemIoCtxImpl::get_file(
|
TestMemRadosClient::SharedFile TestMemIoCtxImpl::get_file(
|
||||||
const std::string &oid, bool write) {
|
const std::string &oid, bool write, const SnapContext &snapc) {
|
||||||
assert(m_pool->file_lock.is_locked() || m_pool->file_lock.is_wlocked());
|
assert(m_pool->file_lock.is_locked() || m_pool->file_lock.is_wlocked());
|
||||||
assert(!write || m_pool->file_lock.is_wlocked());
|
assert(!write || m_pool->file_lock.is_wlocked());
|
||||||
|
|
||||||
@ -557,7 +560,6 @@ TestMemRadosClient::SharedFile TestMemIoCtxImpl::get_file(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (write) {
|
if (write) {
|
||||||
const SnapContext &snapc = get_snap_context();
|
|
||||||
bool new_version = false;
|
bool new_version = false;
|
||||||
if (!file || !file->exists) {
|
if (!file || !file->exists) {
|
||||||
file = TestMemRadosClient::SharedFile(new TestMemRadosClient::File());
|
file = TestMemRadosClient::SharedFile(new TestMemRadosClient::File());
|
||||||
@ -572,11 +574,13 @@ TestMemRadosClient::SharedFile TestMemIoCtxImpl::get_file(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t prev_size = file->data.length();
|
bufferlist prev_data = file->data;
|
||||||
file = TestMemRadosClient::SharedFile(
|
file = TestMemRadosClient::SharedFile(
|
||||||
new TestMemRadosClient::File(*file));
|
new TestMemRadosClient::File(*file));
|
||||||
if (prev_size > 0) {
|
file->data.clear();
|
||||||
file->snap_overlap.insert(0, prev_size);
|
append_clone(prev_data, &file->data);
|
||||||
|
if (prev_data.length() > 0) {
|
||||||
|
file->snap_overlap.insert(0, prev_data.length());
|
||||||
}
|
}
|
||||||
new_version = true;
|
new_version = true;
|
||||||
}
|
}
|
||||||
|
@ -45,8 +45,9 @@ public:
|
|||||||
virtual int stat(const std::string& oid, uint64_t *psize, time_t *pmtime);
|
virtual int stat(const std::string& oid, uint64_t *psize, time_t *pmtime);
|
||||||
virtual int truncate(const std::string& oid, uint64_t size);
|
virtual int truncate(const std::string& oid, uint64_t size);
|
||||||
virtual int write(const std::string& oid, bufferlist& bl, size_t len,
|
virtual int write(const std::string& oid, bufferlist& bl, size_t len,
|
||||||
uint64_t off);
|
uint64_t off, const SnapContext &snapc);
|
||||||
virtual int write_full(const std::string& oid, bufferlist& bl);
|
virtual int write_full(const std::string& oid, bufferlist& bl,
|
||||||
|
const SnapContext &snapc);
|
||||||
virtual int xattr_get(const std::string& oid,
|
virtual int xattr_get(const std::string& oid,
|
||||||
std::map<std::string, bufferlist>* attrset);
|
std::map<std::string, bufferlist>* attrset);
|
||||||
virtual int xattr_set(const std::string& oid, const std::string &name,
|
virtual int xattr_set(const std::string& oid, const std::string &name,
|
||||||
@ -63,7 +64,8 @@ private:
|
|||||||
size_t clip_io(size_t off, size_t len, size_t bl_len);
|
size_t clip_io(size_t off, size_t len, size_t bl_len);
|
||||||
void ensure_minimum_length(size_t len, bufferlist *bl);
|
void ensure_minimum_length(size_t len, bufferlist *bl);
|
||||||
|
|
||||||
TestMemRadosClient::SharedFile get_file(const std::string &oid, bool write);
|
TestMemRadosClient::SharedFile get_file(const std::string &oid, bool write,
|
||||||
|
const SnapContext &snapc);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user