mirror of
https://github.com/ceph/ceph
synced 2025-01-02 00:52:22 +00:00
Merge pull request #57432 from cyx1231st/wip-seastore-cleanup-objdata-read
crimson/os/seastore/object_data_handler: cleanup read() Reviewed-by: Myoungwon Oh <myoungwon.oh@samsung.com> Reviewed-by: Xuehan Xu <xuxuehan@qianxin.com>
This commit is contained in:
commit
a8099a6c30
@ -1445,93 +1445,126 @@ ObjectDataHandler::read_ret ObjectDataHandler::read(
|
||||
return seastar::do_with(
|
||||
bufferlist(),
|
||||
[ctx, obj_offset, len](auto &ret) {
|
||||
return with_object_data(
|
||||
ctx,
|
||||
[ctx, obj_offset, len, &ret](const auto &object_data) {
|
||||
LOG_PREFIX(ObjectDataHandler::read);
|
||||
DEBUGT("reading {}~{}",
|
||||
ctx.t,
|
||||
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([ctx, loffset, len, &ret](auto _pins) {
|
||||
// offset~len falls within reserved region and len > 0
|
||||
ceph_assert(_pins.size() >= 1);
|
||||
ceph_assert((*_pins.begin())->get_key() <= loffset);
|
||||
return seastar::do_with(
|
||||
std::move(_pins),
|
||||
loffset,
|
||||
[ctx, loffset, len, &ret](auto &pins, auto ¤t) {
|
||||
return trans_intr::do_for_each(
|
||||
pins,
|
||||
[ctx, loffset, len, ¤t, &ret](auto &pin)
|
||||
-> read_iertr::future<> {
|
||||
ceph_assert(current <= (loffset + len));
|
||||
ceph_assert(
|
||||
(loffset + len) > pin->get_key());
|
||||
laddr_t end = std::min(
|
||||
pin->get_key() + pin->get_length(),
|
||||
loffset + len);
|
||||
if (pin->get_val().is_zero()) {
|
||||
ceph_assert(end > current); // See LBAManager::get_mappings
|
||||
ret.append_zero(end - current);
|
||||
current = end;
|
||||
return seastar::now();
|
||||
} else {
|
||||
LOG_PREFIX(ObjectDataHandler::read);
|
||||
auto key = pin->get_key();
|
||||
bool is_indirect = pin->is_indirect();
|
||||
extent_len_t off = pin->get_intermediate_offset();
|
||||
DEBUGT("reading {}~{}, indirect: {}, "
|
||||
"intermediate offset: {}, current: {}, end: {}",
|
||||
ctx.t,
|
||||
key,
|
||||
pin->get_length(),
|
||||
is_indirect,
|
||||
off,
|
||||
current,
|
||||
end);
|
||||
return ctx.tm.read_pin<ObjectDataBlock>(
|
||||
ctx.t,
|
||||
std::move(pin)
|
||||
).si_then([&ret, ¤t, end, key, off,
|
||||
is_indirect](auto extent) {
|
||||
ceph_assert(
|
||||
is_indirect
|
||||
? (key - off + extent->get_length()) >= end
|
||||
: (extent->get_laddr() + extent->get_length()) >= end);
|
||||
ceph_assert(end > current);
|
||||
ret.append(
|
||||
bufferptr(
|
||||
extent->get_bptr(),
|
||||
off + current - (is_indirect ? key : extent->get_laddr()),
|
||||
end - current));
|
||||
current = end;
|
||||
return seastar::now();
|
||||
}).handle_error_interruptible(
|
||||
read_iertr::pass_further{},
|
||||
crimson::ct_error::assert_all{
|
||||
"ObjectDataHandler::read hit invalid error"
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}).si_then([&ret] {
|
||||
return std::move(ret);
|
||||
});
|
||||
return with_object_data(
|
||||
ctx,
|
||||
[ctx, obj_offset, len, &ret](const auto &object_data) {
|
||||
LOG_PREFIX(ObjectDataHandler::read);
|
||||
DEBUGT("reading {}~{}",
|
||||
ctx.t,
|
||||
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 l_start =
|
||||
object_data.get_reserved_data_base() + obj_offset;
|
||||
return ctx.tm.get_pins(
|
||||
ctx.t,
|
||||
l_start,
|
||||
len
|
||||
).si_then([FNAME, ctx, l_start, len, &ret](auto _pins) {
|
||||
// offset~len falls within reserved region and len > 0
|
||||
ceph_assert(_pins.size() >= 1);
|
||||
ceph_assert((*_pins.begin())->get_key() <= l_start);
|
||||
auto l_end = l_start + len;
|
||||
return seastar::do_with(
|
||||
std::move(_pins),
|
||||
l_start,
|
||||
[FNAME, ctx, l_start, l_end, &ret](auto &pins, auto &l_current) {
|
||||
return trans_intr::do_for_each(
|
||||
pins,
|
||||
[FNAME, ctx, l_start, l_end,
|
||||
&l_current, &ret](auto &pin) -> read_iertr::future<> {
|
||||
auto pin_key = pin->get_key();
|
||||
if (l_current == l_start) {
|
||||
ceph_assert(l_current >= pin_key);
|
||||
} else {
|
||||
assert(l_current > l_start);
|
||||
ceph_assert(l_current == pin_key);
|
||||
}
|
||||
ceph_assert(l_current < l_end);
|
||||
auto pin_len = pin->get_length();
|
||||
assert(pin_len > 0);
|
||||
laddr_t l_pin_end = pin_key + pin_len;
|
||||
ceph_assert(l_current < l_pin_end);
|
||||
laddr_t l_current_end = std::min(l_pin_end, l_end);
|
||||
if (pin->get_val().is_zero()) {
|
||||
DEBUGT("got {}~{} from zero-pin {}~{}",
|
||||
ctx.t,
|
||||
l_current,
|
||||
l_current_end - l_current,
|
||||
pin_key,
|
||||
pin_len);
|
||||
ret.append_zero(l_current_end - l_current);
|
||||
l_current = l_current_end;
|
||||
return seastar::now();
|
||||
}
|
||||
|
||||
// non-zero pin
|
||||
bool is_indirect = pin->is_indirect();
|
||||
laddr_t e_key;
|
||||
extent_len_t e_len;
|
||||
extent_len_t e_off;
|
||||
if (is_indirect) {
|
||||
e_key = pin->get_intermediate_base();
|
||||
e_len = pin->get_intermediate_length();
|
||||
e_off = pin->get_intermediate_offset();
|
||||
DEBUGT("reading {}~{} from indirect-pin {}~{}, direct-pin {}~{}(off={})",
|
||||
ctx.t,
|
||||
l_current,
|
||||
l_current_end - l_current,
|
||||
pin_key,
|
||||
pin_len,
|
||||
e_key,
|
||||
e_len,
|
||||
e_off);
|
||||
assert(e_key <= pin->get_intermediate_key());
|
||||
assert(e_off + pin_len <= e_len);
|
||||
} else {
|
||||
DEBUGT("reading {}~{} from pin {}~{}",
|
||||
ctx.t,
|
||||
l_current,
|
||||
l_current_end - l_current,
|
||||
pin_key,
|
||||
pin_len);
|
||||
e_key = pin_key;
|
||||
e_len = pin_len;
|
||||
e_off = 0;
|
||||
}
|
||||
extent_len_t e_current_off = e_off + l_current - pin_key;
|
||||
return ctx.tm.read_pin<ObjectDataBlock>(
|
||||
ctx.t,
|
||||
std::move(pin)
|
||||
).si_then([&ret, &l_current, l_current_end,
|
||||
#ifndef NDEBUG
|
||||
e_key, e_len, e_current_off](auto extent) {
|
||||
#else
|
||||
e_current_off](auto extent) {
|
||||
#endif
|
||||
assert(e_key == extent->get_laddr());
|
||||
assert(e_len == extent->get_length());
|
||||
ret.append(
|
||||
bufferptr(
|
||||
extent->get_bptr(),
|
||||
e_current_off,
|
||||
l_current_end - l_current));
|
||||
l_current = l_current_end;
|
||||
return seastar::now();
|
||||
}).handle_error_interruptible(
|
||||
read_iertr::pass_further{},
|
||||
crimson::ct_error::assert_all{
|
||||
"ObjectDataHandler::read hit invalid error"
|
||||
}
|
||||
);
|
||||
}); // trans_intr::do_for_each()
|
||||
}); // do_with()
|
||||
});
|
||||
}).si_then([&ret] { // with_object_data()
|
||||
return std::move(ret);
|
||||
});
|
||||
}); // do_with()
|
||||
}
|
||||
|
||||
ObjectDataHandler::fiemap_ret ObjectDataHandler::fiemap(
|
||||
@ -1558,21 +1591,21 @@ ObjectDataHandler::fiemap_ret ObjectDataHandler::fiemap(
|
||||
ceph_assert(!object_data.is_null());
|
||||
ceph_assert((obj_offset + len) <= object_data.get_reserved_data_len());
|
||||
ceph_assert(len > 0);
|
||||
laddr_t loffset =
|
||||
laddr_t l_start =
|
||||
object_data.get_reserved_data_base() + obj_offset;
|
||||
return ctx.tm.get_pins(
|
||||
ctx.t,
|
||||
loffset,
|
||||
l_start,
|
||||
len
|
||||
).si_then([loffset, len, &object_data, &ret](auto &&pins) {
|
||||
).si_then([l_start, len, &object_data, &ret](auto &&pins) {
|
||||
ceph_assert(pins.size() >= 1);
|
||||
ceph_assert((*pins.begin())->get_key() <= loffset);
|
||||
ceph_assert((*pins.begin())->get_key() <= l_start);
|
||||
for (auto &&i: pins) {
|
||||
if (!(i->get_val().is_zero())) {
|
||||
auto ret_left = std::max(i->get_key(), loffset);
|
||||
auto ret_left = std::max(i->get_key(), l_start);
|
||||
auto ret_right = std::min(
|
||||
i->get_key() + i->get_length(),
|
||||
loffset + len);
|
||||
l_start + len);
|
||||
assert(ret_right > ret_left);
|
||||
ret.emplace(
|
||||
std::make_pair(
|
||||
|
Loading…
Reference in New Issue
Block a user