1 /* msync -- Synchronize mapped memory to external storage. Mach version.
2 Copyright (C) 2002-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19 #include <sys/types.h>
20 #include <sys/mman.h>
21 #include <errno.h>
22 #include <sysdep-cancel.h>
23
24 #include <hurd/hurd.h>
25
26 /* Synchronize the region starting at ADDR and extending LEN bytes with the
27 file it maps. Filesystem operations on a file being mapped are
28 unpredictable before this is done. */
29
30 int
msync(void * addr,size_t length,int flags)31 msync (void *addr, size_t length, int flags)
32 {
33 boolean_t should_flush = flags & MS_INVALIDATE ? 1 : 0;
34 boolean_t should_iosync = flags & MS_ASYNC ? 0 : 1;
35
36 vm_address_t cur = (vm_address_t) addr;
37 vm_address_t target = cur + length;
38
39 vm_size_t len;
40 vm_prot_t prot;
41 vm_prot_t max_prot;
42 vm_inherit_t inherit;
43 boolean_t shared;
44 memory_object_name_t obj;
45 vm_offset_t offset;
46
47 kern_return_t err;
48 int cancel_oldtype;
49
50 while (cur < target)
51 {
52 vm_address_t begin = cur;
53
54 err = __vm_region (__mach_task_self (),
55 &begin, &len, &prot, &max_prot, &inherit,
56 &shared, &obj, &offset);
57
58 if (err != KERN_SUCCESS)
59 return __hurd_fail (err);
60
61 if (begin > cur)
62 /* We were given an address before the first region,
63 or we found a hole. */
64 cur = begin;
65
66 if (cur >= target)
67 /* We were given an ending address within a hole. */
68 break;
69
70 if (MACH_PORT_VALID (obj))
71 {
72 vm_size_t sync_len;
73
74 if (begin + len > target)
75 sync_len = target - begin;
76 else
77 sync_len = len;
78
79 cancel_oldtype = LIBC_CANCEL_ASYNC();
80 err = __vm_object_sync (obj, cur - begin + offset, sync_len,
81 should_flush, 1, should_iosync);
82 LIBC_CANCEL_RESET (cancel_oldtype);
83 __mach_port_deallocate (__mach_task_self (), obj);
84
85 if (err)
86 return __hurd_fail (err);
87
88 }
89
90 cur = begin + len;
91 }
92
93 return 0;
94 }
95