Make page-becoming-writable notification a VMA-op only
Subsystems (4)
David Howells
maintainerPATCH 1/1 Make page-becoming-writable notification a VMA-op only
In reply to a message not in the archiveThe attached patch makes the page-becoming-writable notification a VMA operation only - it removes the equivalent address-space operation and the chaining of the call.
Furthermore, it fixes the kAFS filesystem to take account of this.
Signed-off-by David Howells <[email protected]>
---
warthog>diffstat -p1 cachefs-2612rc1mm3.diff
fs/afs/file.c | 30 ++++++++++++++++++++++++++---- include/linux/fs.h | 3 --- mm/filemap.c | 19 +------------------ 3 files changed, 27 insertions(+), 25 deletions(-)
fs/afs/file.c +26 -4
@@ -33,8 +33,10 @@static ssize_t afs_file_write (struct file *file,const char __user *buf,size_t size,loff_t *off); +static int afs_file_mmap (struct file * file,struct vm_area_struct * vma); +#ifdef CONFIG_AFS_FSCACHE -static int afs_file_page_mkwrite (struct page *page); +static int afs_file_page_mkwrite (struct vm_area_struct *vma,struct page *page);#endif struct inode_operations afs_file_inode_operations = {
@@ -44,7 +46,7 @@struct file_operations afs_file_file_operations = { .read = generic_file_read, .write = afs_file_write, - .mmap = generic_file_mmap, + .mmap = afs_file_mmap, #if 0 .open = afs_file_open, .release = afs_file_release,
@@ -58,6 +60,11 @@ .set_page_dirty = __set_page_dirty_nobuffers, .releasepage = afs_file_releasepage, .invalidatepage = afs_file_invalidatepage, +}; + +struct vm_operations_struct afs_fs_vm_operations = { + .nopage = filemap_nopage, + .populate = filemap_populate, #ifdef CONFIG_AFS_FSCACHE .page_mkwrite = afs_file_page_mkwrite, #endif
@@ -81,6 +88,20 @@/*****************************************************************************/ /* +* set up a memory mapping on an AFS file +* - we set our own VMA ops so that we can catch the page becoming writable for +* userspace for shared-writable mmap +*/ +static int afs_file_mmap (struct file *file,struct vm_area_struct *vma) +{ +file_accessed (file); + vma->vm_ops = &afs_fs_vm_operations; +return 0 ; + +}/* end afs_file_mmap() */ + +/*****************************************************************************/ +/* * deal with notification that a page was read from the cache */ #ifdef CONFIG_AFS_FSCACHE
@@ -318,10 +339,11 @@/*****************************************************************************/ /* -* wait for the disc cache to finish writing before permitting +* wait for the disc cache to finish writing before permitting modification of +* our page in the page cache */ #ifdef CONFIG_AFS_FSCACHE -static int afs_file_page_mkwrite (struct page *page) +static int afs_file_page_mkwrite (struct vm_area_struct *vma,struct page *page) {wait_on_page_fs_misc (page);return 0 ;
include/linux/fs.h +0 -3
@@ -332,9 +332,6 @@int (*releasepage) (struct page *,int );ssize_t (*direct_IO)(int ,struct kiocb *,const struct iovec *iov,loff_t offset,unsigned long nr_segs); - -/* notification that a page is about to become writable */ -int (*page_mkwrite)(struct page *page); };struct backing_dev_info ;
mm/filemap.c +1 -18
@@ -1535,25 +1535,11 @@return 0 ; } -/* -* pass notification that a page is becoming writable up to the filesystem -*/ -static int filemap_page_mkwrite (struct vm_area_struct *vma,struct page *page) -{ -return page->mapping->a_ops->page_mkwrite (page); -} -struct vm_operations_struct generic_file_vm_ops = { .nopage = filemap_nopage, .populate = filemap_populate, }; -struct vm_operations_struct generic_file_vm_mkwr_ops = { - .nopage = filemap_nopage, - .populate = filemap_populate, - .page_mkwrite = filemap_page_mkwrite, -}; -/* This is used for a general mmap of a disk file */ int generic_file_mmap (struct file * file,struct vm_area_struct * vma)
@@ -1563,10 +1549,7 @@if (!mapping->a_ops->readpage)return -ENOEXEC ;file_accessed (file); -if (!mapping->a_ops->page_mkwrite) - vma->vm_ops = &generic_file_vm_ops; -else - vma->vm_ops = &generic_file_vm_mkwr_ops; + vma->vm_ops = &generic_file_vm_ops;return 0 ; }EXPORT_SYMBOL (filemap_populate);