X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fos%2Fbluestore%2Fbluestore_types.cc;fp=src%2Fceph%2Fsrc%2Fos%2Fbluestore%2Fbluestore_types.cc;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=06f64d21d4b34b318525f464af2fa29ddec1ef48;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/os/bluestore/bluestore_types.cc b/src/ceph/src/os/bluestore/bluestore_types.cc deleted file mode 100644 index 06f64d2..0000000 --- a/src/ceph/src/os/bluestore/bluestore_types.cc +++ /dev/null @@ -1,1147 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2014 Red Hat - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - * - */ - -#include "bluestore_types.h" -#include "common/Formatter.h" -#include "common/Checksummer.h" -#include "include/stringify.h" - -void ExtentList::add_extents(int64_t start, int64_t count) { - AllocExtent *last_extent = NULL; - bool can_merge = false; - - if (!m_extents->empty()) { - last_extent = &(m_extents->back()); - uint64_t last_offset = last_extent->end() / m_block_size; - uint32_t last_length = last_extent->length / m_block_size; - if ((last_offset == (uint64_t) start) && - (!m_max_blocks || (last_length + count) <= m_max_blocks)) { - can_merge = true; - } - } - - if (can_merge) { - last_extent->length += (count * m_block_size); - } else { - m_extents->emplace_back(AllocExtent(start * m_block_size, - count * m_block_size)); - } -} - -// bluestore_bdev_label_t - -void bluestore_bdev_label_t::encode(bufferlist& bl) const -{ - // be slightly friendly to someone who looks at the device - bl.append("bluestore block device\n"); - bl.append(stringify(osd_uuid)); - bl.append("\n"); - ENCODE_START(2, 1, bl); - ::encode(osd_uuid, bl); - ::encode(size, bl); - ::encode(btime, bl); - ::encode(description, bl); - ::encode(meta, bl); - ENCODE_FINISH(bl); -} - -void bluestore_bdev_label_t::decode(bufferlist::iterator& p) -{ - p.advance(60); // see above - DECODE_START(2, p); - ::decode(osd_uuid, p); - ::decode(size, p); - ::decode(btime, p); - ::decode(description, p); - if (struct_v >= 2) { - ::decode(meta, p); - } - DECODE_FINISH(p); -} - -void bluestore_bdev_label_t::dump(Formatter *f) const -{ - f->dump_stream("osd_uuid") << osd_uuid; - f->dump_unsigned("size", size); - f->dump_stream("btime") << btime; - f->dump_string("description", description); - for (auto& i : meta) { - f->dump_string(i.first.c_str(), i.second); - } -} - -void bluestore_bdev_label_t::generate_test_instances( - list& o) -{ - o.push_back(new bluestore_bdev_label_t); - o.push_back(new bluestore_bdev_label_t); - o.back()->size = 123; - o.back()->btime = utime_t(4, 5); - o.back()->description = "fakey"; - o.back()->meta["foo"] = "bar"; -} - -ostream& operator<<(ostream& out, const bluestore_bdev_label_t& l) -{ - return out << "bdev(osd_uuid " << l.osd_uuid - << ", size 0x" << std::hex << l.size << std::dec - << ", btime " << l.btime - << ", desc " << l.description - << ", " << l.meta.size() << " meta" - << ")"; -} - -// cnode_t - -void bluestore_cnode_t::dump(Formatter *f) const -{ - f->dump_unsigned("bits", bits); -} - -void bluestore_cnode_t::generate_test_instances(list& o) -{ - o.push_back(new bluestore_cnode_t()); - o.push_back(new bluestore_cnode_t(0)); - o.push_back(new bluestore_cnode_t(123)); -} - -// bluestore_extent_ref_map_t - -void bluestore_extent_ref_map_t::_check() const -{ - uint64_t pos = 0; - unsigned refs = 0; - for (const auto &p : ref_map) { - if (p.first < pos) - assert(0 == "overlap"); - if (p.first == pos && p.second.refs == refs) - assert(0 == "unmerged"); - pos = p.first + p.second.length; - refs = p.second.refs; - } -} - -void bluestore_extent_ref_map_t::_maybe_merge_left( - map::iterator& p) -{ - if (p == ref_map.begin()) - return; - auto q = p; - --q; - if (q->second.refs == p->second.refs && - q->first + q->second.length == p->first) { - q->second.length += p->second.length; - ref_map.erase(p); - p = q; - } -} - -void bluestore_extent_ref_map_t::get(uint64_t offset, uint32_t length) -{ - auto p = ref_map.lower_bound(offset); - if (p != ref_map.begin()) { - --p; - if (p->first + p->second.length <= offset) { - ++p; - } - } - while (length > 0) { - if (p == ref_map.end()) { - // nothing after offset; add the whole thing. - p = ref_map.insert( - map::value_type(offset, record_t(length, 1))).first; - break; - } - if (p->first > offset) { - // gap - uint64_t newlen = MIN(p->first - offset, length); - p = ref_map.insert( - map::value_type(offset, - record_t(newlen, 1))).first; - offset += newlen; - length -= newlen; - _maybe_merge_left(p); - ++p; - continue; - } - if (p->first < offset) { - // split off the portion before offset - assert(p->first + p->second.length > offset); - uint64_t left = p->first + p->second.length - offset; - p->second.length = offset - p->first; - p = ref_map.insert(map::value_type( - offset, record_t(left, p->second.refs))).first; - // continue below - } - assert(p->first == offset); - if (length < p->second.length) { - ref_map.insert(make_pair(offset + length, - record_t(p->second.length - length, - p->second.refs))); - p->second.length = length; - ++p->second.refs; - break; - } - ++p->second.refs; - offset += p->second.length; - length -= p->second.length; - _maybe_merge_left(p); - ++p; - } - if (p != ref_map.end()) - _maybe_merge_left(p); - //_check(); -} - -void bluestore_extent_ref_map_t::put( - uint64_t offset, uint32_t length, - PExtentVector *release, - bool *maybe_unshared) -{ - //NB: existing entries in 'release' container must be preserved! - bool unshared = true; - auto p = ref_map.lower_bound(offset); - if (p == ref_map.end() || p->first > offset) { - if (p == ref_map.begin()) { - assert(0 == "put on missing extent (nothing before)"); - } - --p; - if (p->first + p->second.length <= offset) { - assert(0 == "put on missing extent (gap)"); - } - } - if (p->first < offset) { - uint64_t left = p->first + p->second.length - offset; - p->second.length = offset - p->first; - if (p->second.refs != 1) { - unshared = false; - } - p = ref_map.insert(map::value_type( - offset, record_t(left, p->second.refs))).first; - } - while (length > 0) { - assert(p->first == offset); - if (length < p->second.length) { - if (p->second.refs != 1) { - unshared = false; - } - ref_map.insert(make_pair(offset + length, - record_t(p->second.length - length, - p->second.refs))); - if (p->second.refs > 1) { - p->second.length = length; - --p->second.refs; - if (p->second.refs != 1) { - unshared = false; - } - _maybe_merge_left(p); - } else { - if (release) - release->push_back(bluestore_pextent_t(p->first, length)); - ref_map.erase(p); - } - goto out; - } - offset += p->second.length; - length -= p->second.length; - if (p->second.refs > 1) { - --p->second.refs; - if (p->second.refs != 1) { - unshared = false; - } - _maybe_merge_left(p); - ++p; - } else { - if (release) - release->push_back(bluestore_pextent_t(p->first, p->second.length)); - ref_map.erase(p++); - } - } - if (p != ref_map.end()) - _maybe_merge_left(p); - //_check(); -out: - if (maybe_unshared) { - if (unshared) { - // we haven't seen a ref != 1 yet; check the whole map. - for (auto& p : ref_map) { - if (p.second.refs != 1) { - unshared = false; - break; - } - } - } - *maybe_unshared = unshared; - } -} - -bool bluestore_extent_ref_map_t::contains(uint64_t offset, uint32_t length) const -{ - auto p = ref_map.lower_bound(offset); - if (p == ref_map.end() || p->first > offset) { - if (p == ref_map.begin()) { - return false; // nothing before - } - --p; - if (p->first + p->second.length <= offset) { - return false; // gap - } - } - while (length > 0) { - if (p == ref_map.end()) - return false; - if (p->first > offset) - return false; - if (p->first + p->second.length >= offset + length) - return true; - uint64_t overlap = p->first + p->second.length - offset; - offset += overlap; - length -= overlap; - ++p; - } - return true; -} - -bool bluestore_extent_ref_map_t::intersects( - uint64_t offset, - uint32_t length) const -{ - auto p = ref_map.lower_bound(offset); - if (p != ref_map.begin()) { - --p; - if (p->first + p->second.length <= offset) { - ++p; - } - } - if (p == ref_map.end()) - return false; - if (p->first >= offset + length) - return false; - return true; // intersects p! -} - -void bluestore_extent_ref_map_t::dump(Formatter *f) const -{ - f->open_array_section("ref_map"); - for (auto& p : ref_map) { - f->open_object_section("ref"); - f->dump_unsigned("offset", p.first); - f->dump_unsigned("length", p.second.length); - f->dump_unsigned("refs", p.second.refs); - f->close_section(); - } - f->close_section(); -} - -void bluestore_extent_ref_map_t::generate_test_instances( - list& o) -{ - o.push_back(new bluestore_extent_ref_map_t); - o.push_back(new bluestore_extent_ref_map_t); - o.back()->get(10, 10); - o.back()->get(18, 22); - o.back()->get(20, 20); - o.back()->get(10, 25); - o.back()->get(15, 20); -} - -ostream& operator<<(ostream& out, const bluestore_extent_ref_map_t& m) -{ - out << "ref_map("; - for (auto p = m.ref_map.begin(); p != m.ref_map.end(); ++p) { - if (p != m.ref_map.begin()) - out << ","; - out << std::hex << "0x" << p->first << "~" << p->second.length << std::dec - << "=" << p->second.refs; - } - out << ")"; - return out; -} - -// bluestore_blob_use_tracker_t - -void bluestore_blob_use_tracker_t::allocate() -{ - assert(num_au != 0); - bytes_per_au = new uint32_t[num_au]; - for (uint32_t i = 0; i < num_au; ++i) { - bytes_per_au[i] = 0; - } -} - -void bluestore_blob_use_tracker_t::init( - uint32_t full_length, uint32_t _au_size) { - assert(!au_size || is_empty()); - assert(_au_size > 0); - assert(full_length > 0); - clear(); - uint32_t _num_au = ROUND_UP_TO(full_length, _au_size) / _au_size; - au_size = _au_size; - if( _num_au > 1 ) { - num_au = _num_au; - allocate(); - } -} - -void bluestore_blob_use_tracker_t::get( - uint32_t offset, uint32_t length) -{ - assert(au_size); - if (!num_au) { - total_bytes += length; - }else { - auto end = offset + length; - - while (offset < end) { - auto phase = offset % au_size; - bytes_per_au[offset / au_size] += - MIN(au_size - phase, end - offset); - offset += (phase ? au_size - phase : au_size); - } - } -} - -bool bluestore_blob_use_tracker_t::put( - uint32_t offset, uint32_t length, - PExtentVector *release_units) -{ - assert(au_size); - if (release_units) { - release_units->clear(); - } - bool maybe_empty = true; - if (!num_au) { - assert(total_bytes >= length); - total_bytes -= length; - } else { - auto end = offset + length; - uint64_t next_offs = 0; - while (offset < end) { - auto phase = offset % au_size; - size_t pos = offset / au_size; - auto diff = MIN(au_size - phase, end - offset); - assert(diff <= bytes_per_au[pos]); - bytes_per_au[pos] -= diff; - offset += (phase ? au_size - phase : au_size); - if (bytes_per_au[pos] == 0) { - if (release_units) { - if (release_units->empty() || next_offs != pos * au_size) { - release_units->emplace_back(pos * au_size, au_size); - } else { - release_units->back().length += au_size; - } - next_offs += au_size; - } - } else { - maybe_empty = false; // micro optimization detecting we aren't empty - // even in the affected extent - } - } - } - bool empty = maybe_empty ? !is_not_empty() : false; - if (empty && release_units) { - release_units->clear(); - } - return empty; -} - -bool bluestore_blob_use_tracker_t::can_split() const -{ - return num_au > 0; -} - -bool bluestore_blob_use_tracker_t::can_split_at(uint32_t blob_offset) const -{ - assert(au_size); - return (blob_offset % au_size) == 0 && - blob_offset < num_au * au_size; -} - -void bluestore_blob_use_tracker_t::split( - uint32_t blob_offset, - bluestore_blob_use_tracker_t* r) -{ - assert(au_size); - assert(can_split()); - assert(can_split_at(blob_offset)); - assert(r->is_empty()); - - uint32_t new_num_au = blob_offset / au_size; - r->init( (num_au - new_num_au) * au_size, au_size); - - for (auto i = new_num_au; i < num_au; i++) { - r->get((i - new_num_au) * au_size, bytes_per_au[i]); - bytes_per_au[i] = 0; - } - if (new_num_au == 0) { - clear(); - } else if (new_num_au == 1) { - uint32_t tmp = bytes_per_au[0]; - uint32_t _au_size = au_size; - clear(); - au_size = _au_size; - total_bytes = tmp; - } else { - num_au = new_num_au; - } -} - -bool bluestore_blob_use_tracker_t::equal( - const bluestore_blob_use_tracker_t& other) const -{ - if (!num_au && !other.num_au) { - return total_bytes == other.total_bytes && au_size == other.au_size; - } else if (num_au && other.num_au) { - if (num_au != other.num_au || au_size != other.au_size) { - return false; - } - for (size_t i = 0; i < num_au; i++) { - if (bytes_per_au[i] != other.bytes_per_au[i]) { - return false; - } - } - return true; - } - - uint32_t n = num_au ? num_au : other.num_au; - uint32_t referenced = - num_au ? other.get_referenced_bytes() : get_referenced_bytes(); - auto bytes_per_au_tmp = num_au ? bytes_per_au : other.bytes_per_au; - uint32_t my_referenced = 0; - for (size_t i = 0; i < n; i++) { - my_referenced += bytes_per_au_tmp[i]; - if (my_referenced > referenced) { - return false; - } - } - return my_referenced == referenced; -} - -void bluestore_blob_use_tracker_t::dump(Formatter *f) const -{ - f->dump_unsigned("num_au", num_au); - f->dump_unsigned("au_size", au_size); - if (!num_au) { - f->dump_unsigned("total_bytes", total_bytes); - } else { - f->open_array_section("bytes_per_au"); - for (size_t i = 0; i < num_au; ++i) { - f->dump_unsigned("", bytes_per_au[i]); - } - f->close_section(); - } -} - -void bluestore_blob_use_tracker_t::generate_test_instances( - list& o) -{ - o.push_back(new bluestore_blob_use_tracker_t()); - o.back()->init(16, 16); - o.back()->get(10, 10); - o.back()->get(10, 5); - o.push_back(new bluestore_blob_use_tracker_t()); - o.back()->init(60, 16); - o.back()->get(18, 22); - o.back()->get(20, 20); - o.back()->get(15, 20); -} - -ostream& operator<<(ostream& out, const bluestore_blob_use_tracker_t& m) -{ - out << "use_tracker(" << std::hex; - if (!m.num_au) { - out << "0x" << m.au_size - << " " - << "0x" << m.total_bytes; - } else { - out << "0x" << m.num_au - << "*0x" << m.au_size - << " 0x["; - for (size_t i = 0; i < m.num_au; ++i) { - if (i != 0) - out << ","; - out << m.bytes_per_au[i]; - } - out << "]"; - } - out << std::dec << ")"; - return out; -} - -// bluestore_pextent_t - -void bluestore_pextent_t::dump(Formatter *f) const -{ - f->dump_unsigned("offset", offset); - f->dump_unsigned("length", length); -} - -ostream& operator<<(ostream& out, const bluestore_pextent_t& o) { - if (o.is_valid()) - return out << "0x" << std::hex << o.offset << "~" << o.length << std::dec; - else - return out << "!~" << std::hex << o.length << std::dec; -} - -void bluestore_pextent_t::generate_test_instances(list& ls) -{ - ls.push_back(new bluestore_pextent_t); - ls.push_back(new bluestore_pextent_t(1, 2)); -} - -// bluestore_blob_t - -string bluestore_blob_t::get_flags_string(unsigned flags) -{ - string s; - if (flags & FLAG_COMPRESSED) { - if (s.length()) - s += '+'; - s += "compressed"; - } - if (flags & FLAG_CSUM) { - if (s.length()) - s += '+'; - s += "csum"; - } - if (flags & FLAG_HAS_UNUSED) { - if (s.length()) - s += '+'; - s += "has_unused"; - } - if (flags & FLAG_SHARED) { - if (s.length()) - s += '+'; - s += "shared"; - } - - return s; -} - -size_t bluestore_blob_t::get_csum_value_size() const -{ - return Checksummer::get_csum_value_size(csum_type); -} - -void bluestore_blob_t::dump(Formatter *f) const -{ - f->open_array_section("extents"); - for (auto& p : extents) { - f->dump_object("extent", p); - } - f->close_section(); - f->dump_unsigned("logical_length", logical_length); - f->dump_unsigned("compressed_length", compressed_length); - f->dump_unsigned("flags", flags); - f->dump_unsigned("csum_type", csum_type); - f->dump_unsigned("csum_chunk_order", csum_chunk_order); - f->open_array_section("csum_data"); - size_t n = get_csum_count(); - for (unsigned i = 0; i < n; ++i) - f->dump_unsigned("csum", get_csum_item(i)); - f->close_section(); - f->dump_unsigned("unused", unused); -} - -void bluestore_blob_t::generate_test_instances(list& ls) -{ - ls.push_back(new bluestore_blob_t); - ls.push_back(new bluestore_blob_t(0)); - ls.push_back(new bluestore_blob_t); - ls.back()->allocated_test(bluestore_pextent_t(111, 222)); - ls.push_back(new bluestore_blob_t); - ls.back()->init_csum(Checksummer::CSUM_XXHASH32, 16, 65536); - ls.back()->csum_data = buffer::claim_malloc(4, strdup("abcd")); - ls.back()->add_unused(0, 3); - ls.back()->add_unused(8, 8); - ls.back()->allocated_test(bluestore_pextent_t(0x40100000, 0x10000)); - ls.back()->allocated_test( - bluestore_pextent_t(bluestore_pextent_t::INVALID_OFFSET, 0x1000)); - ls.back()->allocated_test(bluestore_pextent_t(0x40120000, 0x10000)); -} - -ostream& operator<<(ostream& out, const bluestore_blob_t& o) -{ - out << "blob(" << o.get_extents(); - if (o.is_compressed()) { - out << " clen 0x" << std::hex - << o.get_logical_length() - << " -> 0x" - << o.get_compressed_payload_length() - << std::dec; - } - if (o.flags) { - out << " " << o.get_flags_string(); - } - if (o.has_csum()) { - out << " " << Checksummer::get_csum_type_string(o.csum_type) - << "/0x" << std::hex << (1ull << o.csum_chunk_order) << std::dec; - } - if (o.has_unused()) - out << " unused=0x" << std::hex << o.unused << std::dec; - out << ")"; - return out; -} - -void bluestore_blob_t::calc_csum(uint64_t b_off, const bufferlist& bl) -{ - switch (csum_type) { - case Checksummer::CSUM_XXHASH32: - Checksummer::calculate( - get_csum_chunk_size(), b_off, bl.length(), bl, &csum_data); - break; - case Checksummer::CSUM_XXHASH64: - Checksummer::calculate( - get_csum_chunk_size(), b_off, bl.length(), bl, &csum_data); - break;; - case Checksummer::CSUM_CRC32C: - Checksummer::calculate( - get_csum_chunk_size(), b_off, bl.length(), bl, &csum_data); - break; - case Checksummer::CSUM_CRC32C_16: - Checksummer::calculate( - get_csum_chunk_size(), b_off, bl.length(), bl, &csum_data); - break; - case Checksummer::CSUM_CRC32C_8: - Checksummer::calculate( - get_csum_chunk_size(), b_off, bl.length(), bl, &csum_data); - break; - } -} - -int bluestore_blob_t::verify_csum(uint64_t b_off, const bufferlist& bl, - int* b_bad_off, uint64_t *bad_csum) const -{ - int r = 0; - - *b_bad_off = -1; - switch (csum_type) { - case Checksummer::CSUM_NONE: - break; - case Checksummer::CSUM_XXHASH32: - *b_bad_off = Checksummer::verify( - get_csum_chunk_size(), b_off, bl.length(), bl, csum_data, bad_csum); - break; - case Checksummer::CSUM_XXHASH64: - *b_bad_off = Checksummer::verify( - get_csum_chunk_size(), b_off, bl.length(), bl, csum_data, bad_csum); - break; - case Checksummer::CSUM_CRC32C: - *b_bad_off = Checksummer::verify( - get_csum_chunk_size(), b_off, bl.length(), bl, csum_data, bad_csum); - break; - case Checksummer::CSUM_CRC32C_16: - *b_bad_off = Checksummer::verify( - get_csum_chunk_size(), b_off, bl.length(), bl, csum_data, bad_csum); - break; - case Checksummer::CSUM_CRC32C_8: - *b_bad_off = Checksummer::verify( - get_csum_chunk_size(), b_off, bl.length(), bl, csum_data, bad_csum); - break; - default: - r = -EOPNOTSUPP; - break; - } - - if (r < 0) - return r; - else if (*b_bad_off >= 0) - return -1; // bad checksum - else - return 0; -} - -void bluestore_blob_t::allocated(uint32_t b_off, uint32_t length, const AllocExtentVector& allocs) -{ - if (extents.size() == 0) { - // if blob is compressed then logical length to be already configured - // otherwise - to be unset. - assert((is_compressed() && logical_length != 0) || - (!is_compressed() && logical_length == 0)); - - extents.reserve(allocs.size() + (b_off ? 1 : 0)); - if (b_off) { - extents.emplace_back( - bluestore_pextent_t(bluestore_pextent_t::INVALID_OFFSET, b_off)); - } - uint32_t new_len = b_off; - for (auto& a : allocs) { - extents.emplace_back(a.offset, a.length); - new_len += a.length; - } - if (!is_compressed()) { - logical_length = new_len; - } - } else { - assert(!is_compressed()); // partial allocations are forbidden when - // compressed - assert(b_off < logical_length); - uint32_t cur_offs = 0; - auto start_it = extents.begin(); - size_t pos = 0; - while(true) { - assert(start_it != extents.end()); - if (cur_offs + start_it->length > b_off) { - break; - } - cur_offs += start_it->length; - ++start_it; - ++pos; - } - uint32_t head = b_off - cur_offs; - uint32_t end_off = b_off + length; - auto end_it = start_it; - - while (true) { - assert(end_it != extents.end()); - assert(!end_it->is_valid()); - if (cur_offs + end_it->length >= end_off) { - break; - } - cur_offs += end_it->length; - ++end_it; - } - assert(cur_offs + end_it->length >= end_off); - uint32_t tail = cur_offs + end_it->length - end_off; - - start_it = extents.erase(start_it, end_it + 1); - size_t count = allocs.size(); - count += head ? 1 : 0; - count += tail ? 1 : 0; - extents.insert(start_it, - count, - bluestore_pextent_t( - bluestore_pextent_t::INVALID_OFFSET, 0)); - - // Workaround to resolve lack of proper iterator return in vector::insert - // Looks like some gcc/stl implementations still lack it despite c++11 - // support claim - start_it = extents.begin() + pos; - - if (head) { - start_it->length = head; - ++start_it; - } - for(auto& e : allocs) { - *start_it = e; - ++start_it; - } - if (tail) { - start_it->length = tail; - } - } -} - -// cut it out of extents -struct vecbuilder { - PExtentVector v; - uint64_t invalid = 0; - - void add_invalid(uint64_t length) { - invalid += length; - } - void flush() { - if (invalid) { - v.emplace_back(bluestore_pextent_t(bluestore_pextent_t::INVALID_OFFSET, - invalid)); - invalid = 0; - } - } - void add(uint64_t offset, uint64_t length) { - if (offset == bluestore_pextent_t::INVALID_OFFSET) { - add_invalid(length); - } - else { - flush(); - v.emplace_back(bluestore_pextent_t(offset, length)); - } - } -}; - -void bluestore_blob_t::allocated_test(const bluestore_pextent_t& alloc) -{ - extents.emplace_back(alloc); - if (!is_compressed()) { - logical_length += alloc.length; - } -} - -bool bluestore_blob_t::release_extents(bool all, - const PExtentVector& logical, - PExtentVector* r) -{ - // common case: all of it? - if (all) { - uint64_t pos = 0; - for (auto& e : extents) { - if (e.is_valid()) { - r->push_back(e); - } - pos += e.length; - } - assert(is_compressed() || get_logical_length() == pos); - extents.resize(1); - extents[0].offset = bluestore_pextent_t::INVALID_OFFSET; - extents[0].length = pos; - return true; - } - // remove from pextents according to logical release list - vecbuilder vb; - auto loffs_it = logical.begin(); - auto lend = logical.end(); - uint32_t pext_loffs_start = 0; //starting loffset of the current pextent - uint32_t pext_loffs = 0; //current loffset - auto pext_it = extents.begin(); - auto pext_end = extents.end(); - while (pext_it != pext_end) { - if (loffs_it == lend || - pext_loffs_start + pext_it->length <= loffs_it->offset) { - int delta0 = pext_loffs - pext_loffs_start; - assert(delta0 >= 0); - if ((uint32_t)delta0 < pext_it->length) { - vb.add(pext_it->offset + delta0, pext_it->length - delta0); - } - pext_loffs_start += pext_it->length; - pext_loffs = pext_loffs_start; - ++pext_it; - } - else { - //assert(pext_loffs == pext_loffs_start); - int delta0 = pext_loffs - pext_loffs_start; - assert(delta0 >= 0); - - int delta = loffs_it->offset - pext_loffs; - assert(delta >= 0); - if (delta > 0) { - vb.add(pext_it->offset + delta0, delta); - pext_loffs += delta; - } - - PExtentVector::iterator last_r = r->end(); - if (r->begin() != last_r) { - --last_r; - } - uint32_t to_release = loffs_it->length; - do { - uint32_t to_release_part = - MIN(pext_it->length - delta0 - delta, to_release); - auto o = pext_it->offset + delta0 + delta; - if (last_r != r->end() && last_r->offset + last_r->length == o) { - last_r->length += to_release_part; - } - else { - last_r = r->emplace(r->end(), o, to_release_part); - } - to_release -= to_release_part; - pext_loffs += to_release_part; - if (pext_loffs == pext_loffs_start + pext_it->length) { - pext_loffs_start += pext_it->length; - pext_loffs = pext_loffs_start; - pext_it++; - delta0 = delta = 0; - } - } while (to_release > 0 && pext_it != pext_end); - vb.add_invalid(loffs_it->length - to_release); - ++loffs_it; - } - } - vb.flush(); - extents.swap(vb.v); - return false; -} - -void bluestore_blob_t::split(uint32_t blob_offset, bluestore_blob_t& rb) -{ - size_t left = blob_offset; - uint32_t llen_lb = 0; - uint32_t llen_rb = 0; - unsigned i = 0; - for (auto p = extents.begin(); p != extents.end(); ++p, ++i) { - if (p->length <= left) { - left -= p->length; - llen_lb += p->length; - continue; - } - if (left) { - if (p->is_valid()) { - rb.extents.emplace_back(bluestore_pextent_t(p->offset + left, - p->length - left)); - } - else { - rb.extents.emplace_back(bluestore_pextent_t( - bluestore_pextent_t::INVALID_OFFSET, - p->length - left)); - } - llen_rb += p->length - left; - llen_lb += left; - p->length = left; - ++i; - ++p; - } - while (p != extents.end()) { - llen_rb += p->length; - rb.extents.push_back(*p++); - } - extents.resize(i); - logical_length = llen_lb; - rb.logical_length = llen_rb; - break; - } - rb.flags = flags; - - if (has_csum()) { - rb.csum_type = csum_type; - rb.csum_chunk_order = csum_chunk_order; - size_t csum_order = get_csum_chunk_size(); - assert(blob_offset % csum_order == 0); - size_t pos = (blob_offset / csum_order) * get_csum_value_size(); - // deep copy csum data - bufferptr old; - old.swap(csum_data); - rb.csum_data = bufferptr(old.c_str() + pos, old.length() - pos); - csum_data = bufferptr(old.c_str(), pos); - } -} - -// bluestore_shared_blob_t - -void bluestore_shared_blob_t::dump(Formatter *f) const -{ - f->dump_int("sbid", sbid); - f->dump_object("ref_map", ref_map); -} - -void bluestore_shared_blob_t::generate_test_instances( - list& ls) -{ - ls.push_back(new bluestore_shared_blob_t(1)); -} - -ostream& operator<<(ostream& out, const bluestore_shared_blob_t& sb) -{ - out << "(sbid 0x" << std::hex << sb.sbid << std::dec; - out << " " << sb.ref_map << ")"; - return out; -} - -// bluestore_onode_t - -void bluestore_onode_t::shard_info::dump(Formatter *f) const -{ - f->dump_unsigned("offset", offset); - f->dump_unsigned("bytes", bytes); -} - -ostream& operator<<(ostream& out, const bluestore_onode_t::shard_info& si) -{ - return out << std::hex << "0x" << si.offset << "(0x" << si.bytes << " bytes" - << std::dec << ")"; -} - -void bluestore_onode_t::dump(Formatter *f) const -{ - f->dump_unsigned("nid", nid); - f->dump_unsigned("size", size); - f->open_object_section("attrs"); - for (auto p = attrs.begin(); p != attrs.end(); ++p) { - f->open_object_section("attr"); - f->dump_string("name", p->first.c_str()); // it's not quite std::string - f->dump_unsigned("len", p->second.length()); - f->close_section(); - } - f->close_section(); - f->dump_string("flags", get_flags_string()); - f->open_array_section("extent_map_shards"); - for (auto si : extent_map_shards) { - f->dump_object("shard", si); - } - f->close_section(); - f->dump_unsigned("expected_object_size", expected_object_size); - f->dump_unsigned("expected_write_size", expected_write_size); - f->dump_unsigned("alloc_hint_flags", alloc_hint_flags); -} - -void bluestore_onode_t::generate_test_instances(list& o) -{ - o.push_back(new bluestore_onode_t()); - // FIXME -} - -// bluestore_deferred_op_t - -void bluestore_deferred_op_t::dump(Formatter *f) const -{ - f->dump_unsigned("op", (int)op); - f->dump_unsigned("data_len", data.length()); - f->open_array_section("extents"); - for (auto& e : extents) { - f->dump_object("extent", e); - } - f->close_section(); -} - -void bluestore_deferred_op_t::generate_test_instances(list& o) -{ - o.push_back(new bluestore_deferred_op_t); - o.push_back(new bluestore_deferred_op_t); - o.back()->op = OP_WRITE; - o.back()->extents.push_back(bluestore_pextent_t(1, 2)); - o.back()->extents.push_back(bluestore_pextent_t(100, 5)); - o.back()->data.append("my data"); -} - -void bluestore_deferred_transaction_t::dump(Formatter *f) const -{ - f->dump_unsigned("seq", seq); - f->open_array_section("ops"); - for (list::const_iterator p = ops.begin(); p != ops.end(); ++p) { - f->dump_object("op", *p); - } - f->close_section(); - - f->open_array_section("released extents"); - for (interval_set::const_iterator p = released.begin(); p != released.end(); ++p) { - f->open_object_section("extent"); - f->dump_unsigned("offset", p.get_start()); - f->dump_unsigned("length", p.get_len()); - f->close_section(); - } - f->close_section(); -} - -void bluestore_deferred_transaction_t::generate_test_instances(list& o) -{ - o.push_back(new bluestore_deferred_transaction_t()); - o.push_back(new bluestore_deferred_transaction_t()); - o.back()->seq = 123; - o.back()->ops.push_back(bluestore_deferred_op_t()); - o.back()->ops.push_back(bluestore_deferred_op_t()); - o.back()->ops.back().op = bluestore_deferred_op_t::OP_WRITE; - o.back()->ops.back().extents.push_back(bluestore_pextent_t(1,7)); - o.back()->ops.back().data.append("foodata"); -} - -void bluestore_compression_header_t::dump(Formatter *f) const -{ - f->dump_unsigned("type", type); - f->dump_unsigned("length", length); -} - -void bluestore_compression_header_t::generate_test_instances( - list& o) -{ - o.push_back(new bluestore_compression_header_t); - o.push_back(new bluestore_compression_header_t(1)); - o.back()->length = 1234; -}