• NeilBrown's avatar
    NFS: invalidate file size when taking a lock. · 442ce049
    NeilBrown authored
    Prior to commit ca0daa27 ("NFS: Cache aggressively when file is open
    for writing"), NFS would revalidate, or invalidate, the file size when
    taking a lock.  Since that commit it only invalidates the file content.
    
    If the file size is changed on the server while wait for the lock, the
    client will have an incorrect understanding of the file size and could
    corrupt data.  This particularly happens when writing beyond the
    (supposed) end of file and can be easily be demonstrated with
    posix_fallocate().
    
    If an application opens an empty file, waits for a write lock, and then
    calls posix_fallocate(), glibc will determine that the underlying
    filesystem doesn't support fallocate (assuming version 4.1 or earlier)
    and will write out a '0' byte at the end of each 4K page in the region
    being fallocated that is after the end of the file.
    NFS will (usually) detect that these writes are beyond EOF and will
    expand them to cover the whole page, and then will merge the pages.
    Consequently, NFS will write out large blocks of zeroes beyond where it
    thought EOF was.  If EOF had moved, the pre-existing part of the file
    will be over-written.  Locking should have protected against this,
    but it doesn't.
    
    This patch restores the use of nfs_zap_caches() which invalidated the
    cached attributes.  When posix_fallocate() asks for the file size, the
    request will go to the server and get a correct answer.
    
    cc: stable@vger.kernel.org (v4.8+)
    Fixes: ca0daa27 ("NFS: Cache aggressively when file is open for writing")
    Signed-off-by: default avatarNeilBrown <neilb@suse.com>
    Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
    442ce049
file.c 22 KB