diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-01-22 17:13:06 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-01-30 02:05:23 -0500 |
commit | 8b1f9ee56e21e505a3d5d3e33f823006d1abdbaf (patch) | |
tree | 4f26bf0ceb4f834040e02cefc6385087a25ad6ba /fs/nfs/file.c | |
parent | 77f111929d024165e736e919187cff017279bebe (diff) | |
download | lwn-8b1f9ee56e21e505a3d5d3e33f823006d1abdbaf.tar.gz lwn-8b1f9ee56e21e505a3d5d3e33f823006d1abdbaf.zip |
NFS: Optimise nfs_vm_page_mkwrite()
The current model locks the page twice for no good reason. Optimise by
inlining the parts of nfs_write_begin()/nfs_write_end() that we care about.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r-- | fs/nfs/file.c | 36 |
1 files changed, 14 insertions, 22 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index b3bb89f7d5d2..4560fc2ddb4a 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -392,35 +392,27 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) struct file *filp = vma->vm_file; unsigned pagelen; int ret = -EINVAL; - void *fsdata; struct address_space *mapping; - loff_t offset; lock_page(page); mapping = page->mapping; - if (mapping != vma->vm_file->f_path.dentry->d_inode->i_mapping) { - unlock_page(page); - return -EINVAL; - } + if (mapping != vma->vm_file->f_path.dentry->d_inode->i_mapping) + goto out_unlock; + + ret = 0; pagelen = nfs_page_length(page); - offset = (loff_t)page->index << PAGE_CACHE_SHIFT; - unlock_page(page); + if (pagelen == 0) + goto out_unlock; - /* - * we can use mapping after releasing the page lock, because: - * we hold mmap_sem on the fault path, which should pin the vma - * which should pin the file, which pins the dentry which should - * hold a reference on inode. - */ + ret = nfs_flush_incompatible(filp, page); + if (ret != 0) + goto out_unlock; - if (pagelen) { - struct page *page2 = NULL; - ret = nfs_write_begin(filp, mapping, offset, pagelen, - 0, &page2, &fsdata); - if (!ret) - ret = nfs_write_end(filp, mapping, offset, pagelen, - pagelen, page2, fsdata); - } + ret = nfs_updatepage(filp, page, 0, pagelen); + if (ret == 0) + ret = pagelen; +out_unlock: + unlock_page(page); return ret; } |