Commit 8b1f9ee5 authored by Trond Myklebust's avatar Trond Myklebust

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: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 77f11192
...@@ -392,35 +392,27 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) ...@@ -392,35 +392,27 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page)
struct file *filp = vma->vm_file; struct file *filp = vma->vm_file;
unsigned pagelen; unsigned pagelen;
int ret = -EINVAL; int ret = -EINVAL;
void *fsdata;
struct address_space *mapping; struct address_space *mapping;
loff_t offset;
lock_page(page); lock_page(page);
mapping = page->mapping; mapping = page->mapping;
if (mapping != vma->vm_file->f_path.dentry->d_inode->i_mapping) { if (mapping != vma->vm_file->f_path.dentry->d_inode->i_mapping)
unlock_page(page); goto out_unlock;
return -EINVAL;
} ret = 0;
pagelen = nfs_page_length(page); pagelen = nfs_page_length(page);
offset = (loff_t)page->index << PAGE_CACHE_SHIFT; if (pagelen == 0)
unlock_page(page); goto out_unlock;
/* ret = nfs_flush_incompatible(filp, page);
* we can use mapping after releasing the page lock, because: if (ret != 0)
* we hold mmap_sem on the fault path, which should pin the vma goto out_unlock;
* which should pin the file, which pins the dentry which should
* hold a reference on inode.
*/
if (pagelen) { ret = nfs_updatepage(filp, page, 0, pagelen);
struct page *page2 = NULL; if (ret == 0)
ret = nfs_write_begin(filp, mapping, offset, pagelen, ret = pagelen;
0, &page2, &fsdata); out_unlock:
if (!ret) unlock_page(page);
ret = nfs_write_end(filp, mapping, offset, pagelen,
pagelen, page2, fsdata);
}
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment