Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib/mmap-anon.c @ 1000:0fbafade2d85 HEAD
If auth/login process died unexpectedly, the exit status or killing signal
wasn't logged.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 21 Jan 2003 09:58:49 +0200 |
parents | 6c42b9c76464 |
children | 8ef24a824568 |
rev | line source |
---|---|
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
1 /* |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 Copyright (c) 2002 Timo Sirainen |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
4 Permission is hereby granted, free of charge, to any person obtaining |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
5 a copy of this software and associated documentation files (the |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 "Software"), to deal in the Software without restriction, including |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 without limitation the rights to use, copy, modify, merge, publish, |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 distribute, sublicense, and/or sell copies of the Software, and to |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 permit persons to whom the Software is furnished to do so, subject to |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 the following conditions: |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 The above copyright notice and this permission notice shall be |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 included in all copies or substantial portions of the Software. |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
21 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
22 */ |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 |
805
5ac361acb316
Marked all non-trivial buffer modifications with @UNSAFE tag. Several
Timo Sirainen <tss@iki.fi>
parents:
606
diff
changeset
|
24 /* @UNSAFE: whole file */ |
5ac361acb316
Marked all non-trivial buffer modifications with @UNSAFE tag. Several
Timo Sirainen <tss@iki.fi>
parents:
606
diff
changeset
|
25 |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 #include "lib.h" |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 #include "mmap-util.h" |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
29 #include <fcntl.h> |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
30 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
31 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
32 # define MAP_ANONYMOUS MAP_ANON |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
33 #endif |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
34 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
35 #ifndef HAVE_LINUX_MREMAP |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
36 |
863
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
37 #include <stdlib.h> |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
38 #include <sys/mman.h> |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
39 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
40 /* MMAP_BASE_MOVE may be negative as well */ |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
41 #if SSIZE_T_MAX >= LLONG_MAX |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
42 /* 64bit or more */ |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
43 # define MMAP_BASE_MOVE (1024ULL*1024ULL*1024ULL*128ULL) /* 128GB */ |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
44 #else |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
45 /* 32bit most likely */ |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 # define MMAP_BASE_MOVE (1024UL*1024UL*128UL) /* 128M */ |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
47 #endif |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
48 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
49 #define MMAP_SIGNATURE 0xdeadbeef |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
50 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
51 #define PAGE_ALIGN(size) \ |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
52 (((size) + (size_t)page_size-1) & ~(size_t)(page_size-1)) |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
53 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
54 struct movable_header { |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
55 unsigned int signature; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
56 size_t size; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
57 }; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
58 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
59 static int page_size = 0; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
60 static int header_size = 0; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
61 static void *movable_mmap_base = NULL; |
863
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
62 static void *mmap_top_limit, *mmap_heap_bottom, *mmap_heap_top; |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
63 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
64 static void movable_mmap_init(void) |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
65 { |
863
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
66 ssize_t abs_base_move; |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
67 char x; |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
68 |
863
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
69 abs_base_move = MMAP_BASE_MOVE; |
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
70 if (abs_base_move < 0) |
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
71 abs_base_move = -abs_base_move; |
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
72 |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
73 page_size = getpagesize(); |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
74 header_size = page_size; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
75 |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
76 /* keep our allocations far below stack. assumes the stack is |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
77 growing down. */ |
863
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
78 mmap_top_limit = &x - abs_base_move*2; |
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
79 |
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
80 /* keep our allocations far from heap */ |
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
81 mmap_heap_bottom = malloc(1); |
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
82 mmap_heap_top = (char *) mmap_heap_bottom + abs_base_move*2; |
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
83 free(mmap_heap_bottom); |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
84 } |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
85 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
86 static int anon_mmap_fixed(void *address, size_t length) |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
87 { |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
88 void *base; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
89 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
90 #ifdef MAP_ANONYMOUS |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
91 base = mmap(address, length, PROT_READ | PROT_WRITE, |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
93 #else |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
94 int fd; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
95 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
96 /* mmap()ing /dev/zero should be the same with some platforms */ |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
97 fd = open("/dev/zero", O_RDWR); |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
98 if (fd == -1) |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
99 i_fatal("Can't open /dev/zero for creating anonymous mmap"); |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
100 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
101 base = mmap(address, length, PROT_READ | PROT_WRITE, |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
102 MAP_FIXED | MAP_PRIVATE, fd, 0); |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
103 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
104 (void)close(fd); |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
105 #endif |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
106 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
107 if (base != MAP_FAILED && base != address) { |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
108 /* shouldn't happen with MAP_FIXED, but who knows.. */ |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
109 if (munmap(base, length) < 0) |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
110 i_panic("munmap() failed: %m"); |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
111 base = MAP_FAILED; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
112 errno = EINVAL; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
113 } |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
114 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
115 return base == MAP_FAILED ? -1 : 0; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
116 } |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
117 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
118 void *mmap_anon(size_t length) |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
119 { |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
120 struct movable_header *hdr; |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
121 void *next_mmap_base; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
122 ssize_t offset; |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
123 int ret; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
124 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
125 if (header_size == 0) |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
126 movable_mmap_init(); |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
127 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
128 /* we need extra page to store the pieces which construct |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
129 the full mmap. also allocate only page-aligned mmap sizes. */ |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
130 length = PAGE_ALIGN(length + header_size); |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
131 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
132 if (movable_mmap_base == NULL) { |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
133 /* this is fully guessing */ |
242 | 134 movable_mmap_base = (char *) NULL + |
405 | 135 PAGE_ALIGN((size_t)((char *)mmap_anon - (char *)NULL)); |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
136 } |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
137 |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
138 offset = MMAP_BASE_MOVE; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
139 for (;;) { |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
140 next_mmap_base = (char *) movable_mmap_base + offset; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
141 if ((char *) next_mmap_base < (char *) movable_mmap_base) { |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
142 /* we're wrapping, fix the offset a bit so we won't |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
143 just loop with same addresses.. */ |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
144 offset /= 2; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
145 if (offset/10 < page_size) { |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
146 /* enough tries */ |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
147 errno = ENOMEM; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
148 return MAP_FAILED; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
149 } |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
150 } |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
151 |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
152 movable_mmap_base = next_mmap_base; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
153 |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
154 if ((char *) movable_mmap_base > |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
155 (char *) movable_mmap_base + length) { |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
156 /* too high, would wrap */ |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
157 continue; |
405 | 158 } |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
159 |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
160 if ((char *) movable_mmap_base + length >= |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
161 (char *) mmap_top_limit) { |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
162 /* too high, stack could grow over it */ |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
163 continue; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
164 } |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
165 |
863
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
166 if ((char *) movable_mmap_base >= (char *) mmap_heap_bottom && |
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
167 (char *) movable_mmap_base < (char *) mmap_heap_top) { |
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
168 /* too near heap */ |
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
169 continue; |
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
170 } |
8ecfe2c250ee
Keep the mmap()ed area far from heap.
Timo Sirainen <tss@iki.fi>
parents:
858
diff
changeset
|
171 |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
172 if (movable_mmap_base == NULL) |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
173 continue; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
174 |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
175 ret = anon_mmap_fixed(movable_mmap_base, length); |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
176 if (ret == 0) |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
177 break; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
178 |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
179 if (ret < 0 && errno != EINVAL) |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
180 return MAP_FAILED; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
181 } |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
182 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
183 /* initialize the header */ |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
184 hdr = movable_mmap_base; |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
185 hdr->signature = MMAP_SIGNATURE; |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
186 hdr->size = length - header_size; |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
187 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
188 return (char *) hdr + header_size; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
189 } |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
190 |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
191 static int mremap_try_grow(struct movable_header *hdr, size_t new_size) |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
192 { |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
193 void *grow_base; |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
194 |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
195 grow_base = (char *) hdr + header_size + hdr->size; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
196 if ((char *) grow_base <= (char *) hdr + header_size || |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
197 (char *) grow_base >= (char *) mmap_top_limit) { |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
198 /* overflows valid address range */ |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
199 return 0; |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
200 } |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
201 |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
202 if (anon_mmap_fixed(grow_base, new_size - hdr->size) < 0) { |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
203 if (errno == EINVAL) { |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
204 /* can't grow, wanted address space is already in use */ |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
205 return 0; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
206 } |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
207 |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
208 return -1; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
209 } |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
210 |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
211 hdr->size = new_size; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
212 return 1; |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
213 } |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
214 |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
215 static void *mremap_move(struct movable_header *hdr, size_t new_size) |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
216 { |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
217 void *new_base; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
218 char *p; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
219 size_t block_size, old_size; |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
220 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
221 new_base = mmap_anon(new_size - header_size); |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
222 if (new_base == MAP_FAILED) |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
223 return MAP_FAILED; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
224 |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
225 /* If we're moving large memory areas, it takes less memory to |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
226 copy the memory pages in smaller blocks. */ |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
227 old_size = hdr->size; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
228 block_size = 1024*1024; |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
229 |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
230 p = (char *) (hdr + header_size + hdr->size); |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
231 do { |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
232 if (block_size > old_size) |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
233 block_size = old_size; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
234 p -= block_size; |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
235 |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
236 memcpy((char *) new_base + (p - (char *) hdr), p, block_size); |
873 | 237 if (munmap((void *) p, block_size) < 0) |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
238 i_panic("munmap() failed: %m"); |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
239 } while (p != (char *) hdr); |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
240 |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
241 return new_base; |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
242 } |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
243 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
244 void *mremap_anon(void *old_address, size_t old_size __attr_unused__, |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
245 size_t new_size, unsigned long flags) |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
246 { |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
247 struct movable_header *hdr; |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
248 int ret; |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
249 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
250 if (old_address == NULL || old_address == MAP_FAILED) { |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
251 errno = EINVAL; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
252 return MAP_FAILED; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
253 } |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
254 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
255 hdr = (struct movable_header *) ((char *) old_address - header_size); |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
256 if (hdr->signature != MMAP_SIGNATURE) |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
257 i_panic("movable_mremap(): Invalid old_address"); |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
258 |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
259 new_size = PAGE_ALIGN(new_size); |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
260 |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
261 if (new_size > hdr->size) { |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
262 /* grow */ |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
263 ret = mremap_try_grow(hdr, new_size); |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
264 if (ret > 0) |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
265 return old_address; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
266 if (ret < 0) |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
267 return MAP_FAILED; |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
268 |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
269 if ((flags & MREMAP_MAYMOVE) == 0) { |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
270 errno = ENOMEM; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
271 return MAP_FAILED; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
272 } |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
273 |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
274 return mremap_move(hdr, new_size); |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
275 } |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
276 |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
277 if (new_size < hdr->size) { |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
278 /* shrink */ |
873 | 279 if (munmap((void *) ((char *) hdr + header_size + new_size), |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
280 hdr->size - new_size) < 0) |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
281 i_panic("munmap() failed: %m"); |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
282 hdr->size = new_size; |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
283 } |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
284 |
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
285 return old_address; |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
286 } |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
287 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
288 int munmap_anon(void *start, size_t length __attr_unused__) |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
289 { |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
290 struct movable_header *hdr; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
291 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
292 if (start == NULL || start == MAP_FAILED) { |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
293 errno = EINVAL; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
294 return -1; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
295 } |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
296 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
297 hdr = (struct movable_header *) ((char *) start - header_size); |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
298 if (hdr->signature != MMAP_SIGNATURE) |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
299 i_panic("movable_munmap(): Invalid address"); |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
300 |
873 | 301 if (munmap((void *) hdr, hdr->size + header_size) < 0) |
858
8f4bd02461e0
Old implementation was overly complex and stupid.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
302 i_panic("munmap() failed: %m"); |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
303 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
304 return 0; |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
305 } |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
306 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
307 #else |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
308 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
309 void *mmap_anon(size_t length) |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
310 { |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
311 return mmap(NULL, length, PROT_READ | PROT_WRITE, |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
312 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
313 } |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
314 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
315 void *mremap_anon(void *old_address, size_t old_size, size_t new_size, |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
316 unsigned long flags) |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
317 { |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
318 return mremap(old_address, old_size, new_size, flags); |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
319 } |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
320 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
321 int munmap_anon(void *start, size_t length) |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
322 { |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
323 return munmap(start, length); |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
324 } |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
325 |
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
326 #endif |