/*
         * O_APPEND implies that we must revalidate the file length.
         */
-       if (iocb->ki_flags & IOCB_APPEND) {
+       if (iocb->ki_flags & IOCB_APPEND || iocb->ki_pos > i_size_read(inode)) {
                result = nfs_revalidate_file_size(inode, file);
                if (result)
                        goto out;
        }
-       if (iocb->ki_pos > i_size_read(inode))
-               nfs_revalidate_mapping(inode, file->f_mapping);
 
        since = filemap_sample_wb_err(file->f_mapping);
        nfs_start_io_write(inode);
 
  * the PageUptodate() flag. In this case, we will need to turn off
  * write optimisations that depend on the page contents being correct.
  */
-static bool nfs_write_pageuptodate(struct page *page, struct inode *inode)
+static bool nfs_write_pageuptodate(struct page *page, struct inode *inode,
+                                  unsigned int pagelen)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
 
        if (nfs_have_delegated_attributes(inode))
                goto out;
-       if (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
+       if (nfsi->cache_validity &
+           (NFS_INO_REVAL_PAGECACHE | NFS_INO_INVALID_SIZE))
                return false;
        smp_rmb();
-       if (test_bit(NFS_INO_INVALIDATING, &nfsi->flags))
+       if (test_bit(NFS_INO_INVALIDATING, &nfsi->flags) && pagelen != 0)
                return false;
 out:
-       if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
+       if (nfsi->cache_validity & NFS_INO_INVALID_DATA && pagelen != 0)
                return false;
        return PageUptodate(page) != 0;
 }
  * If the file is opened for synchronous writes then we can just skip the rest
  * of the checks.
  */
-static int nfs_can_extend_write(struct file *file, struct page *page, struct inode *inode)
+static int nfs_can_extend_write(struct file *file, struct page *page,
+                               struct inode *inode, unsigned int pagelen)
 {
        int ret;
        struct file_lock_context *flctx = inode->i_flctx;
 
        if (file->f_flags & O_DSYNC)
                return 0;
-       if (!nfs_write_pageuptodate(page, inode))
+       if (!nfs_write_pageuptodate(page, inode, pagelen))
                return 0;
        if (NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE))
                return 1;
        struct nfs_open_context *ctx = nfs_file_open_context(file);
        struct address_space *mapping = page_file_mapping(page);
        struct inode    *inode = mapping->host;
+       unsigned int    pagelen = nfs_page_length(page);
        int             status = 0;
 
        nfs_inc_stats(inode, NFSIOS_VFSUPDATEPAGE);
        if (!count)
                goto out;
 
-       if (nfs_can_extend_write(file, page, inode)) {
-               count = max(count + offset, nfs_page_length(page));
+       if (nfs_can_extend_write(file, page, inode, pagelen)) {
+               count = max(count + offset, pagelen);
                offset = 0;
        }