Skip to content

Commit 533505d

Browse files
committed
os/bluestore/writer: Split do_write, add handling of compressed
Split do_write into do_write and do_write_with_blobs. The original is used when only uncompressed data is written. The new one accepts stream of data formatted into blobs; the blobs can be compressed or uncompressed. Add blob_create_full_compressed. Fix do_put_new_blobs to handle compressed. Signed-off-by: Adam Kupczyk <[email protected]>
1 parent 880f4aa commit 533505d

File tree

3 files changed

+85
-9
lines changed

3 files changed

+85
-9
lines changed

src/os/bluestore/Writer.cc

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,15 @@ inline void bluestore_blob_use_tracker_t::init_and_ref(
156156
}
157157
}
158158

159+
inline void bluestore_blob_use_tracker_t::init_and_ref_compressed(
160+
uint32_t logical_length)
161+
{
162+
au_size = logical_length;
163+
num_au = 0;
164+
alloc_au = 0;
165+
total_bytes = logical_length;
166+
}
167+
159168
inline void bluestore_blob_t::allocated_full(
160169
uint32_t length,
161170
PExtentVector&& allocs)
@@ -527,8 +536,6 @@ BlueStore::BlobRef BlueStore::Writer::_blob_create_full(
527536
uint32_t blob_length = disk_data.length();
528537
ceph_assert(p2phase<uint32_t>(blob_length, bstore->min_alloc_size) == 0);
529538
BlobRef blob = onode->c->new_blob();
530-
531-
//uint32_t in_blob_end = disk_data.length();
532539
bluestore_blob_t &bblob = blob->dirty_blob();
533540
uint32_t tracked_unit = min_alloc_size;
534541
uint32_t csum_order = // conv 8 -> 32 so "<<" does not overflow
@@ -538,7 +545,6 @@ BlueStore::BlobRef BlueStore::Writer::_blob_create_full(
538545
bblob.calc_csum(0, disk_data);
539546
tracked_unit = std::max(1u << csum_order, min_alloc_size);
540547
}
541-
//std::cout << "blob_length=" << blob_length << std::endl;
542548
blob->dirty_blob_use_tracker().init_and_ref(blob_length, tracked_unit);
543549
PExtentVector blob_allocs;
544550
_get_disk_space(blob_length, blob_allocs);
@@ -610,6 +616,37 @@ void BlueStore::Writer::_maybe_meld_with_prev_extent(exmp_it it)
610616
}
611617
}
612618

619+
BlueStore::BlobRef BlueStore::Writer::_blob_create_full_compressed(
620+
bufferlist& disk_data,
621+
uint32_t compressed_length,
622+
bufferlist& object_data)
623+
{
624+
uint32_t disk_length = disk_data.length();
625+
uint32_t object_length = object_data.length();
626+
ceph_assert(p2phase<uint32_t>(disk_length, bstore->min_alloc_size) == 0);
627+
BlobRef blob = onode->c->new_blob();
628+
629+
bluestore_blob_t &bblob = blob->dirty_blob();
630+
uint32_t csum_order = // conv 8 -> 32 so "<<" does not overflow
631+
std::min<uint32_t>(wctx->csum_order, std::countr_zero(disk_length));
632+
if (wctx->csum_type != Checksummer::CSUM_NONE) {
633+
bblob.init_csum(wctx->csum_type, csum_order, disk_length);
634+
bblob.calc_csum(0, disk_data);
635+
}
636+
bblob.set_compressed(object_length, compressed_length);
637+
blob->dirty_blob_use_tracker().init_and_ref_compressed(object_length);
638+
PExtentVector blob_allocs;
639+
_get_disk_space(disk_length, blob_allocs);
640+
_schedule_io(blob_allocs, disk_data); //have to do before move()
641+
//todo: we are setting blob's logical length twice
642+
bblob.allocated_full(object_length, std::move(blob_allocs));
643+
//no unused in compressed //bblob.mark_used(0, disk_length);
644+
statfs_delta.compressed_allocated() += disk_length;
645+
statfs_delta.compressed_original() += object_length;
646+
statfs_delta.compressed() += compressed_length;
647+
return blob;
648+
}
649+
613650
/**
614651
* Note from developer
615652
* This module tries to keep naming convention:
@@ -1041,7 +1078,13 @@ void BlueStore::Writer::_do_put_new_blobs(
10411078
logical_offset = ref_end;
10421079
} else {
10431080
// compressed
1044-
ceph_assert(false);
1081+
BlobRef new_blob = _blob_create_full_compressed(
1082+
bd_it->disk_data, bd_it->compressed_length, bd_it->object_data);
1083+
le = new Extent(
1084+
logical_offset, 0, bd_it->real_length, new_blob);
1085+
dout(20) << __func__ << " new compressed extent+blob " << le->print(pp_mode) << dendl;
1086+
emap.insert(*le);
1087+
logical_offset += bd_it->real_length;
10451088
}
10461089
bstore->logger->inc(l_bluestore_write_big);
10471090
bstore->logger->inc(l_bluestore_write_big_bytes, le->length);
@@ -1389,6 +1432,15 @@ void BlueStore::Writer::do_write(
13891432
if (ref_end < onode->onode.size) {
13901433
ref_end = std::min<uint32_t>(data_end, onode->onode.size);
13911434
}
1435+
do_write_with_blobs(location, data_end, ref_end, bd);
1436+
}
1437+
1438+
void BlueStore::Writer::do_write_with_blobs(
1439+
uint32_t location,
1440+
uint32_t data_end,
1441+
uint32_t ref_end,
1442+
blob_vec& bd)
1443+
{
13921444
dout(20) << "blobs to put:" << blob_data_printer(bd, location) << dendl;
13931445
statfs_delta.stored() += ref_end - location;
13941446
exmp_it after_punch_it =
@@ -1399,9 +1451,15 @@ void BlueStore::Writer::do_write(
13991451
// todo: if we align to disk block before splitting, we could do it in one go
14001452
uint32_t pos = location;
14011453
for (auto& b : bd) {
1402-
bstore->_buffer_cache_write(this->txc, onode, pos, b.disk_data,
1403-
wctx->buffered ? 0 : Buffer::FLAG_NOCACHE);
1404-
pos += b.disk_data.length();
1454+
if (b.is_compressed()) {
1455+
bstore->_buffer_cache_write(this->txc, onode, pos, b.object_data,
1456+
wctx->buffered ? 0 : Buffer::FLAG_NOCACHE);
1457+
pos += b.object_data.length();
1458+
} else {
1459+
bstore->_buffer_cache_write(this->txc, onode, pos, b.disk_data,
1460+
wctx->buffered ? 0 : Buffer::FLAG_NOCACHE);
1461+
pos += b.disk_data.length();
1462+
}
14051463
}
14061464
ceph_assert(pos == data_end);
14071465

@@ -1415,10 +1473,13 @@ void BlueStore::Writer::do_write(
14151473
uint32_t location_tmp = location;
14161474
for (auto& i : bd) {
14171475
uint32_t location_end = location_tmp + i.real_length;
1418-
need_size += p2roundup(location_end, au_size) - p2align(location_tmp, au_size);
1476+
if (i.is_compressed()) {
1477+
need_size += p2roundup(i.disk_data.length(), au_size);
1478+
} else {
1479+
need_size += p2roundup(location_end, au_size) - p2align(location_tmp, au_size);
1480+
}
14191481
location_tmp = location_end;
14201482
}
1421-
14221483
_defer_or_allocate(need_size);
14231484
_do_put_blobs(location, data_end, ref_end, bd, after_punch_it);
14241485
} else {

src/os/bluestore/Writer.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ class BlueStore::Writer {
6060
bufferlist& data
6161
);
6262

63+
void do_write_with_blobs(
64+
uint32_t location,
65+
uint32_t data_end,
66+
uint32_t ref_end,
67+
blob_vec& blobs
68+
);
69+
6370
void debug_iterate_buffers(
6471
std::function<void(uint32_t offset, const bufferlist& data)> data_callback
6572
);
@@ -176,6 +183,11 @@ class BlueStore::Writer {
176183
BlobRef _blob_create_full(
177184
bufferlist& disk_data);
178185

186+
BlobRef _blob_create_full_compressed(
187+
bufferlist& disk_data,
188+
uint32_t compressed_length,
189+
bufferlist& object_data);
190+
179191
void _try_reuse_allocated_l(
180192
exmp_it after_punch_it, // hint, we could have found it ourselves
181193
uint32_t& logical_offset, // will fix value if something consumed

src/os/bluestore/bluestore_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,9 @@ struct bluestore_blob_use_tracker_t {
393393
uint32_t full_length,
394394
uint32_t tracked_chunk);
395395

396+
inline void init_and_ref_compressed(
397+
uint32_t logical_length);
398+
396399
void get(
397400
uint32_t offset,
398401
uint32_t len);

0 commit comments

Comments
 (0)