Jason Banham wrote:> Hello,
>
> I''ve been looking at the source code to the transaction engine /
DMU
> and was wondering what the purpose of dn->dn_assigned_txg was
> for?
An object can be modified in many transactions (dmu_tx_t''s)
simultaneously, but they must all be for the same transaction group
(txg). dn_assigned_txg is this transaction group. The DMU''s consumers
specify which objects will be modified by using the dmu_tx_hold_*
routines. If we allowed the object to be modified in multiple txg''s
simultaneously, we there would be "future leak" bugs, where changes
that
should be part of txg N are committed to disk in txg N-1.
(note that we could have implemented a more fine-grained lockout, eg. on
a per-block (ie, per-dbuf) basis, but that would have been more
complicated for little benefit.)
> Looking through the source, I''ve found the dmu_tx structure but
I''m
> afraid I don''t understand it fully and need some extra
comments/help
> here.
>
> The reason I ask is this line of code within dmu_tx_try_assign()
> (from opensolaris source) :
>
> 757 if (dn->dn_assigned_txg == tx->tx_txg - 1) {
This is checking to see if this dnode is already in the middle of being
modified in the previous txg. In this case, the dnode can not be
modified in this txg (tx_txg) until it is finished with the previous
one. (Note, once it is done being modified in the previous txg, we will
make a copy of each block that was modified, so that we preserve the
previous contents until the can be written to disk, but we can also make
new changes.)
> If this condition is true, then tx->tx_needassign_txh is set, which
> has an impact later on if dmu_tx_wait() is called.
> In simple terms, what are we trying to test for here?
When dmu_tx_wait() is called, we may need to wait for a whole new txg to
be open (which takes seconds) -- eg, if we are running low on space and
need to get a more accurate measure of free space. Or we may simply
need to wait for an object to finish being modified as part of a
previous txg (which typically takes microseconds).
> Which brings me onto the next part - for the most part, I see that
> dmu_tx_wait ends up calling txg_wait_open() to move the
> transaction engine along, but when tx_needassign_txh is set
> we end up taking the other condition.
>
> Could someone tell me what this branch of dmu_tx_wait() is designed
> to do?
See above -- we must wait for the object to finish being modified in the
previous txg.
> Apologies if these are dumb questions.
Not at all; this is a tricky piece of code.
--matt