istream-mmap.c revision c06f4017027263cf3a08becc551f5126409e2a83
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2002-2003 Timo Sirainen */
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen#include "lib.h"
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen#include "ioloop.h"
afb7901ecb5d5566d4cf19be969654946fbaad4bTimo Sirainen#include "mmap-util.h"
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen#include "istream-internal.h"
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen#include <unistd.h>
994bb1a8a80da664083691d41dd9aec5d6fba2bfTimo Sirainen#include <sys/stat.h>
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstruct mmap_istream {
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen struct _istream istream;
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct timeval fstat_cache_stamp;
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen void *mmap_base;
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen off_t mmap_offset;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen size_t mmap_block_size;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen uoff_t v_size;
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen unsigned int autoclose_fd:1;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen};
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic size_t mmap_pagemask = 0;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainenstatic void _close(struct _iostream *stream)
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen{
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (mstream->autoclose_fd && mstream->istream.fd != -1) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (close(mstream->istream.fd) < 0)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen i_error("mmap_istream.close() failed: %m");
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen mstream->istream.fd = -1;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic void i_stream_munmap(struct mmap_istream *mstream)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct _istream *_stream = &mstream->istream;
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen if (_stream->buffer != NULL) {
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen if (munmap(mstream->mmap_base, _stream->buffer_size) < 0)
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen i_error("mmap_istream.munmap() failed: %m");
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen mstream->mmap_base = NULL;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen _stream->buffer = NULL;
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen _stream->buffer_size = 0;
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen mstream->mmap_offset = 0;
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen }
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic void _destroy(struct _iostream *stream)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen i_stream_munmap(mstream);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainenstatic void _set_max_buffer_size(struct _iostream *stream, size_t max_size)
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen /* allow only full page sizes */
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (max_size < mmap_get_page_size())
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen mstream->mmap_block_size = mmap_get_page_size();
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen else {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (max_size % mmap_get_page_size() != 0) {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen max_size += mmap_get_page_size() -
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen (max_size % mmap_get_page_size());
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen mstream->mmap_block_size = max_size;
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen }
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic ssize_t _read(struct _istream *stream)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
b66412da78711db8423288847ecfb08469609a03Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen size_t aligned_skip;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen uoff_t top;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen stream->istream.stream_errno = 0;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (stream->pos < stream->buffer_size) {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen /* more bytes available without needing to mmap() */
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen stream->pos = stream->buffer_size;
afb7901ecb5d5566d4cf19be969654946fbaad4bTimo Sirainen return stream->pos - stream->skip;
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen }
d6cc34b076dced6ebf8af47d72c8242357288312Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen if (stream->istream.v_offset >= mstream->v_size) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen stream->istream.eof = TRUE;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return -1;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen aligned_skip = stream->skip & ~mmap_pagemask;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (aligned_skip == 0 && mstream->mmap_base != NULL) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen /* didn't skip enough bytes */
b66412da78711db8423288847ecfb08469609a03Timo Sirainen return -2;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen }
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen stream->skip -= aligned_skip;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen mstream->mmap_offset += aligned_skip;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (mstream->mmap_base != NULL) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (munmap(mstream->mmap_base, stream->buffer_size) < 0)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen i_error("io_stream_read_mmaped(): munmap() failed: %m");
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen top = mstream->v_size - mstream->mmap_offset;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen stream->buffer_size = I_MIN(top, mstream->mmap_block_size);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen i_assert((uoff_t)mstream->mmap_offset + stream->buffer_size <=
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen mstream->v_size);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (stream->buffer_size == 0) {
b66412da78711db8423288847ecfb08469609a03Timo Sirainen /* don't bother even trying mmap */
b66412da78711db8423288847ecfb08469609a03Timo Sirainen mstream->mmap_base = NULL;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen stream->buffer = NULL;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen } else {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen mstream->mmap_base =
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen mmap(NULL, stream->buffer_size, PROT_READ, MAP_PRIVATE,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen stream->fd, mstream->mmap_offset);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (mstream->mmap_base == MAP_FAILED) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen stream->istream.stream_errno = errno;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen mstream->mmap_base = NULL;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen stream->buffer = NULL;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen stream->buffer_size = 0;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen stream->skip = stream->pos = 0;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen i_error("mmap_istream.mmap() failed: %m");
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen return -1;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen stream->buffer = mstream->mmap_base;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen }
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen if (stream->buffer_size > mmap_get_page_size()) {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen if (madvise(mstream->mmap_base, stream->buffer_size,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen MADV_SEQUENTIAL) < 0)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen i_error("mmap_istream.madvise(): %m");
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen stream->pos = stream->buffer_size;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen i_assert(stream->pos - stream->skip != 0);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen return stream->pos - stream->skip;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic void _seek(struct _istream *stream, uoff_t v_offset,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen bool mark __attr_unused__)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (stream->buffer_size != 0 &&
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen (uoff_t)mstream->mmap_offset <= v_offset &&
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen (uoff_t)mstream->mmap_offset + stream->buffer_size > v_offset) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen /* already mmaped */
b66412da78711db8423288847ecfb08469609a03Timo Sirainen stream->skip = stream->pos = v_offset - mstream->mmap_offset;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen } else {
b66412da78711db8423288847ecfb08469609a03Timo Sirainen /* force reading next time */
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen i_stream_munmap(mstream);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen stream->skip = stream->pos = v_offset;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen }
b66412da78711db8423288847ecfb08469609a03Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen stream->istream.v_offset = v_offset;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen}
b66412da78711db8423288847ecfb08469609a03Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic void _sync(struct _istream *stream)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
b66412da78711db8423288847ecfb08469609a03Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen i_stream_munmap(mstream);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen stream->skip = stream->pos = stream->istream.v_offset;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mstream->fstat_cache_stamp.tv_sec = 0;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen}
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic int fstat_cached(struct mmap_istream *mstream)
5bd2cf0f30371cb0374b026322a6f52fdb20755fTimo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen if (mstream->fstat_cache_stamp.tv_sec == ioloop_timeval.tv_sec &&
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen mstream->fstat_cache_stamp.tv_usec == ioloop_timeval.tv_usec)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen return 0;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (fstat(mstream->istream.fd, &mstream->istream.statbuf) < 0) {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen i_error("mmap_istream.fstat() failed: %m");
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen return -1;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen }
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen mstream->fstat_cache_stamp = ioloop_timeval;
fe219d44d016a40771117bdcb112828cdfad36a4Martti Rannanjärvi return 0;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen}
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic const struct stat *
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen_stat(struct _istream *stream, bool exact __attr_unused__)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen if (fstat_cached(mstream) < 0)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen return NULL;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen return &stream->statbuf;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen}
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstruct istream *i_stream_create_mmap(int fd, pool_t pool, size_t block_size,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen uoff_t start_offset, uoff_t v_size,
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen bool autoclose_fd)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen{
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct mmap_istream *mstream;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen struct istream *istream;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen struct stat st;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen if (mmap_pagemask == 0)
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen mmap_pagemask = mmap_get_page_size()-1;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen if (v_size == 0) {
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen if (fstat(fd, &st) < 0)
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen i_error("i_stream_create_mmap(): fstat() failed: %m");
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen else {
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen v_size = st.st_size;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen if (start_offset > v_size)
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen start_offset = v_size;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen v_size -= start_offset;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen }
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen }
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen mstream = p_new(pool, struct mmap_istream, 1);
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen _set_max_buffer_size(&mstream->istream.iostream, block_size);
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen mstream->autoclose_fd = autoclose_fd;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen mstream->v_size = v_size;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen mstream->istream.iostream.close = _close;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen mstream->istream.iostream.destroy = _destroy;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen mstream->istream.iostream.set_max_buffer_size = _set_max_buffer_size;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen
6b3f3a6561447afb13b2fcc22231d13653e8aff6Timo Sirainen mstream->istream.read = _read;
6b3f3a6561447afb13b2fcc22231d13653e8aff6Timo Sirainen mstream->istream.seek = _seek;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen mstream->istream.sync = _sync;
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen mstream->istream.stat = _stat;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen istream = _i_stream_create(&mstream->istream, pool, fd, start_offset);
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen istream->mmaped = TRUE;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen istream->blocking = TRUE;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen istream->seekable = TRUE;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen return istream;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen}
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen