NFS: Optimize fallocate by refreshing mapping when needed.
authorNeilBrown <neilb@suse.com>
Mon, 24 Jul 2017 03:18:50 +0000 (13:18 +1000)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Thu, 27 Jul 2017 15:22:42 +0000 (11:22 -0400)
commit6ba80d4348bd8cce2a0a6bbc21e5e1e760de42a9
tree592990a3381e71fe05b07604006f52f456071d0a
parent442ce0499c0535f8972b68fa1fda357357a5c953
NFS: Optimize fallocate by refreshing mapping when needed.

posix_fallocate() will allocate space in an NFS file by considering
the last byte of every 4K block.  If it is before EOF, it will read
the byte and if it is zero, a zero is written out.  If it is after EOF,
the zero is unconditionally written.

For the blocks beyond EOF, if NFS believes its cache is valid, it will
expand these writes to write full pages, and then will merge the pages.
This results if (typically) 1MB writes.  If NFS believes its cache is
not valid (particularly if NFS_INO_INVALID_DATA or
NFS_INO_REVAL_PAGECACHE are set - see nfs_write_pageuptodate()), it will
send the individual 1-byte writes. This results in (typically) 256 times
as many RPC requests, and can be substantially slower.

Currently nfs_revalidate_mapping() is only used when reading a file or
mmapping a file, as these are times when the content needs to be
up-to-date.  Writes don't generally need the cache to be up-to-date, but
writes beyond EOF can benefit, particularly in the posix_fallocate()
case.

So this patch calls nfs_revalidate_mapping() when writing beyond EOF -
i.e. when there is a gap between the end of the file and the start of
the write.  If the cache is thought to be out of date (as happens after
taking a file lock), this will cause a GETATTR, and the two flags
mentioned above will be cleared.  With this, posix_fallocate() on a
newly locked file does not generate excessive tiny writes.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
fs/nfs/file.c