<commit_before>/* Copyright (C) 2003-2004 <NAME> */

#include "lib.h"
#include "ioloop.h"
#include "array.h"
#include "buffer.h"
#include "write-full.h"
#include "mail-index-private.h"
#include "mail-index-view-private.h"
#include "mail-index-transaction-private.h"
#include "mail-transaction-log-private.h"

static int log_append_buffer(struct mail_transaction_log_file *file,
			     const buffer_t *buf, const buffer_t *hdr_buf,
			     enum mail_transaction_type type, int external)
{
	struct mail_transaction_header hdr;
	const void *data, *hdr_data;
	size_t size, hdr_data_size;
	uoff_t offset;
	uint32_t hdr_size;

	i_assert((type & MAIL_TRANSACTION_TYPE_MASK) != 0);

	data = buffer_get_data(buf, &size);
	if (size == 0)
		return 0;

	i_assert((size % 4) == 0);

	if (hdr_buf != NULL) {
		hdr_data = buffer_get_data(hdr_buf, &hdr_data_size);
		i_assert((hdr_data_size % 4) == 0);
	} else {
		hdr_data = NULL;
		hdr_data_size = 0;
	}

	memset(&hdr, 0, sizeof(hdr));
	hdr.type = type;
	if (type == MAIL_TRANSACTION_EXPUNGE)
		hdr.type |= MAIL_TRANSACTION_EXPUNGE_PROT;
	if (external)
		hdr.type |= MAIL_TRANSACTION_EXTERNAL;

	hdr_size = mail_index_uint32_to_offset(sizeof(hdr) + size +
					       hdr_data_size);
	if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) {
		do {
			offset = file->sync_offset;
			if (file->first_append_size == 0) {
				/* size will be written later once everything
				   is in disk */
				file->first_append_size = hdr_size;
			} else {
				hdr.size = hdr_size;
			}
			if (pwrite_full(file->fd, &hdr, sizeof(hdr),
					offset) < 0)
				break;
			offset += sizeof(hdr);

			if (hdr_data_size > 0) {
				if (pwrite_full(file->fd, hdr_data,
						hdr_data_size, offset) < 0)
					break;
				offset += hdr_data_size;
			}

			if (pwrite_full(file->fd, data, size, offset) < 0)
				break;

			file->sync_offset = offset + size;
			return 0;
		} while (0);

		/* write failure. */
		if (!ENOSPACE(errno)) {
			mail_index_file_set_syscall_error(file->log->index,
							  file->filepath,
							  "pwrite_full()");
			return -1;
		}

		/* not enough space. fallback to in-memory indexes. */
		if (mail_index_move_to_memory(file->log->index) < 0)
			return -1;
		i_assert(MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file));
	}

	hdr.size = hdr_size;

	i_assert(file->buffer_offset + file->buffer->used ==
		 file->sync_offset);
	buffer_append(file->buffer, &hdr, sizeof(hdr));
	buffer_append(file->buffer, hdr_data, hdr_data_size);
	buffer_append(file->buffer, data, size);<commit_msg>If write fails with "not enough space" error, log it instead of silently handling it.<commit_after>/* Copyright (C) 2003-2004 <NAME> */

#include "lib.h"
#include "ioloop.h"
#include "array.h"
#include "buffer.h"
#include "write-full.h"
#include "mail-index-private.h"
#include "mail-index-view-private.h"
#include "mail-index-transaction-private.h"
#include "mail-transaction-log-private.h"

static int log_append_buffer(struct mail_transaction_log_file *file,
			     const buffer_t *buf, const buffer_t *hdr_buf,
			     enum mail_transaction_type type, int external)
{
	struct mail_transaction_header hdr;
	const void *data, *hdr_data;
	size_t size, hdr_data_size;
	uoff_t offset;
	uint32_t hdr_size;

	i_assert((type & MAIL_TRANSACTION_TYPE_MASK) != 0);

	data = buffer_get_data(buf, &size);
	if (size == 0)
		return 0;

	i_assert((size % 4) == 0);

	if (hdr_buf != NULL) {
		hdr_data = buffer_get_data(hdr_buf, &hdr_data_size);
		i_assert((hdr_data_size % 4) == 0);
	} else {
		hdr_data = NULL;
		hdr_data_size = 0;
	}

	memset(&hdr, 0, sizeof(hdr));
	hdr.type = type;
	if (type == MAIL_TRANSACTION_EXPUNGE)
		hdr.type |= MAIL_TRANSACTION_EXPUNGE_PROT;
	if (external)
		hdr.type |= MAIL_TRANSACTION_EXTERNAL;

	hdr_size = mail_index_uint32_to_offset(sizeof(hdr) + size +
					       hdr_data_size);
	if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) {
		do {
			offset = file->sync_offset;
			if (file->first_append_size == 0) {
				/* size will be written later once everything
				   is in disk */
				file->first_append_size = hdr_size;
			} else {
				hdr.size = hdr_size;
			}
			if (pwrite_full(file->fd, &hdr, sizeof(hdr),
					offset) < 0)
				break;
			offset += sizeof(hdr);

			if (hdr_data_size > 0) {
				if (pwrite_full(file->fd, hdr_data,
						hdr_data_size, offset) < 0)
					break;
				offset += hdr_data_size;
			}

			if (pwrite_full(file->fd, data, size, offset) < 0)
				break;

			file->sync_offset = offset + size;
			return 0;
		} while (0);

		/* write failure. */
		mail_index_file_set_syscall_error(file->log->index,
						  file->filepath,
						  "pwrite_full()");
		if (!ENOSPACE(errno))
			return -1;

		/* not enough space. fallback to in-memory indexes. */
		if (mail_index_move_to_memory(file->log->index) < 0)
			return -1;
		i_assert(MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file));
	}

	hdr.size = hdr_size;

	i_assert(file->buffer_offset + file->buffer->used ==
		 file->sync_offset);
	buffer_append(file->buffer, &hdr, sizeof(hdr));
	buffer_append(file->buffer, hdr_data, hdr_data_size);
	buffer_append(file->buffer, data, size);
{'fraction_non_alphanumeric': 0.13837965700768776, 'fraction_numerical': 0.012221565148827124, 'mean_word_length': 3.818613485280152, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6071385', 'n_tokens_mistral': 2218, 'n_tokens_neox': 1929, 'n_words': 399}