Blame view
mm/msync.c
2.59 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 |
/* * linux/mm/msync.c * * Copyright (C) 1994-1999 Linus Torvalds */ /* * The msync() system call. */ |
8f2e9f157 [PATCH] msync(): ... |
10 |
#include <linux/fs.h> |
1da177e4c Linux-2.6.12-rc2 |
11 12 |
#include <linux/mm.h> #include <linux/mman.h> |
9c50823ee [PATCH] msync(): ... |
13 |
#include <linux/file.h> |
1da177e4c Linux-2.6.12-rc2 |
14 |
#include <linux/syscalls.h> |
e8edc6e03 Detach sched.h fr... |
15 |
#include <linux/sched.h> |
1da177e4c Linux-2.6.12-rc2 |
16 |
|
1da177e4c Linux-2.6.12-rc2 |
17 18 19 |
/* * MS_SYNC syncs the entire file - including mappings. * |
204ec841f [PATCH] mm: msync... |
20 21 22 23 24 |
* MS_ASYNC does not start I/O (it used to, up to 2.5.67). * Nor does it marks the relevant pages dirty (it used to up to 2.6.17). * Now it doesn't do anything, since dirty pages are properly tracked. * * The application may now run fsync() to |
1da177e4c Linux-2.6.12-rc2 |
25 26 27 |
* write out the dirty pages and wait on the writeout and check the result. * Or the application may run fadvise(FADV_DONTNEED) against the fd to start * async writeout immediately. |
16538c407 The comment descr... |
28 |
* So by _not_ starting I/O in MS_ASYNC we provide complete flexibility to |
1da177e4c Linux-2.6.12-rc2 |
29 30 |
* applications. */ |
6a6160a7b [CVE-2009-0029] S... |
31 |
SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags) |
1da177e4c Linux-2.6.12-rc2 |
32 33 |
{ unsigned long end; |
204ec841f [PATCH] mm: msync... |
34 |
struct mm_struct *mm = current->mm; |
1da177e4c Linux-2.6.12-rc2 |
35 |
struct vm_area_struct *vma; |
676758bdb [PATCH] msync: fi... |
36 37 |
int unmapped_error = 0; int error = -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
38 |
|
1da177e4c Linux-2.6.12-rc2 |
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
if (flags & ~(MS_ASYNC | MS_INVALIDATE | MS_SYNC)) goto out; if (start & ~PAGE_MASK) goto out; if ((flags & MS_ASYNC) && (flags & MS_SYNC)) goto out; error = -ENOMEM; len = (len + ~PAGE_MASK) & PAGE_MASK; end = start + len; if (end < start) goto out; error = 0; if (end == start) goto out; /* * If the interval [start,end) covers some unmapped address ranges, * just ignore them, but return -ENOMEM at the end. */ |
204ec841f [PATCH] mm: msync... |
57 58 59 |
down_read(&mm->mmap_sem); vma = find_vma(mm, start); for (;;) { |
9c50823ee [PATCH] msync(): ... |
60 |
struct file *file; |
7fc34a62c mm/msync.c: sync ... |
61 |
loff_t fstart, fend; |
9c50823ee [PATCH] msync(): ... |
62 |
|
204ec841f [PATCH] mm: msync... |
63 64 65 66 |
/* Still start < end. */ error = -ENOMEM; if (!vma) goto out_unlock; |
1da177e4c Linux-2.6.12-rc2 |
67 68 |
/* Here start < vma->vm_end. */ if (start < vma->vm_start) { |
1da177e4c Linux-2.6.12-rc2 |
69 |
start = vma->vm_start; |
204ec841f [PATCH] mm: msync... |
70 71 72 |
if (start >= end) goto out_unlock; unmapped_error = -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
73 74 |
} /* Here vma->vm_start <= start < vma->vm_end. */ |
204ec841f [PATCH] mm: msync... |
75 76 77 78 |
if ((flags & MS_INVALIDATE) && (vma->vm_flags & VM_LOCKED)) { error = -EBUSY; goto out_unlock; |
1da177e4c Linux-2.6.12-rc2 |
79 |
} |
9c50823ee [PATCH] msync(): ... |
80 |
file = vma->vm_file; |
496a8e686 msync: fix incorr... |
81 82 |
fstart = (start - vma->vm_start) + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); |
7fc34a62c mm/msync.c: sync ... |
83 |
fend = fstart + (min(end, vma->vm_end) - start) - 1; |
1da177e4c Linux-2.6.12-rc2 |
84 |
start = vma->vm_end; |
204ec841f [PATCH] mm: msync... |
85 |
if ((flags & MS_SYNC) && file && |
707c21c84 [PATCH] msync(MS_... |
86 |
(vma->vm_flags & VM_SHARED)) { |
707c21c84 [PATCH] msync(MS_... |
87 |
get_file(file); |
204ec841f [PATCH] mm: msync... |
88 |
up_read(&mm->mmap_sem); |
0661a3361 mm: remove rest u... |
89 |
error = vfs_fsync_range(file, fstart, fend, 1); |
707c21c84 [PATCH] msync(MS_... |
90 |
fput(file); |
204ec841f [PATCH] mm: msync... |
91 92 93 94 |
if (error || start >= end) goto out; down_read(&mm->mmap_sem); vma = find_vma(mm, start); |
9c50823ee [PATCH] msync(): ... |
95 |
} else { |
204ec841f [PATCH] mm: msync... |
96 97 98 99 |
if (start >= end) { error = 0; goto out_unlock; } |
9c50823ee [PATCH] msync(): ... |
100 101 |
vma = vma->vm_next; } |
204ec841f [PATCH] mm: msync... |
102 |
} |
9c50823ee [PATCH] msync(): ... |
103 |
out_unlock: |
204ec841f [PATCH] mm: msync... |
104 |
up_read(&mm->mmap_sem); |
9c50823ee [PATCH] msync(): ... |
105 |
out: |
204ec841f [PATCH] mm: msync... |
106 |
return error ? : unmapped_error; |
1da177e4c Linux-2.6.12-rc2 |
107 |
} |