Commit 4899f9c8 authored by Nick Piggin's avatar Nick Piggin Committed by Linus Torvalds

nfs: convert to new aops

[akpm@linux-foundation.org: fix against git-nfs]
[peterz@infradead.org: fix against git-nfs]
Signed-off-by: default avatarNick Piggin <npiggin@suse.de>
Acked-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a20fa20c
...@@ -306,27 +306,50 @@ nfs_fsync(struct file *file, struct dentry *dentry, int datasync) ...@@ -306,27 +306,50 @@ nfs_fsync(struct file *file, struct dentry *dentry, int datasync)
} }
/* /*
* This does the "real" work of the write. The generic routine has * This does the "real" work of the write. We must allocate and lock the
* allocated the page, locked it, done all the page alignment stuff * page to be sent back to the generic routine, which then copies the
* calculations etc. Now we should just copy the data from user * data from user space.
* space and write it back to the real medium..
* *
* If the writer ends up delaying the write, the writer needs to * If the writer ends up delaying the write, the writer needs to
* increment the page use counts until he is done with the page. * increment the page use counts until he is done with the page.
*/ */
static int nfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) static int nfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{ {
return nfs_flush_incompatible(file, page); int ret;
pgoff_t index;
struct page *page;
index = pos >> PAGE_CACHE_SHIFT;
page = __grab_cache_page(mapping, index);
if (!page)
return -ENOMEM;
*pagep = page;
ret = nfs_flush_incompatible(file, page);
if (ret) {
unlock_page(page);
page_cache_release(page);
}
return ret;
} }
static int nfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) static int nfs_write_end(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata)
{ {
long status; unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
int status;
lock_kernel(); lock_kernel();
status = nfs_updatepage(file, page, offset, to-offset); status = nfs_updatepage(file, page, offset, copied);
unlock_kernel(); unlock_kernel();
return status;
unlock_page(page);
page_cache_release(page);
return status < 0 ? status : copied;
} }
static void nfs_invalidate_page(struct page *page, unsigned long offset) static void nfs_invalidate_page(struct page *page, unsigned long offset)
...@@ -354,8 +377,8 @@ const struct address_space_operations nfs_file_aops = { ...@@ -354,8 +377,8 @@ const struct address_space_operations nfs_file_aops = {
.set_page_dirty = __set_page_dirty_nobuffers, .set_page_dirty = __set_page_dirty_nobuffers,
.writepage = nfs_writepage, .writepage = nfs_writepage,
.writepages = nfs_writepages, .writepages = nfs_writepages,
.prepare_write = nfs_prepare_write, .write_begin = nfs_write_begin,
.commit_write = nfs_commit_write, .write_end = nfs_write_end,
.invalidatepage = nfs_invalidate_page, .invalidatepage = nfs_invalidate_page,
.releasepage = nfs_release_page, .releasepage = nfs_release_page,
#ifdef CONFIG_NFS_DIRECTIO #ifdef CONFIG_NFS_DIRECTIO
...@@ -369,18 +392,35 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) ...@@ -369,18 +392,35 @@ 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;
loff_t offset;
lock_page(page); lock_page(page);
if (page->mapping != vma->vm_file->f_path.dentry->d_inode->i_mapping) mapping = page->mapping;
goto out_unlock; if (mapping != vma->vm_file->f_path.dentry->d_inode->i_mapping) {
unlock_page(page);
return -EINVAL;
}
pagelen = nfs_page_length(page); pagelen = nfs_page_length(page);
if (pagelen == 0) offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
goto out_unlock;
ret = nfs_prepare_write(filp, page, 0, pagelen);
if (!ret)
ret = nfs_commit_write(filp, page, 0, pagelen);
out_unlock:
unlock_page(page); unlock_page(page);
/*
* 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.
*/
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);
}
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