unsigned l_off = pos - lp->first;
unsigned b_off = l_off + lp->second.offset;
unsigned b_len = std::min(left, lp->second.length - l_off);
- assert(b_len <= bptr->blob.length - b_off);
ready_regions_t cache_res;
interval_set<uint64_t> cache_interval;
if (ep != o->onode.extent_map.begin()) {
--ep;
b = c->get_blob(o, ep->second.blob);
- if (ep->first + b->blob.get_max_length() <= offset) {
+ if (ep->first + b->blob.get_ondisk_length() <= offset) {
++ep;
}
}
}
int64_t blob = ep->second.blob;
b = c->get_blob(o, ep->second.blob);
- if (!b->blob.is_mutable()) {
+ if (!b->blob.is_mutable() || b->blob.is_compressed()) {
dout(20) << __func__ << " ignoring immutable " << blob << ": " << *b
<< dendl;
++ep;
// new blob.
b = o->blob_map.new_blob(c->cache);
- b->blob.length = min_alloc_size;
- uint64_t b_off = offset % min_alloc_size;
+ unsigned alloc_len = min_alloc_size;
+ uint64_t b_off = offset % alloc_len;
uint64_t b_len = length;
b->bc.write(txc->seq, b_off, bl, wctx->buffered ? 0 : Buffer::FLAG_NOCACHE);
_pad_zeros(&bl, &b_off, &b_len, block_size);
if (b_off)
b->blob.add_unused(0, b_off);
- if (b_off + b_len < b->blob.length)
- b->blob.add_unused(b_off + b_len, b->blob.length - (b_off + b_len));
+ if (b_off + b_len < alloc_len)
+ b->blob.add_unused(b_off + b_len, alloc_len - (b_off + b_len));
o->onode.punch_hole(offset, length, &wctx->lex_old);
bluestore_lextent_t& lex = o->onode.extent_map[offset] =
bluestore_lextent_t(b->id, offset % min_alloc_size, length);
dout(20) << __func__ << " lex 0x" << std::hex << offset << std::dec
<< ": " << lex << dendl;
dout(20) << __func__ << " new " << b->id << ": " << *b << dendl;
- wctx->write(b, b_off, bl);
+ wctx->write(b, alloc_len, b_off, bl);
return;
}
<< std::dec << dendl;
while (length > 0) {
Blob *b = o->blob_map.new_blob(c->cache);
- auto l = b->blob.length = MIN(max_blob_len, length);
+ auto l = MIN(max_blob_len, length);
bufferlist t;
blp.copy(l, t);
b->bc.write(txc->seq, 0, t, wctx->buffered ? 0 : Buffer::FLAG_NOCACHE);
- wctx->write(b, 0, t);
+ wctx->write(b, l, 0, t);
o->onode.punch_hole(offset, l, &wctx->lex_old);
o->onode.extent_map[offset] = bluestore_lextent_t(b->id, 0, l, 0);
b->blob.ref_map.get(0, l);
uint64_t need = 0;
for (auto &wi : wctx->writes) {
- need += wi.b->blob.length;
+ need += wi.blob_length;
}
int r = alloc->reserve(need);
if (r < 0) {
Blob *b = wi.b;
uint64_t b_off = wi.b_off;
bufferlist *l = &wi.bl;
- uint64_t final_length = b->blob.length;
- uint64_t csum_length = b->blob.length;
+ uint64_t final_length = wi.blob_length;
+ uint64_t csum_length = wi.blob_length;
unsigned csum_order;
bufferlist compressed_bl;
CompressorRef c;
bool compressed = false;
if (wctx->compress &&
- b->blob.length > min_alloc_size &&
+ wi.blob_length > min_alloc_size &&
(c = compressor) != nullptr) {
// compress
assert(b_off == 0);
- assert(b->blob.length == l->length());
+ assert(wi.blob_length == l->length());
bluestore_compression_header_t chdr;
chdr.type = c->get_type();
// FIXME: memory alignment here is bad
// pad out to min_alloc_size
compressed_bl.append_zero(newlen - rawlen);
logger->inc(l_bluestore_write_pad_bytes, newlen - rawlen);
- dout(20) << __func__ << hex << " compressed 0x" << b->blob.length
+ dout(20) << __func__ << hex << " compressed 0x" << wi.blob_length
<< " -> 0x" << rawlen << " => 0x" << newlen
<< " with " << chdr.type
<< dec << dendl;
}
if (!compressed) {
b->blob.set_flag(bluestore_blob_t::FLAG_MUTABLE);
- if (l->length() != b->blob.length) {
+ if (l->length() != wi.blob_length) {
// hrm, maybe we could do better here, but let's not bother.
dout(20) << __func__ << " forcing csum_order to block_size_order "
<< block_size_order << dendl;
}
if (b->blob.ref_map.empty()) {
dout(20) << __func__ << " rm blob " << *b << dendl;
- if (compressed) {
- txc->statfs_delta.compressed() -= b->blob.get_payload_length();
- }
+ txc->statfs_delta.compressed() -= b->blob.get_compressed_payload_length();
if (l.blob >= 0) {
o->blob_map.erase(b);
} else {
struct write_item {
Blob *b;
+ uint64_t blob_length;
uint64_t b_off;
bufferlist bl;
- write_item(Blob *b, uint64_t o, bufferlist& bl)
- : b(b), b_off(o), bl(bl) {}
+ write_item(Blob *b, uint64_t blob_len, uint64_t o, bufferlist& bl)
+ : b(b), blob_length(blob_len), b_off(o), bl(bl) {}
};
vector<write_item> writes; ///< blobs we're writing
- void write(Blob *b, uint64_t o, bufferlist& bl) {
- writes.emplace_back(write_item(b, o, bl));
+ void write(Blob *b, uint64_t blob_len, uint64_t o, bufferlist& bl) {
+ writes.emplace_back(write_item(b, blob_len, o, bl));
}
};
{
ENCODE_START(1, 1, bl);
::encode(extents, bl);
- ::encode(length, bl);
::encode(compressed_length, bl);
::encode(flags, bl);
::encode(csum_type, bl);
{
DECODE_START(1, p);
::decode(extents, p);
- ::decode(length, p);
::decode(compressed_length, p);
::decode(flags, p);
::decode(csum_type, p);
f->dump_object("extent", p);
}
f->close_section();
- f->dump_unsigned("length", length);
f->dump_unsigned("compressed_length", compressed_length);
f->dump_unsigned("flags", flags);
f->dump_unsigned("csum_type", csum_type);
void bluestore_blob_t::generate_test_instances(list<bluestore_blob_t*>& ls)
{
ls.push_back(new bluestore_blob_t);
- ls.push_back(new bluestore_blob_t(4096, 0));
- ls.push_back(new bluestore_blob_t(4096, bluestore_pextent_t(111, 222), 12));
- ls.push_back(new bluestore_blob_t(4096, bluestore_pextent_t(111, 222), 12));
+ ls.push_back(new bluestore_blob_t(0));
+ ls.push_back(new bluestore_blob_t(bluestore_pextent_t(111, 222), 12));
+ ls.push_back(new bluestore_blob_t(bluestore_pextent_t(111, 222), 12));
ls.back()->csum_type = CSUM_XXHASH32;
ls.back()->csum_chunk_order = 16;
ls.back()->csum_data = buffer::claim_malloc(4, strdup("abcd"));
ostream& operator<<(ostream& out, const bluestore_blob_t& o)
{
out << "blob(" << o.extents
- << " len 0x" << std::hex << o.length << std::dec
<< " clen 0x" << std::hex << o.compressed_length << std::dec;
if (o.flags) {
out << " " << o.get_flags_string();
}
uint64_t end;
if (p == ref_map.ref_map.end()) {
- end = this->length;
+ end = this->get_ondisk_length();
} else {
end = p->first;
}
}
vector<bluestore_pextent_t> extents; ///< raw data position on device
- uint32_t length; ///< logical (decompressed) length
uint32_t compressed_length; ///< compressed length if any
uint32_t flags; ///< FLAG_*
interval_set<uint32_t> unused; ///< portion that has never been written to
bufferptr csum_data; ///< opaque vector of csum data
- bluestore_blob_t(uint32_t l = 0, uint32_t f = 0)
- : length(l),
- compressed_length(0),
+ bluestore_blob_t(uint32_t f = 0)
+ : compressed_length(0),
flags(f),
csum_type(CSUM_NONE),
csum_chunk_order(12) {
}
- bluestore_blob_t(uint32_t l, const bluestore_pextent_t& ext, uint32_t f = 0)
- : length(l),
- compressed_length(0),
+ bluestore_blob_t(const bluestore_pextent_t& ext, uint32_t f = 0)
+ : compressed_length(0),
flags(f),
csum_type(CSUM_NONE),
csum_chunk_order(12) {
bool is_compressed() const {
return has_flag(FLAG_COMPRESSED);
}
- uint32_t get_payload_length() const {
- return is_compressed() ? compressed_length : length;
- }
- uint32_t get_aligned_payload_length(uint64_t block_size) const {
- uint32_t pl = get_payload_length();
- pl = ROUND_UP_TO(pl, block_size);
- if(csum_type != CSUM_NONE) {
- pl = ROUND_UP_TO(pl, get_csum_chunk_size());
- }
- return pl;
+ uint32_t get_compressed_payload_length() const {
+ return is_compressed() ? compressed_length : 0;
}
uint64_t calc_offset(uint64_t x_off, uint64_t *plen) const {
auto p = extents.begin();
}
}
- uint64_t get_max_length() const {
- if (has_flag(FLAG_COMPRESSED)) {
- return length;
- } else {
- return get_ondisk_length();
- }
- }
uint32_t get_ondisk_length() const {
uint32_t len = 0;
for (auto &p : extents) {
{
bluestore_blob_t b;
vector<bluestore_pextent_t> r;
- b.length = mas * 2;
b.extents.push_back(bluestore_pextent_t(0, mas*2));
b.ref_map.get(0, mas*2);
ASSERT_TRUE(b.is_allocated(0, mas*2));
{
bluestore_blob_t b;
vector<bluestore_pextent_t> r;
- b.length = mas * 2;
b.extents.push_back(bluestore_pextent_t(123, mas*2));
b.ref_map.get(0, mas*2);
b.put_ref(0, mas, mrs, &r);
{
bluestore_blob_t b;
vector<bluestore_pextent_t> r;
- b.length = mas * 4;
b.extents.push_back(bluestore_pextent_t(1, mas));
b.extents.push_back(bluestore_pextent_t(2, mas));
b.extents.push_back(bluestore_pextent_t(3, mas));
{
bluestore_blob_t b;
vector<bluestore_pextent_t> r;
- b.length = mas * 6;
b.extents.push_back(bluestore_pextent_t(1, mas));
b.extents.push_back(bluestore_pextent_t(2, mas));
b.extents.push_back(bluestore_pextent_t(3, mas));
{
bluestore_blob_t b;
vector<bluestore_pextent_t> r;
- b.length = mas * 6;
b.extents.push_back(bluestore_pextent_t(1, mas * 6));
b.ref_map.get(0, mas*6);
b.put_ref(mas, mas, mrs, &r);
{
bluestore_blob_t b;
vector<bluestore_pextent_t> r;
- b.length = mas * 12;
b.extents.push_back(bluestore_pextent_t(1, mas * 4));
b.extents.push_back(bluestore_pextent_t(2, mas * 4));
b.extents.push_back(bluestore_pextent_t(3, mas * 4));
{
bluestore_blob_t b;
vector<bluestore_pextent_t> r;
- b.length = mas * 12;
b.extents.push_back(bluestore_pextent_t(1, mas * 4));
b.extents.push_back(bluestore_pextent_t(2, mas * 4));
b.extents.push_back(bluestore_pextent_t(3, mas * 4));
{
bluestore_blob_t b;
vector<bluestore_pextent_t> r;
- b.length = mas * 12;
b.extents.push_back(bluestore_pextent_t(1, mas * 4));
b.extents.push_back(bluestore_pextent_t(2, mas * 4));
b.extents.push_back(bluestore_pextent_t(3, mas * 4));
{
bluestore_blob_t b;
vector<bluestore_pextent_t> r;
- b.length = mas * 8;
b.extents.push_back(bluestore_pextent_t(1, mas * 8));
b.ref_map.get(0, mas*8);
b.put_ref(0, mas, mrs, &r);
{
bluestore_blob_t b;
vector<bluestore_pextent_t> r;
- b.length = mas * 4;
b.extents.push_back(bluestore_pextent_t(0, mas*4));
- b.init_csum(bluestore_blob_t::CSUM_CRC32C, 14, b.length);
+ b.init_csum(bluestore_blob_t::CSUM_CRC32C, 14, mas * 4);
b.ref_map.get(0, mas*4);
ASSERT_TRUE(b.is_allocated(0, mas*4));
b.put_ref(0, mas*3, mrs, &r);