aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r--fs/nfs/file.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 579cf8a7d4a7..f2270fff4962 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -33,6 +33,7 @@
33#include <asm/system.h> 33#include <asm/system.h>
34 34
35#include "delegation.h" 35#include "delegation.h"
36#include "internal.h"
36#include "iostat.h" 37#include "iostat.h"
37 38
38#define NFSDBG_FACILITY NFSDBG_FILE 39#define NFSDBG_FACILITY NFSDBG_FILE
@@ -55,6 +56,8 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
55static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); 56static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
56static int nfs_setlease(struct file *file, long arg, struct file_lock **fl); 57static int nfs_setlease(struct file *file, long arg, struct file_lock **fl);
57 58
59static struct vm_operations_struct nfs_file_vm_ops;
60
58const struct file_operations nfs_file_operations = { 61const struct file_operations nfs_file_operations = {
59 .llseek = nfs_file_llseek, 62 .llseek = nfs_file_llseek,
60 .read = do_sync_read, 63 .read = do_sync_read,
@@ -257,8 +260,11 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
257 dentry->d_parent->d_name.name, dentry->d_name.name); 260 dentry->d_parent->d_name.name, dentry->d_name.name);
258 261
259 status = nfs_revalidate_mapping(inode, file->f_mapping); 262 status = nfs_revalidate_mapping(inode, file->f_mapping);
260 if (!status) 263 if (!status) {
261 status = generic_file_mmap(file, vma); 264 vma->vm_ops = &nfs_file_vm_ops;
265 vma->vm_flags |= VM_CAN_NONLINEAR;
266 file_accessed(file);
267 }
262 return status; 268 return status;
263} 269}
264 270
@@ -346,6 +352,31 @@ const struct address_space_operations nfs_file_aops = {
346 .launder_page = nfs_launder_page, 352 .launder_page = nfs_launder_page,
347}; 353};
348 354
355static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page)
356{
357 struct file *filp = vma->vm_file;
358 unsigned pagelen;
359 int ret = -EINVAL;
360
361 lock_page(page);
362 if (page->mapping != vma->vm_file->f_path.dentry->d_inode->i_mapping)
363 goto out_unlock;
364 pagelen = nfs_page_length(page);
365 if (pagelen == 0)
366 goto out_unlock;
367 ret = nfs_prepare_write(filp, page, 0, pagelen);
368 if (!ret)
369 ret = nfs_commit_write(filp, page, 0, pagelen);
370out_unlock:
371 unlock_page(page);
372 return ret;
373}
374
375static struct vm_operations_struct nfs_file_vm_ops = {
376 .fault = filemap_fault,
377 .page_mkwrite = nfs_vm_page_mkwrite,
378};
379
349static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov, 380static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
350 unsigned long nr_segs, loff_t pos) 381 unsigned long nr_segs, loff_t pos)
351{ 382{