Skip to content

Commit 5259529

Browse files
committed
Check is blk alloced for normal volume write free blk.
In crash recovery case, volume write can write to index and to disk and then crash. In this case index has stale blk ids which are not alloced, but they can be freed next time a write happens on same lba.
1 parent b4f1ad4 commit 5259529

4 files changed

Lines changed: 18 additions & 10 deletions

File tree

conanfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
class HomeBlocksConan(ConanFile):
1111
name = "homeblocks"
12-
version = "5.0.4"
12+
version = "5.0.5"
1313

1414
homepage = "https://github.com/eBay/HomeBlocks"
1515
description = "Block Store built on HomeStore"

src/lib/volume/tests/test_volume_io.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,7 @@ TEST_F(VolumeIOTest, WriteCrash) {
767767
auto vol = volume_list().back();
768768
generate_write_io_single(vol, 1000 /* start_lba */, 100 /* nblks*/);
769769
restart(2);
770+
LOGINFO("First restart done");
770771
// TODO read and verify zeros for no data.
771772

772773
// Crash after journal write. After crash, index should be recovered.
@@ -775,15 +776,17 @@ TEST_F(VolumeIOTest, WriteCrash) {
775776
vol = volume_list().back();
776777
generate_write_io_single(vol, 2000 /* start_lba */, 100 /* nblks*/);
777778
restart(2);
779+
LOGINFO("Second restart done");
778780

779781
vol->verify_data(2000 /* start_lba */, 2100 /* max_lba */, 25 /* nlbas_per_io */);
780-
782+
LOGINFO("Verify data done");
781783
// remove the flip points
782784
for (auto& flip : flip_points) {
783785
g_helper->remove_flip(flip);
784786
}
785787

786788
generate_write_io_single(vol, 1000 /* start_lba */, 100 /* nblks*/);
789+
LOGINFO("Verify data done");
787790
LOGINFO("WriteCrash test done");
788791
}
789792

src/lib/volume/volume.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ VolumeManager::NullAsyncResult Volume::write(const vol_interface_req_ptr& vol_re
213213
std::vector< homestore::MultiBlkId > new_blkids;
214214
auto result = rd()->alloc_blks(data_size, hints, new_blkids);
215215
if (result) {
216-
LOGE("Failed to allocate blocks");
216+
LOGE("Failed to allocate blocks data_size={}", data_size);
217217
return std::unexpected(VolumeError::NO_SPACE_LEFT);
218218
}
219219
COUNTER_INCREMENT(*metrics_, volume_write_count, 1);
@@ -239,7 +239,7 @@ VolumeManager::NullAsyncResult Volume::write(const vol_interface_req_ptr& vol_re
239239
lba_t start_lba = vol_req->lba;
240240
for (auto& blkid : new_blkids) {
241241
DEBUG_ASSERT_EQ(blkid.num_pieces(), 1, "Multiple blkid pieces");
242-
LOGT("volume write blkid={} lba={}", blkid.to_integer(), start_lba);
242+
LOGT("volume write blkid={} start_lba={}", blkid.to_string(), start_lba);
243243

244244
// Split the large blkid to individual blkid having only one block because each LBA points
245245
// to a blkid containing single blk which is stored in index value. Calculate the checksum for each
@@ -248,8 +248,8 @@ VolumeManager::NullAsyncResult Volume::write(const vol_interface_req_ptr& vol_re
248248
auto new_bid = BlkId{blkid.blk_num() + i, 1 /* nblks */, blkid.chunk_num()};
249249
auto csum = crc16_t10dif(init_crc_16, static_cast< unsigned char* >(data_buffer), blk_size);
250250
blocks_info.emplace(start_lba + i, BlockInfo{new_bid, BlkId{}, csum});
251-
LOGT("volume write blkid={} csum={} lba={}", new_bid.to_string(),
252-
blocks_info[start_lba + i].new_checksum, start_lba + i);
251+
LOGT("volume write blkid={} csum={} start_lba={} lba={}", new_bid.to_string(),
252+
blocks_info[start_lba + i].new_checksum, start_lba, start_lba + i);
253253
data_buffer += blk_size;
254254
}
255255

@@ -267,7 +267,10 @@ VolumeManager::NullAsyncResult Volume::write(const vol_interface_req_ptr& vol_re
267267
vol_req->journal_start_time = Clock::now();
268268
// Collect all old blocks to write to journal.
269269
for (auto& [_, info] : blocks_info) {
270-
if (info.old_blkid.is_valid()) { old_blkids.emplace_back(info.old_blkid); }
270+
if (info.old_blkid.is_valid()) {
271+
LOGT("volume write start_lba={} old blkids={}", vol_req->lba, info.old_blkid.to_string());
272+
old_blkids.emplace_back(info.old_blkid);
273+
}
271274
}
272275

273276
auto csum_size = sizeof(homestore::csum_t) * vol_req->nlbas;

src/lib/volume_mgr.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,12 +370,14 @@ void HomeBlocksImpl::on_write(int64_t lsn, const sisl::blob& header, const sisl:
370370
BlkId old_blkid = *r_cast< const BlkId* >(key_buffer);
371371
if (repl_ctx == nullptr) {
372372
if (homestore::hs()->data_service().is_blk_alloced(old_blkid)) {
373-
LOGT("on_write free blk {} start_lba {}", old_blkid, journal_entry->start_lba);
373+
LOGT("volume write on commit free blk {} start_lba {}", old_blkid, journal_entry->start_lba);
374374
homestore::hs()->data_service().free_blk_now(old_blkid);
375375
}
376376
} else {
377-
LOGT("on_write free blk {} start_lba {}", old_blkid, journal_entry->start_lba);
378-
homestore::hs()->data_service().free_blk_now(old_blkid);
377+
if (homestore::hs()->data_service().is_blk_alloced(old_blkid)) {
378+
LOGT("volume write on commit free blk {} start_lba {}", old_blkid, journal_entry->start_lba);
379+
vol_ptr->rd()->async_free_blks(lsn, old_blkid);
380+
}
379381
}
380382
key_buffer += sizeof(BlkId);
381383
}

0 commit comments

Comments
 (0)