HAMMER 14/many - historical access cleanup, itimes, bug fixes.
With this commit most historical accesses work and I can go through at least
two cycles of cpdup / rm -rf without crashing.
* Fix a bug in the B-Tree code related to searches on historical records.
These records are differentiated by key.create_tid but unlike the rest
of the key the matching algorithm has to be somewhat more sophisticated.
e.g. A search as of time 10 needs to find a record with a create_tid of 5.
To make this work properly we use a trick when we generate the separator
when splitting a leaf. see hammer_btree.c / hammer_make_separator().
* Recycle inodes a link count of 0 immediately.
* Optimization: Do not flush backing store to disk on reclaim.
* Add a per-inode read-only flag. Mark all historical inodes as read-only
* Implement read-only semantics in the vnops and assert attempts to modify
inodes marked read-only.
* Properly record the last transaction id for use when synchronizing
inodes to the platter. There were a few cases when late synchronizations
were using the wrong transaction id, breaking user expectations when
accessing historical data after a sync.
* Update the itimes (atime and mtime). These are non-historical updates by
default (meaning we just overwrite the latest inode record instead of
deleting it and inserting a new one). A future mount option will allow
these updates to operate historically (the coding is trivial)... didn't
you always want to know the last time a file was accessed prior to a
particular date? Think about it...
* Fix an inode memory leak. The inode in-memory structure must be freed
on last reference. There were cases where it was being left in the
HAMMER cache.
* Optimization: Reduce vnode scan overhead during 'sync' by improving
on the inode flags which indicate that some sort of sync is required.
* Optimization: Don't flush inodes when their link count drops by 1, try
to only flush them when their link drops to 0.
* Fix a couple of potential deadlocks.
* Fix a case in the vnops code where an inode was not being properly flagged
as being dirty.