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:
Yingxin 2024-05-16 14:18:46 +08:00 committed by GitHub
commit a8099a6c30
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -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 &current) {
return trans_intr::do_for_each(
pins,
[ctx, loffset, len, &current, &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, &current, 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(