mail-transaction-log.c revision 73e7998716853b5b7621c06aea0022dccda70ad1
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen/* this lock should never exist for a long time.. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#define LOG_DOTLOCK_IMMEDIATE_STALE_TIMEOUT 300
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenmail_transaction_log_file_open_or_create(struct mail_transaction_log *log,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *path);
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainenstatic int mail_transaction_log_rotate(struct mail_transaction_log *log,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenstatic int mail_transaction_log_lock_head(struct mail_transaction_log *log);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenmail_transaction_log_file_set_corrupted(struct mail_transaction_log_file *file,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *fmt, ...)
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen mail_index_file_set_syscall_error(file->log->index,
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen "Corrupted transaction log file %s: %s",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmail_transaction_log_file_dotlock(struct mail_transaction_log_file *file)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ret = file_lock_dotlock(file->filepath, NULL, FALSE,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_index_file_set_syscall_error(file->log->index,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "file_lock_dotlock()");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "Timeout while waiting for release of "
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen "dotlock for transaction log file %s",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmail_transaction_log_file_undotlock(struct mail_transaction_log_file *file)
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen ret = file_unlock_dotlock(file->filepath, &file->log->dotlock);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_index_file_set_syscall_error(file->log->index,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen "Dotlock was lost for transaction log file %s",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmail_transaction_log_file_lock(struct mail_transaction_log_file *file)
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen return mail_transaction_log_file_dotlock(file);
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen ret = file_wait_lock_full(file->fd, F_WRLCK, DEFAULT_LOCK_TIMEOUT,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen mail_index_file_set_syscall_error(file->log->index,
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen "file_wait_lock()");
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen "Timeout while waiting for release of "
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen "fcntl() lock for transaction log file %s",
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainenmail_transaction_log_file_unlock(struct mail_transaction_log_file *file)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_index_file_set_syscall_error(file->log->index,
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen "file_wait_lock()");
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen !(((file)->hdr.file_seq == (index)->hdr->log_file_seq && \
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen sizeof(struct mail_transaction_log_header)) || \
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen ((file)->hdr.prev_file_seq == (index)->hdr->log_file_seq && \
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen (file)->hdr.prev_file_offset == (index)->hdr->log_file_offset))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic int mail_transaction_log_check_file_seq(struct mail_transaction_log *log)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen unsigned int lock_id;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ret = mail_index_lock_shared(index, TRUE, &lock_id);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen else if (INDEX_HAS_MISSING_LOGS(index, file)) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* broken - fix it by creating a new log file */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ret = mail_transaction_log_rotate(log, F_UNLCK);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmail_transaction_log_open_or_create(struct mail_index *index)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen log->head = mail_transaction_log_file_open_or_create(log, path);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* head log file isn't same as head index file -
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen shouldn't happen except in race conditions. lock them and
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen check again - FIXME: missing error handling. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen (void)mail_transaction_log_check_file_seq(log);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid mail_transaction_log_close(struct mail_transaction_log *log)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmail_transaction_log_file_close(struct mail_transaction_log_file *file)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (munmap(file->mmap_base, file->mmap_size) < 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_index_file_set_syscall_error(file->log->index,
9aceb071780a949f4e8bf41d3cf80735d9ac7fdfTimo Sirainen mail_index_file_set_syscall_error(file->log->index,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmail_transaction_log_file_read_hdr(struct mail_transaction_log_file *file)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ret = pread_full(file->fd, &file->hdr, sizeof(file->hdr), 0);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen // FIXME: handle ESTALE
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_index_file_set_syscall_error(file->log->index,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "pread_full()");
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen "unexpected end of file while reading header");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* corrupted */
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen "Transaction log file %s: marked corrupted",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (file->hdr.indexid != file->log->index->indexid) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* creating index file, silently rebuild
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen transaction log as well */
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen /* index file was probably just rebuilt and we don't know
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen about it yet */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "Transaction log file %s: invalid indexid (%u != %u)",
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainenmail_transaction_log_file_create2(struct mail_transaction_log *log,
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen unsigned int lock_id;
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen /* log creation is locked now - see if someone already created it */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen mail_index_file_set_syscall_error(index, path,
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen } else if (st.st_ino == ino && CMP_DEV_T(st.st_dev, dev)) {
573085b4b25b0bbae8d27969df2c91702eefa23eTimo Sirainen /* same file, still broken */
0ee3fdb5e94ae6f34cb873ca3c9858342621e55fTimo Sirainen (void)file_dotlock_delete(path, LOG_NEW_DOTLOCK_SUFFIX,
1b04762685272a53643ac2179939537a44c7c044Timo Sirainen mail_index_file_set_syscall_error(index, path, "open()");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (mail_index_lock_shared(index, TRUE, &lock_id) < 0)
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen hdr.prev_file_offset = index->hdr->log_file_offset;
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen if (log->head != NULL && hdr.file_seq <= log->head->hdr.file_seq) {
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen /* make sure the sequence grows */
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen mail_index_file_set_syscall_error(index, path,
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen "write_full()");
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen mail_index_file_set_syscall_error(index, path, "dup()");
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen if (file_dotlock_replace(path, LOG_NEW_DOTLOCK_SUFFIX, fd, FALSE) <= 0)
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen /* success */
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainenmail_transaction_log_file_create(struct mail_transaction_log *log,
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen /* With dotlocking we might already have path.lock created, so this
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen filename has to be different. */
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen fd = file_dotlock_open(path, NULL, LOG_NEW_DOTLOCK_SUFFIX,
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen LOG_DOTLOCK_IMMEDIATE_STALE_TIMEOUT, NULL, NULL);
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen mail_index_file_set_syscall_error(log->index, path,
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen "file_dotlock_open()");
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen fd2 = mail_transaction_log_file_create2(log, path, fd, dev, ino);
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen (void)file_dotlock_delete(path, LOG_NEW_DOTLOCK_SUFFIX, fd);
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainenmail_transaction_log_file_fd_open(struct mail_transaction_log *log,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen mail_index_file_set_syscall_error(log->index, path, "fstat()");
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen file = i_new(struct mail_transaction_log_file, 1);
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen file->sync_offset = sizeof(struct mail_transaction_log_header);
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen ret = mail_transaction_log_file_read_hdr(file);
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen /* corrupted header */
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen fd = mail_transaction_log_file_create(log, path,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen mail_index_file_set_syscall_error(log->index, path,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ret = mail_transaction_log_file_read_hdr(file);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen file->hdr.file_seq == log->index->map->log_file_seq &&
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* we can get a valid log offset from index file. initialize
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen sync_offset from it so we don't have to read the whole log
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen file from beginning. */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen file->sync_offset = log->index->map->log_file_offset;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen for (p = &log->tail; *p != NULL; p = &(*p)->next) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if ((*p)->hdr.file_seq >= file->hdr.file_seq) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* log replaced with file having same sequence as
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen previous one. shouldn't happen unless previous
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen log file was corrupted.. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmail_transaction_log_file_open_or_create(struct mail_transaction_log *log,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen mail_index_file_set_syscall_error(log->index, path,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen fd = mail_transaction_log_file_create(log, path, 0, 0);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen return mail_transaction_log_file_fd_open(log, path, fd);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainenvoid mail_transaction_logs_clean(struct mail_transaction_log *log)
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if ((*p)->refcount != 0)
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainenmail_transaction_log_rotate(struct mail_transaction_log *log, int lock)
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen fd = mail_transaction_log_file_create(log, log->head->filepath,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen file = mail_transaction_log_file_fd_open(log, log->head->filepath, fd);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if (mail_transaction_log_file_lock(file) < 0) {
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainenstatic int mail_transaction_log_recreate(struct mail_transaction_log *log)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen unsigned int lock_id;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (mail_index_lock_shared(log->index, TRUE, &lock_id) < 0)
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen ret = mail_transaction_log_rotate(log, FALSE);
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainenstatic int mail_transaction_log_refresh(struct mail_transaction_log *log)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen mail_index_file_set_syscall_error(log->index, path, "stat()");
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen /* same file */
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen file = mail_transaction_log_file_open_or_create(log, path);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenint mail_transaction_log_file_find(struct mail_transaction_log *log,
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen for (file = log->tail; file != NULL; file = file->next) {
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainenmail_transaction_log_file_sync(struct mail_transaction_log_file *file)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen while (file->sync_offset - file->buffer_offset + sizeof(*hdr) <= size) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen hdr = CONST_PTR_OFFSET(data, file->sync_offset -
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen hdr_size = mail_index_offset_to_uint32(hdr->size);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* unfinished */
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen size = file->sync_offset - file->buffer_offset;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if (file->sync_offset - file->buffer_offset + hdr_size > size)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenmail_transaction_log_file_read(struct mail_transaction_log_file *file,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (file->buffer != NULL && file->buffer_offset > offset) {
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen /* we have to insert missing data to beginning of buffer */
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen buffer_copy(file->buffer, size, file->buffer, 0, (size_t)-1);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen data = buffer_get_space_unsafe(file->buffer, 0, size);
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen ret = pread_full(file->fd, data, size, offset);
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen "Unexpected end of file");
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* log file was deleted in NFS server,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen fail silently */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen mail_index_file_set_syscall_error(file->log->index,
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen file->buffer = buffer_create_dynamic(default_pool,
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen /* read all records */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen read_offset = file->buffer_offset + buffer_get_used_size(file->buffer);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen data = buffer_append_space_unsafe(file->buffer, LOG_PREFETCH);
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen ret = pread(file->fd, data, LOG_PREFETCH, read_offset);
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen } while (ret > 0 || (ret < 0 && errno == EINTR));
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* log file was deleted in NFS server, fail silently */
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen mail_index_file_set_syscall_error(file->log->index, file->filepath,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenint mail_transaction_log_file_map(struct mail_transaction_log_file *file,
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen /* corrupted */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen "offset (%"PRIuUOFF_T") < header size (%"PRIuSIZE_T")",
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen /* with mmap_no_write we could alternatively just write to log with
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen msync() rather than pwrite(). that'd cause slightly more disk I/O,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen so rather use more memory. */
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen use_mmap = !index->mmap_disable && !index->mmap_no_write;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (file->buffer != NULL && file->buffer_offset <= start_offset) {
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen /* see if we already have it */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen mail_index_file_set_syscall_error(index, file->filepath,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (file->mmap_base != NULL && st.st_size == file->mmap_size &&
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* it's all mmaped already */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (munmap(file->mmap_base, file->mmap_size) < 0) {
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen mail_index_file_set_syscall_error(index, file->filepath,
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen ret = mail_transaction_log_file_read(file, start_offset);
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen /* make sure we don't leave ourself in
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen inconsistent state */
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen file->mmap_base = mmap(NULL, file->mmap_size, PROT_READ,
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen mail_index_file_set_syscall_error(index, file->filepath,
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen file->buffer = buffer_create_const_data(default_pool,
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen if (end_offset != (uoff_t)-1 && end_offset > file->sync_offset) {
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen "end_offset (%"PRIuUOFF_T") > current sync_offset "
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen "(%"PRIuSIZE_T")", end_offset, file->sync_offset);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenstatic int mail_transaction_log_lock_head(struct mail_transaction_log *log)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* we want to get the head file locked. this is a bit racy,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen since by the time we have it locked a new log file may have been
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen creating new log file requires locking the head file, so if we
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen can lock it and don't see another file, we can be sure no-one is
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen creating a new log at the moment */
7e95ba7f38b9b421287d36c6152f8a9e6b9f225bTimo Sirainen /* success */
2eb0402a28bd0422e0170160808c67d6c7274689Timo Sirainen /* try again */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmail_transaction_log_append_fix(struct mail_index_transaction *t,
const void *data)
if (deleted) {
dest++;
const char *name;
t->extra_intros =
t_push();
t_pop();
struct mail_index_transaction *t)
const void *data;
int ret;
case MAIL_TRANSACTION_APPEND:
case MAIL_TRANSACTION_CACHE_RESET: {
case MAIL_TRANSACTION_EXTRA_INTRO: {
for (i = 0; i < size; i++)
return ret;
if (size == 0)
hdr_data_size = 0;
if (external)
hdr_size =
if (hdr_data_size > 0) {
struct mail_transaction_cache_reset u;
memset(&u, 0, sizeof(u));
return buf;
static const buffer_t *
struct mail_transaction_header_update u;
int state = 0;
memset(&u, 0, sizeof(u));
if (state == 0) {
state++;
if (state > 0) {
u.size);
state = 0;
return buf;
struct mail_index_transaction *t,
int ret;
t_push();
t_pop();
return ret;
unsigned int i, lock_id;
int ret;
if (!t->log_updates) {
*log_file_seq_r = 0;
*log_file_offset_r = 0;
sizeof(struct mail_index_extra_record_info));
ret = 0;
if (t->new_cache_file_seq != 0) {
size = 0;
&size);
&idx);
if (ret < 0)
if (ret < 0) {
t->hide_transaction) {
if (ret < 0) {
if (ret < 0)
return ret;