aboutsummaryrefslogtreecommitdiffstats
path: root/mm/shmem.c
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2007-07-19 04:47:03 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-19 13:04:41 -0400
commitd0217ac04ca6591841e5665f518e38064f4e65bd (patch)
treed3309094bb734d34773f97d642593e298a5cfcfc /mm/shmem.c
parented2f2f9b3ff8debdf512f7687b232c3c1d7d60d7 (diff)
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 <npiggin@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/shmem.c')
-rw-r--r--mm/shmem.c29
1 files changed, 10 insertions, 19 deletions
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:
1309 return error; 1309 return error;
1310} 1310}
1311 1311
1312static struct page *shmem_fault(struct vm_area_struct *vma, 1312static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1313 struct fault_data *fdata)
1314{ 1313{
1315 struct inode *inode = vma->vm_file->f_path.dentry->d_inode; 1314 struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
1316 struct page *page = NULL;
1317 int error; 1315 int error;
1316 int ret;
1318 1317
1319 BUG_ON(!(vma->vm_flags & VM_CAN_INVALIDATE)); 1318 if (((loff_t)vmf->pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode))
1319 return VM_FAULT_SIGBUS;
1320 1320
1321 if (((loff_t)fdata->pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode)) { 1321 error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_FAULT, &ret);
1322 fdata->type = VM_FAULT_SIGBUS; 1322 if (error)
1323 return NULL; 1323 return ((error == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS);
1324 }
1325
1326 error = shmem_getpage(inode, fdata->pgoff, &page,
1327 SGP_FAULT, &fdata->type);
1328 if (error) {
1329 fdata->type = ((error == -ENOMEM)?VM_FAULT_OOM:VM_FAULT_SIGBUS);
1330 return NULL;
1331 }
1332 1324
1333 mark_page_accessed(page); 1325 mark_page_accessed(vmf->page);
1334 return page; 1326 return ret | FAULT_RET_LOCKED;
1335} 1327}
1336 1328
1337#ifdef CONFIG_NUMA 1329#ifdef CONFIG_NUMA
@@ -1378,7 +1370,7 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
1378{ 1370{
1379 file_accessed(file); 1371 file_accessed(file);
1380 vma->vm_ops = &shmem_vm_ops; 1372 vma->vm_ops = &shmem_vm_ops;
1381 vma->vm_flags |= VM_CAN_INVALIDATE | VM_CAN_NONLINEAR; 1373 vma->vm_flags |= VM_CAN_NONLINEAR;
1382 return 0; 1374 return 0;
1383} 1375}
1384 1376
@@ -2560,6 +2552,5 @@ int shmem_zero_setup(struct vm_area_struct *vma)
2560 fput(vma->vm_file); 2552 fput(vma->vm_file);
2561 vma->vm_file = file; 2553 vma->vm_file = file;
2562 vma->vm_ops = &shmem_vm_ops; 2554 vma->vm_ops = &shmem_vm_ops;
2563 vma->vm_flags |= VM_CAN_INVALIDATE;
2564 return 0; 2555 return 0;
2565} 2556}