From d0217ac04ca6591841e5665f518e38064f4e65bd Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Thu, 19 Jul 2007 01:47:03 -0700 Subject: mm: fault feedback #1 Change ->fault prototype. We now return an int, which contains VM_FAULT_xxx code in the low byte, and FAULT_RET_xxx code in the next byte. FAULT_RET_ code tells the VM whether a page was found, whether it has been locked, and potentially other things. This is not quite the way he wanted it yet, but that's changed in the next patch (which requires changes to arch code). This means we no longer set VM_CAN_INVALIDATE in the vma in order to say that a page is locked which requires filemap_nopage to go away (because we can no longer remain backward compatible without that flag), but we were going to do that anyway. struct fault_data is renamed to struct vm_fault as Linus asked. address is now a void __user * that we should firmly encourage drivers not to use without really good reason. The page is now returned via a page pointer in the vm_fault struct. Signed-off-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/shmem.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) (limited to 'mm/shmem.c') diff --git a/mm/shmem.c b/mm/shmem.c index 6b44440f1b24..0a555af8733d 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1309,29 +1309,21 @@ failed: return error; } -static struct page *shmem_fault(struct vm_area_struct *vma, - struct fault_data *fdata) +static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct inode *inode = vma->vm_file->f_path.dentry->d_inode; - struct page *page = NULL; int error; + int ret; - BUG_ON(!(vma->vm_flags & VM_CAN_INVALIDATE)); + if (((loff_t)vmf->pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode)) + return VM_FAULT_SIGBUS; - if (((loff_t)fdata->pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode)) { - fdata->type = VM_FAULT_SIGBUS; - return NULL; - } - - error = shmem_getpage(inode, fdata->pgoff, &page, - SGP_FAULT, &fdata->type); - if (error) { - fdata->type = ((error == -ENOMEM)?VM_FAULT_OOM:VM_FAULT_SIGBUS); - return NULL; - } + error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_FAULT, &ret); + if (error) + return ((error == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS); - mark_page_accessed(page); - return page; + mark_page_accessed(vmf->page); + return ret | FAULT_RET_LOCKED; } #ifdef CONFIG_NUMA @@ -1378,7 +1370,7 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma) { file_accessed(file); vma->vm_ops = &shmem_vm_ops; - vma->vm_flags |= VM_CAN_INVALIDATE | VM_CAN_NONLINEAR; + vma->vm_flags |= VM_CAN_NONLINEAR; return 0; } @@ -2560,6 +2552,5 @@ int shmem_zero_setup(struct vm_area_struct *vma) fput(vma->vm_file); vma->vm_file = file; vma->vm_ops = &shmem_vm_ops; - vma->vm_flags |= VM_CAN_INVALIDATE; return 0; } -- cgit v1.2.3