static int
mail_transaction_log_file_insert_read(struct mail_transaction_log_file *file,
				      uoff_t offset)
{
	void *data;
	size_t size;
	ssize_t ret;

	size = file->buffer_offset - offset;
	buffer_copy(file->buffer, size, file->buffer, 0, (size_t)-1);

	data = buffer_get_space_unsafe(file->buffer, 0, size);
	ret = pread_full(file->fd, data, size, offset);
	if (ret > 0) {
		/* success */
		file->buffer_offset -= size;
		return 1;
	}

	/* failure. don't leave ourself to inconsistent state */
	buffer_copy(file->buffer, 0, file->buffer, size, (size_t)-1);
	buffer_set_used_size(file->buffer, file->buffer->used - size);

	if (ret == 0) {
		mail_transaction_log_file_set_corrupted(file, "file shrank");
		return 0;
	} else if (errno == ESTALE) {
		/* log file was deleted in NFS server, fail silently */
		return 0;
	} else {
		log_file_set_syscall_error(file, "pread()");
		return -1;
	}
}
Exemple #2
0
static int squat_uidlist_map(struct squat_uidlist *uidlist)
{
	const struct squat_uidlist_file_header *mmap_hdr = uidlist->mmap_base;
	int ret;

	if (mmap_hdr != NULL && !uidlist->building &&
	    uidlist->hdr.block_list_offset == mmap_hdr->block_list_offset) {
		/* file hasn't changed */
		return 1;
	}

	if ((uidlist->trie->flags & SQUAT_INDEX_FLAG_MMAP_DISABLE) == 0) {
		if (mmap_hdr == NULL || uidlist->building ||
		    uidlist->mmap_size < mmap_hdr->used_file_size) {
			if (squat_uidlist_mmap(uidlist) < 0)
				return -1;
		}

		if (!uidlist->building) {
			memcpy(&uidlist->hdr, uidlist->mmap_base,
			       sizeof(uidlist->hdr));
		}
	} else if (uidlist->building) {
		/* we want to update blocks mapping, but using the header
		   in memory */
	} else {
		ret = pread_full(uidlist->fd, &uidlist->hdr,
				 sizeof(uidlist->hdr), 0);
		if (ret <= 0) {
			if (ret < 0) {
				i_error("pread(%s) failed: %m", uidlist->path);
				return -1;
			}
			i_error("Corrupted %s: File too small", uidlist->path);
			return 0;
		}
		uidlist->data = NULL;
		uidlist->data_size = 0;
	}
	if (uidlist->file_cache == NULL &&
	    (uidlist->trie->flags & SQUAT_INDEX_FLAG_MMAP_DISABLE) != 0)
		uidlist->file_cache = file_cache_new(uidlist->fd);
	return squat_uidlist_map_header(uidlist);
}
Exemple #3
0
static int i_stream_seekable_write_failed(struct seekable_istream *sstream)
{
	struct istream_private *stream = &sstream->istream;
	void *data;

	i_assert(sstream->fd != -1);

	stream->max_buffer_size = (size_t)-1;
	data = i_stream_alloc(stream, sstream->write_peak);

	if (pread_full(sstream->fd, data, sstream->write_peak, 0) < 0) {
		i_error("istream-seekable: read(%s) failed: %m", sstream->temp_path);
		memarea_unref(&stream->memarea);
		return -1;
	}
	i_stream_destroy(&sstream->fd_input);
	i_close_fd(&sstream->fd);

	i_free_and_null(sstream->temp_path);
	return 0;
}
static int i_stream_seekable_write_failed(struct seekable_istream *sstream)
{
    struct istream_private *stream = &sstream->istream;
    void *data;

    i_assert(sstream->membuf == NULL);

    sstream->membuf =
        buffer_create_dynamic(default_pool, sstream->write_peak);
    data = buffer_append_space_unsafe(sstream->membuf, sstream->write_peak);

    if (pread_full(sstream->fd, data, sstream->write_peak, 0) < 0) {
        i_error("istream-seekable: read(%s) failed: %m", sstream->temp_path);
        buffer_free(&sstream->membuf);
        return -1;
    }
    i_stream_destroy(&sstream->fd_input);
    i_close_fd(&sstream->fd);

    stream->max_buffer_size = (size_t)-1;
    i_free_and_null(sstream->temp_path);
    return 0;
}