projects
/
platform
/
adaptation
/
renesas_rcar
/
renesas_kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
vfs: fix data corruption when blocksize < pagesize for mmaped data
[platform/adaptation/renesas_rcar/renesas_kernel.git]
/
mm
/
nommu.c
diff --git
a/mm/nommu.c
b/mm/nommu.c
index
8740213
..
3ee4f74
100644
(file)
--- a/
mm/nommu.c
+++ b/
mm/nommu.c
@@
-15,6
+15,7
@@
#include <linux/export.h>
#include <linux/mm.h>
#include <linux/export.h>
#include <linux/mm.h>
+#include <linux/vmacache.h>
#include <linux/mman.h>
#include <linux/swap.h>
#include <linux/file.h>
#include <linux/mman.h>
#include <linux/swap.h>
#include <linux/file.h>
@@
-768,16
+769,23
@@
static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
*/
static void delete_vma_from_mm(struct vm_area_struct *vma)
{
*/
static void delete_vma_from_mm(struct vm_area_struct *vma)
{
+ int i;
struct address_space *mapping;
struct mm_struct *mm = vma->vm_mm;
struct address_space *mapping;
struct mm_struct *mm = vma->vm_mm;
+ struct task_struct *curr = current;
kenter("%p", vma);
protect_vma(vma, 0);
mm->map_count--;
kenter("%p", vma);
protect_vma(vma, 0);
mm->map_count--;
- if (mm->mmap_cache == vma)
- mm->mmap_cache = NULL;
+ for (i = 0; i < VMACACHE_SIZE; i++) {
+ /* if the vma is cached, invalidate the entire cache */
+ if (curr->vmacache[i] == vma) {
+ vmacache_invalidate(curr->mm);
+ break;
+ }
+ }
/* remove the VMA from the mapping */
if (vma->vm_file) {
/* remove the VMA from the mapping */
if (vma->vm_file) {
@@
-825,8
+833,8
@@
struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
struct vm_area_struct *vma;
/* check the cache first */
struct vm_area_struct *vma;
/* check the cache first */
- vma =
ACCESS_ONCE(mm->mmap_cache
);
- if (
vma && vma->vm_start <= addr && vma->vm_end > addr
)
+ vma =
vmacache_find(mm, addr
);
+ if (
likely(vma)
)
return vma;
/* trawl the list (there may be multiple mappings in which addr
return vma;
/* trawl the list (there may be multiple mappings in which addr
@@
-835,7
+843,7
@@
struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
if (vma->vm_start > addr)
return NULL;
if (vma->vm_end > addr) {
if (vma->vm_start > addr)
return NULL;
if (vma->vm_end > addr) {
-
mm->mmap_cache = vma
;
+
vmacache_update(addr, vma)
;
return vma;
}
}
return vma;
}
}
@@
-874,8
+882,8
@@
static struct vm_area_struct *find_vma_exact(struct mm_struct *mm,
unsigned long end = addr + len;
/* check the cache first */
unsigned long end = addr + len;
/* check the cache first */
- vma =
mm->mmap_cache
;
- if (vma
&& vma->vm_start == addr && vma->vm_end == end
)
+ vma =
vmacache_find_exact(mm, addr, end)
;
+ if (vma)
return vma;
/* trawl the list (there may be multiple mappings in which addr
return vma;
/* trawl the list (there may be multiple mappings in which addr
@@
-886,7
+894,7
@@
static struct vm_area_struct *find_vma_exact(struct mm_struct *mm,
if (vma->vm_start > addr)
return NULL;
if (vma->vm_end == end) {
if (vma->vm_start > addr)
return NULL;
if (vma->vm_end == end) {
-
mm->mmap_cache = vma
;
+
vmacache_update(addr, vma)
;
return vma;
}
}
return vma;
}
}