istream-mmap.c revision 8cb72c59d5ea4e9e5f638d7ec840bb853f5a188e
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen/* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenstatic void i_stream_mmap_close(struct iostream_private *stream)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen if (mstream->autoclose_fd && mstream->istream.fd != -1) {
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen i_stream_get_name(&mstream->istream.istream));
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenstatic void i_stream_munmap(struct mmap_istream *mstream)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen struct istream_private *_stream = &mstream->istream;
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen if (munmap(mstream->mmap_base, _stream->buffer_size) < 0) {
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenstatic void i_stream_mmap_destroy(struct iostream_private *stream)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenstatic size_t mstream_get_mmap_block_size(struct istream_private *stream)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen return (stream->max_buffer_size + mmap_get_page_size() - 1) & ~
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenstatic ssize_t i_stream_mmap_read(struct istream_private *stream)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen /* more bytes available without needing to mmap() */
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen if (stream->istream.v_offset >= mstream->v_size) {
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen if (aligned_skip == 0 && mstream->mmap_base != NULL) {
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen /* didn't skip enough bytes */
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen if (munmap(mstream->mmap_base, stream->buffer_size) < 0) {
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen stream->buffer_size = I_MIN(top, mstream_get_mmap_block_size(stream));
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen i_assert((uoff_t)mstream->mmap_offset + stream->buffer_size <=
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen /* don't bother even trying mmap */
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen mmap(NULL, stream->buffer_size, PROT_READ, MAP_PRIVATE,
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen if (stream->buffer_size > mmap_get_page_size()) {
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen if (madvise(mstream->mmap_base, stream->buffer_size,
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenstatic void i_stream_mmap_seek(struct istream_private *stream, uoff_t v_offset,
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen (uoff_t)mstream->mmap_offset + stream->buffer_size > v_offset) {
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen /* already mmaped */
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen stream->skip = stream->pos = v_offset - mstream->mmap_offset;
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen /* force reading next time */
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenstatic void i_stream_mmap_sync(struct istream_private *stream)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen stream->skip = stream->pos = stream->istream.v_offset;
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenstatic int fstat_cached(struct mmap_istream *mstream)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen if (mstream->fstat_cache_stamp.tv_sec == ioloop_timeval.tv_sec &&
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen mstream->fstat_cache_stamp.tv_usec == ioloop_timeval.tv_usec)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen if (fstat(mstream->istream.fd, &mstream->istream.statbuf) < 0) {
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen i_stream_get_name(&mstream->istream.istream));
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenstatic const struct stat *
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Siraineni_stream_mmap_stat(struct istream_private *stream, bool exact ATTR_UNUSED)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen struct mmap_istream *mstream = (struct mmap_istream *) stream;
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainenstruct istream *i_stream_create_mmap(int fd, size_t block_size,
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen i_error("i_stream_create_mmap(): fstat() failed: %m");
return istream;