From: Jason Dillaman Date: Thu, 3 Sep 2020 13:40:50 +0000 (-0400) Subject: librbd: optionally disable read-from-parent for object-extent IO requests X-Git-Tag: v17.0.0~993^2~7 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=63cd9dfa143bc72691716bd9b40ccc435f4ec746;p=ceph.git librbd: optionally disable read-from-parent for object-extent IO requests Deep-copy (and eventually crypto) will need a way to prevent read-from-parent IO requests. This introduces an optional flag at the object-extent IO layer to disable that functionality. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/cache/ObjectCacherObjectDispatch.cc b/src/librbd/cache/ObjectCacherObjectDispatch.cc index 71b72e90f8782..92539478d764f 100644 --- a/src/librbd/cache/ObjectCacherObjectDispatch.cc +++ b/src/librbd/cache/ObjectCacherObjectDispatch.cc @@ -183,7 +183,7 @@ void ObjectCacherObjectDispatch::shut_down(Context* on_finish) { template bool ObjectCacherObjectDispatch::read( uint64_t object_no, const io::Extents &extents, IOContext io_context, - int op_flags, const ZTracer::Trace &parent_trace, + int op_flags, int read_flags, const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, io::Extents* extent_map, uint64_t* version, int* object_dispatch_flags, io::DispatchResult* dispatch_result, Context** on_finish, Context* on_dispatched) { @@ -202,6 +202,11 @@ bool ObjectCacherObjectDispatch::read( on_dispatched = util::create_async_context_callback(*m_image_ctx, on_dispatched); + // embed the RBD-internal read flags in the genenric RADOS op_flags and + op_flags = ((op_flags & ~ObjectCacherWriteback::READ_FLAGS_MASK) | + ((read_flags << ObjectCacherWriteback::READ_FLAGS_SHIFT) & + ObjectCacherWriteback::READ_FLAGS_MASK)); + m_image_ctx->image_lock.lock_shared(); auto rd = m_object_cacher->prepare_read( io_context->read_snap().value_or(CEPH_NOSNAP), read_data, op_flags); diff --git a/src/librbd/cache/ObjectCacherObjectDispatch.h b/src/librbd/cache/ObjectCacherObjectDispatch.h index ece4a75146721..ca60b04b1d8fb 100644 --- a/src/librbd/cache/ObjectCacherObjectDispatch.h +++ b/src/librbd/cache/ObjectCacherObjectDispatch.h @@ -43,7 +43,7 @@ public: bool read( uint64_t object_no, const io::Extents &extents, IOContext io_context, - int op_flags, const ZTracer::Trace &parent_trace, + int op_flags, int read_flags, const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, io::Extents* extent_map, uint64_t* version, int* object_dispatch_flags, io::DispatchResult* dispatch_result, Context** on_finish, diff --git a/src/librbd/cache/ObjectCacherWriteback.cc b/src/librbd/cache/ObjectCacherWriteback.cc index 4c7f193f7ae30..b99438a65d6b9 100644 --- a/src/librbd/cache/ObjectCacherWriteback.cc +++ b/src/librbd/cache/ObjectCacherWriteback.cc @@ -142,9 +142,13 @@ void ObjectCacherWriteback::read(const object_t& oid, uint64_t object_no, io_context->read_snap(snapid); } + // extract the embedded RBD read flags from the op_flags + int read_flags = (op_flags & READ_FLAGS_MASK) >> READ_FLAGS_SHIFT; + op_flags &= ~READ_FLAGS_MASK; + auto req = io::ObjectDispatchSpec::create_read( m_ictx, io::OBJECT_DISPATCH_LAYER_CACHE, object_no, {{off, len}}, - io_context, op_flags, trace, &req_comp->bl, + io_context, op_flags, read_flags, trace, &req_comp->bl, &req_comp->extent_map, nullptr, req_comp); req->send(); } diff --git a/src/librbd/cache/ObjectCacherWriteback.h b/src/librbd/cache/ObjectCacherWriteback.h index 6d7f367b614fc..d8c2ebbd991d0 100644 --- a/src/librbd/cache/ObjectCacherWriteback.h +++ b/src/librbd/cache/ObjectCacherWriteback.h @@ -19,6 +19,9 @@ namespace cache { class ObjectCacherWriteback : public WritebackHandler { public: + static const int READ_FLAGS_MASK = 0xF000; + static const int READ_FLAGS_SHIFT = 24; + ObjectCacherWriteback(ImageCtx *ictx, ceph::mutex& lock); // Note that oloc, trunc_size, and trunc_seq are ignored diff --git a/src/librbd/cache/ParentCacheObjectDispatch.cc b/src/librbd/cache/ParentCacheObjectDispatch.cc index 78abaa148c86c..6b81198b96137 100644 --- a/src/librbd/cache/ParentCacheObjectDispatch.cc +++ b/src/librbd/cache/ParentCacheObjectDispatch.cc @@ -66,7 +66,7 @@ void ParentCacheObjectDispatch::init(Context* on_finish) { template bool ParentCacheObjectDispatch::read( uint64_t object_no, const io::Extents &extents, IOContext io_context, - int op_flags, const ZTracer::Trace &parent_trace, + int op_flags, int read_flags, const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, io::Extents* extent_map, uint64_t* version, int* object_dispatch_flags, io::DispatchResult* dispatch_result, Context** on_finish, Context* on_dispatched) { diff --git a/src/librbd/cache/ParentCacheObjectDispatch.h b/src/librbd/cache/ParentCacheObjectDispatch.h index 603ae252fdfae..910c5e32b15a1 100644 --- a/src/librbd/cache/ParentCacheObjectDispatch.h +++ b/src/librbd/cache/ParentCacheObjectDispatch.h @@ -45,7 +45,7 @@ public: bool read( uint64_t object_no, const io::Extents &extents, IOContext io_context, - int op_flags, const ZTracer::Trace &parent_trace, + int op_flags, int read_flags, const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, io::Extents* extent_map, uint64_t* version, int* object_dispatch_flags, io::DispatchResult* dispatch_result, Context** on_finish, diff --git a/src/librbd/cache/WriteAroundObjectDispatch.cc b/src/librbd/cache/WriteAroundObjectDispatch.cc index 0992afafbddb8..e202b08b6c068 100644 --- a/src/librbd/cache/WriteAroundObjectDispatch.cc +++ b/src/librbd/cache/WriteAroundObjectDispatch.cc @@ -58,7 +58,7 @@ void WriteAroundObjectDispatch::shut_down(Context* on_finish) { template bool WriteAroundObjectDispatch::read( uint64_t object_no, const io::Extents &extents, IOContext io_context, - int op_flags, const ZTracer::Trace &parent_trace, + int op_flags, int read_flags, const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, io::Extents* extent_map, uint64_t* version, int* object_dispatch_flags, io::DispatchResult* dispatch_result, Context** on_finish, Context* on_dispatched) { diff --git a/src/librbd/cache/WriteAroundObjectDispatch.h b/src/librbd/cache/WriteAroundObjectDispatch.h index 73c470f6aad54..8086ddc546b58 100644 --- a/src/librbd/cache/WriteAroundObjectDispatch.h +++ b/src/librbd/cache/WriteAroundObjectDispatch.h @@ -43,7 +43,7 @@ public: bool read( uint64_t object_no, const io::Extents &extents, IOContext io_context, - int op_flags, const ZTracer::Trace &parent_trace, + int op_flags, int read_flags, const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, io::Extents* extent_map, uint64_t* version, int* object_dispatch_flags, io::DispatchResult* dispatch_result, Context** on_finish, diff --git a/src/librbd/crypto/CryptoObjectDispatch.cc b/src/librbd/crypto/CryptoObjectDispatch.cc index 197747628bc0b..782d1468a8504 100644 --- a/src/librbd/crypto/CryptoObjectDispatch.cc +++ b/src/librbd/crypto/CryptoObjectDispatch.cc @@ -38,7 +38,7 @@ struct C_EncryptedObjectReadRequest : public Context { C_EncryptedObjectReadRequest( I* image_ctx, CryptoInterface* crypto, uint64_t object_no, uint64_t object_off, uint64_t object_len, IOContext io_context, - int op_flags, const ZTracer::Trace &parent_trace, + int op_flags, int read_flags, const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, int* object_dispatch_flags, Context** on_finish, Context* on_dispatched) : image_ctx(image_ctx), @@ -61,8 +61,9 @@ struct C_EncryptedObjectReadRequest : public Context { req = io::ObjectDispatchSpec::create_read( image_ctx, io::OBJECT_DISPATCH_LAYER_CRYPTO, object_no, - {{object_off, object_len}}, io_context, op_flags, parent_trace, - &req_comp->bl, &req_comp->extent_map, nullptr, req_comp); + {{object_off, object_len}}, io_context, op_flags, read_flags, + parent_trace, &req_comp->bl, &req_comp->extent_map, nullptr, + req_comp); } void send() { @@ -111,8 +112,8 @@ void CryptoObjectDispatch::shut_down(Context* on_finish) { template bool CryptoObjectDispatch::read( - uint64_t object_no, const io::Extents &extents, - IOContext io_context, int op_flags, const ZTracer::Trace &parent_trace, + uint64_t object_no, const io::Extents &extents, IOContext io_context, + int op_flags, int read_flags, const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, io::Extents* extent_map, uint64_t* version, int* object_dispatch_flags, io::DispatchResult* dispatch_result, Context** on_finish, Context* on_dispatched) { @@ -132,8 +133,8 @@ bool CryptoObjectDispatch::read( *dispatch_result = io::DISPATCH_RESULT_COMPLETE; auto req = new C_EncryptedObjectReadRequest( m_image_ctx, m_crypto, object_no, object_off, object_len, io_context, - op_flags, parent_trace, read_data, object_dispatch_flags, on_finish, - on_dispatched); + op_flags, read_flags, parent_trace, read_data, object_dispatch_flags, + on_finish, on_dispatched); req->send(); return true; } diff --git a/src/librbd/crypto/CryptoObjectDispatch.h b/src/librbd/crypto/CryptoObjectDispatch.h index 053be22d4ef60..68f1acf48d06f 100644 --- a/src/librbd/crypto/CryptoObjectDispatch.h +++ b/src/librbd/crypto/CryptoObjectDispatch.h @@ -33,7 +33,7 @@ public: bool read( uint64_t object_no, const io::Extents &extents, - IOContext io_context, int op_flags, + IOContext io_context, int op_flags, int read_flags, const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, io::Extents* extent_map, uint64_t* version, int* object_dispatch_flags, io::DispatchResult* dispatch_result, Context** on_finish, diff --git a/src/librbd/io/ImageRequest.cc b/src/librbd/io/ImageRequest.cc index 8869e5b19813c..b9b624b597515 100644 --- a/src/librbd/io/ImageRequest.cc +++ b/src/librbd/io/ImageRequest.cc @@ -177,7 +177,7 @@ void readahead(I *ictx, const Extents& image_extents, IOContext io_context) { object_extent.length); auto req = io::ObjectDispatchSpec::create_read( ictx, io::OBJECT_DISPATCH_LAYER_NONE, object_extent.object_no, - {{object_extent.offset, object_extent.length}}, io_context, 0, {}, + {{object_extent.offset, object_extent.length}}, io_context, 0, 0, {}, &req_comp->read_data, &req_comp->extent_map, nullptr, req_comp); req->send(); } @@ -482,7 +482,7 @@ void ImageReadRequest::send_request() { aio_comp, oe.offset, oe.length, std::move(oe.buffer_extents)); auto req = ObjectDispatchSpec::create_read( &image_ctx, OBJECT_DISPATCH_LAYER_NONE, oe.object_no, - {{oe.offset, oe.length}}, this->m_io_context, m_op_flags, this->m_trace, + {{oe.offset, oe.length}}, this->m_io_context, m_op_flags, 0, this->m_trace, &req_comp->bl, &req_comp->extent_map, nullptr, req_comp); req->send(); } diff --git a/src/librbd/io/ObjectDispatch.cc b/src/librbd/io/ObjectDispatch.cc index af8ec04df24b0..fde16482b5c37 100644 --- a/src/librbd/io/ObjectDispatch.cc +++ b/src/librbd/io/ObjectDispatch.cc @@ -34,7 +34,7 @@ void ObjectDispatch::shut_down(Context* on_finish) { template bool ObjectDispatch::read( uint64_t object_no, const Extents &extents, IOContext io_context, - int op_flags, const ZTracer::Trace &parent_trace, + int op_flags, int read_flags, const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, Extents* extent_map, uint64_t* version, int* object_dispatch_flags, DispatchResult* dispatch_result, Context** on_finish, Context* on_dispatched) { @@ -43,9 +43,9 @@ bool ObjectDispatch::read( *dispatch_result = DISPATCH_RESULT_COMPLETE; auto req = new ObjectReadRequest(m_image_ctx, object_no, extents, - io_context, op_flags, parent_trace, - read_data, extent_map, version, - on_dispatched); + io_context, op_flags, read_flags, + parent_trace, read_data, extent_map, + version, on_dispatched); req->send(); return true; } diff --git a/src/librbd/io/ObjectDispatch.h b/src/librbd/io/ObjectDispatch.h index 9bbaa5e2f65d4..3d7f9eba9a335 100644 --- a/src/librbd/io/ObjectDispatch.h +++ b/src/librbd/io/ObjectDispatch.h @@ -34,7 +34,7 @@ public: bool read( uint64_t object_no, const Extents &extents, IOContext io_context, - int op_flags, const ZTracer::Trace &parent_trace, + int op_flags, int read_flags, const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, Extents* extent_map, uint64_t* version, int* object_dispatch_flags, DispatchResult* dispatch_result, Context** on_finish, diff --git a/src/librbd/io/ObjectDispatchInterface.h b/src/librbd/io/ObjectDispatchInterface.h index a4525bee883e7..92fd13de7f15f 100644 --- a/src/librbd/io/ObjectDispatchInterface.h +++ b/src/librbd/io/ObjectDispatchInterface.h @@ -35,7 +35,7 @@ struct ObjectDispatchInterface { virtual bool read( uint64_t object_no, const Extents &extents, - IOContext io_context, int op_flags, + IOContext io_context, int op_flags, int read_flags, const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, Extents* extent_map, uint64_t* version, int* object_dispatch_flags, DispatchResult* dispatch_result, Context** on_finish, diff --git a/src/librbd/io/ObjectDispatchSpec.h b/src/librbd/io/ObjectDispatchSpec.h index ee0e88fed7e4f..c9daae6c08282 100644 --- a/src/librbd/io/ObjectDispatchSpec.h +++ b/src/librbd/io/ObjectDispatchSpec.h @@ -44,15 +44,16 @@ public: struct ReadRequest : public RequestBase { const Extents extents; + int read_flags; ceph::bufferlist* read_data; Extents* extent_map; uint64_t* version; ReadRequest(uint64_t object_no, const Extents &extents, - ceph::bufferlist* read_data, Extents* extent_map, - uint64_t* version) - : RequestBase(object_no), extents(extents), read_data(read_data), - extent_map(extent_map), version(version) { + int read_flags, ceph::bufferlist* read_data, + Extents* extent_map, uint64_t* version) + : RequestBase(object_no), extents(extents), read_flags(read_flags), + read_data(read_data), extent_map(extent_map), version(version) { } }; @@ -170,13 +171,14 @@ public: static ObjectDispatchSpec* create_read( ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer, uint64_t object_no, const Extents &extents, IOContext io_context, - int op_flags, const ZTracer::Trace &parent_trace, + int op_flags, int read_flags, const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, Extents* extent_map, uint64_t* version, Context* on_finish) { return new ObjectDispatchSpec(image_ctx->io_object_dispatcher, object_dispatch_layer, ReadRequest{object_no, extents, - read_data, extent_map, version}, + read_flags, read_data, extent_map, + version}, io_context, op_flags, parent_trace, on_finish); } diff --git a/src/librbd/io/ObjectDispatcher.cc b/src/librbd/io/ObjectDispatcher.cc index 380cda279d96f..432573c132be6 100644 --- a/src/librbd/io/ObjectDispatcher.cc +++ b/src/librbd/io/ObjectDispatcher.cc @@ -108,7 +108,8 @@ struct ObjectDispatcher::SendVisitor : public boost::static_visitor { bool operator()(ObjectDispatchSpec::ReadRequest& read) const { return object_dispatch->read( read.object_no, read.extents, object_dispatch_spec->io_context, - object_dispatch_spec->op_flags, object_dispatch_spec->parent_trace, + object_dispatch_spec->op_flags, read.read_flags, + object_dispatch_spec->parent_trace, read.read_data, read.extent_map, read.version, &object_dispatch_spec->object_dispatch_flags, &object_dispatch_spec->dispatch_result, diff --git a/src/librbd/io/ObjectRequest.cc b/src/librbd/io/ObjectRequest.cc index 04646fcd8b3bf..bdb724535a9be 100644 --- a/src/librbd/io/ObjectRequest.cc +++ b/src/librbd/io/ObjectRequest.cc @@ -201,13 +201,13 @@ void ObjectRequest::finish(int r) { template ObjectReadRequest::ObjectReadRequest( I *ictx, uint64_t objectno, const Extents &extents, - IOContext io_context, int op_flags, const ZTracer::Trace &parent_trace, - ceph::bufferlist* read_data, Extents* extent_map, uint64_t* version, - Context *completion) - : ObjectRequest(ictx, objectno, io_context, "read", parent_trace, - completion), - m_extents(extents), m_op_flags(op_flags), m_read_data(read_data), - m_extent_map(extent_map), m_version(version) { + IOContext io_context, int op_flags, int read_flags, + const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, + Extents* extent_map, uint64_t* version, Context *completion) + : ObjectRequest(ictx, objectno, io_context, "read", + parent_trace, completion), + m_extents(extents), m_op_flags(op_flags), m_read_flags(read_flags), + m_read_data(read_data), m_extent_map(extent_map), m_version(version) { } template @@ -299,6 +299,11 @@ void ObjectReadRequest::handle_read_object(int r) { template void ObjectReadRequest::read_parent() { + if ((m_read_flags & READ_FLAG_DISABLE_READ_FROM_PARENT) != 0) { + this->finish(-ENOENT); + return; + } + I *image_ctx = this->m_ictx; ldout(image_ctx->cct, 20) << dendl; diff --git a/src/librbd/io/ObjectRequest.h b/src/librbd/io/ObjectRequest.h index dab819f637a73..35da69abdd83c 100644 --- a/src/librbd/io/ObjectRequest.h +++ b/src/librbd/io/ObjectRequest.h @@ -94,19 +94,19 @@ class ObjectReadRequest : public ObjectRequest { public: static ObjectReadRequest* create( ImageCtxT *ictx, uint64_t objectno, const Extents &extents, - IOContext io_context, int op_flags, const ZTracer::Trace &parent_trace, - ceph::bufferlist* read_data, Extents* extent_map, uint64_t* version, - Context *completion) { + IOContext io_context, int op_flags, int read_flags, + const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, + Extents* extent_map, uint64_t* version, Context *completion) { return new ObjectReadRequest(ictx, objectno, extents, io_context, op_flags, - parent_trace, read_data, extent_map, version, - completion); + read_flags, parent_trace, read_data, + extent_map, version, completion); } ObjectReadRequest( ImageCtxT *ictx, uint64_t objectno, const Extents &extents, - IOContext io_context, int op_flags, const ZTracer::Trace &parent_trace, - ceph::bufferlist* read_data, Extents* extent_map, uint64_t* version, - Context *completion); + IOContext io_context, int op_flags, int read_flags, + const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, + Extents* extent_map, uint64_t* version, Context *completion); void send() override; @@ -142,6 +142,7 @@ private: typedef std::vector ExtentResults; ExtentResults m_extent_results; int m_op_flags; + int m_read_flags; ceph::bufferlist* m_read_data; Extents* m_extent_map; diff --git a/src/librbd/io/SimpleSchedulerObjectDispatch.cc b/src/librbd/io/SimpleSchedulerObjectDispatch.cc index f16167957dbe4..2886de0aba080 100644 --- a/src/librbd/io/SimpleSchedulerObjectDispatch.cc +++ b/src/librbd/io/SimpleSchedulerObjectDispatch.cc @@ -220,7 +220,7 @@ void SimpleSchedulerObjectDispatch::shut_down(Context* on_finish) { template bool SimpleSchedulerObjectDispatch::read( uint64_t object_no, const Extents &extents, IOContext io_context, - int op_flags, const ZTracer::Trace &parent_trace, + int op_flags, int read_flags, const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, Extents* extent_map, uint64_t* version, int* object_dispatch_flags, DispatchResult* dispatch_result, Context** on_finish, Context* on_dispatched) { diff --git a/src/librbd/io/SimpleSchedulerObjectDispatch.h b/src/librbd/io/SimpleSchedulerObjectDispatch.h index cc34ac9903975..faf965dc14992 100644 --- a/src/librbd/io/SimpleSchedulerObjectDispatch.h +++ b/src/librbd/io/SimpleSchedulerObjectDispatch.h @@ -50,7 +50,7 @@ public: bool read( uint64_t object_no, const Extents &extents, IOContext io_context, - int op_flags, const ZTracer::Trace &parent_trace, + int op_flags, int read_flags, const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, Extents* extent_map, uint64_t* version, int* object_dispatch_flags, DispatchResult* dispatch_result, Context** on_finish, diff --git a/src/librbd/io/Types.h b/src/librbd/io/Types.h index 58f4ef3919905..bce9fd22762e4 100644 --- a/src/librbd/io/Types.h +++ b/src/librbd/io/Types.h @@ -106,6 +106,10 @@ enum ObjectDispatchLayer { OBJECT_DISPATCH_LAYER_LAST }; +enum { + READ_FLAG_DISABLE_READ_FROM_PARENT = 1UL << 0, +}; + enum { OBJECT_WRITE_FLAG_CREATE_EXCLUSIVE = 1UL << 0 }; diff --git a/src/librbd/journal/ObjectDispatch.h b/src/librbd/journal/ObjectDispatch.h index 64f0ab251d68b..a523fa390de12 100644 --- a/src/librbd/journal/ObjectDispatch.h +++ b/src/librbd/journal/ObjectDispatch.h @@ -38,7 +38,7 @@ public: bool read( uint64_t object_no, const io::Extents &extents, IOContext io_context, - int op_flags, const ZTracer::Trace &parent_trace, + int op_flags, int read_flags, const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data, io::Extents* extent_map, uint64_t* version, int* object_dispatch_flags, io::DispatchResult* dispatch_result, Context** on_finish, diff --git a/src/test/librbd/cache/test_mock_ParentCacheObjectDispatch.cc b/src/test/librbd/cache/test_mock_ParentCacheObjectDispatch.cc index 1185500e332de..f3947ebe84d80 100644 --- a/src/test/librbd/cache/test_mock_ParentCacheObjectDispatch.cc +++ b/src/test/librbd/cache/test_mock_ParentCacheObjectDispatch.cc @@ -362,7 +362,7 @@ TEST_F(TestMockParentCacheObjectDispatch, test_read) { io::DispatchResult dispatch_result; ceph::bufferlist read_data; mock_parent_image_cache->read( - 0, {{0, 4096}}, mock_image_ctx.get_data_io_context(), 0, {}, &read_data, + 0, {{0, 4096}}, mock_image_ctx.get_data_io_context(), 0, 0, {}, &read_data, nullptr, nullptr, nullptr, &dispatch_result, nullptr, &on_dispatched); ASSERT_EQ(0, on_dispatched.wait()); @@ -415,7 +415,7 @@ TEST_F(TestMockParentCacheObjectDispatch, test_read_dne) { C_SaferCond on_dispatched; io::DispatchResult dispatch_result; mock_parent_image_cache->read( - 0, {{0, 4096}}, mock_image_ctx.get_data_io_context(), 0, {}, nullptr, + 0, {{0, 4096}}, mock_image_ctx.get_data_io_context(), 0, 0, {}, nullptr, nullptr, nullptr, nullptr, &dispatch_result, nullptr, &on_dispatched); ASSERT_EQ(0, on_dispatched.wait()); diff --git a/src/test/librbd/crypto/test_mock_CryptoObjectDispatch.cc b/src/test/librbd/crypto/test_mock_CryptoObjectDispatch.cc index 8ae7c1d39aea5..af5932130512d 100644 --- a/src/test/librbd/crypto/test_mock_CryptoObjectDispatch.cc +++ b/src/test/librbd/crypto/test_mock_CryptoObjectDispatch.cc @@ -136,7 +136,7 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, Discard) { TEST_F(TestMockCryptoCryptoObjectDispatch, ReadFail) { expect_object_read(); ASSERT_TRUE(mock_crypto_object_dispatch->read( - 0, {{0, 4096}}, mock_image_ctx->get_data_io_context(), 0, {}, &data, + 0, {{0, 4096}}, mock_image_ctx->get_data_io_context(), 0, 0, {}, &data, &extent_map, nullptr, &object_dispatch_flags, &dispatch_result, &on_finish, on_dispatched)); ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE); @@ -150,8 +150,8 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, ReadFail) { TEST_F(TestMockCryptoCryptoObjectDispatch, Read) { expect_object_read(); ASSERT_TRUE(mock_crypto_object_dispatch->read( - 0, {{0, 4096}}, mock_image_ctx->get_data_io_context(), 0, {}, &data, - &extent_map, nullptr, &object_dispatch_flags, &dispatch_result, + 0, {{0, 4096}}, mock_image_ctx->get_data_io_context(), 0, 0, {}, + &data, &extent_map, nullptr, &object_dispatch_flags, &dispatch_result, &on_finish, on_dispatched)); ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE); ASSERT_NE(on_finish, &finished_cond); diff --git a/src/test/librbd/io/test_mock_ObjectRequest.cc b/src/test/librbd/io/test_mock_ObjectRequest.cc index 902dc41be32ee..3e2fbbdbeb849 100644 --- a/src/test/librbd/io/test_mock_ObjectRequest.cc +++ b/src/test/librbd/io/test_mock_ObjectRequest.cc @@ -427,7 +427,7 @@ TEST_F(TestMockIoObjectRequest, Read) { uint64_t version; auto req = MockObjectReadRequest::create( &mock_image_ctx, 0, {{0, 4096}, {8192, 4096}}, - mock_image_ctx.get_data_io_context(), 0, {}, + mock_image_ctx.get_data_io_context(), 0, 0, {}, &bl, &extent_map, &version, &ctx); req->send(); ASSERT_EQ(0, ctx.wait()); @@ -468,7 +468,7 @@ TEST_F(TestMockIoObjectRequest, SparseReadThreshold) { auto req = MockObjectReadRequest::create( &mock_image_ctx, 0, {{0, ictx->sparse_read_threshold_bytes}}, - mock_image_ctx.get_data_io_context(), 0, {}, &bl, + mock_image_ctx.get_data_io_context(), 0, 0, {}, &bl, &extent_map, nullptr, &ctx); req->send(); ASSERT_EQ(0, ctx.wait()); @@ -496,7 +496,7 @@ TEST_F(TestMockIoObjectRequest, ReadError) { C_SaferCond ctx; auto req = MockObjectReadRequest::create( &mock_image_ctx, 0, {{0, 4096}}, - mock_image_ctx.get_data_io_context(), 0, {}, &bl, &extent_map, + mock_image_ctx.get_data_io_context(), 0, 0, {}, &bl, &extent_map, nullptr, &ctx); req->send(); ASSERT_EQ(-EPERM, ctx.wait()); @@ -543,7 +543,7 @@ TEST_F(TestMockIoObjectRequest, ParentRead) { C_SaferCond ctx; auto req = MockObjectReadRequest::create( &mock_image_ctx, 0, {{0, 4096}}, - mock_image_ctx.get_data_io_context(), 0, {}, &bl, &extent_map, + mock_image_ctx.get_data_io_context(), 0, 0, {}, &bl, &extent_map, nullptr, &ctx); req->send(); ASSERT_EQ(0, ctx.wait()); @@ -590,12 +590,56 @@ TEST_F(TestMockIoObjectRequest, ParentReadError) { C_SaferCond ctx; auto req = MockObjectReadRequest::create( &mock_image_ctx, 0, {{0, 4096}}, - mock_image_ctx.get_data_io_context(), 0, {}, &bl, &extent_map, + mock_image_ctx.get_data_io_context(), 0, 0, {}, &bl, &extent_map, nullptr, &ctx); req->send(); ASSERT_EQ(-EPERM, ctx.wait()); } +TEST_F(TestMockIoObjectRequest, SkipParentRead) { + REQUIRE_FEATURE(RBD_FEATURE_LAYERING); + + librbd::Image image; + librbd::RBD rbd; + ASSERT_EQ(0, rbd.open(m_ioctx, image, m_image_name.c_str(), NULL)); + ASSERT_EQ(0, image.snap_create("one")); + ASSERT_EQ(0, image.snap_protect("one")); + image.close(); + + std::string clone_name = get_temp_image_name(); + int order = 0; + ASSERT_EQ(0, rbd.clone(m_ioctx, m_image_name.c_str(), "one", m_ioctx, + clone_name.c_str(), RBD_FEATURE_LAYERING, &order)); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(clone_name, &ictx)); + ictx->sparse_read_threshold_bytes = 8096; + ictx->clone_copy_on_read = false; + + MockTestImageCtx mock_image_ctx(*ictx); + mock_image_ctx.parent = &mock_image_ctx; + + MockObjectMap mock_object_map; + if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) { + mock_image_ctx.object_map = &mock_object_map; + } + + InSequence seq; + expect_object_may_exist(mock_image_ctx, 0, true); + expect_get_read_flags(mock_image_ctx, CEPH_NOSNAP, 0); + expect_read(mock_image_ctx, ictx->get_object_name(0), 0, 4096, "", -ENOENT); + + bufferlist bl; + Extents extent_map; + C_SaferCond ctx; + auto req = MockObjectReadRequest::create( + &mock_image_ctx, 0, {{0, 4096}}, mock_image_ctx.get_data_io_context(), 0, + READ_FLAG_DISABLE_READ_FROM_PARENT, {}, &bl, &extent_map, + nullptr, &ctx); + req->send(); + ASSERT_EQ(-ENOENT, ctx.wait()); +} + TEST_F(TestMockIoObjectRequest, CopyOnRead) { REQUIRE_FEATURE(RBD_FEATURE_LAYERING); @@ -642,7 +686,7 @@ TEST_F(TestMockIoObjectRequest, CopyOnRead) { C_SaferCond ctx; auto req = MockObjectReadRequest::create( &mock_image_ctx, 0, {{0, 4096}}, - mock_image_ctx.get_data_io_context(), 0, {}, &bl, &extent_map, + mock_image_ctx.get_data_io_context(), 0, 0, {}, &bl, &extent_map, nullptr, &ctx); req->send(); ASSERT_EQ(0, ctx.wait()); diff --git a/src/test/librbd/io/test_mock_SimpleSchedulerObjectDispatch.cc b/src/test/librbd/io/test_mock_SimpleSchedulerObjectDispatch.cc index febbfdb8bdbb1..dd7625cecb8a4 100644 --- a/src/test/librbd/io/test_mock_SimpleSchedulerObjectDispatch.cc +++ b/src/test/librbd/io/test_mock_SimpleSchedulerObjectDispatch.cc @@ -132,7 +132,7 @@ TEST_F(TestMockIoSimpleSchedulerObjectDispatch, Read) { C_SaferCond cond; Context *on_finish = &cond; ASSERT_FALSE(mock_simple_scheduler_object_dispatch.read( - 0, {{0, 4096}}, mock_image_ctx.get_data_io_context(), 0, {}, nullptr, + 0, {{0, 4096}}, mock_image_ctx.get_data_io_context(), 0, 0, {}, nullptr, nullptr, nullptr, nullptr, nullptr, &on_finish, nullptr)); ASSERT_EQ(on_finish, &cond); // not modified on_finish->complete(0); diff --git a/src/test/librbd/mock/io/MockObjectDispatch.h b/src/test/librbd/mock/io/MockObjectDispatch.h index b873964c21e08..ccdde9f74b160 100644 --- a/src/test/librbd/mock/io/MockObjectDispatch.h +++ b/src/test/librbd/mock/io/MockObjectDispatch.h @@ -30,7 +30,7 @@ public: DispatchResult*, Context*)); bool read( uint64_t object_no, const Extents& extents, IOContext io_context, - int op_flags, const ZTracer::Trace& parent_trace, + int op_flags, int read_flags, const ZTracer::Trace& parent_trace, ceph::bufferlist* read_data, Extents* extent_map, uint64_t* version, int* dispatch_flags, DispatchResult* dispatch_result, Context** on_finish, Context* on_dispatched) {