write: compute all the updates we need and perform them in parallel

When a single request comes in with a set of buffers (e.g. from a large
sequential I/O) we partition the request into unit which align with
the underlying file block structure, and then write almost everything in
parallel. The only metadata which is deliberately left until the end
is the BAT, which has to point to a well-formed block.

Note if we crash half-way through, an arbitrary subset of the [bufs]
will have been committed, but the file metadata will be intact.

Note we still write the whole BAT every time we allocate a block.
We should keep track of which sectors need flushing.

Signed-off-by: David Scott <dave.scott@eu.citrix.com>