2 ==== this is for locking rules etc, not for discussion ===============
4 b->refcnt counts the references to a block. These include:
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
13 If you have a reference to a block, you can always get another 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
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.
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.
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
39 Can be manipulated under mapping->private_lock if it is permitted
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.
48 Set or cleared under ->private_lock. refcounted when ->iblock set.
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.
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).
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
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
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.
75 phase_leafs is protected by fs->lock for walking and manipulation.
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.
83 ------------------------
85 Normally data blocks are not phase-flipped. They simply
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.
91 -------------------------