hammer2 - refactor filesystem sync 4/N
* Save synchronized iroot blockmaps for snapshot code, and use them
in the snapshot code.
* Improve dependency handling and syncq/sideq flagging for
dependencies. Also improve the hammer2_inode_t reordering
code that allows the frontend to continue operating on dirty
inodes simultaneous with a filesystem sync.
* Move inode deletion into the filesystem sync code (in addition to
creation), for the same reason.
* Fix lost ref counts in the snapshot code which were causing umount
panics.
* Stabilization pass on volume flush code. Since flushes stop at
inode boundaries, we must properly flush the superroot before
flushing the volume header. That is, the flush sequence is:
- flush inodes for PFS (flushes inode content)
- flush PFS root inode (flushes through to inodes)
- flush superroot inode (flushes through to PFS root)
- flush volume header (flushes voulume header to superroot)
Theoretically this allows the filesystem asynchronously write data
and inodes flushed by the kernel's buffer cache and vnode code
concurrent with a filesystem flush without messing up filesystem
consistency, because these asynchronously flushed inodes are not
included (or have already been flushed) in the filesystem flush that
is already underway.
* Filesystem consistency still not perfect (using snapshot-debug
directive to test during heavy filesystem modification loads,
directory entries are sometimes desynchronized from their inodes).