hammer2 - Revamp flush and xopq mechanism, stabilization
* Originally the xopq mechanism was meant to allow multiple worker
threads to share the same queue in a NxM configuration, but for
all intents and purposes we changed to a one-queue-per-thread
mechanic. Formalize this by associating the queue directly with
the thread structure.
* Separate out strategy-related XOPs from vnop-related XOPs, using half
the worker threads for strategy XOPs and the other half for vnop XOPs.
This fixes at least one deadlock which could occur if a strategy XOP
was queued after a vnop on the same worker thread. Since the
buffers related to the strategy XOP were locked, it could prevent
the vnop ahead of it from being able to execute.
* Cleanup the xopq sleep/wakeup mechanism and also fix a 30-60 second
stall when a xop-xop dependency is present on the same queue. The
clearing of the older xop was not waking up the worker thread.
* Revamp the transaction code, putpages via UIO_NOCOPY vop_write's,
and vop_strategy, to allow all buffer-cache-related I/Os to execute
concurrent with a flush. This fixes several deadlocks and long stalls
that could occur during flushes. Nominal modifying vnops will still
interlock with flushes, for now.
* Remove the PREFLUSH flag, it is no longer relevant.
* NOTE - Flush code probably doesn't completely handle modifying races
yet and needs more work. However, such races should be restricted to
buffer-cache-related I/Os only and thus it should be possible to
interlock them on an inode-by-inode basis.