+ .migratepage = nfs_migrate_page,
+ .launder_page = nfs_launder_page,
+ .error_remove_page = generic_error_remove_page,
+};
+
+/*
+ * Notification that a PTE pointing to an NFS page is about to be made
+ * writable, implying that someone is about to modify the page through a
+ * shared-writable mapping
+ */
+static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ struct page *page = vmf->page;
+ struct file *filp = vma->vm_file;
+ struct dentry *dentry = filp->f_path.dentry;
+ unsigned pagelen;
+ int ret = -EINVAL;
+ struct address_space *mapping;
+
+ dfprintk(PAGECACHE, "NFS: vm_page_mkwrite(%s/%s(%ld), offset %lld)\n",
+ dentry->d_parent->d_name.name, dentry->d_name.name,
+ filp->f_mapping->host->i_ino,
+ (long long)page_offset(page));
+
+ /* make sure the cache has finished storing the page */
+ nfs_fscache_wait_on_page_write(NFS_I(dentry->d_inode), page);
+
+ lock_page(page);
+ mapping = page->mapping;
+ if (mapping != dentry->d_inode->i_mapping)
+ goto out_unlock;
+
+ ret = 0;
+ pagelen = nfs_page_length(page);
+ if (pagelen == 0)
+ goto out_unlock;
+
+ ret = nfs_flush_incompatible(filp, page);
+ if (ret != 0)
+ goto out_unlock;
+
+ ret = nfs_updatepage(filp, page, 0, pagelen);
+out_unlock:
+ if (!ret)
+ return VM_FAULT_LOCKED;
+ unlock_page(page);
+ return VM_FAULT_SIGBUS;
+}
+
+static const struct vm_operations_struct nfs_file_vm_ops = {
+ .fault = filemap_fault,
+ .page_mkwrite = nfs_vm_page_mkwrite,