]> git.neil.brown.name Git - LaFS.git/blob - rules.doc
More refcounting fixes and stuff...
[LaFS.git] / rules.doc
1
2 ==== this is for locking rules etc, not for discussion ===============
3
4 b->refcnt counts the references to a block.  These include:
5
6    - transient references
7    - ->parent references from children
8    - The flags:  Dirty, Pinned, Alloc, Realloc, Uninc
9    - presence on an ->orphans list (is that B_Orphan?)
10    - The presence of inode->iblock implies a counted reference through
11              inode->dblock
12
13 If you have a reference to a block, you can always get another reference.
14 Without a reference:
15   A hashtable lookup holding the hashtable spinlock can find an indexblock.
16   A reference from page->private under mapping->private_lock can find a datablock.
17   A ->parent link can be followed 
18            Under private_lock or
19            under i_mutex (for InoIdx, inode->dblock->inode->i_mutex)
20   A ->siblings list can be walked under ->private_lock
21   inode->dblock is permanent - it only goes when the dblock is destroyed
22          If we have a reference to the iblock, then ->dblock can be followed
23          otherwise we need private_lock
24   inode->iblock can take a reference under ->private lock or i_mutex.
25         
26 When you drop a reference:
27   For index blocks, if refcnt hits zero the block must go on the freelist.
28   For data blocks, just drop the reference - memory sweep will find it.
29
30
31 blk->parent:
32
33   If NULL, can be set. under mapping->private_lock
34   If refcnt==0, ->parent can be set to NULL under same lock that allows 
35           us to take a reference
36   Can be changed (for index block split/combine) under i_mutex and ->private_lock
37
38 blk->siblings
39   Can be manipulated under mapping->private_lock if it is permitted
40    to change ->parent
41   Can be walked under ->private_lock or i_mutex
42   When ->parent is NULL blk->siblings is empty for data blocks, and
43   blk->siblings is on LAFSI(inode)->free_index for index blocks.
44   Note that ->free_index is protected by hash_lock, not ->private_lock.
45
46
47 inode->dblock
48    Set or cleared under ->private_lock.  refcounted when ->iblock set.
49
50 inode->iblock
51    Can be set from NULL under ->private_lock, and otherwise can only
52    be changed under i_mutex.
53    FIXME what do I need to read this given index tree can shrink and grow??
54    Note that this reference isn't counted.  It is similar to a reference
55     held by the index hash table.
56
57 ->lru is used for the global list of free indexblocks, and for
58   phase_leafs, clean_leafs and a cluster list.
59   Membership on the last three is a counted reference.
60   So if ->lru is not empty then checking the refcnt can determing if
61   the block is on the freelist (0) or another list (non-zero).
62
63   Once a block gets on a (non-freelist) lru list it stays there until
64   the list owner explicitly removes it.  These lists are protected by
65   fs->lock.
66   Note that a block can get on the wrong list in a number of ways due
67   to various races.  This doesn't matter.  It will eventually be found
68   and dealt with.
69   A block first appears on a *_leafs lists protected by fs->lock.
70   It is eventually allocated by a clean/flush thread and moves to
71   the cluster lists which is protected by a cluster lock.
72   Then it moves to a pending_blocks list protected by fs->lock again.
73   Then it is released.
74
75 phase_leafs is protected by fs->lock for walking and manipulation.
76
77 blk->peers
78    Entries are added under ->private_lock.
79    If we "know" we hold a reference to all possible entries (as cleaner
80    might) we can safely walk the list, else use private_lock.
81
82
83 ------------------------
84 Phase filp:
85  Normally data blocks are not phase-flipped.  They simply
86  loose their pinning.
87  For inode data blocks, when the index block flips, the pinning
88  and reservations are transferred to the datablock which is
89  then written and un-pinned.
90
91 -------------------------
92 Lock ordering:
93
94   ->private_lock
95      fs->lock             phase_flip