mail-transaction-log.c revision d143077bd518de129b8d446fb58e003903e50867
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce/* Copyright (C) 2003-2004 Timo Sirainen */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce/* this lock should never exist for a long time.. */
7a162ca3ea0bf8ef6b13795a00baa28d17f6131dJakub Hrozekmail_transaction_log_file_open_or_create(struct mail_transaction_log *log,
7a162ca3ea0bf8ef6b13795a00baa28d17f6131dJakub Hrozek const char *path);
197da163943868216f704fb34031e7d5576e8aeeJakub Hrozekstatic int mail_transaction_log_rotate(struct mail_transaction_log *log,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorcestatic int mail_transaction_log_lock_head(struct mail_transaction_log *log);
f35f4e4c8bd5b834504c0554552d78db3624706aFabiano Fidênciomail_transaction_log_file_set_corrupted(struct mail_transaction_log_file *file,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce const char *fmt, ...)
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce mail_index_file_set_syscall_error(file->log->index,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "Corrupted transaction log file %s: %s",
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorcemail_transaction_log_file_dotlock(struct mail_transaction_log_file *file)
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = file_lock_dotlock(file->filepath, NULL, FALSE,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce mail_index_file_set_syscall_error(file->log->index,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce "file_lock_dotlock()");
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce "Timeout while waiting for release of "
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce "dotlock for transaction log file %s",
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozekmail_transaction_log_file_undotlock(struct mail_transaction_log_file *file)
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = file_unlock_dotlock(file->filepath, &file->log->dotlock);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce mail_index_file_set_syscall_error(file->log->index,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce "Dotlock was lost for transaction log file %s",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorcemail_transaction_log_file_lock(struct mail_transaction_log_file *file)
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (file->log->index->lock_method == MAIL_INDEX_LOCK_DOTLOCK)
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = mail_index_lock_fd(file->log->index, file->fd, F_WRLCK,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce mail_index_file_set_syscall_error(file->log->index,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "mail_index_wait_lock_fd()");
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "Timeout while waiting for release of "
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "fcntl() lock for transaction log file %s",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorcemail_transaction_log_file_unlock(struct mail_transaction_log_file *file)
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek if (file->log->index->lock_method == MAIL_INDEX_LOCK_DOTLOCK) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = mail_index_lock_fd(file->log->index, file->fd, F_UNLCK, 0);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce mail_index_file_set_syscall_error(file->log->index,
f35f4e4c8bd5b834504c0554552d78db3624706aFabiano Fidêncio "mail_index_wait_lock_fd()");
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce !(((file)->hdr.file_seq == (index)->hdr->log_file_seq && \
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce sizeof(struct mail_transaction_log_header)) || \
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ((file)->hdr.prev_file_seq == (index)->hdr->log_file_seq && \
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce (file)->hdr.prev_file_offset == (index)->hdr->log_file_offset))
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorcestatic int mail_transaction_log_check_file_seq(struct mail_transaction_log *log)
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce unsigned int lock_id;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = mail_index_lock_shared(index, TRUE, &lock_id);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek else if (INDEX_HAS_MISSING_LOGS(index, file)) {
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek /* broken - fix it by creating a new log file */
a9d46b86993ee8d87fddf0ba50665c0b1b78ebb7Simo Sorcemail_transaction_log_open_or_create(struct mail_index *index)
8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1Jakub Hrozek const char *path;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce log->head = mail_transaction_log_file_open_or_create(log, path);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek /* head log file isn't same as head index file -
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek shouldn't happen except in race conditions. lock them and
392f48c039d7a6d70bce6ae2d122042391653566Jakub Hrozek check again - FIXME: missing error handling. */
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozekvoid mail_transaction_log_close(struct mail_transaction_log *log)
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorcemail_transaction_log_file_close(struct mail_transaction_log_file *file)
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (munmap(file->mmap_base, file->mmap_size) < 0) {
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek mail_index_file_set_syscall_error(file->log->index,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "munmap()");
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce mail_index_file_set_syscall_error(file->log->index,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorcemail_transaction_log_file_read_hdr(struct mail_transaction_log_file *file)
f35f4e4c8bd5b834504c0554552d78db3624706aFabiano Fidêncio ret = pread_full(file->fd, &file->hdr, sizeof(file->hdr), 0);
8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1Jakub Hrozek // FIXME: handle ESTALE
f35f4e4c8bd5b834504c0554552d78db3624706aFabiano Fidêncio mail_index_file_set_syscall_error(file->log->index,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "pread_full()");
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "unexpected end of file while reading header");
8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1Jakub Hrozek /* corrupted */
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "Transaction log file %s: marked corrupted",
392f48c039d7a6d70bce6ae2d122042391653566Jakub Hrozek if (file->hdr.indexid != file->log->index->indexid) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce /* creating index file, silently rebuild
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek transaction log as well */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce /* index file was probably just rebuilt and we don't know
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce about it yet */
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "Transaction log file %s: invalid indexid (%u != %u)",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorcemail_transaction_log_file_create2(struct mail_transaction_log *log,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce unsigned int lock_id;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce /* log creation is locked now - see if someone already created it */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce } else if (st.st_ino == ino && CMP_DEV_T(st.st_dev, dev)) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce /* same file, still broken */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce (void)file_dotlock_delete(path, LOG_NEW_DOTLOCK_SUFFIX,
a9d46b86993ee8d87fddf0ba50665c0b1b78ebb7Simo Sorce mail_index_file_set_syscall_error(index, path, "open()");
d806427f200dc1ffd44d37724eb40125af5cc8c2Fabiano Fidêncio if (mail_index_lock_shared(index, TRUE, &lock_id) < 0)
a9d46b86993ee8d87fddf0ba50665c0b1b78ebb7Simo Sorce hdr.prev_file_offset = index->hdr->log_file_offset;
a9d46b86993ee8d87fddf0ba50665c0b1b78ebb7Simo Sorce if (log->head != NULL && hdr.file_seq <= log->head->hdr.file_seq) {
a9d46b86993ee8d87fddf0ba50665c0b1b78ebb7Simo Sorce /* make sure the sequence grows */
d806427f200dc1ffd44d37724eb40125af5cc8c2Fabiano Fidêncio "write_full()");
d806427f200dc1ffd44d37724eb40125af5cc8c2Fabiano Fidêncio mail_index_file_set_syscall_error(index, path, "dup()");
d806427f200dc1ffd44d37724eb40125af5cc8c2Fabiano Fidêncio if (file_dotlock_replace(path, LOG_NEW_DOTLOCK_SUFFIX, fd, FALSE) <= 0)
d806427f200dc1ffd44d37724eb40125af5cc8c2Fabiano Fidêncio /* success */
efc65e78fa4e01e6cecc8690a9899af61213be62Fabiano Fidênciomail_transaction_log_file_create(struct mail_transaction_log *log,
efc65e78fa4e01e6cecc8690a9899af61213be62Fabiano Fidêncio /* With dotlocking we might already have path.lock created, so this
197da163943868216f704fb34031e7d5576e8aeeJakub Hrozek filename has to be different. */
efc65e78fa4e01e6cecc8690a9899af61213be62Fabiano Fidêncio fd = file_dotlock_open(path, NULL, LOG_NEW_DOTLOCK_SUFFIX,
197da163943868216f704fb34031e7d5576e8aeeJakub Hrozek LOG_DOTLOCK_IMMEDIATE_STALE_TIMEOUT, NULL, NULL);
efc65e78fa4e01e6cecc8690a9899af61213be62Fabiano Fidêncio mail_index_file_set_syscall_error(log->index, path,
efc65e78fa4e01e6cecc8690a9899af61213be62Fabiano Fidêncio "file_dotlock_open()");
efc65e78fa4e01e6cecc8690a9899af61213be62Fabiano Fidêncio fd2 = mail_transaction_log_file_create2(log, path, fd, dev, ino);
197da163943868216f704fb34031e7d5576e8aeeJakub Hrozek (void)file_dotlock_delete(path, LOG_NEW_DOTLOCK_SUFFIX, fd);
65a38b8c9cabde6c46cc0e9868f54cb9bb10afbfFabiano Fidênciomail_transaction_log_file_fd_open(struct mail_transaction_log *log,
65a38b8c9cabde6c46cc0e9868f54cb9bb10afbfFabiano Fidêncio mail_index_file_set_syscall_error(log->index, path, "fstat()");
65a38b8c9cabde6c46cc0e9868f54cb9bb10afbfFabiano Fidêncio file = i_new(struct mail_transaction_log_file, 1);
65a38b8c9cabde6c46cc0e9868f54cb9bb10afbfFabiano Fidêncio file->sync_offset = sizeof(struct mail_transaction_log_header);
65a38b8c9cabde6c46cc0e9868f54cb9bb10afbfFabiano Fidêncio ret = mail_transaction_log_file_read_hdr(file);
65a38b8c9cabde6c46cc0e9868f54cb9bb10afbfFabiano Fidêncio /* corrupted header */
65a38b8c9cabde6c46cc0e9868f54cb9bb10afbfFabiano Fidêncio fd = mail_transaction_log_file_create(log, path,
7171a7584dda534dde5409f3e7f4657e845ece15Fabiano Fidêncio mail_index_file_set_syscall_error(log->index, path,
7171a7584dda534dde5409f3e7f4657e845ece15Fabiano Fidêncio ret = mail_transaction_log_file_read_hdr(file);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce file->hdr.file_seq == log->index->map->log_file_seq &&
8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1Jakub Hrozek /* we can get a valid log offset from index file. initialize
8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1Jakub Hrozek sync_offset from it so we don't have to read the whole log
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce file from beginning. */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce file->sync_offset = log->index->map->log_file_offset;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce for (p = &log->tail; *p != NULL; p = &(*p)->next) {
392f48c039d7a6d70bce6ae2d122042391653566Jakub Hrozek if ((*p)->hdr.file_seq >= file->hdr.file_seq) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce /* log replaced with file having same sequence as
a9d46b86993ee8d87fddf0ba50665c0b1b78ebb7Simo Sorce previous one. shouldn't happen unless previous
a9d46b86993ee8d87fddf0ba50665c0b1b78ebb7Simo Sorce log file was corrupted.. */
65a38b8c9cabde6c46cc0e9868f54cb9bb10afbfFabiano Fidênciomail_transaction_log_file_open_or_create(struct mail_transaction_log *log,
7171a7584dda534dde5409f3e7f4657e845ece15Fabiano Fidêncio mail_index_file_set_syscall_error(log->index, path,
7171a7584dda534dde5409f3e7f4657e845ece15Fabiano Fidêncio fd = mail_transaction_log_file_create(log, path, 0, 0);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek return mail_transaction_log_file_fd_open(log, path, fd);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorcevoid mail_transaction_logs_clean(struct mail_transaction_log *log)
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek if ((*p)->refcount != 0)
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozekmail_transaction_log_rotate(struct mail_transaction_log *log, int lock)
a9d46b86993ee8d87fddf0ba50665c0b1b78ebb7Simo Sorce fd = mail_transaction_log_file_create(log, log->head->filepath,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek file = mail_transaction_log_file_fd_open(log, log->head->filepath, fd);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek if (mail_transaction_log_file_lock(file) < 0) {
ab7b33fd7d820688545d5994a402cedf4bcdb6e1Fabiano Fidênciostatic int mail_transaction_log_recreate(struct mail_transaction_log *log)
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce unsigned int lock_id;
ab7b33fd7d820688545d5994a402cedf4bcdb6e1Fabiano Fidêncio if (mail_index_lock_shared(log->index, TRUE, &lock_id) < 0)
8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1Jakub Hrozekstatic int mail_transaction_log_refresh(struct mail_transaction_log *log)
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek const char *path;
392f48c039d7a6d70bce6ae2d122042391653566Jakub Hrozek mail_index_file_set_syscall_error(log->index, path, "stat()");
ab7b33fd7d820688545d5994a402cedf4bcdb6e1Fabiano Fidêncio /* same file */
ab7b33fd7d820688545d5994a402cedf4bcdb6e1Fabiano Fidêncio file = mail_transaction_log_file_open_or_create(log, path);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorceint mail_transaction_log_file_find(struct mail_transaction_log *log,
a9d46b86993ee8d87fddf0ba50665c0b1b78ebb7Simo Sorce for (file = log->tail; file != NULL; file = file->next) {
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozekmail_transaction_log_file_sync(struct mail_transaction_log_file *file)
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek const void *data;
efc65e78fa4e01e6cecc8690a9899af61213be62Fabiano Fidêncio data = buffer_get_data(file->buffer, &size);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek while (file->sync_offset - file->buffer_offset + sizeof(*hdr) <= size) {
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek hdr = CONST_PTR_OFFSET(data, file->sync_offset -
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek hdr_size = mail_index_offset_to_uint32(hdr->size);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek /* unfinished */
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek if (file->sync_offset - file->buffer_offset + hdr_size > size)
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozekmail_transaction_log_file_read(struct mail_transaction_log_file *file,
a9d46b86993ee8d87fddf0ba50665c0b1b78ebb7Simo Sorce if (file->buffer != NULL && file->buffer_offset > offset) {
f35f4e4c8bd5b834504c0554552d78db3624706aFabiano Fidêncio /* we have to insert missing data to beginning of buffer */
f35f4e4c8bd5b834504c0554552d78db3624706aFabiano Fidêncio buffer_copy(file->buffer, size, file->buffer, 0, (size_t)-1);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce data = buffer_get_space_unsafe(file->buffer, 0, size);
8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1Jakub Hrozek ret = pread_full(file->fd, data, size, offset);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "Unexpected end of file");
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce /* log file was deleted in NFS server,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce fail silently */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce mail_index_file_set_syscall_error(file->log->index,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce buffer_create_dynamic(default_pool, LOG_PREFETCH);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce /* read all records */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce read_offset = file->buffer_offset + buffer_get_used_size(file->buffer);
8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1Jakub Hrozek data = buffer_append_space_unsafe(file->buffer, LOG_PREFETCH);
8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1Jakub Hrozek ret = pread(file->fd, data, LOG_PREFETCH, read_offset);
8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1Jakub Hrozek } while (ret > 0 || (ret < 0 && errno == EINTR));
8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1Jakub Hrozek /* log file was deleted in NFS server, fail silently */
8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1Jakub Hrozek mail_index_file_set_syscall_error(file->log->index, file->filepath,
8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1Jakub Hrozekint mail_transaction_log_file_map(struct mail_transaction_log_file *file,
8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1Jakub Hrozek /* corrupted */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "offset (%"PRIuUOFF_T") < header size (%"PRIuSIZE_T")",
f35f4e4c8bd5b834504c0554552d78db3624706aFabiano Fidêncio /* with mmap_no_write we could alternatively just write to log with
f35f4e4c8bd5b834504c0554552d78db3624706aFabiano Fidêncio msync() rather than pwrite(). that'd cause slightly more disk I/O,
f35f4e4c8bd5b834504c0554552d78db3624706aFabiano Fidêncio so rather use more memory. */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce use_mmap = !index->mmap_disable && !index->mmap_no_write;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (file->buffer != NULL && file->buffer_offset <= start_offset) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce /* see if we already have it */
a9d46b86993ee8d87fddf0ba50665c0b1b78ebb7Simo Sorce mail_index_file_set_syscall_error(index, file->filepath,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (file->mmap_base != NULL && (uoff_t)st.st_size == file->mmap_size &&
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce /* it's all mmaped already */
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce if (munmap(file->mmap_base, file->mmap_size) < 0) {
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce mail_index_file_set_syscall_error(index, file->filepath,
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce "munmap()");
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce ret = mail_transaction_log_file_read(file, start_offset);
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce /* make sure we don't leave ourself in
197da163943868216f704fb34031e7d5576e8aeeJakub Hrozek inconsistent state */
8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1Jakub Hrozek file->mmap_base = mmap(NULL, file->mmap_size, PROT_READ,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce mail_index_file_set_syscall_error(index, file->filepath,
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce file->buffer = buffer_create_const_data(default_pool,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (end_offset != (uoff_t)-1 && end_offset > file->sync_offset) {
73ce539aa70f43ccd5302b3ef8a02ff028558b12Jakub Hrozek "end_offset (%"PRIuUOFF_T") > current sync_offset "
73ce539aa70f43ccd5302b3ef8a02ff028558b12Jakub Hrozek "(%"PRIuSIZE_T")", end_offset, file->sync_offset);
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorcestatic int mail_transaction_log_lock_head(struct mail_transaction_log *log)
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce /* we want to get the head file locked. this is a bit racy,
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce since by the time we have it locked a new log file may have been
8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1Jakub Hrozek creating new log file requires locking the head file, so if we
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce can lock it and don't see another file, we can be sure no-one is
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce creating a new log at the moment */
a9d46b86993ee8d87fddf0ba50665c0b1b78ebb7Simo Sorce /* success */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce /* try again */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorcestatic int mail_transaction_log_scan_pending(struct mail_transaction_log *log,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek const void *data;
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek sync_view = mail_transaction_log_view_open(log);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek ret = mail_transaction_log_view_set(sync_view, t->view->log_file_seq,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce while ((ret = mail_transaction_log_view_next(sync_view,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce const struct mail_transaction_cache_reset *reset = data;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce /* make sure we're not writing cache_offsets to old cache file */
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (t->new_cache_file_seq == 0 && max_cache_file_seq != 0 &&
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce rec = buffer_get_modifyable_data(t->appends, &size);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek for (i = 0; i < size; i++)
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozekstatic int log_append_buffer(struct mail_transaction_log_file *file,
6c82774653f37945bdd0a311eb1ecc289cac683dLukas Slebodnik i_assert((type & MAIL_TRANSACTION_TYPE_MASK) != 0);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce hdr_data = buffer_get_data(hdr_buf, &hdr_data_size);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce mail_index_uint32_to_offset(sizeof(hdr) + size + hdr_data_size);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce /* size will be written later once everything is in disk */
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (pwrite_full(file->fd, &hdr, sizeof(hdr), file->sync_offset) < 0)
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek if (pwrite_full(file->fd, hdr_data, hdr_data_size,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (pwrite_full(file->fd, data, size, file->sync_offset) < 0)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorcestatic const buffer_t *get_cache_reset_buf(struct mail_index_transaction *t)
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek memset(&u, 0, sizeof(u));
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce buf = buffer_create_static_hard(pool_datastack_create(), sizeof(u));
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozekstatic const buffer_t *
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozeklog_get_hdr_update_buffer(struct mail_index_transaction *t)
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek memset(&u, 0, sizeof(u));
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek buf = buffer_create_dynamic(pool_datastack_create(), 256);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce for (offset = 0; offset <= sizeof(t->hdr_change); offset++) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (offset < sizeof(t->hdr_change) && t->hdr_mask[offset]) {
if (state > 0) {
u.size);
state = 0;
return buf;
struct mail_index_transaction *t,
size = 0;
struct mail_index_transaction *t)
update_count = 0;
resize_count = 0;
ext_id) < 0)
unsigned int i, lock_id;
int ret;
if (!t->log_updates) {
*log_file_seq_r = 0;
*log_file_offset_r = 0;
ret = 0;
if (t->new_cache_file_seq != 0) {
size = 0;
if (ret < 0)
if (ret < 0) {
t->hide_transaction) {
if (ret < 0) {
if (ret < 0)
return ret;