aboutsummaryrefslogtreecommitdiffstats
path: root/mm/msync.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/msync.c')
-rw-r--r--mm/msync.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/mm/msync.c b/mm/msync.c
index 632df4527c01..a5c673669ca6 100644
--- a/mm/msync.c
+++ b/mm/msync.c
@@ -58,6 +58,7 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags)
58 vma = find_vma(mm, start); 58 vma = find_vma(mm, start);
59 for (;;) { 59 for (;;) {
60 struct file *file; 60 struct file *file;
61 loff_t fstart, fend;
61 62
62 /* Still start < end. */ 63 /* Still start < end. */
63 error = -ENOMEM; 64 error = -ENOMEM;
@@ -77,12 +78,17 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags)
77 goto out_unlock; 78 goto out_unlock;
78 } 79 }
79 file = vma->vm_file; 80 file = vma->vm_file;
81 fstart = start + ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
82 fend = fstart + (min(end, vma->vm_end) - start) - 1;
80 start = vma->vm_end; 83 start = vma->vm_end;
81 if ((flags & MS_SYNC) && file && 84 if ((flags & MS_SYNC) && file &&
82 (vma->vm_flags & VM_SHARED)) { 85 (vma->vm_flags & VM_SHARED)) {
83 get_file(file); 86 get_file(file);
84 up_read(&mm->mmap_sem); 87 up_read(&mm->mmap_sem);
85 error = vfs_fsync(file, 0); 88 if (vma->vm_flags & VM_NONLINEAR)
89 error = vfs_fsync(file, 1);
90 else
91 error = vfs_fsync_range(file, fstart, fend, 1);
86 fput(file); 92 fput(file);
87 if (error || start >= end) 93 if (error || start >= end)
88 goto out; 94 goto out;