istream-mmap.c revision c06f4017027263cf3a08becc551f5126409e2a83
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2002-2003 Timo Sirainen */
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (mstream->autoclose_fd && mstream->istream.fd != -1) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic void i_stream_munmap(struct mmap_istream *mstream)
4babe70b863c71ea330cbf32ac0b71876f4f9137Timo Sirainen if (munmap(mstream->mmap_base, _stream->buffer_size) < 0)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainenstatic void _set_max_buffer_size(struct _iostream *stream, size_t max_size)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen /* allow only full page sizes */
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen mstream->mmap_block_size = mmap_get_page_size();
b66412da78711db8423288847ecfb08469609a03Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen /* more bytes available without needing to mmap() */
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen if (stream->istream.v_offset >= mstream->v_size) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (aligned_skip == 0 && mstream->mmap_base != NULL) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen /* didn't skip enough bytes */
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (munmap(mstream->mmap_base, stream->buffer_size) < 0)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen i_error("io_stream_read_mmaped(): munmap() failed: %m");
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen stream->buffer_size = I_MIN(top, mstream->mmap_block_size);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen i_assert((uoff_t)mstream->mmap_offset + stream->buffer_size <=
b66412da78711db8423288847ecfb08469609a03Timo Sirainen /* don't bother even trying mmap */
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen mmap(NULL, stream->buffer_size, PROT_READ, MAP_PRIVATE,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen if (stream->buffer_size > mmap_get_page_size()) {
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen if (madvise(mstream->mmap_base, stream->buffer_size,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstatic void _seek(struct _istream *stream, uoff_t v_offset,
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
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;
b66412da78711db8423288847ecfb08469609a03Timo Sirainen /* force reading next time */
b66412da78711db8423288847ecfb08469609a03Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen stream->skip = stream->pos = stream->istream.v_offset;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic int fstat_cached(struct mmap_istream *mstream)
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 if (fstat(mstream->istream.fd, &mstream->istream.statbuf) < 0) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic const struct stat *
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen_stat(struct _istream *stream, bool exact __attr_unused__)
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
b58fbcc79c40f867eccae98548fcd25a16823433Timo Sirainenstruct istream *i_stream_create_mmap(int fd, pool_t pool, size_t block_size,
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen i_error("i_stream_create_mmap(): fstat() failed: %m");
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen mstream = p_new(pool, struct mmap_istream, 1);
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen _set_max_buffer_size(&mstream->istream.iostream, block_size);
9c0716dfcd6b575419776848dd7157186ef58d57Timo Sirainen mstream->istream.iostream.set_max_buffer_size = _set_max_buffer_size;