static int mail_transaction_log_refresh(struct mail_transaction_log *log, bool nfs_flush) { struct mail_transaction_log_file *file; struct stat st; i_assert(log->head != NULL); if (MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(log->head)) return 0; if (nfs_flush && log->nfs_flush) nfs_flush_file_handle_cache(log->filepath); if (nfs_safe_stat(log->filepath, &st) < 0) { if (errno != ENOENT) { mail_index_file_set_syscall_error(log->index, log->filepath, "stat()"); return -1; } /* see if the whole directory got deleted */ if (nfs_safe_stat(log->index->dir, &st) < 0 && errno == ENOENT) { log->index->index_deleted = TRUE; return -1; } /* the file should always exist at this point. if it doesn't, someone deleted it manually while the index was open. try to handle this nicely by creating a new log file. */ file = log->head; if (mail_transaction_log_create(log, FALSE) < 0) return -1; i_assert(file->refcount > 0); file->refcount--; log->index->need_recreate = TRUE; return 0; } else if (log->head->st_ino == st.st_ino && CMP_DEV_T(log->head->st_dev, st.st_dev)) { /* NFS: log files get rotated to .log.2 files instead of being unlinked, so we don't bother checking if the existing file has already been unlinked here (in which case inodes could match but point to different files) */ return 0; } file = mail_transaction_log_file_alloc(log, log->filepath); if (mail_transaction_log_file_open(file, FALSE) <= 0) { mail_transaction_log_file_free(&file); return -1; } i_assert(!file->locked); if (--log->head->refcount == 0) mail_transaction_logs_clean(log); mail_transaction_log_set_head(log, file); return 0; }
void mail_transaction_log_indexid_changed(struct mail_transaction_log *log) { struct mail_transaction_log_file *file; mail_transaction_logs_clean(log); for (file = log->files; file != NULL; file = file->next) { if (file->hdr.indexid != log->index->indexid) { mail_transaction_log_file_set_corrupted(file, "indexid changed: %u -> %u", file->hdr.indexid, log->index->indexid); } } if (log->head != NULL && log->head->hdr.indexid != log->index->indexid) { if (--log->head->refcount == 0) mail_transaction_log_file_free(&log->head); (void)mail_transaction_log_create(log, FALSE); } }