Skip to content

Commit 091e7da

Browse files
mayastor-borstiagolobocastro
mayastor-bors
andcommitted
Merge #1597
1597: fix(rebuild/partial): set bits for written blks only r=tiagolobocastro a=tiagolobocastro The blk used to calculate the end segment was offset by 1 which can lead to rebuilding more data than the one which was actually written into. Example, if we write 1 blk to offset 4, then we only need to rebuild offset 4, and not offset 5 (4 + 1). Co-authored-by: Tiago Castro <tiagolobocastro@gmail.com>
2 parents 6359093 + 5489802 commit 091e7da

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

io-engine/src/core/segment_map.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ impl SegmentMap {
6868
assert_ne!(self.num_blocks, 0);
6969

7070
let start_seg = self.lbn_to_seg(lbn);
71-
let end_seg = self.lbn_to_seg(lbn + lbn_cnt);
71+
// when `lbn_cnt` is 1 means we write only the `lbn` blk, not `lbn` + 1
72+
let end_seg = self.lbn_to_seg(lbn + lbn_cnt - 1);
7273
for i in start_seg ..= end_seg {
7374
self.segments.set(i, value);
7475
}

io-engine/tests/nexus_rebuild_partial.rs

+39
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,45 @@ async fn nexus_partial_rebuild_offline_online() {
364364

365365
// check that 3 segments were rebuilt.
366366
assert_eq!(hist[0].blocks_transferred, 3 * SEG_BLK);
367+
368+
// Offline the replica.
369+
nex_0
370+
.offline_child_replica_wait(&repl_0, Duration::from_secs(1))
371+
.await
372+
.unwrap();
373+
374+
let children = nex_0.get_nexus().await.unwrap().children;
375+
assert_eq!(children[0].state(), ChildState::Degraded);
376+
assert_eq!(children[0].state_reason(), ChildStateReason::ByClient);
377+
378+
validate_replicas(&vec![repl_0.clone(), repl_1.clone()]).await;
379+
380+
test_write_to_nexus(
381+
&nex_0,
382+
DataSize::from_kb_blocks(0, 0),
383+
3,
384+
DataSize::from_kb(64),
385+
)
386+
.await
387+
.unwrap();
388+
389+
// Bring the child online. That will trigger partial rebuild.
390+
nex_0.online_child_replica(&repl_0).await.unwrap();
391+
nex_0
392+
.wait_children_online(std::time::Duration::from_secs(10))
393+
.await
394+
.unwrap();
395+
396+
validate_replicas(&vec![repl_0.clone(), repl_1.clone()]).await;
397+
398+
let hist = nex_0.get_rebuild_history().await.unwrap();
399+
assert_eq!(hist.len(), 2);
400+
assert_eq!(hist[1].child_uri, repl_0.shared_uri());
401+
assert_eq!(hist[1].src_uri, repl_1.shared_uri());
402+
assert!(hist[1].is_partial);
403+
404+
// check that 3 segments were rebuilt.
405+
assert_eq!(hist[1].blocks_transferred, 3 * SEG_BLK);
367406
}
368407

369408
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]

0 commit comments

Comments
 (0)