@@ -1445,93 +1445,126 @@ ObjectDataHandler::read_ret ObjectDataHandler::read(
14451445 return seastar::do_with (
14461446 bufferlist (),
14471447 [ctx, obj_offset, len](auto &ret) {
1448- return with_object_data (
1449- ctx,
1450- [ctx, obj_offset, len, &ret](const auto &object_data) {
1451- LOG_PREFIX (ObjectDataHandler::read);
1452- DEBUGT (" reading {}~{}" ,
1453- ctx.t ,
1454- object_data.get_reserved_data_base (),
1455- object_data.get_reserved_data_len ());
1456- /* Assumption: callers ensure that onode size is <= reserved
1457- * size and that len is adjusted here prior to call */
1458- ceph_assert (!object_data.is_null ());
1459- ceph_assert ((obj_offset + len) <= object_data.get_reserved_data_len ());
1460- ceph_assert (len > 0 );
1461- laddr_t loffset =
1462- object_data.get_reserved_data_base () + obj_offset;
1463- return ctx.tm .get_pins (
1464- ctx.t ,
1465- loffset,
1466- len
1467- ).si_then ([ctx, loffset, len, &ret](auto _pins) {
1468- // offset~len falls within reserved region and len > 0
1469- ceph_assert (_pins.size () >= 1 );
1470- ceph_assert ((*_pins.begin ())->get_key () <= loffset);
1471- return seastar::do_with (
1472- std::move (_pins),
1473- loffset,
1474- [ctx, loffset, len, &ret](auto &pins, auto ¤t) {
1475- return trans_intr::do_for_each (
1476- pins,
1477- [ctx, loffset, len, ¤t, &ret](auto &pin)
1478- -> read_iertr::future<> {
1479- ceph_assert (current <= (loffset + len));
1480- ceph_assert (
1481- (loffset + len) > pin->get_key ());
1482- laddr_t end = std::min (
1483- pin->get_key () + pin->get_length (),
1484- loffset + len);
1485- if (pin->get_val ().is_zero ()) {
1486- ceph_assert (end > current); // See LBAManager::get_mappings
1487- ret.append_zero (end - current);
1488- current = end;
1489- return seastar::now ();
1490- } else {
1491- LOG_PREFIX (ObjectDataHandler::read);
1492- auto key = pin->get_key ();
1493- bool is_indirect = pin->is_indirect ();
1494- extent_len_t off = pin->get_intermediate_offset ();
1495- DEBUGT (" reading {}~{}, indirect: {}, "
1496- " intermediate offset: {}, current: {}, end: {}" ,
1497- ctx.t ,
1498- key,
1499- pin->get_length (),
1500- is_indirect,
1501- off,
1502- current,
1503- end);
1504- return ctx.tm .read_pin <ObjectDataBlock>(
1505- ctx.t ,
1506- std::move (pin)
1507- ).si_then ([&ret, ¤t, end, key, off,
1508- is_indirect](auto extent) {
1509- ceph_assert (
1510- is_indirect
1511- ? (key - off + extent->get_length ()) >= end
1512- : (extent->get_laddr () + extent->get_length ()) >= end);
1513- ceph_assert (end > current);
1514- ret.append (
1515- bufferptr (
1516- extent->get_bptr (),
1517- off + current - (is_indirect ? key : extent->get_laddr ()),
1518- end - current));
1519- current = end;
1520- return seastar::now ();
1521- }).handle_error_interruptible (
1522- read_iertr::pass_further{},
1523- crimson::ct_error::assert_all{
1524- " ObjectDataHandler::read hit invalid error"
1525- }
1526- );
1527- }
1528- });
1529- });
1530- });
1531- }).si_then ([&ret] {
1532- return std::move (ret);
1533- });
1448+ return with_object_data (
1449+ ctx,
1450+ [ctx, obj_offset, len, &ret](const auto &object_data) {
1451+ LOG_PREFIX (ObjectDataHandler::read);
1452+ DEBUGT (" reading {}~{}" ,
1453+ ctx.t ,
1454+ object_data.get_reserved_data_base (),
1455+ object_data.get_reserved_data_len ());
1456+ /* Assumption: callers ensure that onode size is <= reserved
1457+ * size and that len is adjusted here prior to call */
1458+ ceph_assert (!object_data.is_null ());
1459+ ceph_assert ((obj_offset + len) <= object_data.get_reserved_data_len ());
1460+ ceph_assert (len > 0 );
1461+ laddr_t l_start =
1462+ object_data.get_reserved_data_base () + obj_offset;
1463+ return ctx.tm .get_pins (
1464+ ctx.t ,
1465+ l_start,
1466+ len
1467+ ).si_then ([FNAME, ctx, l_start, len, &ret](auto _pins) {
1468+ // offset~len falls within reserved region and len > 0
1469+ ceph_assert (_pins.size () >= 1 );
1470+ ceph_assert ((*_pins.begin ())->get_key () <= l_start);
1471+ auto l_end = l_start + len;
1472+ return seastar::do_with (
1473+ std::move (_pins),
1474+ l_start,
1475+ [FNAME, ctx, l_start, l_end, &ret](auto &pins, auto &l_current) {
1476+ return trans_intr::do_for_each (
1477+ pins,
1478+ [FNAME, ctx, l_start, l_end,
1479+ &l_current, &ret](auto &pin) -> read_iertr::future<> {
1480+ auto pin_key = pin->get_key ();
1481+ if (l_current == l_start) {
1482+ ceph_assert (l_current >= pin_key);
1483+ } else {
1484+ assert (l_current > l_start);
1485+ ceph_assert (l_current == pin_key);
1486+ }
1487+ ceph_assert (l_current < l_end);
1488+ auto pin_len = pin->get_length ();
1489+ assert (pin_len > 0 );
1490+ laddr_t l_pin_end = pin_key + pin_len;
1491+ ceph_assert (l_current < l_pin_end);
1492+ laddr_t l_current_end = std::min (l_pin_end, l_end);
1493+ if (pin->get_val ().is_zero ()) {
1494+ DEBUGT (" got {}~{} from zero-pin {}~{}" ,
1495+ ctx.t ,
1496+ l_current,
1497+ l_current_end - l_current,
1498+ pin_key,
1499+ pin_len);
1500+ ret.append_zero (l_current_end - l_current);
1501+ l_current = l_current_end;
1502+ return seastar::now ();
1503+ }
1504+
1505+ // non-zero pin
1506+ bool is_indirect = pin->is_indirect ();
1507+ laddr_t e_key;
1508+ extent_len_t e_len;
1509+ extent_len_t e_off;
1510+ if (is_indirect) {
1511+ e_key = pin->get_intermediate_base ();
1512+ e_len = pin->get_intermediate_length ();
1513+ e_off = pin->get_intermediate_offset ();
1514+ DEBUGT (" reading {}~{} from indirect-pin {}~{}, direct-pin {}~{}(off={})" ,
1515+ ctx.t ,
1516+ l_current,
1517+ l_current_end - l_current,
1518+ pin_key,
1519+ pin_len,
1520+ e_key,
1521+ e_len,
1522+ e_off);
1523+ assert (e_key <= pin->get_intermediate_key ());
1524+ assert (e_off + pin_len <= e_len);
1525+ } else {
1526+ DEBUGT (" reading {}~{} from pin {}~{}" ,
1527+ ctx.t ,
1528+ l_current,
1529+ l_current_end - l_current,
1530+ pin_key,
1531+ pin_len);
1532+ e_key = pin_key;
1533+ e_len = pin_len;
1534+ e_off = 0 ;
1535+ }
1536+ extent_len_t e_current_off = e_off + l_current - pin_key;
1537+ return ctx.tm .read_pin <ObjectDataBlock>(
1538+ ctx.t ,
1539+ std::move (pin)
1540+ ).si_then ([&ret, &l_current, l_current_end,
1541+ #ifndef NDEBUG
1542+ e_key, e_len, e_current_off](auto extent) {
1543+ #else
1544+ e_current_off](auto extent) {
1545+ #endif
1546+ assert (e_key == extent->get_laddr ());
1547+ assert (e_len == extent->get_length ());
1548+ ret.append (
1549+ bufferptr (
1550+ extent->get_bptr (),
1551+ e_current_off,
1552+ l_current_end - l_current));
1553+ l_current = l_current_end;
1554+ return seastar::now ();
1555+ }).handle_error_interruptible (
1556+ read_iertr::pass_further{},
1557+ crimson::ct_error::assert_all{
1558+ " ObjectDataHandler::read hit invalid error"
1559+ }
1560+ );
1561+ }); // trans_intr::do_for_each()
1562+ }); // do_with()
1563+ });
1564+ }).si_then ([&ret] { // with_object_data()
1565+ return std::move (ret);
15341566 });
1567+ }); // do_with()
15351568}
15361569
15371570ObjectDataHandler::fiemap_ret ObjectDataHandler::fiemap (
@@ -1558,21 +1591,21 @@ ObjectDataHandler::fiemap_ret ObjectDataHandler::fiemap(
15581591 ceph_assert (!object_data.is_null ());
15591592 ceph_assert ((obj_offset + len) <= object_data.get_reserved_data_len ());
15601593 ceph_assert (len > 0 );
1561- laddr_t loffset =
1594+ laddr_t l_start =
15621595 object_data.get_reserved_data_base () + obj_offset;
15631596 return ctx.tm .get_pins (
15641597 ctx.t ,
1565- loffset ,
1598+ l_start ,
15661599 len
1567- ).si_then ([loffset , len, &object_data, &ret](auto &&pins) {
1600+ ).si_then ([l_start , len, &object_data, &ret](auto &&pins) {
15681601 ceph_assert (pins.size () >= 1 );
1569- ceph_assert ((*pins.begin ())->get_key () <= loffset );
1602+ ceph_assert ((*pins.begin ())->get_key () <= l_start );
15701603 for (auto &&i: pins) {
15711604 if (!(i->get_val ().is_zero ())) {
1572- auto ret_left = std::max (i->get_key (), loffset );
1605+ auto ret_left = std::max (i->get_key (), l_start );
15731606 auto ret_right = std::min (
15741607 i->get_key () + i->get_length (),
1575- loffset + len);
1608+ l_start + len);
15761609 assert (ret_right > ret_left);
15771610 ret.emplace (
15781611 std::make_pair (
0 commit comments