mirror of
https://github.com/ceph/ceph
synced 2025-04-01 23:02:17 +00:00
Merge pull request #59182 from zhscn/wip-4k-laddr
crimson/os/seastore: make laddr_t block aligned Reviewed-by: Yingxin Cheng <yingxin.cheng@intel.com>
This commit is contained in:
commit
fc16b162be
src
crimson
os/seastore
backref
btree
cache.hcached_extent.hladdr_interval_set.hlba_manager/btree
object_data_handler.ccobject_data_handler.homap_manager/btree
onode.honode_manager/staged-fltree
fltree_onode_manager.ccfltree_onode_manager.hnode.ccnode_extent_accessor.h
seastore.ccseastore_types.ccseastore_types.htransaction_manager.cctransaction_manager.hnode_extent_manager
node_layout.hnode_types.hstages
value.ccvalue.htools/store_nbd
test/crimson/seastore
@ -17,7 +17,7 @@ using BackrefNode = FixedKVNode<paddr_t>;
|
||||
|
||||
struct backref_map_val_t {
|
||||
extent_len_t len = 0; ///< length of extents
|
||||
laddr_t laddr = 0; ///< logical address of extents
|
||||
laddr_t laddr = L_ADDR_MIN; ///< logical address of extents
|
||||
extent_types_t type = extent_types_t::ROOT;
|
||||
|
||||
backref_map_val_t() = default;
|
||||
@ -36,7 +36,7 @@ std::ostream& operator<<(std::ostream &out, const backref_map_val_t& val);
|
||||
|
||||
struct backref_map_val_le_t {
|
||||
extent_len_le_t len = init_extent_len_le(0);
|
||||
laddr_le_t laddr = laddr_le_t(0);
|
||||
laddr_le_t laddr = laddr_le_t(L_ADDR_MIN);
|
||||
extent_types_le_t type = 0;
|
||||
|
||||
backref_map_val_le_t() = default;
|
||||
|
@ -226,12 +226,18 @@ public:
|
||||
assert(!is_end());
|
||||
auto val = get_val();
|
||||
auto key = get_key();
|
||||
node_key_t end{};
|
||||
if constexpr (std::is_same_v<node_key_t, laddr_t>) {
|
||||
end = (key + val.len).checked_to_laddr();
|
||||
} else {
|
||||
end = key + val.len;
|
||||
}
|
||||
return std::make_unique<pin_t>(
|
||||
ctx,
|
||||
leaf.node,
|
||||
leaf.pos,
|
||||
val,
|
||||
fixed_kv_node_meta_t<node_key_t>{ key, key + val.len, 0 });
|
||||
fixed_kv_node_meta_t<node_key_t>{ key, end, 0 });
|
||||
}
|
||||
|
||||
typename leaf_node_t::Ref get_leaf_node() {
|
||||
|
@ -977,10 +977,9 @@ public:
|
||||
TCachedExtentRef<T> ext;
|
||||
if (original_bptr.has_value()) {
|
||||
// shallow copy the buffer from original extent
|
||||
auto nbp = ceph::bufferptr(
|
||||
*original_bptr,
|
||||
remap_laddr - original_laddr,
|
||||
remap_length);
|
||||
auto remap_offset = remap_laddr.get_byte_distance<
|
||||
extent_len_t>(original_laddr);
|
||||
auto nbp = ceph::bufferptr(*original_bptr, remap_offset, remap_length);
|
||||
// ExtentPlacementManager::alloc_new_extent will make a new
|
||||
// (relative/temp) paddr, so make extent directly
|
||||
ext = CachedExtent::make_cached_extent_ref<T>(std::move(nbp));
|
||||
|
@ -1325,7 +1325,7 @@ public:
|
||||
void on_rewrite(Transaction&, CachedExtent &extent, extent_len_t off) final {
|
||||
assert(get_type() == extent.get_type());
|
||||
auto &lextent = (LogicalCachedExtent&)extent;
|
||||
set_laddr(lextent.get_laddr() + off);
|
||||
set_laddr((lextent.get_laddr() + off).checked_to_laddr());
|
||||
}
|
||||
|
||||
bool has_laddr() const {
|
||||
|
758
src/crimson/os/seastore/laddr_interval_set.h
Normal file
758
src/crimson/os/seastore/laddr_interval_set.h
Normal file
@ -0,0 +1,758 @@
|
||||
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
|
||||
// vim: ts=8 sw=2 smarttab
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "crimson/os/seastore/seastore_types.h"
|
||||
|
||||
namespace crimson::os::seastore {
|
||||
namespace details {
|
||||
|
||||
// this interval_set structure is copied from include/interval_set.h to allow
|
||||
// use the different type for length as the laddr_t becomes struct, and avoid
|
||||
// changing the behaviors of other components.
|
||||
//
|
||||
// The latest commit is 58860ce3f60489d258aaa10fd783e68083261937
|
||||
|
||||
template<typename T, typename L, template<typename, typename, typename ...> class C = std::map>
|
||||
class interval_set {
|
||||
public:
|
||||
using Map = C<T, L>;
|
||||
using value_type = typename Map::value_type;
|
||||
using offset_type = T;
|
||||
using length_type = L;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
using size_type = typename Map::size_type;
|
||||
|
||||
class const_iterator;
|
||||
|
||||
class iterator
|
||||
{
|
||||
public:
|
||||
using difference_type = ssize_t;
|
||||
using value_type = typename Map::value_type;
|
||||
using pointer = typename Map::value_type*;
|
||||
using reference = typename Map::value_type&;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
|
||||
explicit iterator(typename Map::iterator iter)
|
||||
: _iter(iter)
|
||||
{ }
|
||||
|
||||
// For the copy constructor and assignment operator, the compiler-generated functions, which
|
||||
// perform simple bitwise copying, should be fine.
|
||||
|
||||
bool operator==(const iterator& rhs) const {
|
||||
return (_iter == rhs._iter);
|
||||
}
|
||||
|
||||
bool operator!=(const iterator& rhs) const {
|
||||
return (_iter != rhs._iter);
|
||||
}
|
||||
|
||||
// Dereference this iterator to get a pair.
|
||||
reference operator*() const {
|
||||
return *_iter;
|
||||
}
|
||||
|
||||
// Return the interval start.
|
||||
offset_type get_start() const {
|
||||
return _iter->first;
|
||||
}
|
||||
|
||||
// Return the interval length.
|
||||
length_type get_len() const {
|
||||
return _iter->second;
|
||||
}
|
||||
|
||||
offset_type get_end() const {
|
||||
return _iter->first + _iter->second;
|
||||
}
|
||||
|
||||
// Set the interval length.
|
||||
void set_len(const length_type& len) {
|
||||
_iter->second = len;
|
||||
}
|
||||
|
||||
// Preincrement
|
||||
iterator& operator++()
|
||||
{
|
||||
++_iter;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Postincrement
|
||||
iterator operator++(int)
|
||||
{
|
||||
iterator prev(_iter);
|
||||
++_iter;
|
||||
return prev;
|
||||
}
|
||||
|
||||
// Predecrement
|
||||
iterator& operator--()
|
||||
{
|
||||
--_iter;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Postdecrement
|
||||
iterator operator--(int)
|
||||
{
|
||||
iterator prev(_iter);
|
||||
--_iter;
|
||||
return prev;
|
||||
}
|
||||
|
||||
friend class interval_set::const_iterator;
|
||||
|
||||
protected:
|
||||
typename Map::iterator _iter;
|
||||
friend class interval_set;
|
||||
};
|
||||
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
using difference_type = ssize_t;
|
||||
using value_type = const typename Map::value_type;
|
||||
using pointer = const typename Map::value_type*;
|
||||
using reference = const typename Map::value_type&;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
|
||||
explicit const_iterator(typename Map::const_iterator iter)
|
||||
: _iter(iter)
|
||||
{ }
|
||||
|
||||
const_iterator(const iterator &i)
|
||||
: _iter(i._iter)
|
||||
{ }
|
||||
|
||||
// For the copy constructor and assignment operator, the compiler-generated functions, which
|
||||
// perform simple bitwise copying, should be fine.
|
||||
|
||||
bool operator==(const const_iterator& rhs) const {
|
||||
return (_iter == rhs._iter);
|
||||
}
|
||||
|
||||
bool operator!=(const const_iterator& rhs) const {
|
||||
return (_iter != rhs._iter);
|
||||
}
|
||||
|
||||
// Dereference this iterator to get a pair.
|
||||
reference operator*() const {
|
||||
return *_iter;
|
||||
}
|
||||
|
||||
// Return the interval start.
|
||||
offset_type get_start() const {
|
||||
return _iter->first;
|
||||
}
|
||||
offset_type get_end() const {
|
||||
return _iter->first + _iter->second;
|
||||
}
|
||||
|
||||
// Return the interval length.
|
||||
length_type get_len() const {
|
||||
return _iter->second;
|
||||
}
|
||||
|
||||
// Preincrement
|
||||
const_iterator& operator++()
|
||||
{
|
||||
++_iter;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Postincrement
|
||||
const_iterator operator++(int)
|
||||
{
|
||||
const_iterator prev(_iter);
|
||||
++_iter;
|
||||
return prev;
|
||||
}
|
||||
|
||||
// Predecrement
|
||||
iterator& operator--()
|
||||
{
|
||||
--_iter;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Postdecrement
|
||||
iterator operator--(int)
|
||||
{
|
||||
iterator prev(_iter);
|
||||
--_iter;
|
||||
return prev;
|
||||
}
|
||||
|
||||
protected:
|
||||
typename Map::const_iterator _iter;
|
||||
};
|
||||
|
||||
interval_set() = default;
|
||||
interval_set(Map&& other) {
|
||||
m.swap(other);
|
||||
for (const auto& p : m) {
|
||||
_size += p.second;
|
||||
}
|
||||
}
|
||||
|
||||
size_type num_intervals() const
|
||||
{
|
||||
return m.size();
|
||||
}
|
||||
|
||||
iterator begin() {
|
||||
return iterator(m.begin());
|
||||
}
|
||||
|
||||
iterator lower_bound(T start) {
|
||||
return iterator(find_inc_m(start));
|
||||
}
|
||||
|
||||
iterator end() {
|
||||
return iterator(m.end());
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
return const_iterator(m.begin());
|
||||
}
|
||||
|
||||
const_iterator lower_bound(T start) const {
|
||||
return const_iterator(find_inc(start));
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return const_iterator(m.end());
|
||||
}
|
||||
|
||||
// helpers
|
||||
private:
|
||||
auto find_inc(T start) const {
|
||||
auto p = m.lower_bound(start); // p->first >= start
|
||||
if (p != m.begin() &&
|
||||
(p == m.end() || p->first > start)) {
|
||||
--p; // might overlap?
|
||||
if (p->first + p->second <= start)
|
||||
++p; // it doesn't.
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
auto find_inc_m(T start) {
|
||||
auto p = m.lower_bound(start);
|
||||
if (p != m.begin() &&
|
||||
(p == m.end() || p->first > start)) {
|
||||
--p; // might overlap?
|
||||
if (p->first + p->second <= start)
|
||||
++p; // it doesn't.
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
auto find_adj(T start) const {
|
||||
auto p = m.lower_bound(start);
|
||||
if (p != m.begin() &&
|
||||
(p == m.end() || p->first > start)) {
|
||||
--p; // might touch?
|
||||
if (p->first + p->second < start)
|
||||
++p; // it doesn't.
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
auto find_adj_m(T start) {
|
||||
auto p = m.lower_bound(start);
|
||||
if (p != m.begin() &&
|
||||
(p == m.end() || p->first > start)) {
|
||||
--p; // might touch?
|
||||
if (p->first + p->second < start)
|
||||
++p; // it doesn't.
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void intersection_size_asym(const interval_set &s, const interval_set &l) {
|
||||
auto ps = s.m.begin();
|
||||
ceph_assert(ps != s.m.end());
|
||||
auto offset = ps->first;
|
||||
bool first = true;
|
||||
auto mi = m.begin();
|
||||
|
||||
while (1) {
|
||||
if (first)
|
||||
first = false;
|
||||
auto pl = l.find_inc(offset);
|
||||
if (pl == l.m.end())
|
||||
break;
|
||||
while (ps != s.m.end() && ps->first + ps->second <= pl->first)
|
||||
++ps;
|
||||
if (ps == s.m.end())
|
||||
break;
|
||||
offset = pl->first + pl->second;
|
||||
if (offset <= ps->first) {
|
||||
offset = ps->first;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*ps == *pl) {
|
||||
do {
|
||||
mi = m.insert(mi, *ps);
|
||||
_size += ps->second;
|
||||
++ps;
|
||||
++pl;
|
||||
} while (ps != s.m.end() && pl != l.m.end() && *ps == *pl);
|
||||
if (ps == s.m.end())
|
||||
break;
|
||||
offset = ps->first;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto start = std::max<T>(ps->first, pl->first);
|
||||
auto en = std::min<T>(ps->first + ps->second, offset);
|
||||
ceph_assert(en > start);
|
||||
mi = m.emplace_hint(mi, start, en - start);
|
||||
_size += mi->second;
|
||||
if (ps->first + ps->second <= offset) {
|
||||
++ps;
|
||||
if (ps == s.m.end())
|
||||
break;
|
||||
offset = ps->first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool subset_size_sym(const interval_set &b) const {
|
||||
auto pa = m.begin(), pb = b.m.begin();
|
||||
const auto a_end = m.end(), b_end = b.m.end();
|
||||
|
||||
while (pa != a_end && pb != b_end) {
|
||||
while (pb->first + pb->second <= pa->first) {
|
||||
++pb;
|
||||
if (pb == b_end)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*pa == *pb) {
|
||||
do {
|
||||
++pa;
|
||||
++pb;
|
||||
} while (pa != a_end && pb != b_end && *pa == *pb);
|
||||
continue;
|
||||
}
|
||||
|
||||
// interval begins before other
|
||||
if (pa->first < pb->first)
|
||||
return false;
|
||||
// interval is longer than other
|
||||
if (pa->first + pa->second > pb->first + pb->second)
|
||||
return false;
|
||||
|
||||
++pa;
|
||||
}
|
||||
|
||||
return pa == a_end;
|
||||
}
|
||||
|
||||
public:
|
||||
bool operator==(const interval_set& other) const {
|
||||
return _size == other._size && m == other.m;
|
||||
}
|
||||
|
||||
uint64_t size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
void bound_encode(size_t& p) const {
|
||||
denc_traits<Map>::bound_encode(m, p);
|
||||
}
|
||||
void encode(ceph::buffer::list::contiguous_appender& p) const {
|
||||
denc(m, p);
|
||||
}
|
||||
void decode(ceph::buffer::ptr::const_iterator& p) {
|
||||
denc(m, p);
|
||||
_size = 0;
|
||||
for (const auto& p : m) {
|
||||
_size += p.second;
|
||||
}
|
||||
}
|
||||
void decode(ceph::buffer::list::iterator& p) {
|
||||
denc(m, p);
|
||||
_size = 0;
|
||||
for (const auto& p : m) {
|
||||
_size += p.second;
|
||||
}
|
||||
}
|
||||
|
||||
void encode_nohead(ceph::buffer::list::contiguous_appender& p) const {
|
||||
denc_traits<Map>::encode_nohead(m, p);
|
||||
}
|
||||
void decode_nohead(int n, ceph::buffer::ptr::const_iterator& p) {
|
||||
denc_traits<Map>::decode_nohead(n, m, p);
|
||||
_size = 0;
|
||||
for (const auto& p : m) {
|
||||
_size += p.second;
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
m.clear();
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
bool contains(T i, T *pstart=0, L *plen=0) const {
|
||||
auto p = find_inc(i);
|
||||
if (p == m.end()) return false;
|
||||
if (p->first > i) return false;
|
||||
if (p->first+p->second <= i) return false;
|
||||
ceph_assert(p->first <= i && p->first+p->second > i);
|
||||
if (pstart)
|
||||
*pstart = p->first;
|
||||
if (plen)
|
||||
*plen = p->second;
|
||||
return true;
|
||||
}
|
||||
bool contains(T start, L len) const {
|
||||
auto p = find_inc(start);
|
||||
if (p == m.end()) return false;
|
||||
if (p->first > start) return false;
|
||||
if (p->first+p->second <= start) return false;
|
||||
ceph_assert(p->first <= start && p->first+p->second > start);
|
||||
if (p->first+p->second < start+len) return false;
|
||||
return true;
|
||||
}
|
||||
bool intersects(T start, L len) const {
|
||||
interval_set a;
|
||||
a.insert(start, len);
|
||||
interval_set i;
|
||||
i.intersection_of( *this, a );
|
||||
if (i.empty()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// outer range of set
|
||||
bool empty() const {
|
||||
return m.empty();
|
||||
}
|
||||
offset_type range_start() const {
|
||||
ceph_assert(!empty());
|
||||
auto p = m.begin();
|
||||
return p->first;
|
||||
}
|
||||
offset_type range_end() const {
|
||||
ceph_assert(!empty());
|
||||
auto p = m.rbegin();
|
||||
return p->first + p->second;
|
||||
}
|
||||
|
||||
// interval start after p (where p not in set)
|
||||
bool starts_after(T i) const {
|
||||
ceph_assert(!contains(i));
|
||||
auto p = find_inc(i);
|
||||
if (p == m.end()) return false;
|
||||
return true;
|
||||
}
|
||||
offset_type start_after(T i) const {
|
||||
ceph_assert(!contains(i));
|
||||
auto p = find_inc(i);
|
||||
return p->first;
|
||||
}
|
||||
|
||||
// interval end that contains start
|
||||
offset_type end_after(T start) const {
|
||||
ceph_assert(contains(start));
|
||||
auto p = find_inc(start);
|
||||
return p->first+p->second;
|
||||
}
|
||||
|
||||
void insert(T val) {
|
||||
insert(val, 1);
|
||||
}
|
||||
|
||||
void insert(T start, L len, T *pstart=0, L *plen=0) {
|
||||
//cout << "insert " << start << "~" << len << endl;
|
||||
ceph_assert(len > 0);
|
||||
_size += len;
|
||||
auto p = find_adj_m(start);
|
||||
if (p == m.end()) {
|
||||
m[start] = len; // new interval
|
||||
if (pstart)
|
||||
*pstart = start;
|
||||
if (plen)
|
||||
*plen = len;
|
||||
} else {
|
||||
if (p->first < start) {
|
||||
|
||||
if (p->first + p->second != start) {
|
||||
//cout << "p is " << p->first << "~" << p->second << ", start is " << start << ", len is " << len << endl;
|
||||
ceph_abort();
|
||||
}
|
||||
|
||||
p->second += len; // append to end
|
||||
|
||||
auto n = p;
|
||||
++n;
|
||||
if (pstart)
|
||||
*pstart = p->first;
|
||||
if (n != m.end() &&
|
||||
start+len == n->first) { // combine with next, too!
|
||||
p->second += n->second;
|
||||
if (plen)
|
||||
*plen = p->second;
|
||||
m.erase(n);
|
||||
} else {
|
||||
if (plen)
|
||||
*plen = p->second;
|
||||
}
|
||||
} else {
|
||||
if (start+len == p->first) {
|
||||
if (pstart)
|
||||
*pstart = start;
|
||||
if (plen)
|
||||
*plen = len + p->second;
|
||||
L psecond = p->second;
|
||||
m.erase(p);
|
||||
m[start] = len + psecond; // append to front
|
||||
} else {
|
||||
ceph_assert(p->first > start+len);
|
||||
if (pstart)
|
||||
*pstart = start;
|
||||
if (plen)
|
||||
*plen = len;
|
||||
m[start] = len; // new interval
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void swap(interval_set& other) {
|
||||
m.swap(other.m);
|
||||
std::swap(_size, other._size);
|
||||
}
|
||||
|
||||
void erase(const iterator &i) {
|
||||
_size -= i.get_len();
|
||||
m.erase(i._iter);
|
||||
}
|
||||
|
||||
void erase(T val) {
|
||||
erase(val, 1);
|
||||
}
|
||||
|
||||
void erase(T start, L len,
|
||||
std::function<bool(T, L)> claim = {}) {
|
||||
auto p = find_inc_m(start);
|
||||
|
||||
_size -= len;
|
||||
|
||||
ceph_assert(p != m.end());
|
||||
ceph_assert(p->first <= start);
|
||||
|
||||
L before = start - p->first;
|
||||
ceph_assert(p->second >= before+len);
|
||||
L after = p->second - before - len;
|
||||
if (before) {
|
||||
if (claim && claim(p->first, before)) {
|
||||
_size -= before;
|
||||
m.erase(p);
|
||||
} else {
|
||||
p->second = before; // shorten bit before
|
||||
}
|
||||
} else {
|
||||
m.erase(p);
|
||||
}
|
||||
if (after) {
|
||||
if (claim && claim(start + len, after)) {
|
||||
_size -= after;
|
||||
} else {
|
||||
m[start + len] = after;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void subtract(const interval_set &a) {
|
||||
for (const auto& [start, len] : a.m) {
|
||||
erase(start, len);
|
||||
}
|
||||
}
|
||||
|
||||
void insert(const interval_set &a) {
|
||||
for (const auto& [start, len] : a.m) {
|
||||
insert(start, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void intersection_of(const interval_set &a, const interval_set &b) {
|
||||
ceph_assert(&a != this);
|
||||
ceph_assert(&b != this);
|
||||
clear();
|
||||
|
||||
const interval_set *s, *l;
|
||||
|
||||
if (a.size() < b.size()) {
|
||||
s = &a;
|
||||
l = &b;
|
||||
} else {
|
||||
s = &b;
|
||||
l = &a;
|
||||
}
|
||||
|
||||
if (!s->size())
|
||||
return;
|
||||
|
||||
/*
|
||||
* Use the lower_bound algorithm for larger size ratios
|
||||
* where it performs better, but not for smaller size
|
||||
* ratios where sequential search performs better.
|
||||
*/
|
||||
if (l->size() / s->size() >= 10) {
|
||||
intersection_size_asym(*s, *l);
|
||||
return;
|
||||
}
|
||||
|
||||
auto pa = a.m.begin();
|
||||
auto pb = b.m.begin();
|
||||
auto mi = m.begin();
|
||||
|
||||
while (pa != a.m.end() && pb != b.m.end()) {
|
||||
// passing?
|
||||
if (pa->first + pa->second <= pb->first)
|
||||
{ pa++; continue; }
|
||||
if (pb->first + pb->second <= pa->first)
|
||||
{ pb++; continue; }
|
||||
|
||||
if (*pa == *pb) {
|
||||
do {
|
||||
mi = m.insert(mi, *pa);
|
||||
_size += pa->second;
|
||||
++pa;
|
||||
++pb;
|
||||
} while (pa != a.m.end() && pb != b.m.end() && *pa == *pb);
|
||||
continue;
|
||||
}
|
||||
|
||||
T start = std::max(pa->first, pb->first);
|
||||
T en = std::min(pa->first+pa->second, pb->first+pb->second);
|
||||
ceph_assert(en > start);
|
||||
mi = m.emplace_hint(mi, start, en - start);
|
||||
_size += mi->second;
|
||||
if (pa->first+pa->second > pb->first+pb->second)
|
||||
pb++;
|
||||
else
|
||||
pa++;
|
||||
}
|
||||
}
|
||||
void intersection_of(const interval_set& b) {
|
||||
interval_set a;
|
||||
swap(a);
|
||||
intersection_of(a, b);
|
||||
}
|
||||
|
||||
void union_of(const interval_set &a, const interval_set &b) {
|
||||
ceph_assert(&a != this);
|
||||
ceph_assert(&b != this);
|
||||
clear();
|
||||
|
||||
//cout << "union_of" << endl;
|
||||
|
||||
// a
|
||||
m = a.m;
|
||||
_size = a._size;
|
||||
|
||||
// - (a*b)
|
||||
interval_set ab;
|
||||
ab.intersection_of(a, b);
|
||||
subtract(ab);
|
||||
|
||||
// + b
|
||||
insert(b);
|
||||
return;
|
||||
}
|
||||
void union_of(const interval_set &b) {
|
||||
interval_set a;
|
||||
swap(a);
|
||||
union_of(a, b);
|
||||
}
|
||||
void union_insert(T off, L len) {
|
||||
interval_set a;
|
||||
a.insert(off, len);
|
||||
union_of(a);
|
||||
}
|
||||
|
||||
bool subset_of(const interval_set &big) const {
|
||||
if (!size())
|
||||
return true;
|
||||
if (size() > big.size())
|
||||
return false;
|
||||
if (range_end() > big.range_end())
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Use the lower_bound algorithm for larger size ratios
|
||||
* where it performs better, but not for smaller size
|
||||
* ratios where sequential search performs better.
|
||||
*/
|
||||
if (big.size() / size() < 10)
|
||||
return subset_size_sym(big);
|
||||
|
||||
for (const auto& [start, len] : m) {
|
||||
if (!big.contains(start, len)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* build a subset of @other, starting at or after @start, and including
|
||||
* @len worth of values, skipping holes. e.g.,
|
||||
* span_of([5~10,20~5], 8, 5) -> [8~2,20~3]
|
||||
*/
|
||||
void span_of(const interval_set &other, T start, L len) {
|
||||
clear();
|
||||
auto p = other.find_inc(start);
|
||||
if (p == other.m.end())
|
||||
return;
|
||||
if (p->first < start) {
|
||||
if (p->first + p->second < start)
|
||||
return;
|
||||
if (p->first + p->second < start + len) {
|
||||
L howmuch = p->second - (start - p->first);
|
||||
insert(start, howmuch);
|
||||
len -= howmuch;
|
||||
p++;
|
||||
} else {
|
||||
insert(start, len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (p != other.m.end() && len > 0) {
|
||||
if (p->second < len) {
|
||||
insert(p->first, p->second);
|
||||
len -= p->second;
|
||||
p++;
|
||||
} else {
|
||||
insert(p->first, len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Move contents of m into another Map. Use that instead of
|
||||
* encoding interval_set into bufferlist then decoding it back into Map.
|
||||
*/
|
||||
Map detach() && {
|
||||
return std::move(m);
|
||||
}
|
||||
|
||||
private:
|
||||
// data
|
||||
uint64_t _size = 0;
|
||||
Map m; // map start -> len
|
||||
};
|
||||
} // namespace details
|
||||
using laddr_interval_set_t = details::interval_set<laddr_t, extent_len_t>;
|
||||
} // namespace crimson::os::seastore
|
@ -316,7 +316,7 @@ BtreeLBAManager::_alloc_extents(
|
||||
assert((info.key == L_ADDR_NULL) == (laddr_null));
|
||||
if (!laddr_null) {
|
||||
assert(info.key >= last_end);
|
||||
last_end = info.key + info.len;
|
||||
last_end = (info.key + info.len).checked_to_laddr();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -325,7 +325,8 @@ BtreeLBAManager::_alloc_extents(
|
||||
total_len += info.len;
|
||||
}
|
||||
} else {
|
||||
total_len = alloc_infos.back().key + alloc_infos.back().len - hint;
|
||||
auto end = alloc_infos.back().key + alloc_infos.back().len;
|
||||
total_len = end.get_byte_distance<extent_len_t>(hint);
|
||||
}
|
||||
|
||||
struct state_t {
|
||||
@ -381,7 +382,7 @@ BtreeLBAManager::_alloc_extents(
|
||||
interruptible::ready_future_marker{},
|
||||
seastar::stop_iteration::yes);
|
||||
} else {
|
||||
state.last_end = pos.get_key() + pos.get_val().len;
|
||||
state.last_end = (pos.get_key() + pos.get_val().len).checked_to_laddr();
|
||||
TRACET("{}~{}, hint={}, state: {}~{}, repeat ... -- {}",
|
||||
t, addr, total_len, hint,
|
||||
pos.get_key(), pos.get_val().len,
|
||||
@ -431,7 +432,7 @@ BtreeLBAManager::_alloc_extents(
|
||||
return iter.next(c).si_then([&state, &alloc_info](auto it) {
|
||||
state.insert_iter = it;
|
||||
if (alloc_info.key == L_ADDR_NULL) {
|
||||
state.last_end += alloc_info.len;
|
||||
state.last_end = (state.last_end + alloc_info.len).checked_to_laddr();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -128,7 +128,7 @@ public:
|
||||
assert(intermediate_key >= intermediate_base);
|
||||
assert((intermediate_key == L_ADDR_NULL)
|
||||
== (intermediate_base == L_ADDR_NULL));
|
||||
return intermediate_key - intermediate_base;
|
||||
return intermediate_key.get_byte_distance<extent_len_t>(intermediate_base);
|
||||
}
|
||||
|
||||
extent_len_t get_intermediate_length() const final {
|
||||
@ -465,7 +465,7 @@ public:
|
||||
: L_ADDR_NULL;
|
||||
auto remap_offset = remap.offset;
|
||||
auto remap_len = remap.len;
|
||||
auto remap_laddr = orig_laddr + remap_offset;
|
||||
auto remap_laddr = (orig_laddr + remap_offset).checked_to_laddr();
|
||||
ceph_assert(intermediate_base != L_ADDR_NULL);
|
||||
ceph_assert(intermediate_key != L_ADDR_NULL);
|
||||
ceph_assert(remap_len < orig_len);
|
||||
@ -476,7 +476,7 @@ public:
|
||||
" intermediate_base: {}, intermediate_key: {}", t,
|
||||
remap_laddr, orig_paddr, remap_len,
|
||||
intermediate_base, intermediate_key);
|
||||
auto remapped_intermediate_key = intermediate_key + remap_offset;
|
||||
auto remapped_intermediate_key = (intermediate_key + remap_offset).checked_to_laddr();
|
||||
alloc_infos.emplace_back(
|
||||
alloc_mapping_info_t::create_indirect(
|
||||
remap_laddr,
|
||||
@ -485,7 +485,7 @@ public:
|
||||
}
|
||||
fut = alloc_cloned_mappings(
|
||||
t,
|
||||
remaps.front().offset + orig_laddr,
|
||||
(remaps.front().offset + orig_laddr).checked_to_laddr(),
|
||||
std::move(alloc_infos)
|
||||
).si_then([&orig_mapping](auto imappings) mutable {
|
||||
std::vector<LBAMappingRef> mappings;
|
||||
@ -504,7 +504,7 @@ public:
|
||||
} else { // !orig_mapping->is_indirect()
|
||||
fut = alloc_extents(
|
||||
t,
|
||||
remaps.front().offset + orig_laddr,
|
||||
(remaps.front().offset + orig_laddr).checked_to_laddr(),
|
||||
std::move(extents),
|
||||
EXTENT_DEFAULT_REF_COUNT);
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ BtreeLBAMappingRef LBALeafNode::get_mapping(
|
||||
this,
|
||||
iter.get_offset(),
|
||||
val,
|
||||
lba_node_meta_t{laddr, laddr + val.len, 0});
|
||||
lba_node_meta_t{laddr, (laddr + val.len).checked_to_laddr(), 0});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "crimson/common/log.h"
|
||||
|
||||
#include "crimson/os/seastore/object_data_handler.h"
|
||||
#include "crimson/os/seastore/laddr_interval_set.h"
|
||||
|
||||
namespace {
|
||||
seastar::logger& logger() {
|
||||
@ -63,7 +64,7 @@ struct extent_to_write_t {
|
||||
}
|
||||
|
||||
laddr_t get_end_addr() const {
|
||||
return addr + len;
|
||||
return (addr + len).checked_to_laddr();
|
||||
}
|
||||
|
||||
static extent_to_write_t create_data(
|
||||
@ -169,7 +170,7 @@ struct extent_to_remap_t {
|
||||
nullptr, new_offset, new_len, p->get_key(), p->get_length(), b);
|
||||
}
|
||||
|
||||
uint64_t laddr_start;
|
||||
laddr_t laddr_start;
|
||||
extent_len_t length;
|
||||
std::optional<bufferlist> bl;
|
||||
|
||||
@ -180,7 +181,7 @@ private:
|
||||
pin(std::move(pin)), new_offset(new_offset), new_len(new_len) {}
|
||||
extent_to_remap_t(type_t type,
|
||||
LBAMappingRef &&pin, extent_len_t new_offset, extent_len_t new_len,
|
||||
uint64_t ori_laddr, extent_len_t ori_len, std::optional<bufferlist> b)
|
||||
laddr_t ori_laddr, extent_len_t ori_len, std::optional<bufferlist> b)
|
||||
: type(type),
|
||||
pin(std::move(pin)), new_offset(new_offset), new_len(new_len),
|
||||
laddr_start(ori_laddr), length(ori_len), bl(b) {}
|
||||
@ -267,7 +268,7 @@ overwrite_ops_t prepare_ops_list(
|
||||
ops.to_remap.push_back(extent_to_remap_t::create_remap2(
|
||||
std::move(front.pin),
|
||||
front.len,
|
||||
back.addr - front.addr - front.len));
|
||||
back.addr.get_byte_distance<extent_len_t>(front.addr) - front.len));
|
||||
ops.to_remove.pop_front();
|
||||
} else {
|
||||
// prepare to_remap, happens in one or multiple extents
|
||||
@ -288,13 +289,13 @@ overwrite_ops_t prepare_ops_list(
|
||||
back.pin->get_key() + back.pin->get_length());
|
||||
ops.to_remap.push_back(extent_to_remap_t::create_remap1(
|
||||
std::move(back.pin),
|
||||
back.addr - back.pin->get_key(),
|
||||
back.addr.get_byte_distance<extent_len_t>(back.pin->get_key()),
|
||||
back.len));
|
||||
ops.to_remove.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
interval_set<uint64_t> pre_alloc_addr_removed, pre_alloc_addr_remapped;
|
||||
laddr_interval_set_t pre_alloc_addr_removed, pre_alloc_addr_remapped;
|
||||
if (delta_based_overwrite_max_extent_size) {
|
||||
for (auto &r : ops.to_remove) {
|
||||
if (r->is_data_stable() && !r->is_zero_reserved()) {
|
||||
@ -321,7 +322,7 @@ overwrite_ops_t prepare_ops_list(
|
||||
erased_num = std::erase_if(
|
||||
ops.to_remove,
|
||||
[®ion, &to_remap](auto &r) {
|
||||
interval_set<uint64_t> range;
|
||||
laddr_interval_set_t range;
|
||||
range.insert(r->get_key(), r->get_length());
|
||||
if (range.contains(region.addr, region.len) && !r->is_clone()) {
|
||||
to_remap.push_back(extent_to_remap_t::create_overwrite(
|
||||
@ -337,12 +338,13 @@ overwrite_ops_t prepare_ops_list(
|
||||
erased_num = std::erase_if(
|
||||
ops.to_remap,
|
||||
[®ion, &to_remap](auto &r) {
|
||||
interval_set<uint64_t> range;
|
||||
laddr_interval_set_t range;
|
||||
range.insert(r.pin->get_key(), r.pin->get_length());
|
||||
if (range.contains(region.addr, region.len) && !r.pin->is_clone()) {
|
||||
to_remap.push_back(extent_to_remap_t::create_overwrite(
|
||||
region.addr - range.begin().get_start(), region.len,
|
||||
std::move(r.pin), *region.to_write));
|
||||
region.addr.get_byte_distance<
|
||||
extent_len_t> (range.begin().get_start()),
|
||||
region.len, std::move(r.pin), *region.to_write));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -519,7 +521,6 @@ ObjectDataHandler::write_ret do_insertions(
|
||||
[ctx](auto ®ion) {
|
||||
LOG_PREFIX(object_data_handler.cc::do_insertions);
|
||||
if (region.is_data()) {
|
||||
assert_aligned(region.addr);
|
||||
assert_aligned(region.len);
|
||||
ceph_assert(region.len == region.bl->length());
|
||||
DEBUGT("allocating extent: {}~{}",
|
||||
@ -544,7 +545,7 @@ ObjectDataHandler::write_ret do_insertions(
|
||||
off);
|
||||
}
|
||||
iter.copy(extent->get_length(), extent->get_bptr().c_str());
|
||||
off += extent->get_length();
|
||||
off = (off + extent->get_length()).checked_to_laddr();
|
||||
left -= extent->get_length();
|
||||
}
|
||||
return ObjectDataHandler::write_iertr::now();
|
||||
@ -625,13 +626,16 @@ std::ostream& operator<<(
|
||||
* left_paddr right_paddr
|
||||
*/
|
||||
struct overwrite_plan_t {
|
||||
// addresses
|
||||
// reserved data base of object data
|
||||
laddr_t data_base;
|
||||
|
||||
// addresses about extents
|
||||
laddr_t pin_begin;
|
||||
laddr_t pin_end;
|
||||
paddr_t left_paddr;
|
||||
paddr_t right_paddr;
|
||||
laddr_t data_begin;
|
||||
laddr_t data_end;
|
||||
laddr_offset_t data_begin;
|
||||
laddr_offset_t data_end;
|
||||
laddr_t aligned_data_begin;
|
||||
laddr_t aligned_data_end;
|
||||
|
||||
@ -646,42 +650,43 @@ struct overwrite_plan_t {
|
||||
|
||||
public:
|
||||
extent_len_t get_left_size() const {
|
||||
return data_begin - pin_begin;
|
||||
return data_begin.get_byte_distance<extent_len_t>(pin_begin);
|
||||
}
|
||||
|
||||
extent_len_t get_left_extent_size() const {
|
||||
return aligned_data_begin - pin_begin;
|
||||
return aligned_data_begin.get_byte_distance<extent_len_t>(pin_begin);
|
||||
}
|
||||
|
||||
extent_len_t get_left_alignment_size() const {
|
||||
return data_begin - aligned_data_begin;
|
||||
return data_begin.get_byte_distance<extent_len_t>(aligned_data_begin);
|
||||
}
|
||||
|
||||
extent_len_t get_right_size() const {
|
||||
return pin_end - data_end;
|
||||
return pin_end.get_byte_distance<extent_len_t>(data_end);
|
||||
}
|
||||
|
||||
extent_len_t get_right_extent_size() const {
|
||||
return pin_end - aligned_data_end;
|
||||
return pin_end.get_byte_distance<extent_len_t>(aligned_data_end);
|
||||
}
|
||||
|
||||
extent_len_t get_right_alignment_size() const {
|
||||
return aligned_data_end - data_end;
|
||||
return aligned_data_end.get_byte_distance<extent_len_t>(data_end);
|
||||
}
|
||||
|
||||
extent_len_t get_aligned_data_size() const {
|
||||
return aligned_data_end - aligned_data_begin;
|
||||
return aligned_data_end.get_byte_distance<extent_len_t>(aligned_data_begin);
|
||||
}
|
||||
|
||||
extent_len_t get_pins_size() const {
|
||||
return pin_end - pin_begin;
|
||||
return pin_end.get_byte_distance<extent_len_t>(pin_begin);
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(
|
||||
std::ostream& out,
|
||||
const overwrite_plan_t& overwrite_plan) {
|
||||
return out << "overwrite_plan_t("
|
||||
<< "pin_begin=" << overwrite_plan.pin_begin
|
||||
<< "data_base=" << overwrite_plan.data_base
|
||||
<< ", pin_begin=" << overwrite_plan.pin_begin
|
||||
<< ", pin_end=" << overwrite_plan.pin_end
|
||||
<< ", left_paddr=" << overwrite_plan.left_paddr
|
||||
<< ", right_paddr=" << overwrite_plan.right_paddr
|
||||
@ -697,18 +702,20 @@ public:
|
||||
<< ")";
|
||||
}
|
||||
|
||||
overwrite_plan_t(laddr_t offset,
|
||||
overwrite_plan_t(laddr_t data_base,
|
||||
objaddr_t offset,
|
||||
extent_len_t len,
|
||||
const lba_pin_list_t& pins,
|
||||
extent_len_t block_size) :
|
||||
data_base(data_base),
|
||||
pin_begin(pins.front()->get_key()),
|
||||
pin_end(pins.back()->get_key() + pins.back()->get_length()),
|
||||
pin_end((pins.back()->get_key() + pins.back()->get_length()).checked_to_laddr()),
|
||||
left_paddr(pins.front()->get_val()),
|
||||
right_paddr(pins.back()->get_val()),
|
||||
data_begin(offset),
|
||||
data_end(offset + len),
|
||||
aligned_data_begin(p2align((uint64_t)data_begin, (uint64_t)block_size)),
|
||||
aligned_data_end(p2roundup((uint64_t)data_end, (uint64_t)block_size)),
|
||||
data_begin(data_base + offset),
|
||||
data_end(data_base + offset + len),
|
||||
aligned_data_begin(data_begin.get_aligned_laddr()),
|
||||
aligned_data_end(data_end.get_roundup_laddr()),
|
||||
left_operation(overwrite_operation_t::UNKNOWN),
|
||||
right_operation(overwrite_operation_t::UNKNOWN),
|
||||
block_size(block_size),
|
||||
@ -725,11 +732,6 @@ public:
|
||||
private:
|
||||
// refer to overwrite_plan_t description
|
||||
void validate() const {
|
||||
ceph_assert(pin_begin % block_size == 0);
|
||||
ceph_assert(pin_end % block_size == 0);
|
||||
ceph_assert(aligned_data_begin % block_size == 0);
|
||||
ceph_assert(aligned_data_end % block_size == 0);
|
||||
|
||||
ceph_assert(pin_begin <= aligned_data_begin);
|
||||
ceph_assert(aligned_data_begin <= data_begin);
|
||||
ceph_assert(data_begin <= data_end);
|
||||
@ -941,9 +943,9 @@ operate_ret operate_right(context_t ctx, LBAMappingRef &pin, const overwrite_pla
|
||||
std::nullopt);
|
||||
} else {
|
||||
auto append_offset =
|
||||
overwrite_plan.data_end
|
||||
- right_pin_begin
|
||||
+ pin->get_intermediate_offset();
|
||||
overwrite_plan.data_end.get_byte_distance<
|
||||
extent_len_t>(right_pin_begin)
|
||||
+ pin->get_intermediate_offset();
|
||||
return ctx.tm.read_pin<ObjectDataBlock>(
|
||||
ctx.t, pin->duplicate()
|
||||
).si_then([append_offset, append_len](auto right_extent) {
|
||||
@ -973,9 +975,9 @@ operate_ret operate_right(context_t ctx, LBAMappingRef &pin, const overwrite_pla
|
||||
std::nullopt);
|
||||
} else {
|
||||
auto append_offset =
|
||||
overwrite_plan.data_end
|
||||
- right_pin_begin
|
||||
+ pin->get_intermediate_offset();
|
||||
overwrite_plan.data_end.get_byte_distance<
|
||||
extent_len_t>(right_pin_begin)
|
||||
+ pin->get_intermediate_offset();
|
||||
return ctx.tm.read_pin<ObjectDataBlock>(
|
||||
ctx.t, pin->duplicate()
|
||||
).si_then([append_offset, append_len,
|
||||
@ -1081,14 +1083,14 @@ ObjectDataHandler::clear_ret ObjectDataHandler::trim_data_reservation(
|
||||
extent_to_write_list_t(),
|
||||
[ctx, size, &object_data, this](auto &pins, auto &to_write) {
|
||||
LOG_PREFIX(ObjectDataHandler::trim_data_reservation);
|
||||
DEBUGT("object_data: {}~{}",
|
||||
ctx.t,
|
||||
object_data.get_reserved_data_base(),
|
||||
object_data.get_reserved_data_len());
|
||||
auto data_base = object_data.get_reserved_data_base();
|
||||
auto data_len = object_data.get_reserved_data_len();
|
||||
DEBUGT("object_data: {}~{}", ctx.t, data_base, data_len);
|
||||
laddr_t aligned_start = (data_base + size).get_aligned_laddr();
|
||||
loffset_t aligned_length =
|
||||
data_len - aligned_start.get_byte_distance<loffset_t>(data_base);
|
||||
return ctx.tm.get_pins(
|
||||
ctx.t,
|
||||
object_data.get_reserved_data_base() + size,
|
||||
object_data.get_reserved_data_len() - size
|
||||
ctx.t, aligned_start, aligned_length
|
||||
).si_then([ctx, size, &pins, &object_data, &to_write](auto _pins) {
|
||||
_pins.swap(pins);
|
||||
ceph_assert(pins.size());
|
||||
@ -1101,8 +1103,8 @@ ObjectDataHandler::clear_ret ObjectDataHandler::trim_data_reservation(
|
||||
ceph_assert(pin.get_key() >= object_data.get_reserved_data_base());
|
||||
ceph_assert(
|
||||
pin.get_key() <= object_data.get_reserved_data_base() + size);
|
||||
auto pin_offset = pin.get_key() -
|
||||
object_data.get_reserved_data_base();
|
||||
auto pin_offset = pin.get_key().template get_byte_distance<extent_len_t>(
|
||||
object_data.get_reserved_data_base());
|
||||
if ((pin.get_key() == (object_data.get_reserved_data_base() + size)) ||
|
||||
(pin.get_val().is_zero())) {
|
||||
/* First pin is exactly at the boundary or is a zero pin. Either way,
|
||||
@ -1126,7 +1128,7 @@ ObjectDataHandler::clear_ret ObjectDataHandler::trim_data_reservation(
|
||||
pin.get_key(),
|
||||
size - pin_offset));
|
||||
to_write.push_back(extent_to_write_t::create_zero(
|
||||
object_data.get_reserved_data_base() + roundup_size,
|
||||
(object_data.get_reserved_data_base() + roundup_size).checked_to_laddr(),
|
||||
object_data.get_reserved_data_len() - roundup_size));
|
||||
return clear_iertr::now();
|
||||
} else {
|
||||
@ -1151,7 +1153,7 @@ ObjectDataHandler::clear_ret ObjectDataHandler::trim_data_reservation(
|
||||
pin.get_key(),
|
||||
bl));
|
||||
to_write.push_back(extent_to_write_t::create_zero(
|
||||
object_data.get_reserved_data_base() + roundup_size,
|
||||
(object_data.get_reserved_data_base() + roundup_size).checked_to_laddr(),
|
||||
object_data.get_reserved_data_len() - roundup_size));
|
||||
return clear_iertr::now();
|
||||
});
|
||||
@ -1186,12 +1188,13 @@ ObjectDataHandler::clear_ret ObjectDataHandler::trim_data_reservation(
|
||||
* optionally on the right.
|
||||
*/
|
||||
extent_to_write_list_t get_to_writes_with_zero_buffer(
|
||||
laddr_t data_base,
|
||||
const extent_len_t block_size,
|
||||
laddr_t offset, extent_len_t len,
|
||||
objaddr_t offset, extent_len_t len,
|
||||
std::optional<bufferptr> &&headptr, std::optional<bufferptr> &&tailptr)
|
||||
{
|
||||
auto zero_left = p2roundup(offset, (laddr_t)block_size);
|
||||
auto zero_right = p2align(offset + len, (laddr_t)block_size);
|
||||
auto zero_left = p2roundup(offset, (objaddr_t)block_size);
|
||||
auto zero_right = p2align(offset + len, (objaddr_t)block_size);
|
||||
auto left = headptr ? (offset - headptr->length()) : offset;
|
||||
auto right = tailptr ?
|
||||
(offset + len + tailptr->length()) :
|
||||
@ -1207,8 +1210,6 @@ extent_to_write_list_t get_to_writes_with_zero_buffer(
|
||||
(!tailptr && (right == zero_right)));
|
||||
|
||||
assert(right > left);
|
||||
assert((left % block_size) == 0);
|
||||
assert((right % block_size) == 0);
|
||||
|
||||
// zero region too small for a reserved section,
|
||||
// headptr and tailptr in same extent
|
||||
@ -1225,7 +1226,8 @@ extent_to_write_list_t get_to_writes_with_zero_buffer(
|
||||
assert(bl.length() % block_size == 0);
|
||||
assert(bl.length() == (right - left));
|
||||
extent_to_write_list_t ret;
|
||||
ret.push_back(extent_to_write_t::create_data(left, bl));
|
||||
ret.push_back(extent_to_write_t::create_data(
|
||||
(data_base + left).checked_to_laddr(), bl));
|
||||
return ret;
|
||||
} else {
|
||||
// reserved section between ends, headptr and tailptr in different extents
|
||||
@ -1236,10 +1238,13 @@ extent_to_write_list_t get_to_writes_with_zero_buffer(
|
||||
headbl.append_zero(zero_left - left - headbl.length());
|
||||
assert(headbl.length() % block_size == 0);
|
||||
assert(headbl.length() > 0);
|
||||
ret.push_back(extent_to_write_t::create_data(left, headbl));
|
||||
ret.push_back(extent_to_write_t::create_data(
|
||||
(data_base + left).checked_to_laddr(), headbl));
|
||||
}
|
||||
// reserved zero region
|
||||
ret.push_back(extent_to_write_t::create_zero(zero_left, zero_right - zero_left));
|
||||
ret.push_back(extent_to_write_t::create_zero(
|
||||
(data_base + zero_left).checked_to_laddr(),
|
||||
zero_right - zero_left));
|
||||
assert(ret.back().len % block_size == 0);
|
||||
assert(ret.back().len > 0);
|
||||
if (tailptr) {
|
||||
@ -1248,7 +1253,8 @@ extent_to_write_list_t get_to_writes_with_zero_buffer(
|
||||
tailbl.append_zero(right - zero_right - tailbl.length());
|
||||
assert(tailbl.length() % block_size == 0);
|
||||
assert(tailbl.length() > 0);
|
||||
ret.push_back(extent_to_write_t::create_data(zero_right, tailbl));
|
||||
ret.push_back(extent_to_write_t::create_data(
|
||||
(data_base + zero_right).checked_to_laddr(), tailbl));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1270,7 +1276,8 @@ extent_to_write_list_t get_to_writes(laddr_t offset, bufferlist &bl)
|
||||
|
||||
ObjectDataHandler::write_ret ObjectDataHandler::overwrite(
|
||||
context_t ctx,
|
||||
laddr_t offset,
|
||||
laddr_t data_base,
|
||||
objaddr_t offset,
|
||||
extent_len_t len,
|
||||
std::optional<bufferlist> &&bl,
|
||||
lba_pin_list_t &&_pins)
|
||||
@ -1278,11 +1285,11 @@ ObjectDataHandler::write_ret ObjectDataHandler::overwrite(
|
||||
if (bl.has_value()) {
|
||||
assert(bl->length() == len);
|
||||
}
|
||||
overwrite_plan_t overwrite_plan(offset, len, _pins, ctx.tm.get_block_size());
|
||||
overwrite_plan_t overwrite_plan(data_base, offset, len, _pins, ctx.tm.get_block_size());
|
||||
return seastar::do_with(
|
||||
std::move(_pins),
|
||||
extent_to_write_list_t(),
|
||||
[ctx, len, offset, overwrite_plan, bl=std::move(bl), this]
|
||||
[ctx, data_base, len, offset, overwrite_plan, bl=std::move(bl), this]
|
||||
(auto &pins, auto &to_write) mutable
|
||||
{
|
||||
LOG_PREFIX(ObjectDataHandler::overwrite);
|
||||
@ -1297,7 +1304,7 @@ ObjectDataHandler::write_ret ObjectDataHandler::overwrite(
|
||||
ctx,
|
||||
pins.front(),
|
||||
overwrite_plan
|
||||
).si_then([ctx, len, offset, overwrite_plan, bl=std::move(bl),
|
||||
).si_then([ctx, data_base, len, offset, overwrite_plan, bl=std::move(bl),
|
||||
&to_write, &pins, this](auto p) mutable {
|
||||
auto &[left_extent, headptr] = p;
|
||||
if (left_extent) {
|
||||
@ -1311,7 +1318,7 @@ ObjectDataHandler::write_ret ObjectDataHandler::overwrite(
|
||||
ctx,
|
||||
pins.back(),
|
||||
overwrite_plan
|
||||
).si_then([ctx, len, offset,
|
||||
).si_then([ctx, data_base, len, offset,
|
||||
pin_begin=overwrite_plan.pin_begin,
|
||||
pin_end=overwrite_plan.pin_end,
|
||||
bl=std::move(bl), headptr=std::move(headptr),
|
||||
@ -1322,8 +1329,7 @@ ObjectDataHandler::write_ret ObjectDataHandler::overwrite(
|
||||
bufferlist write_bl;
|
||||
if (headptr) {
|
||||
write_bl.append(*headptr);
|
||||
write_offset -= headptr->length();
|
||||
assert_aligned(write_offset);
|
||||
write_offset = write_offset - headptr->length();
|
||||
}
|
||||
write_bl.claim_append(*bl);
|
||||
if (tailptr) {
|
||||
@ -1332,11 +1338,12 @@ ObjectDataHandler::write_ret ObjectDataHandler::overwrite(
|
||||
}
|
||||
splice_extent_to_write(
|
||||
to_write,
|
||||
get_to_writes(write_offset, write_bl));
|
||||
get_to_writes((data_base + write_offset).checked_to_laddr(), write_bl));
|
||||
} else {
|
||||
splice_extent_to_write(
|
||||
to_write,
|
||||
get_to_writes_with_zero_buffer(
|
||||
data_base,
|
||||
ctx.tm.get_block_size(),
|
||||
offset,
|
||||
len,
|
||||
@ -1388,14 +1395,20 @@ ObjectDataHandler::zero_ret ObjectDataHandler::zero(
|
||||
object_data,
|
||||
p2roundup(offset + len, ctx.tm.get_block_size())
|
||||
).si_then([this, ctx, offset, len, &object_data] {
|
||||
auto logical_offset = object_data.get_reserved_data_base() + offset;
|
||||
auto data_base = object_data.get_reserved_data_base();
|
||||
laddr_offset_t l_start = data_base + offset;
|
||||
laddr_offset_t l_end = l_start + len;
|
||||
laddr_t aligned_start = l_start.get_aligned_laddr();
|
||||
loffset_t aligned_length =
|
||||
l_end.get_roundup_laddr().get_byte_distance<
|
||||
loffset_t>(aligned_start);
|
||||
return ctx.tm.get_pins(
|
||||
ctx.t,
|
||||
logical_offset,
|
||||
len
|
||||
).si_then([this, ctx, logical_offset, len](auto pins) {
|
||||
aligned_start,
|
||||
aligned_length
|
||||
).si_then([this, ctx, data_base, offset, len](auto pins) {
|
||||
return overwrite(
|
||||
ctx, logical_offset, len,
|
||||
ctx, data_base, offset, len,
|
||||
std::nullopt, std::move(pins));
|
||||
});
|
||||
});
|
||||
@ -1423,15 +1436,21 @@ ObjectDataHandler::write_ret ObjectDataHandler::write(
|
||||
object_data,
|
||||
p2roundup(offset + bl.length(), ctx.tm.get_block_size())
|
||||
).si_then([this, ctx, offset, &object_data, &bl] {
|
||||
auto logical_offset = object_data.get_reserved_data_base() + offset;
|
||||
auto data_base = object_data.get_reserved_data_base();
|
||||
laddr_offset_t l_start = data_base + offset;
|
||||
laddr_offset_t l_end = l_start + bl.length();
|
||||
laddr_t aligned_start = l_start.get_aligned_laddr();
|
||||
loffset_t aligned_length =
|
||||
l_end.get_roundup_laddr().get_byte_distance<
|
||||
loffset_t>(aligned_start);
|
||||
return ctx.tm.get_pins(
|
||||
ctx.t,
|
||||
logical_offset,
|
||||
bl.length()
|
||||
).si_then([this, ctx,logical_offset, &bl](
|
||||
aligned_start,
|
||||
aligned_length
|
||||
).si_then([this, ctx, offset, data_base, &bl](
|
||||
auto pins) {
|
||||
return overwrite(
|
||||
ctx, logical_offset, bl.length(),
|
||||
ctx, data_base, offset, bl.length(),
|
||||
bufferlist(bl), std::move(pins));
|
||||
});
|
||||
});
|
||||
@ -1459,17 +1478,21 @@ ObjectDataHandler::read_ret ObjectDataHandler::read(
|
||||
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 =
|
||||
laddr_offset_t l_start =
|
||||
object_data.get_reserved_data_base() + obj_offset;
|
||||
laddr_offset_t l_end = l_start + len;
|
||||
laddr_t aligned_start = l_start.get_aligned_laddr();
|
||||
loffset_t aligned_length =
|
||||
l_end.get_roundup_laddr().get_byte_distance<
|
||||
loffset_t>(aligned_start);
|
||||
return ctx.tm.get_pins(
|
||||
ctx.t,
|
||||
l_start,
|
||||
len
|
||||
).si_then([FNAME, ctx, l_start, len, &ret](auto _pins) {
|
||||
aligned_start,
|
||||
aligned_length
|
||||
).si_then([FNAME, ctx, l_start, l_end, &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,
|
||||
@ -1488,17 +1511,19 @@ ObjectDataHandler::read_ret ObjectDataHandler::read(
|
||||
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;
|
||||
laddr_offset_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);
|
||||
laddr_offset_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,
|
||||
l_current_end.get_byte_distance<loffset_t>(l_current),
|
||||
pin_key,
|
||||
pin_len);
|
||||
ret.append_zero(l_current_end - l_current);
|
||||
ret.append_zero(
|
||||
l_current_end.get_byte_distance<
|
||||
extent_len_t>(l_current));
|
||||
l_current = l_current_end;
|
||||
return seastar::now();
|
||||
}
|
||||
@ -1515,7 +1540,7 @@ ObjectDataHandler::read_ret ObjectDataHandler::read(
|
||||
DEBUGT("reading {}~{} from indirect-pin {}~{}, direct-pin {}~{}(off={})",
|
||||
ctx.t,
|
||||
l_current,
|
||||
l_current_end - l_current,
|
||||
l_current_end.get_byte_distance<extent_len_t>(l_current),
|
||||
pin_key,
|
||||
pin_len,
|
||||
e_key,
|
||||
@ -1527,14 +1552,16 @@ ObjectDataHandler::read_ret ObjectDataHandler::read(
|
||||
DEBUGT("reading {}~{} from pin {}~{}",
|
||||
ctx.t,
|
||||
l_current,
|
||||
l_current_end - l_current,
|
||||
l_current_end.get_byte_distance<
|
||||
extent_len_t>(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;
|
||||
extent_len_t e_current_off = (l_current + e_off)
|
||||
.template get_byte_distance<extent_len_t>(pin_key);
|
||||
return ctx.tm.read_pin<ObjectDataBlock>(
|
||||
ctx.t,
|
||||
std::move(pin)
|
||||
@ -1550,7 +1577,7 @@ ObjectDataHandler::read_ret ObjectDataHandler::read(
|
||||
bufferptr(
|
||||
extent->get_bptr(),
|
||||
e_current_off,
|
||||
l_current_end - l_current));
|
||||
l_current_end.get_byte_distance<extent_len_t>(l_current)));
|
||||
l_current = l_current_end;
|
||||
return seastar::now();
|
||||
}).handle_error_interruptible(
|
||||
@ -1592,26 +1619,32 @@ 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 l_start =
|
||||
laddr_offset_t l_start =
|
||||
object_data.get_reserved_data_base() + obj_offset;
|
||||
laddr_offset_t l_end = l_start + len;
|
||||
laddr_t aligned_start = l_start.get_aligned_laddr();
|
||||
loffset_t aligned_length =
|
||||
l_end.get_roundup_laddr().get_byte_distance<
|
||||
loffset_t>(aligned_start);
|
||||
return ctx.tm.get_pins(
|
||||
ctx.t,
|
||||
l_start,
|
||||
len
|
||||
aligned_start,
|
||||
aligned_length
|
||||
).si_then([l_start, len, &object_data, &ret](auto &&pins) {
|
||||
ceph_assert(pins.size() >= 1);
|
||||
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(), l_start);
|
||||
auto ret_right = std::min(
|
||||
laddr_offset_t ret_left = std::max(laddr_offset_t(i->get_key(), 0), l_start);
|
||||
laddr_offset_t ret_right = std::min(
|
||||
i->get_key() + i->get_length(),
|
||||
l_start + len);
|
||||
assert(ret_right > ret_left);
|
||||
ret.emplace(
|
||||
std::make_pair(
|
||||
ret_left - object_data.get_reserved_data_base(),
|
||||
ret_right - ret_left
|
||||
ret_left.get_byte_distance<uint64_t>(
|
||||
object_data.get_reserved_data_base()),
|
||||
ret_right.get_byte_distance<uint64_t>(ret_left)
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -1689,11 +1722,13 @@ ObjectDataHandler::clone_ret ObjectDataHandler::clone_extents(
|
||||
return trans_intr::do_for_each(
|
||||
pins,
|
||||
[&last_pos, &object_data, ctx, data_base](auto &pin) {
|
||||
auto offset = pin->get_key() - data_base;
|
||||
auto offset = pin->get_key().template get_byte_distance<
|
||||
extent_len_t>(data_base);
|
||||
ceph_assert(offset == last_pos);
|
||||
auto fut = TransactionManager::alloc_extent_iertr
|
||||
::make_ready_future<LBAMappingRef>();
|
||||
auto addr = object_data.get_reserved_data_base() + offset;
|
||||
laddr_t addr = (object_data.get_reserved_data_base() + offset)
|
||||
.checked_to_laddr();
|
||||
if (pin->get_val().is_zero()) {
|
||||
fut = ctx.tm.reserve_region(ctx.t, addr, pin->get_length());
|
||||
} else {
|
||||
@ -1711,7 +1746,7 @@ ObjectDataHandler::clone_ret ObjectDataHandler::clone_extents(
|
||||
if (last_pos != object_data.get_reserved_data_len()) {
|
||||
return ctx.tm.reserve_region(
|
||||
ctx.t,
|
||||
object_data.get_reserved_data_base() + last_pos,
|
||||
(object_data.get_reserved_data_base() + last_pos).checked_to_laddr(),
|
||||
object_data.get_reserved_data_len() - last_pos
|
||||
).si_then([](auto) {
|
||||
return seastar::now();
|
||||
|
@ -229,7 +229,8 @@ private:
|
||||
/// Updates region [_offset, _offset + bl.length) to bl
|
||||
write_ret overwrite(
|
||||
context_t ctx, ///< [in] ctx
|
||||
laddr_t offset, ///< [in] write offset
|
||||
laddr_t data_base, ///< [in] data base laddr
|
||||
objaddr_t offset, ///< [in] write offset
|
||||
extent_len_t len, ///< [in] len to write, len == bl->length() if bl
|
||||
std::optional<bufferlist> &&bl, ///< [in] buffer to write, empty for zeros
|
||||
lba_pin_list_t &&pins ///< [in] set of pins overlapping above region
|
||||
|
@ -46,7 +46,7 @@ struct omap_node_meta_le_t {
|
||||
struct omap_inner_key_t {
|
||||
uint16_t key_off = 0;
|
||||
uint16_t key_len = 0;
|
||||
laddr_t laddr = 0;
|
||||
laddr_t laddr = L_ADDR_MIN;
|
||||
|
||||
omap_inner_key_t() = default;
|
||||
omap_inner_key_t(uint16_t off, uint16_t len, laddr_t addr)
|
||||
@ -70,7 +70,7 @@ struct omap_inner_key_t {
|
||||
struct omap_inner_key_le_t {
|
||||
ceph_le16 key_off{0};
|
||||
ceph_le16 key_len{0};
|
||||
laddr_le_t laddr{0};
|
||||
laddr_le_t laddr{L_ADDR_MIN};
|
||||
|
||||
omap_inner_key_le_t() = default;
|
||||
omap_inner_key_le_t(const omap_inner_key_le_t &) = default;
|
||||
|
@ -82,8 +82,9 @@ public:
|
||||
assert(default_metadata_offset);
|
||||
assert(default_metadata_range);
|
||||
uint64_t range_blocks = default_metadata_range / block_size;
|
||||
return get_hint() + default_metadata_offset +
|
||||
(((uint32_t)std::rand() % range_blocks) * block_size);
|
||||
auto random_offset = default_metadata_offset +
|
||||
(((uint32_t)std::rand() % range_blocks) * block_size);
|
||||
return (get_hint() + random_offset).checked_to_laddr();
|
||||
}
|
||||
laddr_t get_data_hint() const {
|
||||
return get_hint();
|
||||
|
@ -12,7 +12,7 @@ namespace crimson::os::seastore::onode {
|
||||
void FLTreeOnode::Recorder::apply_value_delta(
|
||||
ceph::bufferlist::const_iterator &bliter,
|
||||
NodeExtentMutable &value,
|
||||
laddr_t value_addr)
|
||||
laddr_offset_t value_addr_offset)
|
||||
{
|
||||
LOG_PREFIX(FLTreeOnode::Recorder::apply_value_delta);
|
||||
delta_op_t op;
|
||||
|
@ -66,7 +66,7 @@ struct FLTreeOnode final : Onode, Value {
|
||||
void apply_value_delta(
|
||||
ceph::bufferlist::const_iterator &bliter,
|
||||
NodeExtentMutable &value,
|
||||
laddr_t value_addr) final;
|
||||
laddr_offset_t value_addr_offset) final;
|
||||
|
||||
void encode_update(NodeExtentMutable &payload_mut, delta_op_t op);
|
||||
};
|
||||
|
@ -435,7 +435,7 @@ eagain_ifuture<Ref<Node>> Node::load_root(context_t c, RootNodeTracker& root_tra
|
||||
assert(_super);
|
||||
auto root_addr = _super->get_root_laddr();
|
||||
assert(root_addr != L_ADDR_NULL);
|
||||
TRACET("loading root_addr={:x} ...", c.t, root_addr);
|
||||
TRACET("loading root_addr={} ...", c.t, root_addr);
|
||||
return Node::load(c, root_addr, true
|
||||
).si_then([c, _super = std::move(_super),
|
||||
&root_tracker, FNAME](auto root) mutable {
|
||||
@ -693,22 +693,22 @@ eagain_ifuture<Ref<Node>> Node::load(
|
||||
eagain_iertr::pass_further{},
|
||||
crimson::ct_error::input_output_error::assert_failure(
|
||||
[FNAME, c, addr, expect_is_level_tail] {
|
||||
ERRORT("EIO -- addr={:x}, is_level_tail={}",
|
||||
ERRORT("EIO -- addr={}, is_level_tail={}",
|
||||
c.t, addr, expect_is_level_tail);
|
||||
}),
|
||||
crimson::ct_error::invarg::assert_failure(
|
||||
[FNAME, c, addr, expect_is_level_tail] {
|
||||
ERRORT("EINVAL -- addr={:x}, is_level_tail={}",
|
||||
ERRORT("EINVAL -- addr={}, is_level_tail={}",
|
||||
c.t, addr, expect_is_level_tail);
|
||||
}),
|
||||
crimson::ct_error::enoent::assert_failure(
|
||||
[FNAME, c, addr, expect_is_level_tail] {
|
||||
ERRORT("ENOENT -- addr={:x}, is_level_tail={}",
|
||||
ERRORT("ENOENT -- addr={}, is_level_tail={}",
|
||||
c.t, addr, expect_is_level_tail);
|
||||
}),
|
||||
crimson::ct_error::erange::assert_failure(
|
||||
[FNAME, c, addr, expect_is_level_tail] {
|
||||
ERRORT("ERANGE -- addr={:x}, is_level_tail={}",
|
||||
ERRORT("ERANGE -- addr={}, is_level_tail={}",
|
||||
c.t, addr, expect_is_level_tail);
|
||||
})
|
||||
).si_then([FNAME, c, addr, expect_is_level_tail](auto extent)
|
||||
@ -717,13 +717,13 @@ eagain_ifuture<Ref<Node>> Node::load(
|
||||
auto header = extent->get_header();
|
||||
auto field_type = header.get_field_type();
|
||||
if (!field_type) {
|
||||
ERRORT("load addr={:x}, is_level_tail={} error, "
|
||||
ERRORT("load addr={}, is_level_tail={} error, "
|
||||
"got invalid header -- {}",
|
||||
c.t, addr, expect_is_level_tail, fmt::ptr(extent));
|
||||
ceph_abort("fatal error");
|
||||
}
|
||||
if (header.get_is_level_tail() != expect_is_level_tail) {
|
||||
ERRORT("load addr={:x}, is_level_tail={} error, "
|
||||
ERRORT("load addr={}, is_level_tail={} error, "
|
||||
"is_level_tail mismatch -- {}",
|
||||
c.t, addr, expect_is_level_tail, fmt::ptr(extent));
|
||||
ceph_abort("fatal error");
|
||||
@ -732,7 +732,7 @@ eagain_ifuture<Ref<Node>> Node::load(
|
||||
auto node_type = header.get_node_type();
|
||||
if (node_type == node_type_t::LEAF) {
|
||||
if (extent->get_length() != c.vb.get_leaf_node_size()) {
|
||||
ERRORT("load addr={:x}, is_level_tail={} error, "
|
||||
ERRORT("load addr={}, is_level_tail={} error, "
|
||||
"leaf length mismatch -- {}",
|
||||
c.t, addr, expect_is_level_tail, fmt::ptr(extent));
|
||||
ceph_abort("fatal error");
|
||||
@ -743,7 +743,7 @@ eagain_ifuture<Ref<Node>> Node::load(
|
||||
new LeafNode(derived_ptr, std::move(impl)));
|
||||
} else if (node_type == node_type_t::INTERNAL) {
|
||||
if (extent->get_length() != c.vb.get_internal_node_size()) {
|
||||
ERRORT("load addr={:x}, is_level_tail={} error, "
|
||||
ERRORT("load addr={}, is_level_tail={} error, "
|
||||
"internal length mismatch -- {}",
|
||||
c.t, addr, expect_is_level_tail, fmt::ptr(extent));
|
||||
ceph_abort("fatal error");
|
||||
@ -1084,7 +1084,7 @@ eagain_ifuture<> InternalNode::apply_children_merge(
|
||||
auto left_addr = left_child->impl->laddr();
|
||||
auto& right_pos = right_child->parent_info().position;
|
||||
auto right_addr = right_child->impl->laddr();
|
||||
DEBUGT("apply {}'s child {} (was {:#x}) at pos({}), "
|
||||
DEBUGT("apply {}'s child {} (was {}) at pos({}), "
|
||||
"to merge with {} at pos({}), update_index={} ...",
|
||||
c.t, get_name(), left_child->get_name(), origin_left_addr, left_pos,
|
||||
right_child->get_name(), right_pos, update_index);
|
||||
@ -1572,12 +1572,12 @@ eagain_ifuture<Ref<Node>> InternalNode::get_or_track_child(
|
||||
return [this, position, child_addr, c, FNAME] {
|
||||
auto found = tracked_child_nodes.find(position);
|
||||
if (found != tracked_child_nodes.end()) {
|
||||
TRACET("loaded child tracked {} at pos({}) addr={:x}",
|
||||
TRACET("loaded child tracked {} at pos({}) addr={}",
|
||||
c.t, found->second->get_name(), position, child_addr);
|
||||
return eagain_iertr::make_ready_future<Ref<Node>>(found->second);
|
||||
}
|
||||
// the child is not loaded yet
|
||||
TRACET("loading child at pos({}) addr={:x} ...",
|
||||
TRACET("loading child at pos({}) addr={} ...",
|
||||
c.t, position, child_addr);
|
||||
bool level_tail = position.is_end();
|
||||
return Node::load(c, child_addr, level_tail
|
||||
|
@ -173,7 +173,7 @@ class DeltaRecorderT final: public DeltaRecorder {
|
||||
auto p_addr = reinterpret_cast<laddr_packed_t*>(
|
||||
mut.get_write() + update_offset);
|
||||
SUBDEBUG(seastore_onode,
|
||||
"apply {:#x} to offset {:#x} ...",
|
||||
"apply {} to offset {:#x} ...",
|
||||
new_addr, update_offset);
|
||||
layout_t::update_child_addr(mut, new_addr, p_addr);
|
||||
break;
|
||||
@ -526,12 +526,12 @@ class NodeExtentAccessorT {
|
||||
crimson::ct_error::input_output_error::assert_failure(
|
||||
[FNAME, c, alloc_size, l_to_discard = extent->get_laddr()] {
|
||||
SUBERRORT(seastore_onode,
|
||||
"EIO during allocate -- node_size={}, to_discard={:x}",
|
||||
"EIO during allocate -- node_size={}, to_discard={}",
|
||||
c.t, alloc_size, l_to_discard);
|
||||
})
|
||||
).si_then([this, c, FNAME] (auto fresh_extent) {
|
||||
SUBDEBUGT(seastore_onode,
|
||||
"update addr from {:#x} to {:#x} ...",
|
||||
"update addr from {} to {} ...",
|
||||
c.t, extent->get_laddr(), fresh_extent->get_laddr());
|
||||
assert(fresh_extent);
|
||||
assert(fresh_extent->is_initial_pending());
|
||||
@ -555,14 +555,14 @@ class NodeExtentAccessorT {
|
||||
[FNAME, c, l_to_discard = to_discard->get_laddr(),
|
||||
l_fresh = fresh_extent->get_laddr()] {
|
||||
SUBERRORT(seastore_onode,
|
||||
"EIO during retire -- to_disgard={:x}, fresh={:x}",
|
||||
"EIO during retire -- to_disgard={}, fresh={}",
|
||||
c.t, l_to_discard, l_fresh);
|
||||
}),
|
||||
crimson::ct_error::enoent::assert_failure(
|
||||
[FNAME, c, l_to_discard = to_discard->get_laddr(),
|
||||
l_fresh = fresh_extent->get_laddr()] {
|
||||
SUBERRORT(seastore_onode,
|
||||
"ENOENT during retire -- to_disgard={:x}, fresh={:x}",
|
||||
"ENOENT during retire -- to_disgard={}, fresh={}",
|
||||
c.t, l_to_discard, l_fresh);
|
||||
})
|
||||
);
|
||||
@ -582,11 +582,11 @@ class NodeExtentAccessorT {
|
||||
eagain_iertr::pass_further{},
|
||||
crimson::ct_error::input_output_error::assert_failure(
|
||||
[FNAME, c, addr] {
|
||||
SUBERRORT(seastore_onode, "EIO -- addr={:x}", c.t, addr);
|
||||
SUBERRORT(seastore_onode, "EIO -- addr={}", c.t, addr);
|
||||
}),
|
||||
crimson::ct_error::enoent::assert_failure(
|
||||
[FNAME, c, addr] {
|
||||
SUBERRORT(seastore_onode, "ENOENT -- addr={:x}", c.t, addr);
|
||||
SUBERRORT(seastore_onode, "ENOENT -- addr={}", c.t, addr);
|
||||
})
|
||||
#ifndef NDEBUG
|
||||
).si_then([c] {
|
||||
|
@ -28,7 +28,7 @@ class DummySuper final: public Super {
|
||||
laddr_t get_root_laddr() const override { return *p_root_laddr; }
|
||||
void write_root_laddr(context_t c, laddr_t addr) override {
|
||||
LOG_PREFIX(OTree::Dummy);
|
||||
SUBDEBUGT(seastore_onode, "update root {:#x} ...", c.t, addr);
|
||||
SUBDEBUGT(seastore_onode, "update root {} ...", c.t, addr);
|
||||
*p_root_laddr = addr;
|
||||
}
|
||||
private:
|
||||
@ -77,7 +77,7 @@ class DummyNodeExtentManager final: public NodeExtentManager {
|
||||
|
||||
read_iertr::future<NodeExtentRef> read_extent(
|
||||
Transaction& t, laddr_t addr) override {
|
||||
SUBTRACET(seastore_onode, "reading at {:#x} ...", t, addr);
|
||||
SUBTRACET(seastore_onode, "reading at {} ...", t, addr);
|
||||
if constexpr (SYNC) {
|
||||
return read_extent_sync(t, addr);
|
||||
} else {
|
||||
@ -90,7 +90,7 @@ class DummyNodeExtentManager final: public NodeExtentManager {
|
||||
|
||||
alloc_iertr::future<NodeExtentRef> alloc_extent(
|
||||
Transaction& t, laddr_t hint, extent_len_t len) override {
|
||||
SUBTRACET(seastore_onode, "allocating {}B with hint {:#x} ...", t, len, hint);
|
||||
SUBTRACET(seastore_onode, "allocating {}B with hint {} ...", t, len, hint);
|
||||
if constexpr (SYNC) {
|
||||
return alloc_extent_sync(t, len);
|
||||
} else {
|
||||
@ -104,7 +104,7 @@ class DummyNodeExtentManager final: public NodeExtentManager {
|
||||
retire_iertr::future<> retire_extent(
|
||||
Transaction& t, NodeExtentRef extent) override {
|
||||
SUBTRACET(seastore_onode,
|
||||
"retiring {}B at {:#x} -- {} ...",
|
||||
"retiring {}B at {} -- {} ...",
|
||||
t, extent->get_length(), extent->get_laddr(), *extent);
|
||||
if constexpr (SYNC) {
|
||||
return retire_extent_sync(t, extent);
|
||||
@ -140,7 +140,7 @@ class DummyNodeExtentManager final: public NodeExtentManager {
|
||||
assert(iter != allocate_map.end());
|
||||
auto extent = iter->second;
|
||||
SUBTRACET(seastore_onode,
|
||||
"read {}B at {:#x} -- {}",
|
||||
"read {}B at {} -- {}",
|
||||
t, extent->get_length(), extent->get_laddr(), *extent);
|
||||
assert(extent->get_laddr() == addr);
|
||||
return read_iertr::make_ready_future<NodeExtentRef>(extent);
|
||||
@ -150,14 +150,15 @@ class DummyNodeExtentManager final: public NodeExtentManager {
|
||||
Transaction& t, extent_len_t len) {
|
||||
assert(len % ALIGNMENT == 0);
|
||||
auto r = ceph::buffer::create_aligned(len, ALIGNMENT);
|
||||
auto addr = reinterpret_cast<laddr_t>(r->get_data());
|
||||
auto addr = laddr_t::from_byte_offset(
|
||||
reinterpret_cast<laddr_t::Unsigned>(r->get_data()));
|
||||
auto bp = ceph::bufferptr(std::move(r));
|
||||
auto extent = Ref<DummyNodeExtent>(new DummyNodeExtent(std::move(bp)));
|
||||
extent->set_laddr(addr);
|
||||
assert(allocate_map.find(extent->get_laddr()) == allocate_map.end());
|
||||
allocate_map.insert({extent->get_laddr(), extent});
|
||||
SUBDEBUGT(seastore_onode,
|
||||
"allocated {}B at {:#x} -- {}",
|
||||
"allocated {}B at {} -- {}",
|
||||
t, extent->get_length(), extent->get_laddr(), *extent);
|
||||
assert(extent->get_length() == len);
|
||||
return alloc_iertr::make_ready_future<NodeExtentRef>(extent);
|
||||
@ -172,13 +173,13 @@ class DummyNodeExtentManager final: public NodeExtentManager {
|
||||
auto iter = allocate_map.find(addr);
|
||||
assert(iter != allocate_map.end());
|
||||
allocate_map.erase(iter);
|
||||
SUBDEBUGT(seastore_onode, "retired {}B at {:#x}", t, len, addr);
|
||||
SUBDEBUGT(seastore_onode, "retired {}B at {}", t, len, addr);
|
||||
return retire_iertr::now();
|
||||
}
|
||||
|
||||
getsuper_iertr::future<Super::URef> get_super_sync(
|
||||
Transaction& t, RootNodeTracker& tracker) {
|
||||
SUBTRACET(seastore_onode, "got root {:#x}", t, root_laddr);
|
||||
SUBTRACET(seastore_onode, "got root {}", t, root_laddr);
|
||||
return getsuper_iertr::make_ready_future<Super::URef>(
|
||||
Super::URef(new DummySuper(t, tracker, &root_laddr)));
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ class SeastoreSuper final: public Super {
|
||||
}
|
||||
void write_root_laddr(context_t c, laddr_t addr) override {
|
||||
LOG_PREFIX(OTree::Seastore);
|
||||
SUBDEBUGT(seastore_onode, "update root {:#x} ...", c.t, addr);
|
||||
SUBDEBUGT(seastore_onode, "update root {} ...", c.t, addr);
|
||||
root_addr = addr;
|
||||
tm.write_onode_root(c.t, addr);
|
||||
}
|
||||
@ -102,10 +102,10 @@ class SeastoreNodeExtentManager final: public TransactionManagerHandle {
|
||||
|
||||
read_iertr::future<NodeExtentRef> read_extent(
|
||||
Transaction& t, laddr_t addr) override {
|
||||
SUBTRACET(seastore_onode, "reading at {:#x} ...", t, addr);
|
||||
SUBTRACET(seastore_onode, "reading at {} ...", t, addr);
|
||||
if constexpr (INJECT_EAGAIN) {
|
||||
if (trigger_eagain()) {
|
||||
SUBDEBUGT(seastore_onode, "reading at {:#x}: trigger eagain", t, addr);
|
||||
SUBDEBUGT(seastore_onode, "reading at {}: trigger eagain", t, addr);
|
||||
t.test_set_conflict();
|
||||
return read_iertr::make_ready_future<NodeExtentRef>();
|
||||
}
|
||||
@ -113,7 +113,7 @@ class SeastoreNodeExtentManager final: public TransactionManagerHandle {
|
||||
return tm.read_extent<SeastoreNodeExtent>(t, addr
|
||||
).si_then([addr, &t](auto&& e) -> read_iertr::future<NodeExtentRef> {
|
||||
SUBTRACET(seastore_onode,
|
||||
"read {}B at {:#x} -- {}",
|
||||
"read {}B at {} -- {}",
|
||||
t, e->get_length(), e->get_laddr(), *e);
|
||||
assert(e->get_laddr() == addr);
|
||||
std::ignore = addr;
|
||||
@ -123,7 +123,7 @@ class SeastoreNodeExtentManager final: public TransactionManagerHandle {
|
||||
|
||||
alloc_iertr::future<NodeExtentRef> alloc_extent(
|
||||
Transaction& t, laddr_t hint, extent_len_t len) override {
|
||||
SUBTRACET(seastore_onode, "allocating {}B with hint {:#x} ...", t, len, hint);
|
||||
SUBTRACET(seastore_onode, "allocating {}B with hint {} ...", t, len, hint);
|
||||
if constexpr (INJECT_EAGAIN) {
|
||||
if (trigger_eagain()) {
|
||||
SUBDEBUGT(seastore_onode, "allocating {}B: trigger eagain", t, len);
|
||||
@ -134,7 +134,7 @@ class SeastoreNodeExtentManager final: public TransactionManagerHandle {
|
||||
return tm.alloc_non_data_extent<SeastoreNodeExtent>(t, hint, len
|
||||
).si_then([len, &t](auto extent) {
|
||||
SUBDEBUGT(seastore_onode,
|
||||
"allocated {}B at {:#x} -- {}",
|
||||
"allocated {}B at {} -- {}",
|
||||
t, extent->get_length(), extent->get_laddr(), *extent);
|
||||
if (!extent->is_initial_pending()) {
|
||||
SUBERRORT(seastore_onode,
|
||||
@ -157,12 +157,12 @@ class SeastoreNodeExtentManager final: public TransactionManagerHandle {
|
||||
auto addr = extent->get_laddr();
|
||||
auto len = extent->get_length();
|
||||
SUBDEBUGT(seastore_onode,
|
||||
"retiring {}B at {:#x} -- {} ...",
|
||||
"retiring {}B at {} -- {} ...",
|
||||
t, len, addr, *extent);
|
||||
if constexpr (INJECT_EAGAIN) {
|
||||
if (trigger_eagain()) {
|
||||
SUBDEBUGT(seastore_onode,
|
||||
"retiring {}B at {:#x} -- {} : trigger eagain",
|
||||
"retiring {}B at {} -- {} : trigger eagain",
|
||||
t, len, addr, *extent);
|
||||
t.test_set_conflict();
|
||||
return retire_iertr::now();
|
||||
@ -170,7 +170,7 @@ class SeastoreNodeExtentManager final: public TransactionManagerHandle {
|
||||
}
|
||||
return tm.remove(t, extent).si_then([addr, len, &t] (unsigned cnt) {
|
||||
assert(cnt == 0);
|
||||
SUBTRACET(seastore_onode, "retired {}B at {:#x} ...", t, len, addr);
|
||||
SUBTRACET(seastore_onode, "retired {}B at {} ...", t, len, addr);
|
||||
});
|
||||
}
|
||||
|
||||
@ -185,7 +185,7 @@ class SeastoreNodeExtentManager final: public TransactionManagerHandle {
|
||||
}
|
||||
}
|
||||
return tm.read_onode_root(t).si_then([this, &t, &tracker](auto root_addr) {
|
||||
SUBTRACET(seastore_onode, "got root {:#x}", t, root_addr);
|
||||
SUBTRACET(seastore_onode, "got root {}", t, root_addr);
|
||||
return Super::URef(new SeastoreSuper(t, tracker, root_addr, tm));
|
||||
});
|
||||
}
|
||||
|
@ -374,8 +374,8 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl {
|
||||
size += sizeof(laddr_t);
|
||||
auto value_ptr = node_stage.get_end_p_laddr();
|
||||
int offset = reinterpret_cast<const char*>(value_ptr) - p_start;
|
||||
os << "\n tail value: 0x"
|
||||
<< std::hex << value_ptr->value << std::dec
|
||||
os << "\n tail value: "
|
||||
<< laddr_t(value_ptr->value)
|
||||
<< " " << size << "B"
|
||||
<< " @" << offset << "B";
|
||||
}
|
||||
@ -845,7 +845,7 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl {
|
||||
const search_position_t& pos, laddr_t dst, laddr_t src) override {
|
||||
if constexpr (NODE_TYPE == node_type_t::INTERNAL) {
|
||||
LOG_PREFIX(OTree::Layout::replace_child_addr);
|
||||
SUBDEBUG(seastore_onode, "update from {:#x} to {:#x} at pos({}) ...", src, dst, pos);
|
||||
SUBDEBUG(seastore_onode, "update from {} to {} at pos({}) ...", src, dst, pos);
|
||||
const laddr_packed_t* p_value;
|
||||
if (pos.is_end()) {
|
||||
assert(is_level_tail());
|
||||
@ -924,8 +924,8 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl {
|
||||
// XXX: maybe also include the extent state
|
||||
std::ostringstream sos;
|
||||
sos << "Node" << NODE_TYPE << FIELD_TYPE
|
||||
<< "@0x" << std::hex << extent.get_laddr()
|
||||
<< "+" << extent.get_length() << std::dec
|
||||
<< "@" << extent.get_laddr()
|
||||
<< "+" << std::hex << extent.get_length() << std::dec
|
||||
<< "Lv" << (unsigned)level()
|
||||
<< (is_level_tail() ? "$" : "");
|
||||
name = sos.str();
|
||||
|
@ -44,10 +44,10 @@ inline std::ostream& operator<<(std::ostream &os, const node_type_t& type) {
|
||||
}
|
||||
|
||||
struct laddr_packed_t {
|
||||
laddr_t value;
|
||||
laddr_le_t value;
|
||||
} __attribute__((packed));
|
||||
inline std::ostream& operator<<(std::ostream& os, const laddr_packed_t& laddr) {
|
||||
return os << "laddr_packed(0x" << std::hex << laddr.value << std::dec << ")";
|
||||
return os << "laddr_packed(" << laddr_t(laddr.value) << ")";
|
||||
}
|
||||
|
||||
using match_stat_t = int8_t;
|
||||
|
@ -46,9 +46,9 @@ static laddr_t get_lba_hint(shard_t shard, pool_t pool, crush_hash_t crush) {
|
||||
// FIXME: It is possible that PGs from different pools share the same prefix
|
||||
// if the mask 0xFF is not long enough, result in unexpected transaction
|
||||
// conflicts.
|
||||
return ((uint64_t)(shard & 0XFF)<<56 |
|
||||
(uint64_t)(pool & 0xFF)<<48 |
|
||||
(uint64_t)(crush )<<16);
|
||||
return laddr_t::from_raw_uint((uint64_t)(shard & 0xFF)<<56 |
|
||||
(uint64_t)(pool & 0xFF)<<48 |
|
||||
(uint64_t)(crush )<<16);
|
||||
}
|
||||
|
||||
struct node_offset_packed_t {
|
||||
|
@ -1443,7 +1443,7 @@ struct staged {
|
||||
if constexpr (NODE_TYPE == node_type_t::LEAF) {
|
||||
os << *value_ptr;
|
||||
} else {
|
||||
os << "0x" << std::hex << value_ptr->value << std::dec;
|
||||
os << laddr_t(value_ptr->value);
|
||||
}
|
||||
os << " " << size << "B"
|
||||
<< " @" << offset << "B";
|
||||
|
@ -22,7 +22,7 @@ const laddr_packed_t* internal_sub_items_t::insert_at(
|
||||
|
||||
auto p_insert = const_cast<char*>(p_shift_end) - size;
|
||||
auto item = internal_sub_item_t{
|
||||
snap_gen_t::from_key(key), laddr_packed_t{value}};
|
||||
snap_gen_t::from_key(key), laddr_packed_t{laddr_le_t{value}}};
|
||||
mut.copy_in_absolute(p_insert, item);
|
||||
return &reinterpret_cast<internal_sub_item_t*>(p_insert)->value;
|
||||
}
|
||||
@ -79,7 +79,7 @@ void internal_sub_items_t::Appender<KT>::append(
|
||||
{
|
||||
p_append -= sizeof(internal_sub_item_t);
|
||||
auto item = internal_sub_item_t{
|
||||
snap_gen_t::from_key(key), laddr_packed_t{value}};
|
||||
snap_gen_t::from_key(key), laddr_packed_t{laddr_le_t{value}}};
|
||||
p_mut->copy_in_absolute(p_append, item);
|
||||
p_value = &reinterpret_cast<internal_sub_item_t*>(p_append)->value;
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ void validate_tree_config(const tree_conf_t& conf)
|
||||
#define _STAGE_T(NodeType) node_to_stage_t<typename NodeType::node_stage_t>
|
||||
#define NXT_T(StageType) staged<typename StageType::next_param_t>
|
||||
|
||||
laddr_t i_value{0};
|
||||
laddr_t i_value = L_ADDR_MIN;
|
||||
auto insert_size_2 =
|
||||
_STAGE_T(InternalNode0)::insert_size(key, i_value);
|
||||
auto insert_size_0 =
|
||||
|
@ -141,7 +141,7 @@ class ValueDeltaRecorder {
|
||||
/// Called by DeltaRecorderT to apply user-defined value delta.
|
||||
virtual void apply_value_delta(ceph::bufferlist::const_iterator&,
|
||||
NodeExtentMutable&,
|
||||
laddr_t) = 0;
|
||||
laddr_offset_t) = 0;
|
||||
|
||||
protected:
|
||||
ValueDeltaRecorder(ceph::bufferlist& encoded) : encoded{encoded} {}
|
||||
|
@ -253,6 +253,8 @@ SeaStore::mount_ertr::future<> SeaStore::mount()
|
||||
ceph_assert(seastar::this_shard_id() == primary_core);
|
||||
return device->mount(
|
||||
).safe_then([this] {
|
||||
ceph_assert(device->get_sharded_device().get_block_size()
|
||||
>= laddr_t::UNIT_SIZE);
|
||||
auto &sec_devices = device->get_sharded_device().get_secondary_devices();
|
||||
return crimson::do_for_each(sec_devices, [this](auto& device_entry) {
|
||||
device_id_t id = device_entry.first;
|
||||
@ -266,6 +268,8 @@ SeaStore::mount_ertr::future<> SeaStore::mount()
|
||||
).then([this, magic, sec_dev = std::move(sec_dev)]() mutable {
|
||||
return sec_dev->mount(
|
||||
).safe_then([this, sec_dev=std::move(sec_dev), magic]() mutable {
|
||||
ceph_assert(sec_dev->get_sharded_device().get_block_size()
|
||||
>= laddr_t::UNIT_SIZE);
|
||||
boost::ignore_unused(magic); // avoid clang warning;
|
||||
assert(sec_dev->get_sharded_device().get_magic() == magic);
|
||||
secondaries.emplace_back(std::move(sec_dev));
|
||||
|
@ -92,6 +92,15 @@ std::ostream& operator<<(std::ostream& out, segment_seq_printer_t seq)
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const laddr_t &laddr) {
|
||||
return out << 'L' << std::hex << laddr.value << std::dec;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const laddr_offset_t &laddr_offset) {
|
||||
return out << laddr_offset.get_aligned_laddr()
|
||||
<< "+" << std::hex << laddr_offset.get_offset() << std::dec;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const pladdr_t &pladdr)
|
||||
{
|
||||
if (pladdr.is_laddr()) {
|
||||
|
@ -192,7 +192,7 @@ private:
|
||||
std::ostream &operator<<(std::ostream &out, const segment_id_t&);
|
||||
|
||||
// ondisk type of segment_id_t
|
||||
struct __attribute((packed)) segment_id_le_t {
|
||||
struct __attribute__((packed)) segment_id_le_t {
|
||||
ceph_le32 segment = ceph_le32(segment_id_t().segment);
|
||||
|
||||
segment_id_le_t(const segment_id_t id) :
|
||||
@ -853,7 +853,7 @@ inline paddr_t paddr_t::block_relative_to(paddr_t rhs) const {
|
||||
return as_res_paddr().block_relative_to(rhs.as_res_paddr());
|
||||
}
|
||||
|
||||
struct __attribute((packed)) paddr_le_t {
|
||||
struct __attribute__((packed)) paddr_le_t {
|
||||
ceph_le64 internal_paddr =
|
||||
ceph_le64(P_ADDR_NULL.internal_paddr);
|
||||
|
||||
@ -1006,33 +1006,249 @@ constexpr journal_seq_t JOURNAL_SEQ_MAX{
|
||||
// JOURNAL_SEQ_NULL == JOURNAL_SEQ_MAX == journal_seq_t{}
|
||||
constexpr journal_seq_t JOURNAL_SEQ_NULL = JOURNAL_SEQ_MAX;
|
||||
|
||||
// logical addr, see LBAManager, TransactionManager
|
||||
using laddr_t = uint64_t;
|
||||
constexpr laddr_t L_ADDR_MIN = std::numeric_limits<laddr_t>::min();
|
||||
constexpr laddr_t L_ADDR_MAX = std::numeric_limits<laddr_t>::max();
|
||||
constexpr laddr_t L_ADDR_NULL = L_ADDR_MAX;
|
||||
constexpr laddr_t L_ADDR_ROOT = L_ADDR_MAX - 1;
|
||||
constexpr laddr_t L_ADDR_LBAT = L_ADDR_MAX - 2;
|
||||
// logical offset between two laddr_t
|
||||
using loffset_t = uint64_t;
|
||||
|
||||
struct __attribute((packed)) laddr_le_t {
|
||||
ceph_le64 laddr = ceph_le64(L_ADDR_NULL);
|
||||
// logical offset within an extent
|
||||
using extent_len_t = uint32_t;
|
||||
constexpr extent_len_t EXTENT_LEN_MAX =
|
||||
std::numeric_limits<extent_len_t>::max();
|
||||
|
||||
using extent_len_le_t = ceph_le32;
|
||||
inline extent_len_le_t init_extent_len_le(extent_len_t len) {
|
||||
return ceph_le32(len);
|
||||
}
|
||||
|
||||
// logical addr, see LBAManager, TransactionManager
|
||||
class laddr_t {
|
||||
public:
|
||||
// the type of underlying integer
|
||||
using Unsigned = uint64_t;
|
||||
static constexpr Unsigned RAW_VALUE_MAX =
|
||||
std::numeric_limits<Unsigned>::max();
|
||||
|
||||
constexpr laddr_t() : laddr_t(RAW_VALUE_MAX) {}
|
||||
|
||||
// laddr_t is block aligned, one logical address represents one 4KiB block in disk
|
||||
static constexpr unsigned UNIT_SHIFT = 12;
|
||||
static constexpr unsigned UNIT_SIZE = 1 << UNIT_SHIFT; // 4096
|
||||
static constexpr unsigned UNIT_MASK = UNIT_SIZE - 1;
|
||||
|
||||
static laddr_t from_byte_offset(Unsigned value) {
|
||||
assert((value & UNIT_MASK) == 0);
|
||||
return laddr_t(value >> UNIT_SHIFT);
|
||||
}
|
||||
|
||||
static constexpr laddr_t from_raw_uint(Unsigned v) {
|
||||
return laddr_t(v);
|
||||
}
|
||||
|
||||
/// laddr_t works like primitive integer type, encode/decode it manually
|
||||
void encode(::ceph::buffer::list::contiguous_appender& p) const {
|
||||
p.append(reinterpret_cast<const char *>(&value), sizeof(Unsigned));
|
||||
}
|
||||
void bound_encode(size_t& p) const {
|
||||
p += sizeof(Unsigned);
|
||||
}
|
||||
void decode(::ceph::buffer::ptr::const_iterator& p) {
|
||||
assert(static_cast<std::size_t>(p.get_end() - p.get_pos()) >= sizeof(Unsigned));
|
||||
memcpy((char *)&value, p.get_pos_add(sizeof(Unsigned)), sizeof(Unsigned));
|
||||
}
|
||||
|
||||
// laddr_offset_t contains one base laddr and one block not aligned
|
||||
// offset(< laddr_t::UNIT_SIZE). It is the return type of plus/minus
|
||||
// overloads for laddr_t and loffset_t.
|
||||
struct laddr_offset_t {
|
||||
explicit laddr_offset_t(laddr_t base)
|
||||
: base(base.value), offset(0) {}
|
||||
laddr_offset_t(laddr_t base, extent_len_t offset)
|
||||
: base(base.value), offset(offset) {
|
||||
assert(offset < laddr_t::UNIT_SIZE);
|
||||
}
|
||||
|
||||
laddr_t get_roundup_laddr() const {
|
||||
if (offset == 0) {
|
||||
return laddr_t(base);
|
||||
} else {
|
||||
assert(offset < laddr_t::UNIT_SIZE);
|
||||
return laddr_t(base + 1);
|
||||
}
|
||||
}
|
||||
laddr_t get_aligned_laddr() const { return laddr_t(base); }
|
||||
extent_len_t get_offset() const {
|
||||
assert(offset < laddr_t::UNIT_SIZE);
|
||||
return offset;
|
||||
}
|
||||
laddr_t checked_to_laddr() const {
|
||||
assert(offset == 0);
|
||||
return laddr_t(base);
|
||||
}
|
||||
|
||||
template<std::unsigned_integral U>
|
||||
U get_byte_distance(const laddr_t &l) const {
|
||||
assert(offset < UNIT_SIZE);
|
||||
if (base >= l.value) {
|
||||
Unsigned udiff = base - l.value;
|
||||
assert(udiff <= (std::numeric_limits<U>::max() >> UNIT_SHIFT));
|
||||
return (static_cast<U>(udiff) << UNIT_SHIFT) + offset;
|
||||
} else { // base < l.value
|
||||
Unsigned udiff = l.value - base;
|
||||
assert(udiff <= (std::numeric_limits<U>::max() >> UNIT_SHIFT));
|
||||
return (static_cast<U>(udiff) << UNIT_SHIFT) - offset;
|
||||
}
|
||||
}
|
||||
|
||||
template<std::unsigned_integral U>
|
||||
U get_byte_distance(const laddr_offset_t &l) const {
|
||||
assert(offset < UNIT_SIZE);
|
||||
if (*this >= l) {
|
||||
Unsigned udiff = base - l.base;
|
||||
assert(udiff <= (std::numeric_limits<U>::max() >> UNIT_SHIFT));
|
||||
return ((static_cast<U>(udiff) << UNIT_SHIFT) + offset) - l.offset;
|
||||
} else { // *this < l
|
||||
Unsigned udiff = l.base - base;
|
||||
assert(udiff <= (std::numeric_limits<U>::max() >> UNIT_SHIFT));
|
||||
return ((static_cast<U>(udiff) << UNIT_SHIFT) + l.offset) - offset;
|
||||
}
|
||||
}
|
||||
|
||||
friend bool operator==(const laddr_offset_t&, const laddr_offset_t&) = default;
|
||||
friend auto operator<=>(const laddr_offset_t&, const laddr_offset_t&) = default;
|
||||
friend std::ostream &operator<<(std::ostream&, const laddr_offset_t&);
|
||||
friend laddr_offset_t operator+(const laddr_offset_t &laddr_offset,
|
||||
const loffset_t &offset) {
|
||||
// laddr_offset_t could access (laddr_t + loffset_t) overload.
|
||||
return laddr_offset.get_aligned_laddr()
|
||||
+ (laddr_offset.get_offset() + offset);
|
||||
}
|
||||
friend laddr_offset_t operator+(const loffset_t &offset,
|
||||
const laddr_offset_t &loffset) {
|
||||
return loffset + offset;
|
||||
}
|
||||
|
||||
friend laddr_offset_t operator-(const laddr_offset_t &laddr_offset,
|
||||
const loffset_t &offset) {
|
||||
if (laddr_offset.get_offset() >= offset) {
|
||||
return laddr_offset_t(
|
||||
laddr_offset.get_aligned_laddr(),
|
||||
laddr_offset.get_offset() - offset);
|
||||
} else {
|
||||
// laddr_offset_t could access (laddr_t - loffset_t) overload.
|
||||
return laddr_offset.get_aligned_laddr()
|
||||
- (offset - laddr_offset.get_offset());
|
||||
}
|
||||
}
|
||||
|
||||
friend class laddr_t;
|
||||
private:
|
||||
// use Unsigned here to avoid incomplete type of laddr_t
|
||||
Unsigned base;
|
||||
extent_len_t offset;
|
||||
};
|
||||
|
||||
template<std::unsigned_integral U>
|
||||
U get_byte_distance(const laddr_offset_t &l) const {
|
||||
if (value <= l.base) {
|
||||
Unsigned udiff = l.base - value;
|
||||
assert(udiff <= (std::numeric_limits<U>::max() >> UNIT_SHIFT));
|
||||
return (static_cast<U>(udiff) << UNIT_SHIFT) + l.offset;
|
||||
} else { // value > l.base
|
||||
Unsigned udiff = value - l.base;
|
||||
assert(udiff <= (std::numeric_limits<U>::max() >> UNIT_SHIFT));
|
||||
return (static_cast<U>(udiff) << UNIT_SHIFT) - l.offset;
|
||||
}
|
||||
}
|
||||
|
||||
template<std::unsigned_integral U>
|
||||
U get_byte_distance(const laddr_t &l) const {
|
||||
Unsigned diff = value > l.value
|
||||
? value - l.value
|
||||
: l.value - value;
|
||||
assert(diff <= (std::numeric_limits<U>::max() >> UNIT_SHIFT));
|
||||
return static_cast<U>(diff) << UNIT_SHIFT;
|
||||
}
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &, const laddr_t &);
|
||||
friend bool operator==(const laddr_t&, const laddr_t&) = default;
|
||||
friend bool operator==(const laddr_t &laddr,
|
||||
const laddr_offset_t &laddr_offset) {
|
||||
return laddr == laddr_offset.get_aligned_laddr()
|
||||
&& 0 == laddr_offset.get_offset();
|
||||
}
|
||||
friend bool operator==(const laddr_offset_t &laddr_offset,
|
||||
const laddr_t &laddr) {
|
||||
return laddr_offset.get_aligned_laddr() == laddr
|
||||
&& laddr_offset.get_offset() == 0;
|
||||
}
|
||||
friend auto operator<=>(const laddr_t&, const laddr_t&) = default;
|
||||
friend auto operator<=>(const laddr_t &laddr,
|
||||
const laddr_offset_t &laddr_offset) {
|
||||
return laddr_offset_t(laddr, 0) <=> laddr_offset;
|
||||
}
|
||||
friend auto operator<=>(const laddr_offset_t &laddr_offset,
|
||||
const laddr_t &laddr) {
|
||||
return laddr_offset <=> laddr_offset_t(laddr, 0);
|
||||
}
|
||||
|
||||
friend laddr_offset_t operator+(const laddr_t &laddr,
|
||||
const loffset_t &offset) {
|
||||
auto base = laddr;
|
||||
base.value += offset >> laddr_t::UNIT_SHIFT;
|
||||
assert(base.value >= laddr.value);
|
||||
return laddr_offset_t(base, offset & laddr_t::UNIT_MASK);
|
||||
}
|
||||
friend laddr_offset_t operator+(const loffset_t &offset,
|
||||
const laddr_t &laddr) {
|
||||
return laddr + offset;
|
||||
}
|
||||
|
||||
friend laddr_offset_t operator-(const laddr_t &laddr, loffset_t offset) {
|
||||
auto base = laddr;
|
||||
auto diff = (offset + laddr_t::UNIT_SIZE - 1) >> laddr_t::UNIT_SHIFT;
|
||||
base.value -= diff;
|
||||
assert(base.value <= laddr.value);
|
||||
offset = (diff << laddr_t::UNIT_SHIFT) - offset;
|
||||
return laddr_offset_t(base, offset);
|
||||
}
|
||||
|
||||
friend struct laddr_le_t;
|
||||
friend struct pladdr_le_t;
|
||||
|
||||
private:
|
||||
// Prevent direct construction of laddr_t with an integer,
|
||||
// always use laddr_t::from_raw_uint instead.
|
||||
constexpr explicit laddr_t(Unsigned value) : value(value) {}
|
||||
Unsigned value;
|
||||
};
|
||||
using laddr_offset_t = laddr_t::laddr_offset_t;
|
||||
|
||||
constexpr laddr_t L_ADDR_MAX = laddr_t::from_raw_uint(laddr_t::RAW_VALUE_MAX);
|
||||
constexpr laddr_t L_ADDR_MIN = laddr_t::from_raw_uint(0);
|
||||
constexpr laddr_t L_ADDR_NULL = L_ADDR_MAX;
|
||||
constexpr laddr_t L_ADDR_ROOT = laddr_t::from_raw_uint(laddr_t::RAW_VALUE_MAX - 1);
|
||||
constexpr laddr_t L_ADDR_LBAT = laddr_t::from_raw_uint(laddr_t::RAW_VALUE_MAX - 2);
|
||||
|
||||
struct __attribute__((packed)) laddr_le_t {
|
||||
ceph_le64 laddr;
|
||||
|
||||
using orig_type = laddr_t;
|
||||
|
||||
laddr_le_t() = default;
|
||||
laddr_le_t() : laddr_le_t(L_ADDR_NULL) {}
|
||||
laddr_le_t(const laddr_le_t &) = default;
|
||||
explicit laddr_le_t(const laddr_t &addr)
|
||||
: laddr(ceph_le64(addr)) {}
|
||||
: laddr(addr.value) {}
|
||||
|
||||
operator laddr_t() const {
|
||||
return laddr_t(laddr);
|
||||
}
|
||||
laddr_le_t& operator=(laddr_t addr) {
|
||||
ceph_le64 val;
|
||||
val = addr;
|
||||
val = addr.value;
|
||||
laddr = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const laddr_le_t&) const = default;
|
||||
};
|
||||
|
||||
constexpr uint64_t PL_ADDR_NULL = std::numeric_limits<uint64_t>::max();
|
||||
@ -1087,7 +1303,7 @@ enum class addr_type_t : uint8_t {
|
||||
MAX=2 // or NONE
|
||||
};
|
||||
|
||||
struct __attribute((packed)) pladdr_le_t {
|
||||
struct __attribute__((packed)) pladdr_le_t {
|
||||
ceph_le64 pladdr = ceph_le64(PL_ADDR_NULL);
|
||||
addr_type_t addr_type = addr_type_t::MAX;
|
||||
|
||||
@ -1097,7 +1313,7 @@ struct __attribute((packed)) pladdr_le_t {
|
||||
: pladdr(
|
||||
ceph_le64(
|
||||
addr.is_laddr() ?
|
||||
std::get<0>(addr.pladdr) :
|
||||
std::get<0>(addr.pladdr).value :
|
||||
std::get<1>(addr.pladdr).internal_paddr)),
|
||||
addr_type(
|
||||
addr.is_laddr() ?
|
||||
@ -1132,16 +1348,6 @@ struct min_max_t<paddr_t> {
|
||||
static constexpr paddr_t null = P_ADDR_NULL;
|
||||
};
|
||||
|
||||
// logical offset, see LBAManager, TransactionManager
|
||||
using extent_len_t = uint32_t;
|
||||
constexpr extent_len_t EXTENT_LEN_MAX =
|
||||
std::numeric_limits<extent_len_t>::max();
|
||||
|
||||
using extent_len_le_t = ceph_le32;
|
||||
inline extent_len_le_t init_extent_len_le(extent_len_t len) {
|
||||
return ceph_le32(len);
|
||||
}
|
||||
|
||||
using extent_ref_count_t = uint32_t;
|
||||
constexpr extent_ref_count_t EXTENT_DEFAULT_REF_COUNT = 1;
|
||||
|
||||
@ -2680,6 +2886,7 @@ struct cache_stats_t {
|
||||
|
||||
WRITE_CLASS_DENC_BOUNDED(crimson::os::seastore::seastore_meta_t)
|
||||
WRITE_CLASS_DENC_BOUNDED(crimson::os::seastore::segment_id_t)
|
||||
WRITE_CLASS_DENC_BOUNDED(crimson::os::seastore::laddr_t)
|
||||
WRITE_CLASS_DENC_BOUNDED(crimson::os::seastore::paddr_t)
|
||||
WRITE_CLASS_DENC_BOUNDED(crimson::os::seastore::journal_seq_t)
|
||||
WRITE_CLASS_DENC_BOUNDED(crimson::os::seastore::delta_info_t)
|
||||
@ -2703,6 +2910,8 @@ template <> struct fmt::formatter<crimson::os::seastore::dirty_io_stats_printer_
|
||||
template <> struct fmt::formatter<crimson::os::seastore::extent_types_t> : fmt::ostream_formatter {};
|
||||
template <> struct fmt::formatter<crimson::os::seastore::journal_seq_t> : fmt::ostream_formatter {};
|
||||
template <> struct fmt::formatter<crimson::os::seastore::journal_tail_delta_t> : fmt::ostream_formatter {};
|
||||
template <> struct fmt::formatter<crimson::os::seastore::laddr_t> : fmt::ostream_formatter {};
|
||||
template <> struct fmt::formatter<crimson::os::seastore::laddr_offset_t> : fmt::ostream_formatter {};
|
||||
template <> struct fmt::formatter<crimson::os::seastore::laddr_list_t> : fmt::ostream_formatter {};
|
||||
template <> struct fmt::formatter<crimson::os::seastore::omap_root_t> : fmt::ostream_formatter {};
|
||||
template <> struct fmt::formatter<crimson::os::seastore::paddr_list_t> : fmt::ostream_formatter {};
|
||||
|
@ -585,7 +585,7 @@ TransactionManager::rewrite_logical_extent(
|
||||
if (first_extent) {
|
||||
fut = lba_manager->update_mapping(
|
||||
t,
|
||||
lextent->get_laddr() + off,
|
||||
(lextent->get_laddr() + off).checked_to_laddr(),
|
||||
lextent->get_length(),
|
||||
lextent->get_paddr(),
|
||||
nlextent->get_length(),
|
||||
@ -599,7 +599,7 @@ TransactionManager::rewrite_logical_extent(
|
||||
ceph_assert(refcount != 0);
|
||||
fut = lba_manager->alloc_extent(
|
||||
t,
|
||||
lextent->get_laddr() + off,
|
||||
(lextent->get_laddr() + off).checked_to_laddr(),
|
||||
*nlextent,
|
||||
refcount
|
||||
).si_then([lextent, nlextent, off](auto mapping) {
|
||||
|
@ -348,7 +348,6 @@ public:
|
||||
LOG_PREFIX(TransactionManager::alloc_non_data_extent);
|
||||
SUBTRACET(seastore_tm, "{} len={}, placement_hint={}, laddr_hint={}",
|
||||
t, T::TYPE, len, placement_hint, laddr_hint);
|
||||
ceph_assert(is_aligned(laddr_hint, epm->get_block_size()));
|
||||
auto ext = cache->alloc_new_non_data_extent<T>(
|
||||
t,
|
||||
len,
|
||||
@ -388,7 +387,6 @@ public:
|
||||
LOG_PREFIX(TransactionManager::alloc_data_extents);
|
||||
SUBTRACET(seastore_tm, "{} len={}, placement_hint={}, laddr_hint={}",
|
||||
t, T::TYPE, len, placement_hint, laddr_hint);
|
||||
ceph_assert(is_aligned(laddr_hint, epm->get_block_size()));
|
||||
auto exts = cache->alloc_new_data_extents<T>(
|
||||
t,
|
||||
len,
|
||||
@ -534,7 +532,7 @@ public:
|
||||
for (auto &remap : remaps) {
|
||||
auto remap_offset = remap.offset;
|
||||
auto remap_len = remap.len;
|
||||
auto remap_laddr = original_laddr + remap_offset;
|
||||
auto remap_laddr = (original_laddr + remap_offset).checked_to_laddr();
|
||||
auto remap_paddr = original_paddr.add_offset(remap_offset);
|
||||
ceph_assert(remap_len < original_len);
|
||||
ceph_assert(remap_offset + remap_len <= original_len);
|
||||
@ -582,7 +580,6 @@ public:
|
||||
extent_len_t len) {
|
||||
LOG_PREFIX(TransactionManager::reserve_region);
|
||||
SUBDEBUGT(seastore_tm, "len={}, laddr_hint={}", t, len, hint);
|
||||
ceph_assert(is_aligned(hint, epm->get_block_size()));
|
||||
return lba_manager->reserve_region(
|
||||
t,
|
||||
hint,
|
||||
@ -615,7 +612,6 @@ public:
|
||||
LOG_PREFIX(TransactionManager::clone_pin);
|
||||
SUBDEBUGT(seastore_tm, "len={}, laddr_hint={}, clone_offset {}",
|
||||
t, mapping.get_length(), hint, intermediate_key);
|
||||
ceph_assert(is_aligned(hint, epm->get_block_size()));
|
||||
return lba_manager->clone_mapping(
|
||||
t,
|
||||
hint,
|
||||
|
@ -27,20 +27,20 @@ seastar::future<> TMDriver::write(
|
||||
"write",
|
||||
[this, offset, &ptr](auto& t)
|
||||
{
|
||||
return tm->remove(t, offset
|
||||
return tm->remove(t, laddr_t::from_byte_offset(offset)
|
||||
).discard_result().handle_error_interruptible(
|
||||
crimson::ct_error::enoent::handle([](auto) { return seastar::now(); }),
|
||||
crimson::ct_error::pass_further_all{}
|
||||
).si_then([this, offset, &t, &ptr] {
|
||||
logger().debug("dec_ref complete");
|
||||
return tm->alloc_data_extents<TestBlock>(t, offset, ptr.length());
|
||||
return tm->alloc_data_extents<TestBlock>(t, laddr_t::from_byte_offset(offset), ptr.length());
|
||||
}).si_then([this, offset, &t, &ptr](auto extents) mutable {
|
||||
boost::ignore_unused(offset); // avoid clang warning;
|
||||
auto off = offset;
|
||||
auto left = ptr.length();
|
||||
size_t written = 0;
|
||||
for (auto &ext : extents) {
|
||||
assert(ext->get_laddr() == (size_t)off);
|
||||
assert(ext->get_laddr() == laddr_t::from_byte_offset(off));
|
||||
assert(ext->get_bptr().length() <= left);
|
||||
ptr.copy_out(written, ext->get_length(), ext->get_bptr().c_str());
|
||||
off += ext->get_length();
|
||||
@ -111,17 +111,17 @@ seastar::future<bufferlist> TMDriver::read(
|
||||
"read",
|
||||
[=, &blret, this](auto& t)
|
||||
{
|
||||
return read_extents(t, offset, size
|
||||
return read_extents(t, laddr_t::from_byte_offset(offset), size
|
||||
).si_then([=, &blret](auto ext_list) {
|
||||
size_t cur = offset;
|
||||
auto cur = laddr_t::from_byte_offset(offset);
|
||||
for (auto &i: ext_list) {
|
||||
if (cur != i.first) {
|
||||
assert(cur < i.first);
|
||||
blret.append_zero(i.first - cur);
|
||||
blret.append_zero(i.first.template get_byte_distance<size_t>(cur));
|
||||
cur = i.first;
|
||||
}
|
||||
blret.append(i.second->get_bptr());
|
||||
cur += i.second->get_bptr().length();
|
||||
cur = (cur + i.second->get_bptr().length()).checked_to_laddr();
|
||||
}
|
||||
if (blret.length() != size) {
|
||||
assert(blret.length() < size);
|
||||
|
@ -32,7 +32,7 @@ struct onode_item_t {
|
||||
void initialize(Transaction& t, Onode& value) const {
|
||||
auto &ftvalue = static_cast<FLTreeOnode&>(value);
|
||||
ftvalue.update_onode_size(t, size);
|
||||
auto oroot = omap_root_t(id, cnt_modify,
|
||||
auto oroot = omap_root_t(laddr_t::from_raw_uint(id), cnt_modify,
|
||||
value.get_metadata_hint(block_size));
|
||||
ftvalue.update_omap_root(t, oroot);
|
||||
validate(value);
|
||||
@ -40,8 +40,8 @@ struct onode_item_t {
|
||||
|
||||
void validate(Onode& value) const {
|
||||
auto& layout = value.get_layout();
|
||||
ceph_assert(laddr_t(layout.size) == laddr_t{size});
|
||||
ceph_assert(layout.omap_root.get(value.get_metadata_hint(block_size)).addr == id);
|
||||
ceph_assert(uint64_t(layout.size) == uint64_t{size});
|
||||
ceph_assert(layout.omap_root.get(value.get_metadata_hint(block_size)).addr == laddr_t::from_raw_uint(id));
|
||||
ceph_assert(layout.omap_root.get(value.get_metadata_hint(block_size)).depth == cnt_modify);
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ TEST_F(a_basic_test_t, 1_basic_sizes)
|
||||
value.payload_size = 8;
|
||||
#define _STAGE_T(NodeType) node_to_stage_t<typename NodeType::node_stage_t>
|
||||
#define NXT_T(StageType) staged<typename StageType::next_param_t>
|
||||
laddr_t i_value{0};
|
||||
laddr_t i_value = L_ADDR_MIN;
|
||||
logger().info("\n"
|
||||
"Bytes of a key-value insertion (full-string):\n"
|
||||
" s-p-c, 'n'-'o', s-g => value_payload(8): typically internal 43B, leaf 59B\n"
|
||||
@ -1047,8 +1047,8 @@ class DummyChildPool {
|
||||
|
||||
static Ref<DummyChild> create_new(
|
||||
const std::set<ghobject_t>& keys, bool is_level_tail, DummyChildPool& pool) {
|
||||
static laddr_t seed = 0;
|
||||
return create(keys, is_level_tail, seed++, pool);
|
||||
static uint64_t seed = 0;
|
||||
return create(keys, is_level_tail, laddr_t::from_raw_uint(seed++), pool);
|
||||
}
|
||||
|
||||
static eagain_ifuture<Ref<DummyChild>> create_initial(
|
||||
|
@ -137,7 +137,7 @@ class TestValue final : public Value {
|
||||
|
||||
void apply_value_delta(ceph::bufferlist::const_iterator& delta,
|
||||
NodeExtentMutable& payload_mut,
|
||||
laddr_t value_addr) override {
|
||||
laddr_offset_t value_addr_offset) override {
|
||||
delta_op_t op;
|
||||
try {
|
||||
ceph::decode(op, delta);
|
||||
@ -159,13 +159,13 @@ class TestValue final : public Value {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
logger().error("OTree::TestValue::Replay: got unknown op {} when replay {:#x}+{:#x}",
|
||||
op, value_addr, payload_mut.get_length());
|
||||
logger().error("OTree::TestValue::Replay: got unknown op {} when replay {}~{:#x}",
|
||||
op, value_addr_offset, payload_mut.get_length());
|
||||
ceph_abort();
|
||||
}
|
||||
} catch (buffer::error& e) {
|
||||
logger().error("OTree::TestValue::Replay: got decode error {} when replay {:#x}+{:#x}",
|
||||
e.what(), value_addr, payload_mut.get_length());
|
||||
logger().error("OTree::TestValue::Replay: got decode error {} when replay {}~{:#x}",
|
||||
e.what(), value_addr_offset, payload_mut.get_length());
|
||||
ceph_abort();
|
||||
}
|
||||
}
|
||||
|
@ -378,14 +378,14 @@ TEST_F(lba_btree_test, basic)
|
||||
run_async([this] {
|
||||
constexpr unsigned total = 16<<10;
|
||||
for (unsigned i = 0; i < total; i += 16) {
|
||||
insert(i, 8);
|
||||
insert(laddr_t::from_raw_uint(i), 8);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < total; i += 16) {
|
||||
check_lower_bound(i);
|
||||
check_lower_bound(i + 4);
|
||||
check_lower_bound(i + 8);
|
||||
check_lower_bound(i + 12);
|
||||
check_lower_bound(laddr_t::from_raw_uint(i));
|
||||
check_lower_bound(laddr_t::from_raw_uint(i + 4));
|
||||
check_lower_bound(laddr_t::from_raw_uint(i + 8));
|
||||
check_lower_bound(laddr_t::from_raw_uint(i + 12));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -500,7 +500,7 @@ struct btree_lba_manager_test : btree_test_base {
|
||||
bottom->first + bottom->second.len <= addr)
|
||||
++bottom;
|
||||
|
||||
auto top = t.mappings.lower_bound(addr + len);
|
||||
auto top = t.mappings.lower_bound((addr + len).checked_to_laddr());
|
||||
return std::make_pair(
|
||||
bottom,
|
||||
top
|
||||
@ -665,7 +665,7 @@ struct btree_lba_manager_test : btree_test_base {
|
||||
[=, &t, this](auto &) {
|
||||
return lba_manager->scan_mappings(
|
||||
*t.t,
|
||||
0,
|
||||
L_ADDR_MIN,
|
||||
L_ADDR_MAX,
|
||||
[iter=t.mappings.begin(), &t](auto l, auto p, auto len) mutable {
|
||||
EXPECT_NE(iter, t.mappings.end());
|
||||
@ -681,7 +681,7 @@ struct btree_lba_manager_test : btree_test_base {
|
||||
TEST_F(btree_lba_manager_test, basic)
|
||||
{
|
||||
run_async([this] {
|
||||
laddr_t laddr = 0x12345678 * block_size;
|
||||
laddr_t laddr = laddr_t::from_byte_offset(0x12345678 * block_size);
|
||||
{
|
||||
// write initial mapping
|
||||
auto t = create_transaction();
|
||||
@ -701,7 +701,7 @@ TEST_F(btree_lba_manager_test, force_split)
|
||||
auto t = create_transaction();
|
||||
logger().debug("opened transaction");
|
||||
for (unsigned j = 0; j < 5; ++j) {
|
||||
alloc_mappings(t, 0, block_size);
|
||||
alloc_mappings(t, L_ADDR_MIN, block_size);
|
||||
if ((i % 10 == 0) && (j == 3)) {
|
||||
check_mappings(t);
|
||||
check_mappings();
|
||||
@ -721,7 +721,7 @@ TEST_F(btree_lba_manager_test, force_split_merge)
|
||||
auto t = create_transaction();
|
||||
logger().debug("opened transaction");
|
||||
for (unsigned j = 0; j < 5; ++j) {
|
||||
auto rets = alloc_mappings(t, 0, block_size);
|
||||
auto rets = alloc_mappings(t, L_ADDR_MIN, block_size);
|
||||
// just to speed things up a bit
|
||||
if ((i % 100 == 0) && (j == 3)) {
|
||||
check_mappings(t);
|
||||
@ -780,7 +780,7 @@ TEST_F(btree_lba_manager_test, single_transaction_split_merge)
|
||||
{
|
||||
auto t = create_transaction();
|
||||
for (unsigned i = 0; i < 400; ++i) {
|
||||
alloc_mappings(t, 0, block_size);
|
||||
alloc_mappings(t, L_ADDR_MIN, block_size);
|
||||
}
|
||||
check_mappings(t);
|
||||
submit_test_transaction(std::move(t));
|
||||
@ -803,7 +803,7 @@ TEST_F(btree_lba_manager_test, single_transaction_split_merge)
|
||||
{
|
||||
auto t = create_transaction();
|
||||
for (unsigned i = 0; i < 600; ++i) {
|
||||
alloc_mappings(t, 0, block_size);
|
||||
alloc_mappings(t, L_ADDR_MIN, block_size);
|
||||
}
|
||||
auto addresses = get_mapped_addresses(t);
|
||||
for (unsigned i = 0; i != addresses.size(); ++i) {
|
||||
@ -831,23 +831,23 @@ TEST_F(btree_lba_manager_test, split_merge_multi)
|
||||
}
|
||||
};
|
||||
iterate([&](auto &t, auto idx) {
|
||||
alloc_mappings(t, idx * block_size, block_size);
|
||||
alloc_mappings(t, laddr_t::from_byte_offset(idx * block_size), block_size);
|
||||
});
|
||||
check_mappings();
|
||||
iterate([&](auto &t, auto idx) {
|
||||
if ((idx % 32) > 0) {
|
||||
decref_mapping(t, idx * block_size);
|
||||
decref_mapping(t, laddr_t::from_byte_offset(idx * block_size));
|
||||
}
|
||||
});
|
||||
check_mappings();
|
||||
iterate([&](auto &t, auto idx) {
|
||||
if ((idx % 32) > 0) {
|
||||
alloc_mappings(t, idx * block_size, block_size);
|
||||
alloc_mappings(t, laddr_t::from_byte_offset(idx * block_size), block_size);
|
||||
}
|
||||
});
|
||||
check_mappings();
|
||||
iterate([&](auto &t, auto idx) {
|
||||
decref_mapping(t, idx * block_size);
|
||||
decref_mapping(t, laddr_t::from_byte_offset(idx * block_size));
|
||||
});
|
||||
check_mappings();
|
||||
});
|
||||
|
@ -218,14 +218,14 @@ struct object_data_handler_test_t:
|
||||
objaddr_t offset,
|
||||
extent_len_t length) {
|
||||
auto ret = with_trans_intr(t, [&](auto &t) {
|
||||
return tm->get_pins(t, offset, length);
|
||||
return tm->get_pins(t, laddr_t::from_byte_offset(offset), length);
|
||||
}).unsafe_get();
|
||||
return ret;
|
||||
}
|
||||
std::list<LBAMappingRef> get_mappings(objaddr_t offset, extent_len_t length) {
|
||||
auto t = create_mutate_transaction();
|
||||
auto ret = with_trans_intr(*t, [&](auto &t) {
|
||||
return tm->get_pins(t, offset, length);
|
||||
return tm->get_pins(t, laddr_t::from_byte_offset(offset), length);
|
||||
}).unsafe_get();
|
||||
return ret;
|
||||
}
|
||||
@ -297,7 +297,7 @@ struct object_data_handler_test_t:
|
||||
"seastore_max_data_allocation_size", "8192").get();
|
||||
}
|
||||
|
||||
laddr_t get_random_laddr(size_t block_size, laddr_t limit) {
|
||||
objaddr_t get_random_write_offset(size_t block_size, objaddr_t limit) {
|
||||
return block_size *
|
||||
std::uniform_int_distribution<>(0, (limit / block_size) - 1)(gen);
|
||||
}
|
||||
@ -632,7 +632,7 @@ TEST_P(object_data_handler_test_t, remap_left) {
|
||||
auto base = pins.front()->get_key();
|
||||
int i = 0;
|
||||
for (auto &pin : pins) {
|
||||
EXPECT_EQ(pin->get_key() - base, res[i]);
|
||||
EXPECT_EQ(pin->get_key().get_byte_distance<size_t>(base), res[i]);
|
||||
i++;
|
||||
}
|
||||
read(0, 128<<10);
|
||||
@ -666,7 +666,7 @@ TEST_P(object_data_handler_test_t, remap_right) {
|
||||
auto base = pins.front()->get_key();
|
||||
int i = 0;
|
||||
for (auto &pin : pins) {
|
||||
EXPECT_EQ(pin->get_key() - base, res[i]);
|
||||
EXPECT_EQ(pin->get_key().get_byte_distance<size_t>(base), res[i]);
|
||||
i++;
|
||||
}
|
||||
read(0, 128<<10);
|
||||
@ -699,7 +699,7 @@ TEST_P(object_data_handler_test_t, remap_right_left) {
|
||||
auto base = pins.front()->get_key();
|
||||
int i = 0;
|
||||
for (auto &pin : pins) {
|
||||
EXPECT_EQ(pin->get_key() - base, res[i]);
|
||||
EXPECT_EQ(pin->get_key().get_byte_distance<size_t>(base), res[i]);
|
||||
i++;
|
||||
}
|
||||
enable_max_extent_size();
|
||||
@ -730,7 +730,7 @@ TEST_P(object_data_handler_test_t, multiple_remap) {
|
||||
auto base = pins.front()->get_key();
|
||||
int i = 0;
|
||||
for (auto &pin : pins) {
|
||||
EXPECT_EQ(pin->get_key() - base, res[i]);
|
||||
EXPECT_EQ(pin->get_key().get_byte_distance<size_t>(base), res[i]);
|
||||
i++;
|
||||
}
|
||||
read(0, 128<<10);
|
||||
@ -769,7 +769,7 @@ TEST_P(object_data_handler_test_t, random_overwrite) {
|
||||
for (unsigned j = 0; j < 100; ++j) {
|
||||
auto t = create_mutate_transaction();
|
||||
for (unsigned k = 0; k < 2; ++k) {
|
||||
write(*t, get_random_laddr(BSIZE, TOTAL), wsize,
|
||||
write(*t, get_random_write_offset(BSIZE, TOTAL), wsize,
|
||||
(char)((j*k) % std::numeric_limits<char>::max()));
|
||||
}
|
||||
submit_transaction(std::move(t));
|
||||
@ -798,7 +798,7 @@ TEST_P(object_data_handler_test_t, overwrite_then_read_within_transaction) {
|
||||
auto pins = get_mappings(*t, base, len);
|
||||
assert(pins.size() == 1);
|
||||
auto pin1 = remap_pin(*t, std::move(pins.front()), 4096, 8192);
|
||||
auto ext = get_extent(*t, base + 4096, 4096 * 2);
|
||||
auto ext = get_extent(*t, laddr_t::from_byte_offset(base + 4096), 4096 * 2);
|
||||
ASSERT_TRUE(ext->is_exist_clean());
|
||||
write(*t, base + 4096, 4096, 'y');
|
||||
ASSERT_TRUE(ext->is_exist_mutation_pending());
|
||||
|
@ -66,9 +66,9 @@ struct transaction_manager_test_t :
|
||||
: TMTestState(num_main_devices, num_cold_devices), gen(rd()) {
|
||||
}
|
||||
|
||||
laddr_t get_random_laddr(size_t block_size, laddr_t limit) {
|
||||
return block_size *
|
||||
std::uniform_int_distribution<>(0, (limit / block_size) - 1)(gen);
|
||||
laddr_t get_random_laddr(size_t block_size, size_t limit) {
|
||||
return laddr_t::from_byte_offset(block_size *
|
||||
std::uniform_int_distribution<>(0, (limit / block_size) - 1)(gen));
|
||||
}
|
||||
|
||||
char get_random_contents() {
|
||||
@ -254,8 +254,8 @@ struct transaction_manager_test_t :
|
||||
EXPECT_EQ(addr, last);
|
||||
break;
|
||||
}
|
||||
EXPECT_FALSE(iter->first - last > len);
|
||||
last = iter->first + iter->second.desc.len;
|
||||
EXPECT_FALSE(iter->first.get_byte_distance<extent_len_t>(last) > len);
|
||||
last = (iter->first + iter->second.desc.len).checked_to_laddr();
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
@ -719,7 +719,7 @@ struct transaction_manager_test_t :
|
||||
[this, &overlay](auto &t) {
|
||||
return lba_manager->scan_mappings(
|
||||
t,
|
||||
0,
|
||||
L_ADDR_MIN,
|
||||
L_ADDR_MAX,
|
||||
[iter=overlay.begin(), &overlay](auto l, auto p, auto len) mutable {
|
||||
EXPECT_NE(iter, overlay.end());
|
||||
@ -830,9 +830,9 @@ struct transaction_manager_test_t :
|
||||
auto t = create_transaction();
|
||||
auto extent = alloc_extent(
|
||||
t,
|
||||
i * BSIZE,
|
||||
laddr_t::from_byte_offset(i * BSIZE),
|
||||
BSIZE);
|
||||
ASSERT_EQ(i * BSIZE, extent->get_laddr());
|
||||
ASSERT_EQ(laddr_t::from_byte_offset(i * BSIZE), extent->get_laddr());
|
||||
submit_transaction(std::move(t));
|
||||
}
|
||||
|
||||
@ -844,7 +844,7 @@ struct transaction_manager_test_t :
|
||||
boost::make_counting_iterator(0lu),
|
||||
boost::make_counting_iterator(BLOCKS),
|
||||
[this, &t](auto i) {
|
||||
return tm->read_extent<TestBlock>(t, i * BSIZE, BSIZE
|
||||
return tm->read_extent<TestBlock>(t, laddr_t::from_byte_offset(i * BSIZE), BSIZE
|
||||
).si_then([](auto) {
|
||||
return seastar::now();
|
||||
});
|
||||
@ -870,9 +870,9 @@ struct transaction_manager_test_t :
|
||||
auto t = create_transaction();
|
||||
auto extent = alloc_extent(
|
||||
t,
|
||||
i * BSIZE,
|
||||
laddr_t::from_byte_offset(i * BSIZE),
|
||||
BSIZE);
|
||||
ASSERT_EQ(i * BSIZE, extent->get_laddr());
|
||||
ASSERT_EQ(laddr_t::from_byte_offset(i * BSIZE), extent->get_laddr());
|
||||
if (try_submit_transaction(std::move(t)))
|
||||
break;
|
||||
}
|
||||
@ -1180,7 +1180,7 @@ struct transaction_manager_test_t :
|
||||
o_len - new_offset - new_len)
|
||||
}
|
||||
).si_then([this, new_offset, new_len, o_laddr, &t, &bl](auto ret) {
|
||||
return tm->alloc_data_extents<TestBlock>(t, o_laddr + new_offset, new_len
|
||||
return tm->alloc_data_extents<TestBlock>(t, (o_laddr + new_offset).checked_to_laddr(), new_len
|
||||
).si_then([this, ret = std::move(ret), new_len,
|
||||
new_offset, o_laddr, &t, &bl](auto extents) mutable {
|
||||
assert(extents.size() == 1);
|
||||
@ -1188,7 +1188,7 @@ struct transaction_manager_test_t :
|
||||
ceph_assert(ret.size() == 2);
|
||||
auto iter = bl.cbegin();
|
||||
iter.copy(new_len, ext->get_bptr().c_str());
|
||||
auto r_laddr = o_laddr + new_offset + new_len;
|
||||
auto r_laddr = (o_laddr + new_offset + new_len).checked_to_laddr();
|
||||
// old pins expired after alloc new extent, need to get it.
|
||||
return tm->get_pin(t, o_laddr
|
||||
).si_then([this, &t, ext = std::move(ext), r_laddr](auto lpin) mutable {
|
||||
@ -1216,7 +1216,7 @@ struct transaction_manager_test_t :
|
||||
o_len - new_offset - new_len)
|
||||
}
|
||||
).si_then([this, new_offset, new_len, o_laddr, &t, &bl](auto ret) {
|
||||
return tm->alloc_data_extents<TestBlock>(t, o_laddr + new_offset, new_len
|
||||
return tm->alloc_data_extents<TestBlock>(t, (o_laddr + new_offset).checked_to_laddr(), new_len
|
||||
).si_then([this, ret = std::move(ret), new_offset, new_len,
|
||||
o_laddr, &t, &bl](auto extents) mutable {
|
||||
assert(extents.size() == 1);
|
||||
@ -1224,7 +1224,7 @@ struct transaction_manager_test_t :
|
||||
ceph_assert(ret.size() == 1);
|
||||
auto iter = bl.cbegin();
|
||||
iter.copy(new_len, ext->get_bptr().c_str());
|
||||
auto r_laddr = o_laddr + new_offset + new_len;
|
||||
auto r_laddr = (o_laddr + new_offset + new_len).checked_to_laddr();
|
||||
return tm->get_pin(t, r_laddr
|
||||
).si_then([ext = std::move(ext)](auto rpin) mutable {
|
||||
return _overwrite_pin_iertr::make_ready_future<
|
||||
@ -1247,7 +1247,7 @@ struct transaction_manager_test_t :
|
||||
new_offset)
|
||||
}
|
||||
).si_then([this, new_offset, new_len, o_laddr, &t, &bl](auto ret) {
|
||||
return tm->alloc_data_extents<TestBlock>(t, o_laddr + new_offset, new_len
|
||||
return tm->alloc_data_extents<TestBlock>(t, (o_laddr + new_offset).checked_to_laddr(), new_len
|
||||
).si_then([this, ret = std::move(ret), new_len, o_laddr, &t, &bl]
|
||||
(auto extents) mutable {
|
||||
assert(extents.size() == 1);
|
||||
@ -1346,10 +1346,10 @@ struct transaction_manager_test_t :
|
||||
void test_remap_pin() {
|
||||
run_async([this] {
|
||||
disable_max_extent_size();
|
||||
constexpr size_t l_offset = 32 << 10;
|
||||
constexpr size_t l_len = 32 << 10;
|
||||
constexpr size_t r_offset = 64 << 10;
|
||||
constexpr size_t r_len = 32 << 10;
|
||||
laddr_t l_offset = laddr_t::from_byte_offset(32 << 10);
|
||||
size_t l_len = 32 << 10;
|
||||
laddr_t r_offset = laddr_t::from_byte_offset(64 << 10);
|
||||
size_t r_len = 32 << 10;
|
||||
{
|
||||
auto t = create_transaction();
|
||||
auto lext = alloc_extent(t, l_offset, l_len);
|
||||
@ -1400,12 +1400,12 @@ struct transaction_manager_test_t :
|
||||
void test_clone_and_remap_pin() {
|
||||
run_async([this] {
|
||||
disable_max_extent_size();
|
||||
constexpr size_t l_offset = 32 << 10;
|
||||
constexpr size_t l_len = 32 << 10;
|
||||
constexpr size_t r_offset = 64 << 10;
|
||||
constexpr size_t r_len = 32 << 10;
|
||||
constexpr size_t l_clone_offset = 96 << 10;
|
||||
constexpr size_t r_clone_offset = 128 << 10;
|
||||
laddr_t l_offset = laddr_t::from_byte_offset(32 << 10);
|
||||
size_t l_len = 32 << 10;
|
||||
laddr_t r_offset = laddr_t::from_byte_offset(64 << 10);
|
||||
size_t r_len = 32 << 10;
|
||||
laddr_t l_clone_offset = laddr_t::from_byte_offset(96 << 10);
|
||||
laddr_t r_clone_offset = laddr_t::from_byte_offset(128 << 10);
|
||||
{
|
||||
auto t = create_transaction();
|
||||
auto lext = alloc_extent(t, l_offset, l_len);
|
||||
@ -1455,12 +1455,12 @@ struct transaction_manager_test_t :
|
||||
void test_overwrite_pin() {
|
||||
run_async([this] {
|
||||
disable_max_extent_size();
|
||||
constexpr size_t m_offset = 8 << 10;
|
||||
constexpr size_t m_len = 56 << 10;
|
||||
constexpr size_t l_offset = 64 << 10;
|
||||
constexpr size_t l_len = 64 << 10;
|
||||
constexpr size_t r_offset = 128 << 10;
|
||||
constexpr size_t r_len = 64 << 10;
|
||||
laddr_t m_offset = laddr_t::from_byte_offset(8 << 10);
|
||||
size_t m_len = 56 << 10;
|
||||
laddr_t l_offset = laddr_t::from_byte_offset(64 << 10);
|
||||
size_t l_len = 64 << 10;
|
||||
laddr_t r_offset = laddr_t::from_byte_offset(128 << 10);
|
||||
size_t r_len = 64 << 10;
|
||||
{
|
||||
auto t = create_transaction();
|
||||
auto m_ext = alloc_extent(t, m_offset, m_len);
|
||||
@ -1538,7 +1538,7 @@ struct transaction_manager_test_t :
|
||||
run_async([this] {
|
||||
disable_max_extent_size();
|
||||
constexpr unsigned REMAP_NUM = 32;
|
||||
constexpr size_t offset = 0;
|
||||
constexpr laddr_t offset = L_ADDR_MIN;
|
||||
constexpr size_t length = 256 << 10;
|
||||
{
|
||||
auto t = create_transaction();
|
||||
@ -1575,7 +1575,8 @@ struct transaction_manager_test_t :
|
||||
if (off == 0 || off >= 255) {
|
||||
continue;
|
||||
}
|
||||
auto new_off = (off << 10) - last_pin->get_key();
|
||||
auto new_off = laddr_t::from_byte_offset(off << 10)
|
||||
.get_byte_distance<extent_len_t>(last_pin->get_key());
|
||||
auto new_len = last_pin->get_length() - new_off;
|
||||
//always remap right extent at new split_point
|
||||
auto pin = remap_pin(t, std::move(last_pin), new_off, new_len);
|
||||
@ -1620,7 +1621,7 @@ struct transaction_manager_test_t :
|
||||
run_async([this] {
|
||||
disable_max_extent_size();
|
||||
constexpr unsigned REMAP_NUM = 32;
|
||||
constexpr size_t offset = 0;
|
||||
constexpr laddr_t offset = L_ADDR_MIN;
|
||||
constexpr size_t length = 256 << 10;
|
||||
{
|
||||
auto t = create_transaction();
|
||||
@ -1665,7 +1666,7 @@ struct transaction_manager_test_t :
|
||||
auto end_off = split_points.front();
|
||||
split_points.pop_front();
|
||||
ASSERT_TRUE(start_off <= end_off);
|
||||
if (((end_off << 10) == pin0->get_key() + pin0->get_length())
|
||||
if ((laddr_t::from_byte_offset(end_off << 10) == pin0->get_key() + pin0->get_length())
|
||||
|| (start_off == end_off)) {
|
||||
if (split_points.empty() && empty_transaction) {
|
||||
early_exit++;
|
||||
@ -1674,7 +1675,8 @@ struct transaction_manager_test_t :
|
||||
continue;
|
||||
}
|
||||
empty_transaction = false;
|
||||
auto new_off = (start_off << 10) - last_rpin->get_key();
|
||||
auto new_off = laddr_t::from_byte_offset(start_off << 10)
|
||||
.get_byte_distance<extent_len_t>(last_rpin->get_key());
|
||||
auto new_len = (end_off - start_off) << 10;
|
||||
bufferlist bl;
|
||||
bl.append(ceph::bufferptr(ceph::buffer::create(new_len, 0)));
|
||||
@ -1766,13 +1768,13 @@ struct tm_random_block_device_test_t :
|
||||
TEST_P(tm_random_block_device_test_t, scatter_allocation)
|
||||
{
|
||||
run_async([this] {
|
||||
constexpr laddr_t ADDR = 0xFF * 4096;
|
||||
laddr_t ADDR = laddr_t::from_byte_offset(0xFF * 4096);
|
||||
epm->prefill_fragmented_devices();
|
||||
auto t = create_transaction();
|
||||
for (int i = 0; i < 1991; i++) {
|
||||
auto extents = alloc_extents(t, ADDR + i * 16384, 16384, 'a');
|
||||
auto extents = alloc_extents(t, (ADDR + i * 16384).checked_to_laddr(), 16384, 'a');
|
||||
}
|
||||
alloc_extents_deemed_fail(t, ADDR + 1991 * 16384, 16384, 'a');
|
||||
alloc_extents_deemed_fail(t, (ADDR + 1991 * 16384).checked_to_laddr(), 16384, 'a');
|
||||
check_mappings(t);
|
||||
check();
|
||||
submit_transaction(std::move(t));
|
||||
@ -1782,9 +1784,9 @@ TEST_P(tm_random_block_device_test_t, scatter_allocation)
|
||||
|
||||
TEST_P(tm_single_device_test_t, basic)
|
||||
{
|
||||
constexpr laddr_t SIZE = 4096;
|
||||
constexpr size_t SIZE = 4096;
|
||||
run_async([this] {
|
||||
constexpr laddr_t ADDR = 0xFF * SIZE;
|
||||
laddr_t ADDR = laddr_t::from_byte_offset(0xFF * SIZE);
|
||||
{
|
||||
auto t = create_transaction();
|
||||
auto extent = alloc_extent(
|
||||
@ -1803,9 +1805,9 @@ TEST_P(tm_single_device_test_t, basic)
|
||||
|
||||
TEST_P(tm_single_device_test_t, mutate)
|
||||
{
|
||||
constexpr laddr_t SIZE = 4096;
|
||||
constexpr size_t SIZE = 4096;
|
||||
run_async([this] {
|
||||
constexpr laddr_t ADDR = 0xFF * SIZE;
|
||||
laddr_t ADDR = laddr_t::from_byte_offset(0xFF * SIZE);
|
||||
{
|
||||
auto t = create_transaction();
|
||||
auto extent = alloc_extent(
|
||||
@ -1841,10 +1843,10 @@ TEST_P(tm_single_device_test_t, mutate)
|
||||
|
||||
TEST_P(tm_single_device_test_t, allocate_lba_conflict)
|
||||
{
|
||||
constexpr laddr_t SIZE = 4096;
|
||||
constexpr size_t SIZE = 4096;
|
||||
run_async([this] {
|
||||
constexpr laddr_t ADDR = 0xFF * SIZE;
|
||||
constexpr laddr_t ADDR2 = 0xFE * SIZE;
|
||||
laddr_t ADDR = laddr_t::from_byte_offset(0xFF * SIZE);
|
||||
laddr_t ADDR2 = laddr_t::from_byte_offset(0xFE * SIZE);
|
||||
auto t = create_transaction();
|
||||
auto t2 = create_transaction();
|
||||
|
||||
@ -1874,14 +1876,14 @@ TEST_P(tm_single_device_test_t, allocate_lba_conflict)
|
||||
|
||||
TEST_P(tm_single_device_test_t, mutate_lba_conflict)
|
||||
{
|
||||
constexpr laddr_t SIZE = 4096;
|
||||
constexpr size_t SIZE = 4096;
|
||||
run_async([this] {
|
||||
{
|
||||
auto t = create_transaction();
|
||||
for (unsigned i = 0; i < 300; ++i) {
|
||||
auto extent = alloc_extent(
|
||||
t,
|
||||
laddr_t(i * SIZE),
|
||||
laddr_t::from_byte_offset(i * SIZE),
|
||||
SIZE);
|
||||
}
|
||||
check_mappings(t);
|
||||
@ -1889,7 +1891,7 @@ TEST_P(tm_single_device_test_t, mutate_lba_conflict)
|
||||
check();
|
||||
}
|
||||
|
||||
constexpr laddr_t ADDR = 150 * SIZE;
|
||||
laddr_t ADDR = laddr_t::from_byte_offset(150 * SIZE);
|
||||
{
|
||||
auto t = create_transaction();
|
||||
auto t2 = create_transaction();
|
||||
@ -1913,17 +1915,17 @@ TEST_P(tm_single_device_test_t, mutate_lba_conflict)
|
||||
|
||||
TEST_P(tm_single_device_test_t, concurrent_mutate_lba_no_conflict)
|
||||
{
|
||||
constexpr laddr_t SIZE = 4096;
|
||||
constexpr size_t SIZE = 4096;
|
||||
constexpr size_t NUM = 500;
|
||||
constexpr laddr_t addr = 0;
|
||||
constexpr laddr_t addr2 = SIZE * (NUM - 1);
|
||||
run_async([this] {
|
||||
laddr_t addr = L_ADDR_MIN;
|
||||
laddr_t addr2 = laddr_t::from_byte_offset(SIZE * (NUM - 1));
|
||||
run_async([this, addr, addr2] {
|
||||
{
|
||||
auto t = create_transaction();
|
||||
for (unsigned i = 0; i < NUM; ++i) {
|
||||
auto extent = alloc_extent(
|
||||
t,
|
||||
laddr_t(i * SIZE),
|
||||
laddr_t::from_byte_offset(i * SIZE),
|
||||
SIZE);
|
||||
}
|
||||
submit_transaction(std::move(t));
|
||||
@ -1945,9 +1947,9 @@ TEST_P(tm_single_device_test_t, concurrent_mutate_lba_no_conflict)
|
||||
|
||||
TEST_P(tm_single_device_test_t, create_remove_same_transaction)
|
||||
{
|
||||
constexpr laddr_t SIZE = 4096;
|
||||
constexpr size_t SIZE = 4096;
|
||||
run_async([this] {
|
||||
constexpr laddr_t ADDR = 0xFF * SIZE;
|
||||
laddr_t ADDR = laddr_t::from_byte_offset(0xFF * SIZE);
|
||||
{
|
||||
auto t = create_transaction();
|
||||
auto extent = alloc_extent(
|
||||
@ -1976,14 +1978,14 @@ TEST_P(tm_single_device_test_t, create_remove_same_transaction)
|
||||
|
||||
TEST_P(tm_single_device_test_t, split_merge_read_same_transaction)
|
||||
{
|
||||
constexpr laddr_t SIZE = 4096;
|
||||
constexpr size_t SIZE = 4096;
|
||||
run_async([this] {
|
||||
{
|
||||
auto t = create_transaction();
|
||||
for (unsigned i = 0; i < 300; ++i) {
|
||||
auto extent = alloc_extent(
|
||||
t,
|
||||
laddr_t(i * SIZE),
|
||||
laddr_t::from_byte_offset(i * SIZE),
|
||||
SIZE);
|
||||
}
|
||||
check_mappings(t);
|
||||
@ -1995,7 +1997,7 @@ TEST_P(tm_single_device_test_t, split_merge_read_same_transaction)
|
||||
for (unsigned i = 0; i < 240; ++i) {
|
||||
dec_ref(
|
||||
t,
|
||||
laddr_t(i * SIZE));
|
||||
laddr_t::from_byte_offset(i * SIZE));
|
||||
}
|
||||
check_mappings(t);
|
||||
submit_transaction(std::move(t));
|
||||
@ -2006,9 +2008,9 @@ TEST_P(tm_single_device_test_t, split_merge_read_same_transaction)
|
||||
|
||||
TEST_P(tm_single_device_test_t, inc_dec_ref)
|
||||
{
|
||||
constexpr laddr_t SIZE = 4096;
|
||||
constexpr size_t SIZE = 4096;
|
||||
run_async([this] {
|
||||
constexpr laddr_t ADDR = 0xFF * SIZE;
|
||||
laddr_t ADDR = laddr_t::from_byte_offset(0xFF * SIZE);
|
||||
{
|
||||
auto t = create_transaction();
|
||||
auto extent = alloc_extent(
|
||||
@ -2053,16 +2055,16 @@ TEST_P(tm_single_device_test_t, inc_dec_ref)
|
||||
|
||||
TEST_P(tm_single_device_test_t, cause_lba_split)
|
||||
{
|
||||
constexpr laddr_t SIZE = 4096;
|
||||
constexpr size_t SIZE = 4096;
|
||||
run_async([this] {
|
||||
for (unsigned i = 0; i < 200; ++i) {
|
||||
auto t = create_transaction();
|
||||
auto extent = alloc_extent(
|
||||
t,
|
||||
i * SIZE,
|
||||
laddr_t::from_byte_offset(i * SIZE),
|
||||
SIZE,
|
||||
(char)(i & 0xFF));
|
||||
ASSERT_EQ(i * SIZE, extent->get_laddr());
|
||||
ASSERT_EQ(laddr_t::from_byte_offset(i * SIZE), extent->get_laddr());
|
||||
submit_transaction(std::move(t));
|
||||
}
|
||||
check();
|
||||
@ -2080,9 +2082,9 @@ TEST_P(tm_single_device_test_t, random_writes)
|
||||
auto t = create_transaction();
|
||||
auto extent = alloc_extent(
|
||||
t,
|
||||
i * BSIZE,
|
||||
laddr_t::from_byte_offset(i * BSIZE),
|
||||
BSIZE);
|
||||
ASSERT_EQ(i * BSIZE, extent->get_laddr());
|
||||
ASSERT_EQ(laddr_t::from_byte_offset(i * BSIZE), extent->get_laddr());
|
||||
submit_transaction(std::move(t));
|
||||
}
|
||||
|
||||
@ -2098,7 +2100,7 @@ TEST_P(tm_single_device_test_t, random_writes)
|
||||
// pad out transaction
|
||||
auto paddings = alloc_extents(
|
||||
t,
|
||||
TOTAL + (k * PADDING_SIZE),
|
||||
laddr_t::from_byte_offset(TOTAL + (k * PADDING_SIZE)),
|
||||
PADDING_SIZE);
|
||||
for (auto &padding : paddings) {
|
||||
dec_ref(t, padding->get_laddr());
|
||||
@ -2131,7 +2133,7 @@ TEST_P(tm_single_device_test_t, find_hole_assert_trigger)
|
||||
|
||||
TEST_P(tm_single_device_intergrity_check_test_t, remap_lazy_read)
|
||||
{
|
||||
constexpr laddr_t offset = 0;
|
||||
constexpr laddr_t offset = L_ADDR_MIN;
|
||||
constexpr size_t length = 256 << 10;
|
||||
run_async([this, offset] {
|
||||
disable_max_extent_size();
|
||||
@ -2184,7 +2186,7 @@ TEST_P(tm_single_device_test_t, invalid_lba_mapping_detect)
|
||||
for (int i = 0; i < LEAF_NODE_CAPACITY; i++) {
|
||||
auto extent = alloc_extent(
|
||||
t,
|
||||
i * 4096,
|
||||
laddr_t::from_byte_offset(i * 4096),
|
||||
4096,
|
||||
'a');
|
||||
}
|
||||
@ -2193,12 +2195,12 @@ TEST_P(tm_single_device_test_t, invalid_lba_mapping_detect)
|
||||
|
||||
{
|
||||
auto t = create_transaction();
|
||||
auto pin = get_pin(t, (LEAF_NODE_CAPACITY - 1) * 4096);
|
||||
auto pin = get_pin(t, laddr_t::from_byte_offset((LEAF_NODE_CAPACITY - 1) * 4096));
|
||||
assert(pin->is_parent_viewable());
|
||||
auto extent = alloc_extent(t, LEAF_NODE_CAPACITY * 4096, 4096, 'a');
|
||||
auto extent = alloc_extent(t, laddr_t::from_byte_offset(LEAF_NODE_CAPACITY * 4096), 4096, 'a');
|
||||
assert(!pin->is_parent_viewable());
|
||||
pin = get_pin(t, LEAF_NODE_CAPACITY * 4096);
|
||||
std::ignore = alloc_extent(t, (LEAF_NODE_CAPACITY + 1) * 4096, 4096, 'a');
|
||||
pin = get_pin(t, laddr_t::from_byte_offset(LEAF_NODE_CAPACITY * 4096));
|
||||
std::ignore = alloc_extent(t, laddr_t::from_byte_offset((LEAF_NODE_CAPACITY + 1) * 4096), 4096, 'a');
|
||||
assert(pin->is_parent_viewable());
|
||||
assert(pin->parent_modified());
|
||||
pin->maybe_fix_pos();
|
||||
|
Loading…
Reference in New Issue
Block a user