From: Stephan Bosch Date: Wed, 15 Sep 2021 23:49:57 +0000 (+0200) Subject: lib-storage: mail-duplicate - Update records from duplicate DB file after acquirement... X-Git-Tag: 2.3.17~50 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dcee43b54cda7000804c3278353574ef908c8119;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: mail-duplicate - Update records from duplicate DB file after acquirement of per-ID lock. The process previously holding the per-ID lock may have updated the DB. --- diff --git a/src/lib-storage/mail-duplicate.c b/src/lib-storage/mail-duplicate.c index 480eb014de..7eb1123ee4 100644 --- a/src/lib-storage/mail-duplicate.c +++ b/src/lib-storage/mail-duplicate.c @@ -68,6 +68,7 @@ struct mail_duplicate_record_header { struct mail_duplicate_transaction { pool_t pool; struct mail_duplicate_db *db; + ino_t db_ino; struct event *event; HASH_TABLE(struct mail_duplicate *, struct mail_duplicate *) hash; @@ -333,6 +334,7 @@ static int mail_duplicate_read_db_file(struct mail_duplicate_transaction *trans) const unsigned char *data; size_t size; int fd; + struct stat st; unsigned int record_size = 0; e_debug(trans->event, "Reading %s", trans->path); @@ -346,6 +348,13 @@ static int mail_duplicate_read_db_file(struct mail_duplicate_transaction *trans) return -1; } + if (fstat(fd, &st) < 0) { + e_error(trans->event, + "stat(%s) failed: %m", trans->path); + return -1; + } + trans->db_ino = st.st_ino; + /* */ input = i_stream_create_fd(fd, DUPLICATE_BUFSIZE); if (i_stream_read_bytes(input, &data, &size, sizeof(hdr)) > 0) { @@ -397,6 +406,27 @@ static void mail_duplicate_read(struct mail_duplicate_transaction *trans) file_dotlock_delete(&dotlock); } +static void mail_duplicate_update(struct mail_duplicate_transaction *trans) +{ + struct stat st; + + if (stat(trans->path, &st) < 0) { + if (errno == ENOENT) { + e_debug(trans->event, "DB file not created yet"); + } else { + e_error(trans->event, + "stat(%s) failed: %m", trans->path); + } + } else if (trans->db_ino == st.st_ino) { + e_debug(trans->event, "DB file not changed"); + } else { + e_debug(trans->event, "DB file changed: " + "Updating duplicate records from DB file"); + + mail_duplicate_read(trans); + } +} + struct mail_duplicate_transaction * mail_duplicate_transaction_begin(struct mail_duplicate_db *db) { @@ -513,6 +543,7 @@ mail_duplicate_check(struct mail_duplicate_transaction *trans, return MAIL_DUPLICATE_CHECK_RESULT_TOO_MANY_LOCKS; } + mail_duplicate_update(trans); if (dup->marked) { e_debug(trans->event, "Check ID: found"); return MAIL_DUPLICATE_CHECK_RESULT_EXISTS;