Skip to content

Commit f2fc9e7

Browse files
committed
crimson/os/seastore: make laddr_t block aligned
Signed-off-by: Zhang Song <[email protected]>
1 parent 9f23d74 commit f2fc9e7

File tree

2 files changed

+182
-38
lines changed

2 files changed

+182
-38
lines changed

src/crimson/os/seastore/seastore_types.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ std::ostream &operator<<(std::ostream &out, const laddr_t &laddr) {
9696
return out << 'L' << std::hex << laddr.value << std::dec;
9797
}
9898

99+
std::ostream &operator<<(std::ostream &out, const laddr_offset_t &laddr_offset) {
100+
return out << laddr_offset.get_aligned_laddr()
101+
<< "+" << std::hex << laddr_offset.get_offset() << std::dec;
102+
}
103+
99104
std::ostream &operator<<(std::ostream &out, const pladdr_t &pladdr)
100105
{
101106
if (pladdr.is_laddr()) {

src/crimson/os/seastore/seastore_types.h

Lines changed: 177 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,19 @@ constexpr journal_seq_t JOURNAL_SEQ_MAX{
10061006
// JOURNAL_SEQ_NULL == JOURNAL_SEQ_MAX == journal_seq_t{}
10071007
constexpr journal_seq_t JOURNAL_SEQ_NULL = JOURNAL_SEQ_MAX;
10081008

1009+
// logical offset between two laddr_t
1010+
using loffset_t = uint64_t;
1011+
1012+
// logical offset within an extent
1013+
using extent_len_t = uint32_t;
1014+
constexpr extent_len_t EXTENT_LEN_MAX =
1015+
std::numeric_limits<extent_len_t>::max();
1016+
1017+
using extent_len_le_t = ceph_le32;
1018+
inline extent_len_le_t init_extent_len_le(extent_len_t len) {
1019+
return ceph_le32(len);
1020+
}
1021+
10091022
// logical addr, see LBAManager, TransactionManager
10101023
class laddr_t {
10111024
public:
@@ -1015,24 +1028,19 @@ class laddr_t {
10151028
std::numeric_limits<Unsigned>::max();
10161029

10171030
constexpr laddr_t() : laddr_t(RAW_VALUE_MAX) {}
1018-
constexpr explicit laddr_t(Unsigned value) : value(value) {}
10191031

1020-
bool is_aligned(Unsigned alignment) const {
1021-
assert(alignment != 0);
1022-
assert((alignment & (alignment - 1)) == 0);
1023-
return value == p2align(value, alignment);
1024-
}
1032+
// laddr_t is block aligned, one logical address represents one 4KiB block in disk
1033+
static constexpr unsigned UNIT_SHIFT = 12;
1034+
static constexpr unsigned UNIT_SIZE = 1 << UNIT_SHIFT; // 4096
1035+
static constexpr unsigned UNIT_MASK = UNIT_SIZE - 1;
10251036

1026-
laddr_t get_aligned_laddr(Unsigned alignment) const {
1027-
assert(alignment != 0);
1028-
assert((alignment & (alignment - 1)) == 0);
1029-
return laddr_t(p2align(value, alignment));
1037+
static laddr_t from_byte_offset(Unsigned value) {
1038+
assert((value & UNIT_MASK) == 0);
1039+
return laddr_t(value >> UNIT_SHIFT);
10301040
}
10311041

1032-
laddr_t get_roundup_laddr(Unsigned alignment) const {
1033-
assert(alignment != 0);
1034-
assert((alignment & (alignment - 1)) == 0);
1035-
return laddr_t(p2roundup(value, alignment));
1042+
static constexpr laddr_t from_raw_uint(Unsigned v) {
1043+
return laddr_t(v);
10361044
}
10371045

10381046
/// laddr_t works like primitive integer type, encode/decode it manually
@@ -1047,38 +1055,178 @@ class laddr_t {
10471055
memcpy((char *)&value, p.get_pos_add(sizeof(Unsigned)), sizeof(Unsigned));
10481056
}
10491057

1050-
friend std::ostream &operator<<(std::ostream &, const laddr_t &);
1058+
// laddr_offset_t contains one base laddr and one block not aligned
1059+
// offset(< laddr_t::UNIT_SIZE). It is the return type of plus/minus
1060+
// overloads for laddr_t and loffset_t.
1061+
struct laddr_offset_t {
1062+
explicit laddr_offset_t(laddr_t base)
1063+
: base(base.value), offset(0) {}
1064+
laddr_offset_t(laddr_t base, extent_len_t offset)
1065+
: base(base.value), offset(offset) {
1066+
assert(offset < laddr_t::UNIT_SIZE);
1067+
}
10511068

1052-
friend auto operator<=>(const laddr_t&, const laddr_t&) = default;
1069+
laddr_t get_roundup_laddr() const {
1070+
if (offset == 0) {
1071+
return laddr_t(base);
1072+
} else {
1073+
assert(offset < laddr_t::UNIT_SIZE);
1074+
return laddr_t(base + 1);
1075+
}
1076+
}
1077+
laddr_t get_aligned_laddr() const { return laddr_t(base); }
1078+
extent_len_t get_offset() const {
1079+
assert(offset < laddr_t::UNIT_SIZE);
1080+
return offset;
1081+
}
1082+
laddr_t checked_to_laddr() const {
1083+
assert(offset == 0);
1084+
return laddr_t(base);
1085+
}
1086+
1087+
template<std::unsigned_integral U>
1088+
U get_byte_distance(const laddr_t &l) const {
1089+
assert(offset < UNIT_SIZE);
1090+
if (base >= l.value) {
1091+
Unsigned udiff = base - l.value;
1092+
assert(udiff <= (std::numeric_limits<U>::max() >> UNIT_SHIFT));
1093+
return (static_cast<U>(udiff) << UNIT_SHIFT) + offset;
1094+
} else { // base < l.value
1095+
Unsigned udiff = l.value - base;
1096+
assert(udiff <= (std::numeric_limits<U>::max() >> UNIT_SHIFT));
1097+
return (static_cast<U>(udiff) << UNIT_SHIFT) - offset;
1098+
}
1099+
}
1100+
1101+
template<std::unsigned_integral U>
1102+
U get_byte_distance(const laddr_offset_t &l) const {
1103+
assert(offset < UNIT_SIZE);
1104+
if (*this >= l) {
1105+
Unsigned udiff = base - l.base;
1106+
assert(udiff <= (std::numeric_limits<U>::max() >> UNIT_SHIFT));
1107+
return ((static_cast<U>(udiff) << UNIT_SHIFT) + offset) - l.offset;
1108+
} else { // *this < l
1109+
Unsigned udiff = l.base - base;
1110+
assert(udiff <= (std::numeric_limits<U>::max() >> UNIT_SHIFT));
1111+
return ((static_cast<U>(udiff) << UNIT_SHIFT) + l.offset) - offset;
1112+
}
1113+
}
1114+
1115+
friend bool operator==(const laddr_offset_t&, const laddr_offset_t&) = default;
1116+
friend auto operator<=>(const laddr_offset_t&, const laddr_offset_t&) = default;
1117+
friend std::ostream &operator<<(std::ostream&, const laddr_offset_t&);
1118+
friend laddr_offset_t operator+(const laddr_offset_t &laddr_offset,
1119+
const loffset_t &offset) {
1120+
// laddr_offset_t could access (laddr_t + loffset_t) overload.
1121+
return laddr_offset.get_aligned_laddr()
1122+
+ (laddr_offset.get_offset() + offset);
1123+
}
1124+
friend laddr_offset_t operator+(const loffset_t &offset,
1125+
const laddr_offset_t &loffset) {
1126+
return loffset + offset;
1127+
}
1128+
1129+
friend laddr_offset_t operator-(const laddr_offset_t &laddr_offset,
1130+
const loffset_t &offset) {
1131+
if (laddr_offset.get_offset() >= offset) {
1132+
return laddr_offset_t(
1133+
laddr_offset.get_aligned_laddr(),
1134+
laddr_offset.get_offset() - offset);
1135+
} else {
1136+
// laddr_offset_t could access (laddr_t - loffset_t) overload.
1137+
return laddr_offset.get_aligned_laddr()
1138+
- (offset - laddr_offset.get_offset());
1139+
}
1140+
}
1141+
1142+
friend class laddr_t;
1143+
private:
1144+
// use Unsigned here to avoid incomplete type of laddr_t
1145+
Unsigned base;
1146+
extent_len_t offset;
1147+
};
10531148

1054-
friend laddr_t operator+(const laddr_t &laddr, const Unsigned &i) {
1055-
return laddr_t{laddr.value + i};
1149+
template<std::unsigned_integral U>
1150+
U get_byte_distance(const laddr_offset_t &l) const {
1151+
if (value <= l.base) {
1152+
Unsigned udiff = l.base - value;
1153+
assert(udiff <= (std::numeric_limits<U>::max() >> UNIT_SHIFT));
1154+
return (static_cast<U>(udiff) << UNIT_SHIFT) + l.offset;
1155+
} else { // value > l.base
1156+
Unsigned udiff = value - l.base;
1157+
assert(udiff <= (std::numeric_limits<U>::max() >> UNIT_SHIFT));
1158+
return (static_cast<U>(udiff) << UNIT_SHIFT) - l.offset;
1159+
}
10561160
}
10571161

1058-
friend laddr_t operator+(const Unsigned &i, const laddr_t &laddr) {
1059-
return laddr_t{laddr.value + i};
1162+
template<std::unsigned_integral U>
1163+
U get_byte_distance(const laddr_t &l) const {
1164+
Unsigned diff = value > l.value
1165+
? value - l.value
1166+
: l.value - value;
1167+
assert(diff <= (std::numeric_limits<U>::max() >> UNIT_SHIFT));
1168+
return static_cast<U>(diff) << UNIT_SHIFT;
10601169
}
10611170

1062-
friend laddr_t operator-(const laddr_t &laddr, const Unsigned &i) {
1063-
return laddr_t{laddr.value - i};
1171+
friend std::ostream &operator<<(std::ostream &, const laddr_t &);
1172+
friend bool operator==(const laddr_t&, const laddr_t&) = default;
1173+
friend bool operator==(const laddr_t &laddr,
1174+
const laddr_offset_t &laddr_offset) {
1175+
return laddr == laddr_offset.get_aligned_laddr()
1176+
&& 0 == laddr_offset.get_offset();
1177+
}
1178+
friend bool operator==(const laddr_offset_t &laddr_offset,
1179+
const laddr_t &laddr) {
1180+
return laddr_offset.get_aligned_laddr() == laddr
1181+
&& laddr_offset.get_offset() == 0;
1182+
}
1183+
friend auto operator<=>(const laddr_t&, const laddr_t&) = default;
1184+
friend auto operator<=>(const laddr_t &laddr,
1185+
const laddr_offset_t &laddr_offset) {
1186+
return laddr_offset_t(laddr, 0) <=> laddr_offset;
1187+
}
1188+
friend auto operator<=>(const laddr_offset_t &laddr_offset,
1189+
const laddr_t &laddr) {
1190+
return laddr_offset <=> laddr_offset_t(laddr, 0);
10641191
}
10651192

1066-
friend Unsigned operator-(const laddr_t &l, const laddr_t &r) {
1067-
return l.value - r.value;
1193+
friend laddr_offset_t operator+(const laddr_t &laddr,
1194+
const loffset_t &offset) {
1195+
auto base = laddr;
1196+
base.value += offset >> laddr_t::UNIT_SHIFT;
1197+
assert(base.value >= laddr.value);
1198+
return laddr_offset_t(base, offset & laddr_t::UNIT_MASK);
1199+
}
1200+
friend laddr_offset_t operator+(const loffset_t &offset,
1201+
const laddr_t &laddr) {
1202+
return laddr + offset;
1203+
}
1204+
1205+
friend laddr_offset_t operator-(const laddr_t &laddr, loffset_t offset) {
1206+
auto base = laddr;
1207+
auto diff = (offset + laddr_t::UNIT_SIZE - 1) >> laddr_t::UNIT_SHIFT;
1208+
base.value -= diff;
1209+
assert(base.value <= laddr.value);
1210+
offset = (diff << laddr_t::UNIT_SHIFT) - offset;
1211+
return laddr_offset_t(base, offset);
10681212
}
10691213

10701214
friend struct laddr_le_t;
10711215
friend struct pladdr_le_t;
10721216

10731217
private:
1218+
// Prevent direct construction of laddr_t with an integer,
1219+
// always use laddr_t::from_raw_uint instead.
1220+
constexpr explicit laddr_t(Unsigned value) : value(value) {}
10741221
Unsigned value;
10751222
};
1223+
using laddr_offset_t = laddr_t::laddr_offset_t;
10761224

1077-
constexpr laddr_t L_ADDR_MAX = laddr_t(laddr_t::RAW_VALUE_MAX);
1078-
constexpr laddr_t L_ADDR_MIN = laddr_t(0);
1225+
constexpr laddr_t L_ADDR_MAX = laddr_t::from_raw_uint(laddr_t::RAW_VALUE_MAX);
1226+
constexpr laddr_t L_ADDR_MIN = laddr_t::from_raw_uint(0);
10791227
constexpr laddr_t L_ADDR_NULL = L_ADDR_MAX;
1080-
constexpr laddr_t L_ADDR_ROOT = laddr_t(laddr_t::RAW_VALUE_MAX - 1);
1081-
constexpr laddr_t L_ADDR_LBAT = laddr_t(laddr_t::RAW_VALUE_MAX - 2);
1228+
constexpr laddr_t L_ADDR_ROOT = laddr_t::from_raw_uint(laddr_t::RAW_VALUE_MAX - 1);
1229+
constexpr laddr_t L_ADDR_LBAT = laddr_t::from_raw_uint(laddr_t::RAW_VALUE_MAX - 2);
10821230

10831231
struct __attribute__((packed)) laddr_le_t {
10841232
ceph_le64 laddr;
@@ -1200,16 +1348,6 @@ struct min_max_t<paddr_t> {
12001348
static constexpr paddr_t null = P_ADDR_NULL;
12011349
};
12021350

1203-
// logical offset, see LBAManager, TransactionManager
1204-
using extent_len_t = uint32_t;
1205-
constexpr extent_len_t EXTENT_LEN_MAX =
1206-
std::numeric_limits<extent_len_t>::max();
1207-
1208-
using extent_len_le_t = ceph_le32;
1209-
inline extent_len_le_t init_extent_len_le(extent_len_t len) {
1210-
return ceph_le32(len);
1211-
}
1212-
12131351
using extent_ref_count_t = uint32_t;
12141352
constexpr extent_ref_count_t EXTENT_DEFAULT_REF_COUNT = 1;
12151353

@@ -2749,6 +2887,7 @@ template <> struct fmt::formatter<crimson::os::seastore::extent_types_t> : fmt::
27492887
template <> struct fmt::formatter<crimson::os::seastore::journal_seq_t> : fmt::ostream_formatter {};
27502888
template <> struct fmt::formatter<crimson::os::seastore::journal_tail_delta_t> : fmt::ostream_formatter {};
27512889
template <> struct fmt::formatter<crimson::os::seastore::laddr_t> : fmt::ostream_formatter {};
2890+
template <> struct fmt::formatter<crimson::os::seastore::laddr_offset_t> : fmt::ostream_formatter {};
27522891
template <> struct fmt::formatter<crimson::os::seastore::laddr_list_t> : fmt::ostream_formatter {};
27532892
template <> struct fmt::formatter<crimson::os::seastore::omap_root_t> : fmt::ostream_formatter {};
27542893
template <> struct fmt::formatter<crimson::os::seastore::paddr_list_t> : fmt::ostream_formatter {};

0 commit comments

Comments
 (0)