* phase but unpin.
*/
if (test_bit(B_Pinned, &ib->b.flags) &&
- !test_bit(B_PinPending, &ib->b.flags) &&
!test_bit(B_Dirty, &ib->b.flags) &&
!test_bit(B_Realloc, &ib->b.flags) &&
atomic_read(&ib->b.refcnt) == 1 && /* This is us */
/* To (mostly) avoid recursion, we have a loop which may
* walk up to the parent.
* The main reason for holding lafs_hash_lock is that it protects
- * ->lru - i.e. all the lists.
+ * ->lru - i.e. all the lists. FIXME that should be fs->lock
*/
LAFS_BUG(atomic_read(&b->refcnt) == 0, b);
while (b) {
/* We own a ref through blk->parent now, but
* after lafs_incorporate, we might not
*/
- getiref(p,MKREF("addblock"));
+ getiref(p,MKREF(addblock));
lafs_iolock_written(&p->b);
lafs_incorporate(fs, p);
lafs_iounlock_block(&p->b);
- putiref(p,MKREF("addblock"));
+ putiref(p,MKREF(addblock));
return 0;
}
}
- transient references
- ->parent references from children
- - The flags: Dirty, Pinned, Alloc, Realloc, Uninc
- - presence on an ->orphans list (is that B_Orphan?)
+ - The flags: Async, Uninc
+ - presence on an ->orphans list
+ - orphan block which needs to be held on to
- The presence of inode->iblock implies a counted reference through
inode->dblock
+ - presence on lists: leaf (phase,clean,account), cleaning, cluster
+ - ref from sibling with PrimaryRef set
+ - reference from segment summary record
+ - if a block has SegRef set, then it owns a reference on a segsum
+ - every segment in 'table' owns reference on segsum block
If you have a reference to a block, you can always get another reference.
Without a reference:
inode->dblock
Set or cleared under ->private_lock. refcounted when ->iblock set.
+ So if we hold a ref on iblock - possible indirect - then can access
+ directly.
inode->iblock
- Can be set from NULL under ->private_lock, and otherwise can only
- be changed under i_mutex.
- FIXME what do I need to read this given index tree can shrink and grow??
+ Can be set to or from NULL under ->private_lock, otherwise need to be
+ IOLocked to change it.
+ If we hold a ref to a child with parent, then we can access iblock with
+ rcu_dereference
Note that this reference isn't counted. It is similar to a reference
held by the index hash table.
->lru is used for the global list of free indexblocks, and for
- phase_leafs, clean_leafs and a cluster list.
- Membership on the last three is a counted reference.
+ phase_leafs, clean_leafs, account_leaf, cluster list, pending io list
+ Membership on all but first is a counted reference.
So if ->lru is not empty then checking the refcnt can determing if
the block is on the freelist (0) or another list (non-zero).
If we "know" we hold a reference to all possible entries (as cleaner
might) we can safely walk the list, else use private_lock.
+Block flags
+
+ B_Index - never changes, distinguished index block from data blocks
+ B_Root - is root block - there is no parent.
+ B_InoIdx - flags the inodes index block. Can be changed when ->iblock can
+ B_Valid - has been loaded or initialised. Never cleared
+ B_Dirty - For data block, the content has changed and not been written out
+ For index blocks this is set as soon as an address is ready to be
+ incorporated.
+ B_Realloc - as above for cleaning. Should change that to use dirty and have
+ a flag for 'new data' which isn't set by cleaner.
+ B_UnincCredit - have a credit to be passed to parent on incorporation
+ B_Uninc - on an uninc list, so phys addr shouldn't change
+ B_Pinned - pinned to the phase determined by B_Phase1.
+ will be considerred for writing in that phase.
+ must be on leaf list unless has children. or not dirty
+ B_Async - cleaner thread wants this when it is unlocked or written
+ B_Segref - own a refernce on the segsum for physaddr
+ B_Credit B_ICredit B_NCredit B_NICredit
+ B_IOLock - used for various locking.
+
+ B_PinPending - data block should stay pinned even if not dirty.
+ Some thread is working on changing it.
+ Cleaner will just dirty it to clean. writepage will skip
+ should need iolock to set this.
+
+ For index blocks we don't need this and just use refcnt.
+ but there are more refs held on data blocks.
+ I think we mainly need this for writepage and cleaner to ignore
------------------------
Phase filp: