Blame view
mm/msync.c
2.63 KB
b24413180 License cleanup: ... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 6 7 8 9 10 |
/* * linux/mm/msync.c * * Copyright (C) 1994-1999 Linus Torvalds */ /* * The msync() system call. */ |
8f2e9f157 [PATCH] msync(): ... |
11 |
#include <linux/fs.h> |
1da177e4c Linux-2.6.12-rc2 |
12 13 |
#include <linux/mm.h> #include <linux/mman.h> |
9c50823ee [PATCH] msync(): ... |
14 |
#include <linux/file.h> |
1da177e4c Linux-2.6.12-rc2 |
15 |
#include <linux/syscalls.h> |
e8edc6e03 Detach sched.h fr... |
16 |
#include <linux/sched.h> |
1da177e4c Linux-2.6.12-rc2 |
17 |
|
1da177e4c Linux-2.6.12-rc2 |
18 19 20 |
/* * MS_SYNC syncs the entire file - including mappings. * |
204ec841f [PATCH] mm: msync... |
21 22 23 24 25 |
* 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 |
26 27 28 |
* 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... |
29 |
* So by _not_ starting I/O in MS_ASYNC we provide complete flexibility to |
1da177e4c Linux-2.6.12-rc2 |
30 31 |
* applications. */ |
6a6160a7b [CVE-2009-0029] S... |
32 |
SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags) |
1da177e4c Linux-2.6.12-rc2 |
33 34 |
{ unsigned long end; |
204ec841f [PATCH] mm: msync... |
35 |
struct mm_struct *mm = current->mm; |
1da177e4c Linux-2.6.12-rc2 |
36 |
struct vm_area_struct *vma; |
676758bdb [PATCH] msync: fi... |
37 38 |
int unmapped_error = 0; int error = -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
39 |
|
1da177e4c Linux-2.6.12-rc2 |
40 41 |
if (flags & ~(MS_ASYNC | MS_INVALIDATE | MS_SYNC)) goto out; |
b0d61c7e5 mm/msync: use off... |
42 |
if (offset_in_page(start)) |
1da177e4c Linux-2.6.12-rc2 |
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
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... |
58 59 60 |
down_read(&mm->mmap_sem); vma = find_vma(mm, start); for (;;) { |
9c50823ee [PATCH] msync(): ... |
61 |
struct file *file; |
7fc34a62c mm/msync.c: sync ... |
62 |
loff_t fstart, fend; |
9c50823ee [PATCH] msync(): ... |
63 |
|
204ec841f [PATCH] mm: msync... |
64 65 66 67 |
/* Still start < end. */ error = -ENOMEM; if (!vma) goto out_unlock; |
1da177e4c Linux-2.6.12-rc2 |
68 69 |
/* Here start < vma->vm_end. */ if (start < vma->vm_start) { |
1da177e4c Linux-2.6.12-rc2 |
70 |
start = vma->vm_start; |
204ec841f [PATCH] mm: msync... |
71 72 73 |
if (start >= end) goto out_unlock; unmapped_error = -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
74 75 |
} /* Here vma->vm_start <= start < vma->vm_end. */ |
204ec841f [PATCH] mm: msync... |
76 77 78 79 |
if ((flags & MS_INVALIDATE) && (vma->vm_flags & VM_LOCKED)) { error = -EBUSY; goto out_unlock; |
1da177e4c Linux-2.6.12-rc2 |
80 |
} |
9c50823ee [PATCH] msync(): ... |
81 |
file = vma->vm_file; |
496a8e686 msync: fix incorr... |
82 83 |
fstart = (start - vma->vm_start) + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); |
7fc34a62c mm/msync.c: sync ... |
84 |
fend = fstart + (min(end, vma->vm_end) - start) - 1; |
1da177e4c Linux-2.6.12-rc2 |
85 |
start = vma->vm_end; |
204ec841f [PATCH] mm: msync... |
86 |
if ((flags & MS_SYNC) && file && |
707c21c84 [PATCH] msync(MS_... |
87 |
(vma->vm_flags & VM_SHARED)) { |
707c21c84 [PATCH] msync(MS_... |
88 |
get_file(file); |
204ec841f [PATCH] mm: msync... |
89 |
up_read(&mm->mmap_sem); |
0661a3361 mm: remove rest u... |
90 |
error = vfs_fsync_range(file, fstart, fend, 1); |
707c21c84 [PATCH] msync(MS_... |
91 |
fput(file); |
204ec841f [PATCH] mm: msync... |
92 93 94 95 |
if (error || start >= end) goto out; down_read(&mm->mmap_sem); vma = find_vma(mm, start); |
9c50823ee [PATCH] msync(): ... |
96 |
} else { |
204ec841f [PATCH] mm: msync... |
97 98 99 100 |
if (start >= end) { error = 0; goto out_unlock; } |
9c50823ee [PATCH] msync(): ... |
101 102 |
vma = vma->vm_next; } |
204ec841f [PATCH] mm: msync... |
103 |
} |
9c50823ee [PATCH] msync(): ... |
104 |
out_unlock: |
204ec841f [PATCH] mm: msync... |
105 |
up_read(&mm->mmap_sem); |
9c50823ee [PATCH] msync(): ... |
106 |
out: |
204ec841f [PATCH] mm: msync... |
107 |
return error ? : unmapped_error; |
1da177e4c Linux-2.6.12-rc2 |
108 |
} |