Difference between revisions of "Documentation/DnodeSync"

Jump to navigation Jump to search
1,834 bytes added ,  23:49, 7 October 2013
Line 28: Line 28:


However, if we aren't freeing the dnode (which is commonly the case) ''dnode_sync'' goes on to finally sync the dirty in-memory buffers for this dnode to disk. It does this with a call to ''dbuf_sync_list'' on a list of dirty records for the current dnode in the current TXG (stored as ''dbuf_dirty_record_t''s).
However, if we aren't freeing the dnode (which is commonly the case) ''dnode_sync'' goes on to finally sync the dirty in-memory buffers for this dnode to disk. It does this with a call to ''dbuf_sync_list'' on a list of dirty records for the current dnode in the current TXG (stored as ''dbuf_dirty_record_t''s).
At a high-level, that's a good summary of ''dnode_sync'' and many of the relevant fields in the ''dnode_t'' object. However, it's pretty hand-wavey on the two core parts of syncing a dnode to disk: the process of syncing freed blocks (''dnode_sync_free_range'') and the process of syncing dirty/written blocks (''dbuf_sync_list'').
== dnode_sync_free_range ==
As described above, ''dnode_sync_free_range'' manages freeing ranges of L0 blocks in a dnode. It is called on one range at a time by ''dnode_sync'' as it iterates over a dnodes ''dn_ranges'' field.
In the most common case, ''dnode_sync_free_range'' operates by following the basic steps below:
# Given that we are currently at the root of the dnode and that we know how many levels the dnode has, calculate the range (start, end) of blocks in the dnode which completely cover the L0 blocks we have been asked to free.
# Iterate through the block pointers stored in the dnode:
## For each block pointer we encounter, bring the indirect block if points to into memory (via ''dbuf_hold_impl'').
## Call ''free_children'' on that indirect block, passing along the range of L0 blocks we've been asked to free.
## If we've also been asked to free indirect nodes, free the current indirect node after processing of its children has completed.
=== free_children ===
''free_children'' takes an indirect block (L1, L2, ...) in a dnode and a range of L0 blocks to be freed. At a high-level, it handles two cases. If the indirect block passed in is an L1 indirect, that means the block pointers contained point directly to data blocks, some or all of which we wish to free. If the indirect block passed in is higher than an L1, then we need to recursively process the next level of indirect blocks instead, while avoiding traversal of unnecessary blocks.
== dbuf_sync_list ==
Editor
90

edits

Navigation menu