[PATCH 04/13] Write entire header during upgrade

Bron Gondwana brong at fastmail.fm
Tue Jan 27 23:15:31 EST 2009


This patch keeps a copy of the index header record written at the start
of the index upgrade so it can write it entirely again at the end rather
than seeking inside and writing just a part of the record.

This is to set up for CRC32 patches later, which will need to have the
complete header record on hand to recalculate.  Otherwise, it's just
neater anyway.
---
 imap/mailbox.c |   60 ++++++++++++++++++++++++++++----------------------------
 1 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/imap/mailbox.c b/imap/mailbox.c
index c421b56..696a79a 100644
--- a/imap/mailbox.c
+++ b/imap/mailbox.c
@@ -1557,7 +1557,9 @@ static void mailbox_upgrade_index_work(struct mailbox *mailbox,
     unsigned msgno;
     bit32 oldstart_offset, oldrecord_size;
     indexbuffer_t ibuf;
+    indexbuffer_t hbuf;
     unsigned char *buf = ibuf.buf, *bufp;
+    unsigned char *headerbuf = hbuf.buf;
     int quota_offset = 0;
     int calculate_flagcounts = 0;
     bit32 numansweredflag = 0;
@@ -1566,43 +1568,43 @@ static void mailbox_upgrade_index_work(struct mailbox *mailbox,
     int old_minor_version = 0;
 
     /* Copy existing header so we can upgrade it */ 
-    memcpy(buf, index_base, INDEX_HEADER_SIZE);
+    memcpy(headerbuf, index_base, INDEX_HEADER_SIZE);
 
-    exists = ntohl(*((bit32 *)(buf+OFFSET_EXISTS)));
+    exists = ntohl(*((bit32 *)(headerbuf+OFFSET_EXISTS)));
 
-    old_minor_version = ntohl(*((bit32 *)(buf+OFFSET_MINOR_VERSION)));
+    old_minor_version = ntohl(*((bit32 *)(headerbuf+OFFSET_MINOR_VERSION)));
 
     /* QUOTA_MAILBOX_USED64 added with minor version 6 */
     if (old_minor_version < 6) {
 	quota_offset = sizeof(bit32);
 	/* upgrade quota to 64-bits (bump existing fields) */
-	memmove(buf+OFFSET_QUOTA_MAILBOX_USED, buf+OFFSET_QUOTA_MAILBOX_USED64,
+	memmove(headerbuf+OFFSET_QUOTA_MAILBOX_USED, headerbuf+OFFSET_QUOTA_MAILBOX_USED64,
 		INDEX_HEADER_SIZE - OFFSET_QUOTA_MAILBOX_USED64 - quota_offset);
 	/* zero the unused 32-bits */
-	*((bit32 *)(buf+OFFSET_QUOTA_MAILBOX_USED64)) = htonl(0);
+	*((bit32 *)(headerbuf+OFFSET_QUOTA_MAILBOX_USED64)) = htonl(0);
     }
 
     /* HIGHESTMODSEQ[_64] added with minor version 8 */
     if (old_minor_version < 8) {
 	/* Set the initial highestmodseq to 1 */
 #ifdef HAVE_LONG_LONG_INT
-	align_htonll(buf+OFFSET_HIGHESTMODSEQ_64, 1);
+	align_htonll(headerbuf+OFFSET_HIGHESTMODSEQ_64, 1);
 #else
-	*((bit32 *)(buf+OFFSET_HIGHESTMODSEQ_64)) = htonl(0);
-	*((bit32 *)(buf+OFFSET_HIGHESTMODSEQ)) = htonl(1);
+	*((bit32 *)(headerbuf+OFFSET_HIGHESTMODSEQ_64)) = htonl(0);
+	*((bit32 *)(headerbuf+OFFSET_HIGHESTMODSEQ)) = htonl(1);
 #endif
     }
 
     /* change version number */
-    *((bit32 *)(buf+OFFSET_MINOR_VERSION)) = htonl(MAILBOX_MINOR_VERSION);
+    *((bit32 *)(headerbuf+OFFSET_MINOR_VERSION)) = htonl(MAILBOX_MINOR_VERSION);
 
     /* save old start_offset; change start_offset */
-    oldstart_offset = ntohl(*((bit32 *)(buf+OFFSET_START_OFFSET)));
-    *((bit32 *)(buf+OFFSET_START_OFFSET)) = htonl(INDEX_HEADER_SIZE);
+    oldstart_offset = ntohl(*((bit32 *)(headerbuf+OFFSET_START_OFFSET)));
+    *((bit32 *)(headerbuf+OFFSET_START_OFFSET)) = htonl(INDEX_HEADER_SIZE);
 
     /* save old record_size; change record_size */
-    oldrecord_size = ntohl(*((bit32 *)(buf+OFFSET_RECORD_SIZE)));
-    *((bit32 *)(buf+OFFSET_RECORD_SIZE)) = htonl(INDEX_RECORD_SIZE);
+    oldrecord_size = ntohl(*((bit32 *)(headerbuf+OFFSET_RECORD_SIZE)));
+    *((bit32 *)(headerbuf+OFFSET_RECORD_SIZE)) = htonl(INDEX_RECORD_SIZE);
 
     /* sanity check the record size */
     if (oldrecord_size > INDEX_RECORD_SIZE) {
@@ -1618,10 +1620,10 @@ static void mailbox_upgrade_index_work(struct mailbox *mailbox,
      * minor version wasn't updated religiously in the early days,
      * so we need to use the old offset instead */
     if (oldstart_offset < OFFSET_POP3_LAST_LOGIN-quota_offset+sizeof(bit32)) {
-	*((bit32 *)(buf+OFFSET_POP3_LAST_LOGIN)) = htonl(0);
+	*((bit32 *)(headerbuf+OFFSET_POP3_LAST_LOGIN)) = htonl(0);
     }
     if (oldstart_offset < OFFSET_UIDVALIDITY-quota_offset+sizeof(bit32)) {
-	*((bit32 *)(buf+OFFSET_UIDVALIDITY)) = htonl(1);
+	*((bit32 *)(headerbuf+OFFSET_UIDVALIDITY)) = htonl(1);
     }
     if (oldstart_offset < OFFSET_FLAGGED-quota_offset+sizeof(bit32)) {
 	struct stat sbuf;
@@ -1640,17 +1642,17 @@ static void mailbox_upgrade_index_work(struct mailbox *mailbox,
     if (oldstart_offset < OFFSET_MAILBOX_OPTIONS-quota_offset+sizeof(bit32)) {
 	unsigned long options = config_getint(IMAPOPT_MAILBOX_DEFAULT_OPTIONS);
 	if (!exists) options |= OPT_POP3_NEW_UIDL;
-	*((bit32 *)(buf+OFFSET_MAILBOX_OPTIONS)) = htonl(options);
+	*((bit32 *)(headerbuf+OFFSET_MAILBOX_OPTIONS)) = htonl(options);
     }
 
-    *((bit32 *)(buf+OFFSET_SPARE0)) = htonl(0); /* RESERVED */
-    *((bit32 *)(buf+OFFSET_SPARE1)) = htonl(0); /* RESERVED */
-    *((bit32 *)(buf+OFFSET_SPARE2)) = htonl(0); /* RESERVED */
-    *((bit32 *)(buf+OFFSET_SPARE3)) = htonl(0); /* RESERVED */
-    *((bit32 *)(buf+OFFSET_SPARE4)) = htonl(0); /* RESERVED */
+    *((bit32 *)(headerbuf+OFFSET_SPARE0)) = htonl(0); /* RESERVED */
+    *((bit32 *)(headerbuf+OFFSET_SPARE1)) = htonl(0); /* RESERVED */
+    *((bit32 *)(headerbuf+OFFSET_SPARE2)) = htonl(0); /* RESERVED */
+    *((bit32 *)(headerbuf+OFFSET_SPARE3)) = htonl(0); /* RESERVED */
+    *((bit32 *)(headerbuf+OFFSET_SPARE4)) = htonl(0); /* RESERVED */
 
     /* Write new header */
-    fwrite(buf, 1, INDEX_HEADER_SIZE, newindex);
+    fwrite(headerbuf, 1, INDEX_HEADER_SIZE, newindex);
 
     /* Write the rest of new index */
     for (msgno = 1; msgno <= exists; msgno++) {
@@ -1735,14 +1737,12 @@ static void mailbox_upgrade_index_work(struct mailbox *mailbox,
 
     if (calculate_flagcounts) {
 	/* go back and add flag counts to header */
-	memset(buf, 0, INDEX_RECORD_SIZE);
-	*((bit32 *)(buf+OFFSET_DELETED)) = htonl(numdeletedflag);
-	*((bit32 *)(buf+OFFSET_ANSWERED)) = htonl(numansweredflag);
-	*((bit32 *)(buf+OFFSET_FLAGGED)) = htonl(numflaggedflag);
-
-	fseek(newindex, OFFSET_DELETED, SEEK_SET);
-	fwrite(buf+OFFSET_DELETED,
-	       OFFSET_FLAGGED+sizeof(bit32)-OFFSET_DELETED, 1, newindex);
+	*((bit32 *)(headerbuf+OFFSET_DELETED)) = htonl(numdeletedflag);
+	*((bit32 *)(headerbuf+OFFSET_ANSWERED)) = htonl(numansweredflag);
+	*((bit32 *)(headerbuf+OFFSET_FLAGGED)) = htonl(numflaggedflag);
+
+	rewind(newindex);
+	fwrite(headerbuf, INDEX_HEADER_SIZE, 1, newindex);
     }
 }
 
-- 
1.5.6.3



More information about the Cyrus-devel mailing list