]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: Add comments to struct mail_transaction_log and related
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 2 Feb 2021 14:13:50 +0000 (16:13 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Mon, 3 May 2021 13:01:05 +0000 (13:01 +0000)
src/lib-index/mail-transaction-log-private.h

index b720e47a988e0ef9a03499e6e9a00d183e5fd516..f08aefb0250fcf6f5071117be73f8a15de05676f 100644 (file)
@@ -22,7 +22,9 @@ struct modseq_cache {
 
 struct mail_transaction_log_file {
        struct mail_transaction_log *log;
-        struct mail_transaction_log_file *next;
+       /* Next file in the mail_transaction_log.files list. Sorted by
+          hdr.file_seq. */
+       struct mail_transaction_log_file *next;
 
        /* refcount=0 is a valid state. files start that way, and they're
           freed only when mail_transaction_logs_clean() is called. */
@@ -31,62 +33,108 @@ struct mail_transaction_log_file {
        char *filepath;
        int fd;
 
+       /* Cached values for last stat()/fstat() */
        ino_t st_ino;
        dev_t st_dev;
        time_t last_mtime;
        uoff_t last_size;
 
+       /* Used to avoid logging mmap() errors too rapidly. */
        time_t last_mmap_error_time;
+       /* If non-NULL, the log file should be rotated. The string contains a
+          human-readable reason why the rotation was requested. */
        char *need_rotate;
 
+       /* Copy of the log file header. Set when opened. */
        struct mail_transaction_log_header hdr;
+       /* Buffer that points to mmap_base */
        buffer_t mmap_buffer;
+       /* Buffer that can be used to access the log file contents. Either
+          points to mmap_buffer, or it's a copy of the file contents starting
+          from buffer_offset. */
        buffer_t *buffer;
+       /* Offset to log where the buffer starts from. 0 with mmaped log. */
        uoff_t buffer_offset;
+       /* If non-NULL, mmap()ed log file */
        void *mmap_base;
        size_t mmap_size;
 
-       /* points to the next uncommitted transaction. usually same as EOF. */
+       /* Offset to log file how far it's been read. Usually it's the same
+          as the log file size. However, if the last multi-record transaction
+          wasn't fully written (or is in the middle of being written), this
+          points to the beginning of the MAIL_TRANSACTION_BOUNDARY record. */
        uoff_t sync_offset;
        /* highest modseq at sync_offset */
        uint64_t sync_highest_modseq;
-       /* last_read_hdr_tail_offset is the offset that was last written to transaction
-          log. max_tail_offset is what should be written to the log the next
-          time a transaction is written. transaction log handling may update
-          max_tail_offset automatically by making it skip external transactions
-          after the last saved offset (to avoid re-reading them needlessly). */
-       uoff_t last_read_hdr_tail_offset, max_tail_offset;
-
-       /* if we've seen _INDEX_[UN9DELETED transaction in this file,
-          this is the offset. otherwise UOFF_T_MAX */
+       /* The last mail_index_header.log_file_tail_offset update that was
+          read from the log. */
+       uoff_t last_read_hdr_tail_offset;
+       /* Update mail_index_header.log_file_tail_offset to this offset the
+          next time a transaction is written. Transaction log handling may
+          increase this automatically by making it skip external transactions
+          after last_read_hdr_tail_offset (to avoid re-reading them
+          needlessly). */
+       uoff_t max_tail_offset;
+
+       /* Last seen offsets for MAIL_TRANSACTION_INDEX_DELETED and
+          MAIL_TRANSACTION_INDEX_UNDELETED records. These are used to update
+          mail_index.index_delete* fields. */
        uoff_t index_deleted_offset, index_undeleted_offset;
 
+       /* Cache to optimize mail_transaction_log_file_get_modseq_next_offset()
+          so it doesn't always have to start from the beginning of the log
+          file to find the wanted modseq. */
        struct modseq_cache modseq_cache[LOG_FILE_MODSEQ_CACHE_SIZE];
 
+       /* Lock for the log file fd. If dotlocking is used, this is NULL and
+          mail_transaction_log.dotlock is used instead. */
        struct file_lock *file_lock;
+       /* Time when the log was successfully locked */
        time_t lock_create_time;
 
+       /* Log is currently locked. */
        bool locked:1;
+       /* TRUE if sync_offset has already been updated while this log was
+          locked. This can be used to optimize away unnecessary checks to see
+          whether there's more data written to log after sync_offset. */
        bool locked_sync_offset_updated:1;
+       /* Log file has found to be corrupted. Stop trying to read it.
+          The indexid is also usually overwritten to be 0 in the log header at
+          this time. */
        bool corrupted:1;
 };
 
 struct mail_transaction_log {
        struct mail_index *index;
-        struct mail_transaction_log_view *views;
+       /* Linked list of all transaction log views */
+       struct mail_transaction_log_view *views;
+       /* Paths to .log and .log.2 */
        char *filepath, *filepath2;
 
-       /* files is a linked list of all the opened log files. the list is
-          sorted by the log file sequence, so that transaction views can use
-          them easily. head contains a pointer to the newest log file. */
-       struct mail_transaction_log_file *files, *head;
+       /* Linked list of all the opened log files. The oldest files may have
+          already been unlinked. The list is sorted by the log file sequence
+          (oldest/lowest first), so that transaction views can use them
+          easily. */
+       struct mail_transaction_log_file *files;
+       /* Latest log file (the last file in the files linked list) */
+       struct mail_transaction_log_file *head;
        /* open_file is used temporarily while opening the log file.
-          if _open() failed, it's left there for _create(). */
+          if mail_transaction_log_open() failed, it's left there for
+          mail_transaction_log_create(). */
        struct mail_transaction_log_file *open_file;
 
+       /* Normally the .log locking is done via their file descriptors, so
+          e.g. rotating a log needs to lock both the old and the new files
+          at the same time. However, when FILE_LOCK_METHOD_DOTLOCK is used,
+          the lock isn't file-specific. There is just a single dotlock that
+          is created by the first log file lock. The second lock simply
+          increases the refcount. (It's not expected that there would be more
+          than 2 locks.) */
        int dotlock_refcount;
        struct dotlock *dotlock;
 
+       /* This session has already checked whether an old .log.2 should be
+          unlinked. */
        bool log_2_unlink_checked:1;
 };