Please enable JavaScript.
Coggle requires JavaScript to display documents.
ublk meta flushing design - Coggle Diagram
ublk meta flushing design
principle
soft update
order metas flushing
triggered by data write IO completion
model data dependency
dedicated meta flushing context
each meta is flushed in sync/dio style
run fsync before flushing each meta
any meta ready for flushing is added to one list, then wakeup meta flushing pthread
any meta flushed is moved to another list, which will be handled in io_uring context
design
describe entry dirty
mark refcount blk entry dirty
add dirty_start index
mark l2 entry dirty
reuse entry reserved bit
can we reuse this dirty info for the cluster's refcount blk entry?
don't use it
mark l1 entry dirty
reuse reserved bit
mark refcount table dirty
reuse reserved bit
mark header dirty
model meta data dependency
l2 slice
when the l2 slice is ready to flush
all dirty entries becomes updated
one new entry is marked as allocated after setting
the entry is changed to updated after the 1st io data is written to image
updated means data has been written to the allocated cluster
but there can be lots of IO written to this cluster
at least one io is written to the cluster pointed by the entry
add one per-slice counter for counting pending ios using entry in allocated state
update all entries into update after the counter becomes zero
when on l2 slice is being flushed, new mapping has to be delayed until the l2 slice becomes clean
check both dirty and being flushed
refcount blk slice
always flushed before l2 slice
can't allocate when the slice is being flushed out
check both dirty and flushing
l1 table
entry is dirty
the entry can be flushed iff all slices are flushed
or store dirty slices & entry idx in one vector
remove one if the slice becomes clean
add one if the slice becomes dirty
add one ready bit?
or simply check all slices are clean
any l2 slice io is done, run this check
not necessary
partition l1 table into 512byte sector, 64 entry in group
if all 64 entries in one group is ready to go, then flush this group
abstract l1_sub_table
u32 id; u64 masks;
if one slice becomes dirty, the slice is added to this sub_table
if one slice becomes clean, the slice is removed from this table
precondition is that the entry is dirty
refcount table
take same approach with l1 table
sync between io thread and meta flushing thread
meta is first put into one to-flush fifo with timestamp
meta is totally usable during this stage
if new entry is added, the meta has to be moved out of to-flush list
when it is ready to flush, meta is moved out of the to-flush fifo and put into flush list
now the meta can't be changed any more
becomes readonly mode
flush list is visible to the flush pthread
after meta is flushed out in the meta flush context
meta is moved into flush_done list
now the meta becomes usable again
if it is originated from dirty free list
free it
requirement
meta data integrity
data loss?
doable
clean design & implementation