Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib/file-cache.c @ 9354:687ac828b964 HEAD
lib-index: modseqs weren't tracked properly within session when changes were done.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 01 Sep 2009 13:05:03 -0400 |
parents | b9faf4db2a9f |
children | 00cd9aacd03c |
rev | line source |
---|---|
8590
b9faf4db2a9f
Updated copyright notices to include year 2009.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
1 /* Copyright (c) 2004-2009 Dovecot authors, see the included COPYING file */ |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 #include "lib.h" |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
4 #include "buffer.h" |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
5 #include "mmap-util.h" |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 #include "file-cache.h" |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 #include <sys/stat.h> |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 struct file_cache { |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 int fd; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 buffer_t *page_bitmask; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 void *mmap_base; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 size_t mmap_length; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 size_t read_highwater; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 }; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 struct file_cache *file_cache_new(int fd) |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 { |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
21 struct file_cache *cache; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
22 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 cache = i_new(struct file_cache, 1); |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 cache->fd = fd; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 cache->page_bitmask = buffer_create_dynamic(default_pool, 128); |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 return cache; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 } |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3378
diff
changeset
|
29 void file_cache_free(struct file_cache **_cache) |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
30 { |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3378
diff
changeset
|
31 struct file_cache *cache = *_cache; |
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3378
diff
changeset
|
32 |
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3378
diff
changeset
|
33 *_cache = NULL; |
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3378
diff
changeset
|
34 |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
35 if (cache->mmap_base != NULL) { |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
36 if (munmap_anon(cache->mmap_base, cache->mmap_length) < 0) |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
37 i_error("munmap_anon() failed: %m"); |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
38 } |
6414
a6a49d5efc59
Changed buffer_free() and buffer_free_without_data() APIs to take ** pointer
Timo Sirainen <tss@iki.fi>
parents:
5144
diff
changeset
|
39 buffer_free(&cache->page_bitmask); |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
40 i_free(cache); |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
41 } |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
42 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
43 void file_cache_set_fd(struct file_cache *cache, int fd) |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
44 { |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
45 cache->fd = fd; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 file_cache_invalidate(cache, 0, cache->mmap_length); |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
47 } |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
48 |
5144
0851c6e96852
Made file_cache_set_size() public.
Timo Sirainen <tss@iki.fi>
parents:
4991
diff
changeset
|
49 int file_cache_set_size(struct file_cache *cache, uoff_t size) |
3378 | 50 { |
51 size_t page_size = mmap_get_page_size(); | |
52 uoff_t diff = size % page_size; | |
4866
4ec6ceb0934a
If mremap_anon() fails, don't leak/crash.
Timo Sirainen <tss@iki.fi>
parents:
4865
diff
changeset
|
53 void *new_base; |
3378 | 54 |
55 if (diff != 0) | |
56 size += page_size - diff; | |
57 | |
58 i_assert((size % page_size) == 0); | |
59 if (size <= cache->mmap_length) | |
60 return 0; | |
61 | |
62 if (size > (size_t)-1) { | |
63 i_error("file_cache_set_size(%"PRIuUOFF_T"): size too large", | |
64 size); | |
65 return -1; | |
66 } | |
67 | |
68 /* grow mmaping */ | |
69 if (cache->mmap_base == NULL) { | |
70 cache->mmap_base = mmap_anon(size); | |
71 if (cache->mmap_base == MAP_FAILED) { | |
72 i_error("mmap_anon(%"PRIuUOFF_T") failed: %m", size); | |
73 cache->mmap_length = 0; | |
74 return -1; | |
75 } | |
76 } else { | |
4866
4ec6ceb0934a
If mremap_anon() fails, don't leak/crash.
Timo Sirainen <tss@iki.fi>
parents:
4865
diff
changeset
|
77 new_base = mremap_anon(cache->mmap_base, cache->mmap_length, |
4ec6ceb0934a
If mremap_anon() fails, don't leak/crash.
Timo Sirainen <tss@iki.fi>
parents:
4865
diff
changeset
|
78 size, MREMAP_MAYMOVE); |
4ec6ceb0934a
If mremap_anon() fails, don't leak/crash.
Timo Sirainen <tss@iki.fi>
parents:
4865
diff
changeset
|
79 if (new_base == MAP_FAILED) { |
3378 | 80 i_error("mremap_anon(%"PRIuUOFF_T") failed: %m", size); |
81 return -1; | |
82 } | |
4866
4ec6ceb0934a
If mremap_anon() fails, don't leak/crash.
Timo Sirainen <tss@iki.fi>
parents:
4865
diff
changeset
|
83 |
4ec6ceb0934a
If mremap_anon() fails, don't leak/crash.
Timo Sirainen <tss@iki.fi>
parents:
4865
diff
changeset
|
84 cache->mmap_base = new_base; |
3378 | 85 } |
86 cache->mmap_length = size; | |
87 return 0; | |
88 } | |
89 | |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
90 ssize_t file_cache_read(struct file_cache *cache, uoff_t offset, size_t size) |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
91 { |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 size_t page_size = mmap_get_page_size(); |
3378 | 93 size_t poffset, psize, dest_offset, dest_size; |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
94 unsigned char *bits, *dest; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
95 ssize_t ret; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
96 |
2916
d1780331ad04
Don't crash if trying to read more than INT_MAX bytes. Just silently allow
Timo Sirainen <tss@iki.fi>
parents:
2868
diff
changeset
|
97 if (size > SSIZE_T_MAX) { |
d1780331ad04
Don't crash if trying to read more than INT_MAX bytes. Just silently allow
Timo Sirainen <tss@iki.fi>
parents:
2868
diff
changeset
|
98 /* make sure our calculations won't overflow. most likely |
d1780331ad04
Don't crash if trying to read more than INT_MAX bytes. Just silently allow
Timo Sirainen <tss@iki.fi>
parents:
2868
diff
changeset
|
99 we'll be reading less data, but allow it anyway so caller |
d1780331ad04
Don't crash if trying to read more than INT_MAX bytes. Just silently allow
Timo Sirainen <tss@iki.fi>
parents:
2868
diff
changeset
|
100 doesn't have to deal with any extra checks. */ |
d1780331ad04
Don't crash if trying to read more than INT_MAX bytes. Just silently allow
Timo Sirainen <tss@iki.fi>
parents:
2868
diff
changeset
|
101 size = SSIZE_T_MAX; |
d1780331ad04
Don't crash if trying to read more than INT_MAX bytes. Just silently allow
Timo Sirainen <tss@iki.fi>
parents:
2868
diff
changeset
|
102 } |
4865
a69ab82d7346
Check against offset/size overflows.
Timo Sirainen <tss@iki.fi>
parents:
4839
diff
changeset
|
103 if (offset >= (uoff_t)-1 - size) |
a69ab82d7346
Check against offset/size overflows.
Timo Sirainen <tss@iki.fi>
parents:
4839
diff
changeset
|
104 size = (uoff_t)-1 - offset; |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
105 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
106 if (offset + size > cache->mmap_length && |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
107 offset + size - cache->mmap_length > 1024*1024) { |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
108 /* growing more than a megabyte, make sure that the |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
109 file is large enough so we don't allocate memory |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
110 more than needed */ |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
111 struct stat st; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
112 |
4023
b19ccbaa3802
Try to handle ESTALE NFS errors the best way we can.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
3879
diff
changeset
|
113 if (fstat(cache->fd, &st) < 0) { |
b19ccbaa3802
Try to handle ESTALE NFS errors the best way we can.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
3879
diff
changeset
|
114 if (errno != ESTALE) |
b19ccbaa3802
Try to handle ESTALE NFS errors the best way we can.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
3879
diff
changeset
|
115 i_error("fstat(file_cache) failed: %m"); |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
116 return -1; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
117 } |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
118 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
119 if (offset + size > (uoff_t)st.st_size) { |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
120 if (offset >= (uoff_t)st.st_size) |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
121 return 0; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
122 size = (uoff_t)st.st_size - offset; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
123 } |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
124 } |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
125 |
3378 | 126 if (file_cache_set_size(cache, offset + size) < 0) |
127 return -1; | |
128 | |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
129 poffset = offset / page_size; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
130 psize = (offset + size + page_size-1) / page_size - poffset; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
131 i_assert(psize > 0); |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
132 |
3371
4bb8af354951
Cache bitmask was still used wrong, maybe now..
Timo Sirainen <tss@iki.fi>
parents:
3370
diff
changeset
|
133 bits = buffer_get_space_unsafe(cache->page_bitmask, 0, |
4839
b8a9a0fd65c5
And accidentally reverted the first buffer overflow fix in the second
Timo Sirainen <tss@iki.fi>
parents:
4837
diff
changeset
|
134 (poffset + psize + CHAR_BIT - 1) / |
b8a9a0fd65c5
And accidentally reverted the first buffer overflow fix in the second
Timo Sirainen <tss@iki.fi>
parents:
4837
diff
changeset
|
135 CHAR_BIT); |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
136 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
137 dest_offset = poffset * page_size; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
138 dest = PTR_OFFSET(cache->mmap_base, dest_offset); |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
139 dest_size = page_size; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
140 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
141 while (psize > 0) { |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
142 if (bits[poffset / CHAR_BIT] & (1 << (poffset % CHAR_BIT))) { |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
143 /* page is already in cache */ |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
144 dest_offset += page_size; |
3378 | 145 if (dest_offset <= cache->read_highwater) { |
146 psize--; poffset++; | |
147 dest += page_size; | |
148 continue; | |
149 } | |
150 | |
151 /* this is the last partially cached block. | |
152 use the caching only if we don't want to | |
153 read past read_highwater */ | |
154 if (offset + size <= cache->read_highwater) { | |
155 i_assert(psize == 1); | |
156 break; | |
157 } | |
158 | |
159 /* mark the block noncached again and | |
160 read it */ | |
161 bits[poffset / CHAR_BIT] &= | |
162 ~(1 << (poffset % CHAR_BIT)); | |
163 dest_offset -= page_size; | |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
164 } |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
165 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
166 ret = pread(cache->fd, dest, dest_size, dest_offset); |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
167 if (ret <= 0) { |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
168 if (ret < 0) |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
169 return -1; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
170 |
3378 | 171 /* EOF. mark the last block as cached even if it |
172 isn't completely. read_highwater tells us how far | |
173 we've actually made. */ | |
4285
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
174 if (dest_offset == cache->read_highwater) { |
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
175 i_assert(poffset == |
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
176 cache->read_highwater / page_size); |
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
177 bits[poffset / CHAR_BIT] |= |
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
178 1 << (poffset % CHAR_BIT); |
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
179 } |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
180 return dest_offset <= offset ? 0 : |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
181 dest_offset - offset < size ? |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
182 dest_offset - offset : size; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
183 } |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
184 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
185 dest += ret; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
186 dest_offset += ret; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
187 |
4285
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
188 if (cache->read_highwater < dest_offset) { |
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
189 unsigned int high_poffset = |
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
190 cache->read_highwater / page_size; |
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
191 |
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
192 /* read_highwater needs to be updated. if we didn't |
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
193 just read that block, we can't trust anymore that |
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
194 we have it cached */ |
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
195 bits[high_poffset / CHAR_BIT] &= |
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
196 ~(1 << (high_poffset % CHAR_BIT)); |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
197 cache->read_highwater = dest_offset; |
4285
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
198 } |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
199 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
200 if ((size_t)ret != dest_size) { |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
201 /* partial read - probably EOF but make sure. */ |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
202 dest_size -= ret; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
203 continue; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
204 } |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
205 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
206 bits[poffset / CHAR_BIT] |= 1 << (poffset % CHAR_BIT); |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
207 dest_size = page_size; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
208 psize--; poffset++; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
209 } |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
210 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
211 return size; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
212 } |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
213 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
214 const void *file_cache_get_map(struct file_cache *cache, size_t *size_r) |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
215 { |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
216 *size_r = cache->read_highwater; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
217 return cache->mmap_base; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
218 } |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
219 |
3374
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
220 void file_cache_write(struct file_cache *cache, const void *data, size_t size, |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
221 uoff_t offset) |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
222 { |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
223 size_t page_size = mmap_get_page_size(); |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
224 unsigned char *bits; |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
225 unsigned int first_page, last_page; |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
226 |
4991
e4afafbb963b
Changed assert so it doesn't give a compiler warning with 32bit systems.
Timo Sirainen <tss@iki.fi>
parents:
4866
diff
changeset
|
227 i_assert((uoff_t)-1 - offset > size); |
4865
a69ab82d7346
Check against offset/size overflows.
Timo Sirainen <tss@iki.fi>
parents:
4839
diff
changeset
|
228 |
3378 | 229 if (file_cache_set_size(cache, offset + size) < 0) { |
230 /* couldn't grow mapping. just make sure the written memory | |
231 area is invalidated then. */ | |
232 file_cache_invalidate(cache, offset, size); | |
3374
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
233 return; |
3378 | 234 } |
235 | |
236 memcpy(PTR_OFFSET(cache->mmap_base, offset), data, size); | |
3374
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
237 |
3378 | 238 if (cache->read_highwater < offset + size) { |
239 unsigned int page = cache->read_highwater / page_size; | |
240 | |
241 bits = buffer_get_space_unsafe(cache->page_bitmask, | |
242 page / CHAR_BIT, 1); | |
243 *bits &= ~(1 << (page % CHAR_BIT)); | |
244 cache->read_highwater = offset + size; | |
245 } | |
3374
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
246 |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
247 /* mark fully written pages cached */ |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
248 if (size >= page_size) { |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
249 first_page = offset / page_size; |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
250 last_page = (offset + size) / page_size; |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
251 if ((offset % page_size) != 0) |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
252 first_page++; |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
253 |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
254 bits = buffer_get_space_unsafe(cache->page_bitmask, 0, |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
255 last_page / CHAR_BIT + 1); |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
256 for (; first_page < last_page; first_page++) { |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
257 bits[first_page / CHAR_BIT] |= |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
258 1 << (first_page % CHAR_BIT); |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
259 } |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
260 } |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
261 } |
8b2dd340e16d
Added file_cache_write() to update cached memory area.
Timo Sirainen <tss@iki.fi>
parents:
3371
diff
changeset
|
262 |
2933
6ec86fd705a6
Changed file_cache_invalidate()'s size argument to uoff_t type.
Timo Sirainen <tss@iki.fi>
parents:
2916
diff
changeset
|
263 void file_cache_invalidate(struct file_cache *cache, uoff_t offset, uoff_t size) |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
264 { |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
265 size_t page_size = mmap_get_page_size(); |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
266 unsigned char *bits, mask; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
267 unsigned int i; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
268 |
4285
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
269 if (offset >= cache->read_highwater || size == 0) |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
270 return; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
271 |
6732
f4b266590003
Drop read_highwater position when invalidating if possible.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
272 if (size > cache->read_highwater - offset) { |
f4b266590003
Drop read_highwater position when invalidating if possible.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
273 /* ignore anything after read highwater */ |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
274 size = cache->read_highwater - offset; |
6732
f4b266590003
Drop read_highwater position when invalidating if possible.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
275 } |
f4b266590003
Drop read_highwater position when invalidating if possible.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
276 if (size >= cache->read_highwater) { |
f4b266590003
Drop read_highwater position when invalidating if possible.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
277 /* we're invalidating everything up to read highwater. |
f4b266590003
Drop read_highwater position when invalidating if possible.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
278 drop the highwater position. */ |
f4b266590003
Drop read_highwater position when invalidating if possible.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
279 cache->read_highwater = offset & ~(page_size-1); |
f4b266590003
Drop read_highwater position when invalidating if possible.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
280 } |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
281 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
282 size = (offset + size + page_size-1) / page_size; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
283 offset /= page_size; |
4285
9f5cdfb282a0
We were caching the EOF block wrongly in some situations.
Timo Sirainen <tss@iki.fi>
parents:
4023
diff
changeset
|
284 i_assert(size > offset); |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
285 size -= offset; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
286 |
2868
316756b50150
Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents:
2866
diff
changeset
|
287 if (size != 1) { |
316756b50150
Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents:
2866
diff
changeset
|
288 /* tell operating system that we don't need the memory anymore |
316756b50150
Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents:
2866
diff
changeset
|
289 and it may free it. don't bother to do it for single pages, |
316756b50150
Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents:
2866
diff
changeset
|
290 there's a good chance that they get re-read back |
316756b50150
Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents:
2866
diff
changeset
|
291 immediately. */ |
316756b50150
Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents:
2866
diff
changeset
|
292 (void)madvise(PTR_OFFSET(cache->mmap_base, offset * page_size), |
316756b50150
Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents:
2866
diff
changeset
|
293 size * page_size, MADV_DONTNEED); |
316756b50150
Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents:
2866
diff
changeset
|
294 } |
316756b50150
Use madvise(MADV_DONTNEED) for invalidated pages to free memory.
Timo Sirainen <tss@iki.fi>
parents:
2866
diff
changeset
|
295 |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
296 bits = buffer_get_space_unsafe(cache->page_bitmask, offset / CHAR_BIT, |
4837
b2bd93ec9c10
And another off-by-one buffer overflow fix.
Timo Sirainen <tss@iki.fi>
parents:
4836
diff
changeset
|
297 1 + (size + CHAR_BIT - 1) / CHAR_BIT); |
2866
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
298 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
299 /* set the first byte */ |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
300 for (i = offset % CHAR_BIT, mask = 0; i < CHAR_BIT && size > 0; i++) { |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
301 mask |= 1 << i; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
302 size--; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
303 } |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
304 *bits++ &= ~mask; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
305 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
306 /* set the middle bytes */ |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
307 memset(bits, 0, size / CHAR_BIT); |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
308 bits += size / CHAR_BIT; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
309 size %= CHAR_BIT; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
310 |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
311 /* set the last byte */ |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
312 if (size > 0) { |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
313 mask = 0; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
314 for (i = 0, mask = 0; i < size; i++) |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
315 mask |= 1 << i; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
316 *bits &= ~mask; |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
317 } |
bf1e718e7370
Cache file works now with mmap_disable=yes. Still needs a few optimizations.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
318 } |