summaryrefslogtreecommitdiff
path: root/fs/proc/task_mmu.c
diff options
context:
space:
mode:
authorBrian Norris <computersforpeace@gmail.com>2014-08-19 11:57:23 -0700
committerBrian Norris <computersforpeace@gmail.com>2014-08-19 11:57:23 -0700
commit5b49ab3e03f68eb49db4bce6290e5707b7f6c6f3 (patch)
tree090c7c069bc6c0f2b368ed8d0af861c275525411 /fs/proc/task_mmu.c
parentb25046b1e5e3f1423434da77ccc859f2f779d1ce (diff)
parent54ea17a597b00e46b3720e75dd7595cd5dfa5670 (diff)
Merge l2-mtd/next into l2-mtd/master
Diffstat (limited to 'fs/proc/task_mmu.c')
-rw-r--r--fs/proc/task_mmu.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index cfa63ee92c96..dfc791c42d64 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -925,15 +925,30 @@ static int pagemap_pte_hole(unsigned long start, unsigned long end,
struct mm_walk *walk)
{
struct pagemapread *pm = walk->private;
- unsigned long addr;
+ unsigned long addr = start;
int err = 0;
- pagemap_entry_t pme = make_pme(PM_NOT_PRESENT(pm->v2));
- for (addr = start; addr < end; addr += PAGE_SIZE) {
- err = add_to_pagemap(addr, &pme, pm);
- if (err)
- break;
+ while (addr < end) {
+ struct vm_area_struct *vma = find_vma(walk->mm, addr);
+ pagemap_entry_t pme = make_pme(PM_NOT_PRESENT(pm->v2));
+ unsigned long vm_end;
+
+ if (!vma) {
+ vm_end = end;
+ } else {
+ vm_end = min(end, vma->vm_end);
+ if (vma->vm_flags & VM_SOFTDIRTY)
+ pme.pme |= PM_STATUS2(pm->v2, __PM_SOFT_DIRTY);
+ }
+
+ for (; addr < vm_end; addr += PAGE_SIZE) {
+ err = add_to_pagemap(addr, &pme, pm);
+ if (err)
+ goto out;
+ }
}
+
+out:
return err;
}