From: chunmei-liu Date: Mon, 7 Feb 2022 22:34:33 +0000 (-0800) Subject: crimson/seastore: support sparse_read X-Git-Tag: v18.0.0~1369^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2baabdaf129c797bb999eccc603f296de0b544fd;p=ceph.git crimson/seastore: support sparse_read add fiemap and readv functions. Signed-off-by: chunmei-liu --- diff --git a/src/crimson/os/seastore/object_data_handler.cc b/src/crimson/os/seastore/object_data_handler.cc index 4e5a55b0d0a..62422997915 100644 --- a/src/crimson/os/seastore/object_data_handler.cc +++ b/src/crimson/os/seastore/object_data_handler.cc @@ -551,6 +551,60 @@ ObjectDataHandler::read_ret ObjectDataHandler::read( }); } +ObjectDataHandler::fiemap_ret ObjectDataHandler::fiemap( + context_t ctx, + objaddr_t obj_offset, + extent_len_t len) +{ + return seastar::do_with( + std::map(), + [ctx, obj_offset, len](auto &ret) { + return with_object_data( + ctx, + [ctx, obj_offset, len, &ret](const auto &object_data) { + LOG_PREFIX(ObjectDataHandler::fiemap); + DEBUGT( + "{}~{}, reservation {}~{}", + ctx.t, + obj_offset, + len, + object_data.get_reserved_data_base(), + object_data.get_reserved_data_len()); + /* Assumption: callers ensure that onode size is <= reserved + * size and that len is adjusted here prior to call */ + ceph_assert(!object_data.is_null()); + ceph_assert((obj_offset + len) <= object_data.get_reserved_data_len()); + ceph_assert(len > 0); + laddr_t loffset = + object_data.get_reserved_data_base() + obj_offset; + return ctx.tm.get_pins( + ctx.t, + loffset, + len + ).si_then([loffset, len, &object_data, &ret](auto &&pins) { + ceph_assert(pins.size() >= 1); + ceph_assert((*pins.begin())->get_laddr() <= loffset); + for (auto &&i: pins) { + if (!(i->get_paddr().is_zero())) { + auto ret_left = std::max(i->get_laddr(), loffset); + auto ret_right = std::min( + i->get_laddr() + i->get_length(), + loffset + len); + assert(ret_right > ret_left); + ret.emplace( + std::make_pair( + ret_left - object_data.get_reserved_data_base(), + ret_right - ret_left + )); + } + } + }); + }).si_then([&ret] { + return std::move(ret); + }); + }); +} + ObjectDataHandler::truncate_ret ObjectDataHandler::truncate( context_t ctx, objaddr_t offset) diff --git a/src/crimson/os/seastore/object_data_handler.h b/src/crimson/os/seastore/object_data_handler.h index c397245125c..dd91f343623 100644 --- a/src/crimson/os/seastore/object_data_handler.h +++ b/src/crimson/os/seastore/object_data_handler.h @@ -74,6 +74,14 @@ public: objaddr_t offset, extent_len_t len); + /// sparse read data, get range interval in [offset, offset + len) + using fiemap_iertr = base_iertr; + using fiemap_ret = fiemap_iertr::future>; + fiemap_ret fiemap( + context_t ctx, + objaddr_t offset, + extent_len_t len); + /// Clears data past offset using truncate_iertr = base_iertr; using truncate_ret = truncate_iertr::future<>; diff --git a/src/crimson/os/seastore/seastore.cc b/src/crimson/os/seastore/seastore.cc index 2702e497309..0323f81e956 100644 --- a/src/crimson/os/seastore/seastore.cc +++ b/src/crimson/os/seastore/seastore.cc @@ -484,6 +484,22 @@ SeaStore::read_errorator::future SeaStore::readv( interval_set& m, uint32_t op_flags) { + return seastar::do_with( + ceph::bufferlist{}, + [=, &oid, &m](auto &ret) { + return crimson::do_for_each( + m, + [=, &oid, &ret](auto &p) { + return read( + ch, oid, p.first, p.second, op_flags + ).safe_then([&ret](auto bl) { + ret.claim_append(bl); + }); + }).safe_then([&ret] { + return read_errorator::make_ready_future + (std::move(ret)); + }); + }); return read_errorator::make_ready_future(); } @@ -853,13 +869,53 @@ seastar::future SeaStore::get_omap_iterator( }); } +SeaStore::_fiemap_ret SeaStore::_fiemap( + Transaction &t, + Onode &onode, + uint64_t off, + uint64_t len) const +{ + return seastar::do_with( + ObjectDataHandler(max_object_size), + [=, &t, &onode] (auto &objhandler) { + return objhandler.fiemap( + ObjectDataHandler::context_t{ + *transaction_manager, + t, + onode, + }, + off, + len); + }); +} seastar::future> SeaStore::fiemap( CollectionRef ch, const ghobject_t& oid, uint64_t off, uint64_t len) { - return seastar::make_ready_future>(); + LOG_PREFIX(SeaStore::fiemap); + DEBUG("oid: {}, off: {}, len: {} ", oid, off, len); + return repeat_with_onode>( + ch, + oid, + Transaction::src_t::READ, + "fiemap_read", + op_type_t::READ, + [=](auto &t, auto &onode) -> _fiemap_ret { + size_t size = onode.get_layout().size; + if (off >= size) { + INFOT("fiemap offset is over onode size!", t); + return seastar::make_ready_future>(); + } + size_t adjust_len = (len == 0) ? + size - off: + std::min(size - off, len); + return _fiemap(t, onode, off, adjust_len); + }).handle_error( + crimson::ct_error::assert_all{ + "Invalid error in SeaStore::fiemap" + }); } void SeaStore::on_error(ceph::os::Transaction &t) { diff --git a/src/crimson/os/seastore/seastore.h b/src/crimson/os/seastore/seastore.h index 93e34c28801..358370ae59e 100644 --- a/src/crimson/os/seastore/seastore.h +++ b/src/crimson/os/seastore/seastore.h @@ -22,6 +22,7 @@ #include "crimson/os/seastore/onode_manager.h" #include "crimson/os/seastore/omap_manager.h" #include "crimson/os/seastore/collection_manager.h" +#include "crimson/os/seastore/object_data_handler.h" namespace crimson::os::seastore { @@ -269,6 +270,13 @@ private: }); } + using _fiemap_ret = ObjectDataHandler::fiemap_ret; + _fiemap_ret _fiemap( + Transaction &t, + Onode &onode, + uint64_t off, + uint64_t len) const; + using _omap_get_value_iertr = OMapManager::base_iertr::extend< crimson::ct_error::enodata >;