/* Copyright (c) 2004-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "buffer.h"
#include "mmap-util.h"
#include "file-cache.h"
struct file_cache {
int fd;
char *path;
void *mmap_base;
};
{
}
{
return cache;
}
{
}
}
{
}
{
void *new_base;
if (diff != 0)
return 0;
return -1;
}
/* grow mmaping */
cache->mmap_length = 0;
return -1;
}
} else {
if (new_base == MAP_FAILED) {
return -1;
}
}
return 0;
}
{
if (size > SSIZE_T_MAX) {
/* make sure our calculations won't overflow. most likely
we'll be reading less data, but allow it anyway so caller
doesn't have to deal with any extra checks. */
size = SSIZE_T_MAX;
}
/* growing more than a megabyte, make sure that the
file is large enough so we don't allocate memory
more than needed */
return -1;
}
return 0;
}
}
return -1;
CHAR_BIT);
while (psize > 0) {
/* page is already in cache */
dest_offset += page_size;
continue;
}
/* this is the last partially cached block.
use the caching only if we don't want to
read past read_highwater */
break;
}
/* mark the block noncached again and
read it */
dest_offset -= page_size;
}
if (ret <= 0) {
if (ret < 0)
return -1;
/* EOF. mark the last block as cached even if it
isn't completely. read_highwater tells us how far
we've actually made. */
}
return dest_offset <= offset ? 0 :
}
dest_offset += ret;
unsigned int high_poffset =
/* read_highwater needs to be updated. if we didn't
just read that block, we can't trust anymore that
we have it cached */
}
/* partial read - probably EOF but make sure. */
continue;
}
}
return size;
}
{
}
{
unsigned char *bits;
/* couldn't grow mapping. just make sure the written memory
area is invalidated then. */
return;
}
}
/* mark fully written pages cached */
first_page++;
}
}
}
{
unsigned int i;
return;
/* ignore anything after read highwater */
}
/* we're invalidating everything up to read highwater.
drop the highwater position. */
}
if (size != 1) {
/* tell operating system that we don't need the memory anymore
and it may free it. don't bother to do it for single pages,
there's a good chance that they get re-read back
immediately. */
}
/* set the first byte */
mask |= 1 << i;
size--;
}
/* set the middle bytes */
/* set the last byte */
if (size > 0) {
mask |= 1 << i;
}
}