Cleanup mmap(2) writes
authorBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 2 Aug 2011 04:28:51 +0000 (21:28 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 2 Aug 2011 17:34:55 +0000 (10:34 -0700)
commit3c0e5c0f455576d045fa443cbab74834d70ded55
treea9c65bf5845dfbf41315efef2e5733a6af82ea9f
parentddd0fd9ef64648333b79b4cc8a13216399cefec9
Cleanup mmap(2) writes

While the existing implementation of .writepage()/zpl_putpage() was
functional it was not entirely correct.  In particular, it would move
dirty pages in to a clean state simply after copying them in to the
ARC cache.  This would result in the pages being lost if the system
were to crash enough though the Linux VFS believed them to be safe on
stable storage.

Since at the moment virtually all I/O, except mmap(2), bypasses the
page cache this isn't as bad as it sounds.  However, as hopefully
start using the page cache more getting this right becomes more
important so it's good to improve this now.

This patch takes a big step in that direction by updating the code
to correctly move dirty pages through a writeback phase before they
are marked clean.  When a dirty page is copied in to the ARC it will
now be set in writeback and a completion callback is registered with
the transaction.  The page will stay in writeback until the dmu runs
the completion callback indicating the page is on stable storage.
At this point the page can be safely marked clean.

This process is normally entirely asynchronous and will be repeated
for every dirty page.  This may initially sound inefficient but most
of these pages will end up in a few txgs.  That means when they are
eventually written to disk they should be nicely batched.  However,
there is room for improvement.  It may still be desirable to batch
up the pages in to larger writes for the dmu.  This would reduce
the number of callbacks and small 4k buffer required by the ARC.

Finally, if the caller requires that the I/O be done synchronously
by setting WB_SYNC_ALL or if ZFS_SYNC_ALWAYS is set.  Then the I/O
will trigger a zil_commit() to flush the data to stable storage.
At which point the registered callbacks will be run leaving the
date safe of disk and marked clean before returning from .writepage.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
include/sys/zfs_vnops.h
module/zfs/zfs_vnops.c
module/zfs/zpl_file.c