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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
50 {
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
51 size_t page_size = mmap_get_page_size();
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
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
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
54
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
55 if (diff != 0)
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
56 size += page_size - diff;
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
57
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
58 i_assert((size % page_size) == 0);
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
59 if (size <= cache->mmap_length)
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
60 return 0;
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
61
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
62 if (size > (size_t)-1) {
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
63 i_error("file_cache_set_size(%"PRIuUOFF_T"): size too large",
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
64 size);
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
65 return -1;
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
66 }
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
67
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
68 /* grow mmaping */
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
69 if (cache->mmap_base == NULL) {
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
70 cache->mmap_base = mmap_anon(size);
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
71 if (cache->mmap_base == MAP_FAILED) {
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
72 i_error("mmap_anon(%"PRIuUOFF_T") failed: %m", size);
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
73 cache->mmap_length = 0;
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
74 return -1;
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
75 }
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
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
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
80 i_error("mremap_anon(%"PRIuUOFF_T") failed: %m", size);
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
81 return -1;
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
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
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
85 }
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
86 cache->mmap_length = size;
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
87 return 0;
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
88 }
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
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
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
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
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
126 if (file_cache_set_size(cache, offset + size) < 0)
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
127 return -1;
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
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
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
145 if (dest_offset <= cache->read_highwater) {
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
146 psize--; poffset++;
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
147 dest += page_size;
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
148 continue;
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
149 }
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
150
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
151 /* this is the last partially cached block.
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
152 use the caching only if we don't want to
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
153 read past read_highwater */
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
154 if (offset + size <= cache->read_highwater) {
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
155 i_assert(psize == 1);
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
156 break;
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
157 }
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
158
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
159 /* mark the block noncached again and
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
160 read it */
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
161 bits[poffset / CHAR_BIT] &=
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
162 ~(1 << (poffset % CHAR_BIT));
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
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
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
171 /* EOF. mark the last block as cached even if it
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
172 isn't completely. read_highwater tells us how far
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
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
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
229 if (file_cache_set_size(cache, offset + size) < 0) {
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
230 /* couldn't grow mapping. just make sure the written memory
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
231 area is invalidated then. */
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
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
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
234 }
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
235
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
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
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
238 if (cache->read_highwater < offset + size) {
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
239 unsigned int page = cache->read_highwater / page_size;
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
240
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
241 bits = buffer_get_space_unsafe(cache->page_bitmask,
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
242 page / CHAR_BIT, 1);
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
243 *bits &= ~(1 << (page % CHAR_BIT));
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
244 cache->read_highwater = offset + size;
6334d2ef2ba5 Optimizations
Timo Sirainen <tss@iki.fi>
parents: 3377
diff changeset
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 }