Blame view
mm/msync.c
2.44 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; |
204ec841f [PATCH] mm: msync... |
61 62 63 64 |
/* Still start < end. */ error = -ENOMEM; if (!vma) goto out_unlock; |
1da177e4c Linux-2.6.12-rc2 |
65 66 |
/* Here start < vma->vm_end. */ if (start < vma->vm_start) { |
1da177e4c Linux-2.6.12-rc2 |
67 |
start = vma->vm_start; |
204ec841f [PATCH] mm: msync... |
68 69 70 |
if (start >= end) goto out_unlock; unmapped_error = -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
71 72 |
} /* Here vma->vm_start <= start < vma->vm_end. */ |
204ec841f [PATCH] mm: msync... |
73 74 75 76 |
if ((flags & MS_INVALIDATE) && (vma->vm_flags & VM_LOCKED)) { error = -EBUSY; goto out_unlock; |
1da177e4c Linux-2.6.12-rc2 |
77 |
} |
9c50823ee [PATCH] msync(): ... |
78 |
file = vma->vm_file; |
1da177e4c Linux-2.6.12-rc2 |
79 |
start = vma->vm_end; |
204ec841f [PATCH] mm: msync... |
80 |
if ((flags & MS_SYNC) && file && |
707c21c84 [PATCH] msync(MS_... |
81 |
(vma->vm_flags & VM_SHARED)) { |
707c21c84 [PATCH] msync(MS_... |
82 |
get_file(file); |
204ec841f [PATCH] mm: msync... |
83 |
up_read(&mm->mmap_sem); |
4c728ef58 add a vfs_fsync h... |
84 |
error = vfs_fsync(file, file->f_path.dentry, 0); |
707c21c84 [PATCH] msync(MS_... |
85 |
fput(file); |
204ec841f [PATCH] mm: msync... |
86 87 88 89 |
if (error || start >= end) goto out; down_read(&mm->mmap_sem); vma = find_vma(mm, start); |
9c50823ee [PATCH] msync(): ... |
90 |
} else { |
204ec841f [PATCH] mm: msync... |
91 92 93 94 |
if (start >= end) { error = 0; goto out_unlock; } |
9c50823ee [PATCH] msync(): ... |
95 96 |
vma = vma->vm_next; } |
204ec841f [PATCH] mm: msync... |
97 |
} |
9c50823ee [PATCH] msync(): ... |
98 |
out_unlock: |
204ec841f [PATCH] mm: msync... |
99 |
up_read(&mm->mmap_sem); |
9c50823ee [PATCH] msync(): ... |
100 |
out: |
204ec841f [PATCH] mm: msync... |
101 |
return error ? : unmapped_error; |
1da177e4c Linux-2.6.12-rc2 |
102 |
} |