aboutsummaryrefslogtreecommitdiffstats
path: root/mm/shmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/shmem.c')
-rw-r--r--mm/shmem.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index 96fa79fb6ad3..5808fadd3944 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -83,6 +83,7 @@ enum sgp_type {
83 SGP_READ, /* don't exceed i_size, don't allocate page */ 83 SGP_READ, /* don't exceed i_size, don't allocate page */
84 SGP_CACHE, /* don't exceed i_size, may allocate page */ 84 SGP_CACHE, /* don't exceed i_size, may allocate page */
85 SGP_WRITE, /* may exceed i_size, may allocate page */ 85 SGP_WRITE, /* may exceed i_size, may allocate page */
86 SGP_NOPAGE, /* same as SGP_CACHE, return with page locked */
86}; 87};
87 88
88static int shmem_getpage(struct inode *inode, unsigned long idx, 89static int shmem_getpage(struct inode *inode, unsigned long idx,
@@ -1289,8 +1290,10 @@ repeat:
1289 } 1290 }
1290done: 1291done:
1291 if (*pagep != filepage) { 1292 if (*pagep != filepage) {
1292 unlock_page(filepage);
1293 *pagep = filepage; 1293 *pagep = filepage;
1294 if (sgp != SGP_NOPAGE)
1295 unlock_page(filepage);
1296
1294 } 1297 }
1295 return 0; 1298 return 0;
1296 1299
@@ -1310,13 +1313,15 @@ static struct page *shmem_nopage(struct vm_area_struct *vma,
1310 unsigned long idx; 1313 unsigned long idx;
1311 int error; 1314 int error;
1312 1315
1316 BUG_ON(!(vma->vm_flags & VM_CAN_INVALIDATE));
1317
1313 idx = (address - vma->vm_start) >> PAGE_SHIFT; 1318 idx = (address - vma->vm_start) >> PAGE_SHIFT;
1314 idx += vma->vm_pgoff; 1319 idx += vma->vm_pgoff;
1315 idx >>= PAGE_CACHE_SHIFT - PAGE_SHIFT; 1320 idx >>= PAGE_CACHE_SHIFT - PAGE_SHIFT;
1316 if (((loff_t) idx << PAGE_CACHE_SHIFT) >= i_size_read(inode)) 1321 if (((loff_t) idx << PAGE_CACHE_SHIFT) >= i_size_read(inode))
1317 return NOPAGE_SIGBUS; 1322 return NOPAGE_SIGBUS;
1318 1323
1319 error = shmem_getpage(inode, idx, &page, SGP_CACHE, type); 1324 error = shmem_getpage(inode, idx, &page, SGP_NOPAGE, type);
1320 if (error) 1325 if (error)
1321 return (error == -ENOMEM)? NOPAGE_OOM: NOPAGE_SIGBUS; 1326 return (error == -ENOMEM)? NOPAGE_OOM: NOPAGE_SIGBUS;
1322 1327
@@ -1414,6 +1419,7 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
1414{ 1419{
1415 file_accessed(file); 1420 file_accessed(file);
1416 vma->vm_ops = &shmem_vm_ops; 1421 vma->vm_ops = &shmem_vm_ops;
1422 vma->vm_flags |= VM_CAN_INVALIDATE;
1417 return 0; 1423 return 0;
1418} 1424}
1419 1425
@@ -2596,5 +2602,6 @@ int shmem_zero_setup(struct vm_area_struct *vma)
2596 fput(vma->vm_file); 2602 fput(vma->vm_file);
2597 vma->vm_file = file; 2603 vma->vm_file = file;
2598 vma->vm_ops = &shmem_vm_ops; 2604 vma->vm_ops = &shmem_vm_ops;
2605 vma->vm_flags |= VM_CAN_INVALIDATE;
2599 return 0; 2606 return 0;
2600} 2607}