[dovecot-cvs] dovecot/src/lib-index Makefile.am,1.9,1.10 mail-custom-flags.c,1.17,1.18 mail-index-compress.c,1.23,1.24 mail-index-data.c,1.36,1.37 mail-index-open.c,1.24,1.25 mail-index-util.c,1.19,1.20 mail-index.c,1.83,1.84 mail-index.h,1.67,1.68 mail-modifylog.c,1.42,1.43 mail-tree.c,1.14,1.15 mail-lockdir.c,1.4,NONE mail-lockdir.h,1.2,NONE

cras at procontrol.fi cras at procontrol.fi
Sun Feb 23 23:06:59 EET 2003


Update of /home/cvs/dovecot/src/lib-index
In directory danu:/tmp/cvs-serv1249/src/lib-index

Modified Files:
	Makefile.am mail-custom-flags.c mail-index-compress.c 
	mail-index-data.c mail-index-open.c mail-index-util.c 
	mail-index.c mail-index.h mail-modifylog.c mail-tree.c 
Removed Files:
	mail-lockdir.c mail-lockdir.h 
Log Message:
Index opening rewrites. We don't try to support .imap.index-<hostname> style
indexes anymore. They just made things more difficult, and it's really not a
good idea to use index files via NFS anyway.

Added support for :INDEX=MEMORY in MAIL env to disable using index files.
Also if we can't open or create index file for any reason, we now fallback
to in-memory indexes. Before we fallbacked only with out of disk space
errors.

If .customflags can't be created, we still work now by not allowing to
create new custom flags.



Index: Makefile.am
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/Makefile.am,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- Makefile.am	6 Oct 2002 00:30:14 -0000	1.9
+++ Makefile.am	23 Feb 2003 21:06:57 -0000	1.10
@@ -17,7 +17,6 @@
         mail-index-update.c \
         mail-index-update-cache.c \
         mail-index-util.c \
-        mail-lockdir.c \
 	mail-modifylog.c \
 	mail-tree.c \
 	mail-tree-redblack.c
@@ -27,6 +26,5 @@
 	mail-index.h \
         mail-index-data.h \
         mail-index-util.h \
-        mail-lockdir.h \
 	mail-modifylog.h \
 	mail-tree.h

Index: mail-custom-flags.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-custom-flags.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- mail-custom-flags.c	5 Jan 2003 13:09:52 -0000	1.17
+++ mail-custom-flags.c	23 Feb 2003 21:06:57 -0000	1.18
@@ -9,9 +9,10 @@
 #include "mail-index-util.h"
 #include "mail-custom-flags.h"
 
+#include <ctype.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <ctype.h>
+#include <sys/stat.h>
 
 /* Header is simply a counter which is increased every time the file is
    updated. This allows other processes to easily notice if there's been
@@ -44,6 +45,11 @@
 {
 	i_assert(function != NULL);
 
+	if (errno == ENOSPC) {
+		mcf->index->nodiskspace = TRUE;
+		return FALSE;
+	}
+
 	index_set_error(mcf->index, "%s failed with custom flags file %s: %m",
 			function, mcf->filepath);
 	return FALSE;
@@ -69,8 +75,8 @@
 static int custom_flags_init(struct mail_custom_flags *mcf)
 {
 	static char buf[HEADER_SIZE] = "0000\n";
+	struct stat st;
 	int failed;
-	off_t pos;
 
 	if (!lock_file(mcf, F_WRLCK))
 		return FALSE;
@@ -78,22 +84,15 @@
 	failed = FALSE;
 
 	/* make sure it's still empty after locking */
-	pos = lseek(mcf->fd, 0, SEEK_END);
-	if (pos >= 0 && pos < HEADER_SIZE)
-		pos = lseek(mcf->fd, 0, SEEK_SET);
-
-	if (pos < 0) {
-		index_cf_set_syscall_error(mcf, "lseek()");
-		failed = TRUE;
-	}
-
-	/* write the header - it's a 4 byte counter as hex */
-	if (!failed && write_full(mcf->fd, buf, HEADER_SIZE) < 0) {
-		if (errno == ENOSPC)
-			mcf->index->nodiskspace = TRUE;
-
-		index_cf_set_syscall_error(mcf, "write_full()");
+	if (fstat(mcf->fd, &st) < 0) {
+		index_cf_set_syscall_error(mcf, "fstat()");
 		failed = TRUE;
+	} else if (st.st_size < HEADER_SIZE) {
+		/* write the header - it's a 4 byte counter as hex */
+		if (write_full(mcf->fd, buf, HEADER_SIZE) < 0) {
+			index_cf_set_syscall_error(mcf, "write_full()");
+			failed = TRUE;
+		}
 	}
 
 	if (!lock_file(mcf, F_UNLCK))
@@ -183,6 +182,11 @@
 		if (mcf->lock_type == F_RDLCK)
 			(void)lock_file(mcf, F_UNLCK);
 
+		if (lseek(mcf->fd, 0, SEEK_SET) < 0) {
+			index_cf_set_syscall_error(mcf, "lseek()");
+			return FALSE;
+		}
+
 		if (!custom_flags_init(mcf))
 			return FALSE;
 
@@ -200,9 +204,13 @@
 	if (mcf->lock_type == type)
 		return TRUE;
 
-	/* FIXME: possibility to use .lock file instead */
-	if (file_wait_lock(mcf->fd, type) <= 0)
-		return index_cf_set_syscall_error(mcf, "file_wait_lock()");
+	if (mcf->fd != -1) {
+		/* FIXME: possibility to use .lock file instead */
+		if (file_wait_lock(mcf->fd, type) <= 0) {
+			index_cf_set_syscall_error(mcf, "file_wait_lock()");
+			return FALSE;
+		}
+	}
 
 	mcf->lock_type = type;
 
@@ -230,13 +238,14 @@
 	const char *path;
 	int fd;
 
-	path = t_strconcat(index->dir, "/", CUSTOM_FLAGS_FILE_NAME, NULL);
-	fd = open(path, O_RDWR | O_CREAT, 0660);
-	if (fd == -1) {
-		if (errno == ENOSPC)
-			index->nodiskspace = TRUE;
-
-		return index_file_set_syscall_error(index, path, "open()");
+	path = t_strconcat(index->custom_flags_dir, "/",
+			   CUSTOM_FLAGS_FILE_NAME, NULL);
+	if (path == NULL)
+		fd = -1;
+	else {
+		fd = open(path, O_RDWR | O_CREAT, 0660);
+		if (fd == -1)
+			index_file_set_syscall_error(index, path, "open()");
 	}
 
 	mcf = i_new(struct mail_custom_flags, 1);
@@ -244,23 +253,26 @@
 	mcf->filepath = i_strdup(path);
 	mcf->fd = fd;
 
-	if (!update_mmap(mcf)) {
-		mail_custom_flags_free(mcf);
-		return FALSE;
-	}
+	if (fd != -1) {
+		if (!update_mmap(mcf)) {
+			(void)close(mcf->fd);
+			mcf->fd = -1;
+		}
 
-	if (mcf->mmap_length < HEADER_SIZE) {
-		/* we just created it, write the header */
-		mcf->syncing = TRUE;
-		if ((!custom_flags_init(mcf) || !update_mmap(mcf)) &&
-		    !index->nodiskspace) {
-			mail_custom_flags_free(mcf);
-			return FALSE;
+		if (mcf->mmap_length < HEADER_SIZE) {
+			/* we just created it, write the header */
+			mcf->syncing = TRUE;
+			if (!custom_flags_init(mcf) || !update_mmap(mcf)) {
+				(void)close(mcf->fd);
+				mcf->fd = -1;
+			}
+			mcf->syncing = FALSE;
 		}
-		mcf->syncing = FALSE;
-		mcf->noupdate = index->nodiskspace;
 	}
 
+	mcf->noupdate = mcf->fd == -1;
+	mcf->index->allow_new_custom_flags = mcf->fd != -1;
+
 	custom_flags_sync(mcf);
 
 	index->custom_flags = mcf;
@@ -279,8 +291,10 @@
 			index_cf_set_syscall_error(mcf, "munmap()");
 	}
 
-	if (close(mcf->fd) < 0)
-		index_cf_set_syscall_error(mcf, "close()");
+	if (mcf->fd != -1) {
+		if (close(mcf->fd) < 0)
+			index_cf_set_syscall_error(mcf, "close()");
+	}
 
 	i_free(mcf->filepath);
 	i_free(mcf);

Index: mail-index-compress.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-compress.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- mail-index-compress.c	5 Jan 2003 13:09:52 -0000	1.23
+++ mail-index-compress.c	23 Feb 2003 21:06:57 -0000	1.24
@@ -132,9 +132,6 @@
 	memset(&data_hdr, 0, sizeof(data_hdr));
 	data_hdr.indexid = index->indexid;
 	if (write_full(fd, &data_hdr, sizeof(data_hdr)) < 0) {
-		if (errno == ENOSPC)
-			index->nodiskspace = TRUE;
-
 		index_file_set_syscall_error(index, path, "write_full()");
 		return FALSE;
 	}
@@ -164,9 +161,6 @@
 
 		if (write_full(fd, mmap_data + rec->data_position,
 			       rec_hdr->data_size) < 0) {
-			if (errno == ENOSPC)
-				index->nodiskspace = TRUE;
-
 			index_file_set_syscall_error(index, path,
 						     "write_full()");
 			return FALSE;
@@ -207,11 +201,8 @@
 		return FALSE;
 
 	fd = mail_index_create_temp_file(index, &temppath);
-	if (fd == -1) {
-		if (errno == ENOSPC)
-			index->nodiskspace = TRUE;
+	if (fd == -1)
 		return FALSE;
-	}
 
 	failed = !mail_index_copy_data(index, fd, temppath);
 

Index: mail-index-data.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-data.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- mail-index-data.c	21 Jan 2003 05:35:06 -0000	1.36
+++ mail-index-data.c	23 Feb 2003 21:06:57 -0000	1.37
@@ -66,6 +66,11 @@
 {
 	i_assert(function != NULL);
 
+	if (errno == ENOSPC) {
+		data->index->nodiskspace = TRUE;
+		return FALSE;
+	}
+
 	index_set_error(data->index, "%s failed with index data file %s: %m",
 			function, data->filepath);
 	return FALSE;
@@ -243,68 +248,52 @@
 	return TRUE;
 }
 
-static const char *init_data_file(struct mail_index *index,
-				  struct mail_index_data_header *hdr,
-				  int fd, const char *temppath)
+static int mail_index_data_init(struct mail_index *index,
+				struct mail_index_data_header *hdr,
+				const char *path, int fd)
 {
-	const char *realpath;
-
 	if (write_full(fd, hdr, sizeof(*hdr)) < 0) {
-		index_file_set_syscall_error(index, temppath, "write_full()");
-		return NULL;
+		index_file_set_syscall_error(index, path, "write_full()");
+		return FALSE;
 	}
 
 	if (file_set_size(fd, INDEX_DATA_INITIAL_SIZE) < 0) {
-		index_file_set_syscall_error(index, temppath,
-					     "file_set_size()");
-		return NULL;
-	}
-
-	/* move temp file into .data file, deleting old one
-	   if it already exists */
-	realpath = t_strconcat(index->filepath, DATA_FILE_PREFIX, NULL);
-	if (rename(temppath, realpath) < 0) {
-		index_set_error(index, "rename(%s, %s) failed: %m",
-				temppath, realpath);
-		return NULL;
+		index_file_set_syscall_error(index, path, "file_set_size()");
+		return FALSE;
 	}
 
-	return realpath;
+	return TRUE;
 }
 
 int mail_index_data_create(struct mail_index *index)
 {
         struct mail_index_data_header hdr;
 	struct mail_index_data *data;
-	const char *temppath, *realpath;
+	const char *path;
 	int fd;
 
+	i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE);
+
 	memset(&hdr, 0, sizeof(struct mail_index_data_header));
 	hdr.indexid = index->indexid;
 	hdr.used_file_size = sizeof(struct mail_index_data_header);
 
-	realpath = NULL;
-
 	/* we'll do anon-mmaping only if initially requested. if we fail
 	   because of out of disk space, we'll just let the main index code
 	   know it and fail. */
-	if (index->nodiskspace) {
+	if (INDEX_IS_IN_MEMORY(index)) {
 		fd = -1;
+		path = NULL;
 	} else {
-		fd = mail_index_create_temp_file(index, &temppath);
+		path = t_strconcat(index->filepath, DATA_FILE_PREFIX, NULL);
+		fd = open(path, O_RDWR | O_CREAT, 0660);
 		if (fd == -1) {
-			if (errno == ENOSPC)
-				index->nodiskspace = TRUE;
+			index_file_set_syscall_error(index, path, "open()");
 			return FALSE;
 		}
 
-		realpath = init_data_file(index, &hdr, fd, temppath);
-		if (realpath == NULL) {
-			if (errno == ENOSPC)
-				index->nodiskspace = TRUE;
-
+		if (!mail_index_data_init(index, &hdr, path, fd)) {
 			(void)close(fd);
-			(void)unlink(temppath);
 			return FALSE;
 		}
 	}
@@ -320,9 +309,11 @@
 		data->mmap_used_length = data->header->used_file_size;
 
 		data->anon_mmap = TRUE;
-		data->filepath = i_strdup("(in-memory index data)");
+		data->filepath =
+			i_strdup_printf("(in-memory index data index for %s)",
+					index->mailbox_path);
 	} else {
-		data->filepath = i_strdup(realpath);
+		data->filepath = i_strdup(path);
 	}
 
 	data->index = index;
@@ -360,20 +351,14 @@
 		return TRUE;
 	}
 
-	if (file_set_size(data->fd, INDEX_DATA_INITIAL_SIZE) < 0) {
-		if (errno == ENOSPC)
-			data->index->nodiskspace = TRUE;
+	if (file_set_size(data->fd, INDEX_DATA_INITIAL_SIZE) < 0)
 		return index_data_set_syscall_error(data, "file_set_size()");
-	}
 
 	if (lseek(data->fd, 0, SEEK_SET) < 0)
 		return index_data_set_syscall_error(data, "lseek()");
 
-	if (write_full(data->fd, &hdr, sizeof(hdr)) < 0) {
-		if (errno == ENOSPC)
-			data->index->nodiskspace = TRUE;
+	if (write_full(data->fd, &hdr, sizeof(hdr)) < 0)
 		return index_data_set_syscall_error(data, "write_full()");
-	}
 
 	data->modified = FALSE;
 	data->fsynced = FALSE;
@@ -440,11 +425,8 @@
 	if (pos < (off_t)sizeof(struct mail_index_data_header))
 		return index_data_set_corrupted(data, "Header is missing");
 
-	if (file_set_size(data->fd, (off_t)new_fsize) < 0) {
-		if (errno == ENOSPC)
-			data->index->nodiskspace = TRUE;
+	if (file_set_size(data->fd, (off_t)new_fsize) < 0)
 		return index_data_set_syscall_error(data, "file_set_size()");
-	}
 
 	return mmap_update(data, 0, 0);
 }

Index: mail-index-open.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-open.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- mail-index-open.c	11 Feb 2003 15:07:31 -0000	1.24
+++ mail-index-open.c	23 Feb 2003 21:06:57 -0000	1.25
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Timo Sirainen */
+/* Copyright (C) 2002-2003 Timo Sirainen */
 
 #include "lib.h"
 #include "ioloop.h"
@@ -12,7 +12,6 @@
 #include "mail-index-data.h"
 #include "mail-index-util.h"
 #include "mail-tree.h"
-#include "mail-lockdir.h"
 #include "mail-modifylog.h"
 #include "mail-custom-flags.h"
 
@@ -21,110 +20,16 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-static const char *index_file_prefixes[] =
-	{ "data", "tree", "log", "log.2", NULL };
-
-static int delete_index(const char *path)
-{
-	char tmp[PATH_MAX];
-	int i;
-
-	/* main index */
-	if (unlink(path) < 0)
-		return FALSE;
-
-	for (i = 0; index_file_prefixes[i] != NULL; i++) {
-		if (i_snprintf(tmp, sizeof(tmp), "%s.%s",
-			       path, index_file_prefixes[i]) < 0)
-			return FALSE;
-
-		if (unlink(tmp) < 0)
-			return FALSE;
-		i++;
-	}
-
-	return TRUE;
-}
-
-static int read_and_verify_header(int fd, struct mail_index_header *hdr,
-				  int check_version)
-{
-	/* read the header */
-	if (lseek(fd, 0, SEEK_SET) != 0)
-		return FALSE;
-
-	if (read(fd, hdr, sizeof(*hdr)) != sizeof(*hdr))
-		return FALSE;
-
-	/* check the compatibility */
-	return hdr->compat_data[1] == MAIL_INDEX_COMPAT_FLAGS &&
-		hdr->compat_data[2] == sizeof(unsigned int) &&
-		hdr->compat_data[3] == sizeof(time_t) &&
-		hdr->compat_data[4] == sizeof(uoff_t) &&
-		hdr->compat_data[5] == MEM_ALIGN_SIZE &&
-		(!check_version || hdr->compat_data[0] == MAIL_INDEX_VERSION);
-}
-
-/* Returns TRUE if we're compatible with given index file. May delete the
-   file if it's from older version. */
-static int mail_check_compatible_index(struct mail_index *index,
-				       const char *path)
-{
-        struct mail_index_header hdr;
-	int fd, compatible;
-
-	fd = open(path, O_RDONLY);
-	if (fd == -1) {
-		if (errno != ENOENT)
-			index_file_set_syscall_error(index, path, "open()");
-		return FALSE;
-	}
-
-	compatible = read_and_verify_header(fd, &hdr, FALSE);
-	if (hdr.compat_data[0] != MAIL_INDEX_VERSION) {
-		/* version mismatch */
-		compatible = FALSE;
-		if (hdr.compat_data[0] < MAIL_INDEX_VERSION) {
-			/* of older version, we don't need it anymore */
-			(void)delete_index(path);
-		}
-	}
-
-	(void)close(fd);
-	return compatible;
-}
-
-/* Returns a file name of compatible index */
-static const char *mail_find_index(struct mail_index *index)
-{
-	const char *name;
-	char path[PATH_MAX];
-
-	hostpid_init();
-
-	/* first try .imap.index-<hostname> */
-	name = t_strconcat(INDEX_FILE_PREFIX "-", my_hostname, NULL);
-	if (str_path(path, sizeof(path), index->dir, name) == 0 &&
-	    mail_check_compatible_index(index, path))
-		return name;
-
-	/* then try the generic .imap.index */
-	name = INDEX_FILE_PREFIX;
-	if (str_path(path, sizeof(path), index->dir, name) == 0 &&
-	    mail_check_compatible_index(index, path))
-		return name;
-
-	return NULL;
-}
-
-static int mail_index_open_init(struct mail_index *index, int update_recent)
+static int mail_index_open_init(struct mail_index *index,
+				enum mail_index_open_flags flags)
 {
 	struct mail_index_header *hdr;
 
 	hdr = index->header;
 
 	/* update \Recent message counters */
-	if (update_recent && hdr->last_nonrecent_uid != hdr->next_uid-1) {
+	if ((flags & MAIL_INDEX_OPEN_FLAG_UPDATE_RECENT) != 0 &&
+	    hdr->last_nonrecent_uid != hdr->next_uid-1) {
 		/* keep last_recent_uid to next_uid-1 */
 		if (index->lock_type == MAIL_LOCK_SHARED) {
 			if (!index->set_lock(index, MAIL_LOCK_UNLOCK))
@@ -157,24 +62,24 @@
 }
 
 static int index_open_and_fix(struct mail_index *index,
-			      int update_recent, int fast)
+			      enum mail_index_open_flags flags)
 {
-	int rebuild;
-
-	if (!mail_index_mmap_update(index))
-		return FALSE;
-
-	rebuild = FALSE;
-
 	/* open/create the index files */
-	if (!mail_index_data_open(index)) {
-		if ((index->set_flags & MAIL_INDEX_FLAG_REBUILD) == 0)
-			return FALSE;
+	if ((flags & _MAIL_INDEX_OPEN_FLAG_CREATING) == 0) {
+		if (!mail_index_data_open(index)) {
+			if ((index->set_flags & MAIL_INDEX_FLAG_REBUILD) == 0)
+				return FALSE;
 
-		/* data file is corrupted, need to rebuild index */
-		rebuild = TRUE;
-		index->set_flags = 0;
+			/* data file is corrupted, need to rebuild index */
+			flags |= _MAIL_INDEX_OPEN_FLAG_CREATING;
+			index->set_flags = 0;
+			index->inconsistent = FALSE;
+		}
+	}
 
+	if ((flags & _MAIL_INDEX_OPEN_FLAG_CREATING) != 0) {
+		if (!mail_index_set_lock(index, MAIL_LOCK_EXCLUSIVE))
+			return FALSE;
 		if (!mail_index_data_create(index))
 			return FALSE;
 	}
@@ -184,20 +89,27 @@
 	if (!mail_custom_flags_open_or_create(index))
 		return FALSE;
 
-	if (rebuild || (index->header->flags & MAIL_INDEX_FLAG_REBUILD)) {
-		/* index is corrupted, rebuild */
+	if ((flags & _MAIL_INDEX_OPEN_FLAG_CREATING) != 0 ||
+	    (index->header->flags & MAIL_INDEX_FLAG_REBUILD) != 0) {
 		if (!index->rebuild(index))
 			return FALSE;
 
-		/* no inconsistency problems while still opening
+		/* no inconsistency problems since we're still opening
 		   the index */
 		index->inconsistent = FALSE;
 	}
 
-	if (!mail_tree_open_or_create(index))
-		return FALSE;
-	if (!mail_modifylog_open_or_create(index))
-		return FALSE;
+	if ((flags & _MAIL_INDEX_OPEN_FLAG_CREATING) == 0) {
+		if (!mail_tree_open_or_create(index))
+			return FALSE;
+		if (!mail_modifylog_open_or_create(index))
+			return FALSE;
+	} else {
+		if (!mail_tree_create(index))
+			return FALSE;
+		if (!mail_modifylog_create(index))
+			return FALSE;
+	}
 
 	if (index->header->flags & MAIL_INDEX_FLAG_FSCK) {
 		/* index needs fscking */
@@ -205,18 +117,12 @@
 			return FALSE;
 	}
 
-	if (!fast && (index->header->flags & MAIL_INDEX_FLAG_COMPRESS)) {
-		/* remove deleted blocks from index file */
-		if (!mail_index_compress(index))
-			return FALSE;
-	}
-
-	if (index->header->flags & MAIL_INDEX_FLAG_REBUILD_TREE) {
+	if ((index->header->flags & MAIL_INDEX_FLAG_REBUILD_TREE) != 0) {
 		if (!mail_tree_rebuild(index->tree))
 			return FALSE;
 	}
 
-	/* sync ourself - before updating cache and compression which
+	/* sync ourself. do it before updating cache and compression which
 	   may happen because of this. */
 	if (!index->sync_and_lock(index, MAIL_LOCK_SHARED, NULL))
 		return FALSE;
@@ -229,262 +135,91 @@
 			return FALSE;
 	}
 
-	if (!fast && (index->header->flags & MAIL_INDEX_FLAG_CACHE_FIELDS)) {
-		/* need to update cached fields */
-		if (!mail_index_update_cache(index))
-			return FALSE;
-	}
-
-	if (!fast && (index->header->flags & MAIL_INDEX_FLAG_COMPRESS_DATA)) {
-		/* remove unused space from index data file.
-		   keep after cache_fields which may move data
-		   and create unused space.. */
-		if (!mail_index_compress_data(index))
-			return FALSE;
-	}
-
-	if (!mail_index_open_init(index, update_recent))
-		return FALSE;
-
-	return TRUE;
-}
+	if ((flags & MAIL_INDEX_OPEN_FLAG_FAST) == 0) {
+		if (index->header->flags & MAIL_INDEX_FLAG_COMPRESS) {
+			/* remove deleted blocks from index file */
+			if (!mail_index_compress(index))
+				return FALSE;
+		}
 
-static int mail_index_verify_header(struct mail_index *index,
-				    struct mail_index_header *hdr)
-{
-	/* if index is being created, we'll wait here until it's finished */
-	if (!mail_index_wait_lock(index, F_RDLCK))
-		return FALSE;
+		if (index->header->flags & MAIL_INDEX_FLAG_CACHE_FIELDS) {
+			/* need to update cached fields */
+			if (!mail_index_update_cache(index))
+				return FALSE;
+		}
 
-	/* check the compatibility anyway just to be sure */
-	if (!read_and_verify_header(index->fd, hdr, TRUE)) {
-		index_set_error(index, "Non-compatible index file %s",
-				index->filepath);
-		(void)mail_index_wait_lock(index, F_UNLCK);
-		return FALSE;
+		if (index->header->flags & MAIL_INDEX_FLAG_COMPRESS_DATA) {
+			/* remove unused space from index data file.
+			   keep after cache updates which may move data
+			   and create unused space */
+			if (!mail_index_compress_data(index))
+				return FALSE;
+		}
 	}
 
-	if (!mail_index_wait_lock(index, F_UNLCK))
+	if (!mail_index_open_init(index, flags))
 		return FALSE;
 
 	return TRUE;
 }
 
-static int mail_index_open_file(struct mail_index *index, const char *path,
-				int update_recent, int fast)
+static int mail_index_read_header(struct mail_index *index,
+				  struct mail_index_header *hdr)
 {
-        struct mail_index_header hdr;
-
-	/* the index file should already be checked that it exists and
-	   we're compatible with it. */
-
-	index->fd = open(path, O_RDWR);
-	if (index->fd == -1)
-		return index_file_set_syscall_error(index, path, "open()");
-	index->filepath = i_strdup(path);
-
-	if (!mail_index_verify_header(index, &hdr)) {
-		(void)close(index->fd);
-		index->fd = -1;
+	ssize_t ret;
 
-		i_free(index->filepath);
-		index->filepath = NULL;
-		return FALSE;
+	ret = read(index->fd, hdr, sizeof(*hdr));
+	if (ret < 0) {
+		index_set_syscall_error(index, "read()");
+		return -1;
 	}
 
-	index->indexid = hdr.indexid;
-
-	/* the shared lock set is just to make sure we drop exclusive lock */
-	if (!index_open_and_fix(index, update_recent, fast) ||
-	    !index->set_lock(index, MAIL_LOCK_UNLOCK)) {
-		mail_index_close(index);
-		return FALSE;
+	if (ret != sizeof(*hdr)) {
+		/* missing data */
+		return 0;
 	}
 
-	return TRUE;
+	return 1;
 }
 
-static int mail_index_init_new_file(struct mail_index *index,
-				    struct mail_index_header *hdr,
-				    const char *temp_path)
+static int mail_index_is_compatible(const struct mail_index_header *hdr)
 {
-	const char *index_path;
-	off_t fsize;
+	return hdr->compat_data[0] == MAIL_INDEX_VERSION &&
+		hdr->compat_data[1] == MAIL_INDEX_COMPAT_FLAGS &&
+		hdr->compat_data[2] == sizeof(unsigned int) &&
+		hdr->compat_data[3] == sizeof(time_t) &&
+		hdr->compat_data[4] == sizeof(uoff_t) &&
+		hdr->compat_data[5] == MEM_ALIGN_SIZE;
+}
 
-	/* set the index's path temporarily */
-	index->filepath = t_strdup_noconst(temp_path);
+static int mail_index_init_file(struct mail_index *index,
+				struct mail_index_header *hdr)
+{
+	hdr->used_file_size = sizeof(*hdr) +
+		INDEX_MIN_RECORDS_COUNT * sizeof(struct mail_index_record);
 
-	if (write_full(index->fd, hdr, sizeof(struct mail_index_header)) < 0) {
-		index_set_syscall_error(index, "write_full()");
-		index->filepath = NULL;
+	if (lseek(index->fd, 0, SEEK_SET) < 0) {
+		index_set_syscall_error(index, "lseek()");
 		return FALSE;
 	}
 
-	fsize = sizeof(struct mail_index_header) +
-		INDEX_MIN_RECORDS_COUNT * sizeof(struct mail_index_record);
-	if (file_set_size(index->fd, fsize) < 0) {
-		index_set_syscall_error(index, "file_set_size()");
-		index->filepath = NULL;
+	if (write_full(index->fd, hdr, sizeof(*hdr)) < 0) {
+		index_set_syscall_error(index, "write_full()");
 		return FALSE;
 	}
 
-	if (mail_index_wait_lock(index, F_WRLCK) <= 0) {
-		index->filepath = NULL;
+	if (file_set_size(index->fd, (off_t)hdr->used_file_size) < 0) {
+		index_set_syscall_error(index, "file_set_size()");
 		return FALSE;
 	}
-	index->filepath = NULL;
-
-	/* move the temp index into the real one. we also need to figure
-	   out what to call ourself on the way. */
-	index_path = t_strconcat(index->dir, "/"INDEX_FILE_PREFIX, NULL);
-	if (link(temp_path, index_path) == 0) {
-		if (unlink(temp_path) < 0) {
-			/* doesn't really matter, log anyway */
-			index_file_set_syscall_error(index, temp_path,
-						     "unlink()");
-		}
-	} else {
-		if (errno != EEXIST) {
-			/* fatal error */
-			index_set_error(index, "link(%s, %s) failed: %m",
-					temp_path, index_path);
-			return FALSE;
-		}
-
-		if (getenv("OVERWRITE_INCOMPATIBLE_INDEX") != NULL) {
-			/* don't try to support different architectures,
-			   just overwrite the index if it's already there. */
-		} else {
-			/* fallback to .imap.index-hostname - we require each
-			   system to have a different hostname so it's safe to
-			   override previous index as well */
-			hostpid_init();
-
-			index_path = t_strconcat(index_path, "-",
-						 my_hostname, NULL);
-		}
-
-		if (rename(temp_path, index_path) < 0) {
-			index_set_error(index, "rename(%s, %s) failed: %m",
-					temp_path, index_path);
-			return FALSE;
-		}
-	}
 
-	index->filepath = i_strdup(index_path);
 	return TRUE;
 }
 
-static int mail_index_create(struct mail_index *index, int *dir_unlocked,
-			     int update_recent)
-{
-	struct mail_index_header hdr;
-	const char *path;
-	int nodiskspace;
-
-	*dir_unlocked = FALSE;
-
-	mail_index_init_header(index, &hdr);
-
-	if (index->nodiskspace) {
-		/* don't even bother trying to create it */
-	} else {
-		/* first create the index into temporary file. */
-		index->fd = mail_index_create_temp_file(index, &path);
-		if (index->fd != -1) {
-			if (!mail_index_init_new_file(index, &hdr, path)) {
-				int old_errno = errno;
-
-				(void)close(index->fd);
-				(void)unlink(path);
-				index->fd = -1;
-
-				errno = old_errno;
-			}
-		}
-
-		if (index->fd == -1 && errno != ENOSPC) {
-			/* fatal failure */
-			return FALSE;
-		}
-	}
-
-	if (index->fd == -1) {
-		/* no space for index files, keep it in memory */
-		index->mmap_full_length = INDEX_FILE_MIN_SIZE;
-		index->mmap_base = mmap_anon(index->mmap_full_length);
-
-		memcpy(index->mmap_base, &hdr, sizeof(hdr));
-		index->header = index->mmap_base;
-		index->mmap_used_length = index->header->used_file_size;
-
-		index->anon_mmap = TRUE;
-		index->filepath = i_strdup("(in-memory index)");
-	}
-
-	index->indexid = hdr.indexid;
-
-	/* the fd is actually already locked, now we're just making it
-	   clear to the indexing code. */
-	if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE)) {
-		mail_index_close(index);
-		return FALSE;
-	}
-
-	/* it's not good to keep the directory locked too long. our index file
-	   is locked which is enough. */
-	if (!*dir_unlocked && mail_index_lock_dir(index, MAIL_LOCK_UNLOCK))
-		*dir_unlocked = TRUE;
-
-	do {
-		if (!mail_custom_flags_open_or_create(index))
-			break;
-		if (!mail_index_data_create(index))
-			break;
-
-		nodiskspace = index->nodiskspace;
-		if (!index->rebuild(index)) {
-			if (!index->anon_mmap && index->nodiskspace) {
-				/* we're out of disk space, keep it in
-				   memory this time */
-				mail_index_close(index);
-
-                                index->nodiskspace = TRUE;
-				return mail_index_create(index, dir_unlocked,
-							 update_recent);
-			}
-			break;
-		}
-
-		/* rebuild() resets the nodiskspace variable */
-		index->nodiskspace = nodiskspace;
-
-		if (!mail_tree_create(index))
-			break;
-		if (!mail_modifylog_create(index))
-			break;
-
-		index->inconsistent = FALSE;
-
-		if (!mail_index_open_init(index, update_recent))
-			break;
-
-		if (!index->set_lock(index, MAIL_LOCK_UNLOCK))
-			break;
-
-		return TRUE;
-	} while (0);
-
-	(void)index->set_lock(index, MAIL_LOCK_UNLOCK);
-
-	mail_index_close(index);
-	return FALSE;
-}
-
 void mail_index_init_header(struct mail_index *index,
 			    struct mail_index_header *hdr)
 {
-	memset(hdr, 0, sizeof(struct mail_index_header));
+	memset(hdr, 0, sizeof(*hdr));
 	hdr->compat_data[0] = MAIL_INDEX_VERSION;
 	hdr->compat_data[1] = MAIL_INDEX_COMPAT_FLAGS;
 	hdr->compat_data[2] = sizeof(unsigned int);
@@ -516,73 +251,136 @@
 	size_t len;
 
 	index->fd = -1;
-	index->dir = i_strdup(dir);
 
-	len = strlen(index->dir);
-	if (index->dir[len-1] == '/')
-		index->dir[len-1] = '\0';
+	if (dir != NULL) {
+		index->dir = i_strdup(dir);
+
+		len = strlen(index->dir);
+		if (index->dir[len-1] == '/')
+			index->dir[len-1] = '\0';
+	}
 
 	index->mail_read_mmaped = getenv("MAIL_READ_MMAPED") != NULL;
 }
 
-int mail_index_open(struct mail_index *index, int update_recent, int fast)
+static int mail_index_create_memory(struct mail_index *index,
+				    enum mail_index_open_flags flags)
 {
-	const char *name, *path;
+	if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
+		return FALSE;
 
-	i_assert(!index->opened);
+	flags |= _MAIL_INDEX_OPEN_FLAG_CREATING;
 
-	/* this isn't initialized anywhere else */
-	index->fd = -1;
+	index->mmap_full_length = INDEX_FILE_MIN_SIZE;
+	index->mmap_base = mmap_anon(index->mmap_full_length);
 
-	mail_index_cleanup_temp_files(index->dir);
+	mail_index_init_header(index, index->mmap_base);
+	index->header = index->mmap_base;
+	index->mmap_used_length = index->header->used_file_size;
 
-	name = mail_find_index(index);
-	if (name == NULL)
-		return FALSE;
+	index->anon_mmap = TRUE;
+	index->lock_type = MAIL_LOCK_EXCLUSIVE;
+	index->indexid = index->header->indexid;
+	index->filepath = i_strdup_printf("(in-memory index for %s)",
+					  index->mailbox_path);
 
-	path = t_strconcat(index->dir, "/", name, NULL);
-	if (!mail_index_open_file(index, path, update_recent, fast))
+	if (!index_open_and_fix(index, flags)) {
+		mail_index_close(index);
 		return FALSE;
+	}
 
-	index->opened = TRUE;
 	return TRUE;
 }
 
-int mail_index_open_or_create(struct mail_index *index,
-			      int update_recent, int fast)
+int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags)
 {
-	int failed, dir_unlocked;
+        struct mail_index_header hdr;
+	const char *path;
+	int ret;
 
 	i_assert(!index->opened);
 
+	if (index->dir == NULL)
+		return mail_index_create_memory(index, flags);
+
 	mail_index_cleanup_temp_files(index->dir);
 
-	if (index->open(index, update_recent, fast))
-	        return TRUE;
+	/* open/create the file */
+        path = t_strconcat(index->dir, "/", INDEX_FILE_PREFIX, NULL);
+	if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) != 0)
+		index->fd = open(path, O_RDWR | O_CREAT, 0660);
+	else
+		index->fd = open(path, O_RDWR);
+	if (index->fd == -1) {
+		if (errno != ENOENT)
+			index_file_set_syscall_error(index, path, "open()");
+		return mail_index_create_memory(index, flags);
+	}
 
-	if (index->index_lock_timeout || index->mailbox_lock_timeout)
-		return FALSE;
+	index->filepath = i_strdup(path);
 
-	/* index wasn't found or it was broken. lock the directory and check
-	   again, just to make sure we don't end up having two index files
-	   due to race condition with another process. */
-	if (!mail_index_lock_dir(index, MAIL_LOCK_EXCLUSIVE))
-		return FALSE;
+	for (;;) {
+		/* if index is being created, we'll wait here until it's
+		   finished */
+		if ((flags & _MAIL_INDEX_OPEN_FLAG_CREATING) == 0)
+			index->lock_type = MAIL_LOCK_SHARED;
+		else
+			index->lock_type = MAIL_LOCK_EXCLUSIVE;
+		if (!mail_index_wait_lock(index,
+					  MAIL_LOCK_TO_FLOCK(index->lock_type)))
+			break;
 
-	failed = FALSE;
-	if (index->open(index, update_recent, fast))
-		dir_unlocked = FALSE;
-	else if (!index->index_lock_timeout && !index->mailbox_lock_timeout) {
-		if (!mail_index_create(index, &dir_unlocked, update_recent))
-			failed = TRUE;
+		if ((ret = mail_index_read_header(index, &hdr)) < 0)
+			break;
+
+		if (ret == 0 || !mail_index_is_compatible(&hdr)) {
+			if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
+				break;
+
+			flags |= _MAIL_INDEX_OPEN_FLAG_CREATING;
+
+			/* so, we're creating the index */
+			if (index->lock_type != MAIL_LOCK_EXCLUSIVE) {
+				/* have to get exclusive lock first */
+				if (!mail_index_wait_lock(index, F_UNLCK))
+					break;
+				continue;
+			}
+
+			mail_index_init_header(index, &hdr);
+			if (!mail_index_init_file(index, &hdr))
+				break;
+		}
+
+		index->indexid = hdr.indexid;
+
+		if (!mail_index_mmap_update(index))
+			break;
+
+		if (index->lock_type == MAIL_LOCK_SHARED) {
+			/* we don't want to keep the shared lock while opening
+			   indexes. opening should work unlocked and some
+			   things want exclusive lock */
+			if (!mail_index_wait_lock(index, F_UNLCK))
+				break;
+			index->lock_type = MAIL_LOCK_UNLOCK;
+		}
+
+		if (!index_open_and_fix(index, flags) ||
+		    !index->set_lock(index, MAIL_LOCK_UNLOCK)) {
+			mail_index_close(index);
+			return mail_index_create_memory(index, flags);
+		}
+
+		index->opened = TRUE;
+		return TRUE;
 	}
 
-	if (!dir_unlocked && !mail_index_lock_dir(index, MAIL_LOCK_UNLOCK))
-		return FALSE;
+	(void)close(index->fd);
+	index->fd = -1;
 
-	if (failed)
-		return FALSE;
+	i_free(index->filepath);
+	index->filepath = NULL;
 
-	index->opened = TRUE;
-	return TRUE;
+	return mail_index_create_memory(index, flags);
 }

Index: mail-index-util.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-util.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- mail-index-util.c	11 Jan 2003 19:55:56 -0000	1.19
+++ mail-index-util.c	23 Feb 2003 21:06:57 -0000	1.20
@@ -52,6 +52,11 @@
 {
 	i_assert(function != NULL);
 
+	if (errno == ENOSPC) {
+		index->nodiskspace = TRUE;
+		return FALSE;
+	}
+
 	index_set_error(index, "%s failed with index file %s: %m",
 			function, index->filepath);
 	return FALSE;
@@ -63,6 +68,11 @@
 	i_assert(filepath != NULL);
 	i_assert(function != NULL);
 
+	if (errno == ENOSPC) {
+		index->nodiskspace = TRUE;
+		return FALSE;
+	}
+
 	index_set_error(index, "%s failed with file %s: %m",
 			function, filepath);
 
@@ -100,8 +110,10 @@
 	if (fd == -1) {
 		if (errno == ENOSPC)
 			index->nodiskspace = TRUE;
-
-		index_set_error(index, "Can't create temp index %s: %m", *path);
+		else {
+			index_set_error(index, "Can't create temp index %s: %m",
+					*path);
+		}
 	}
 
 	return fd;

Index: mail-index.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index.c,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -d -r1.83 -r1.84
--- mail-index.c	22 Jan 2003 19:52:17 -0000	1.83
+++ mail-index.c	23 Feb 2003 21:06:57 -0000	1.84
@@ -170,6 +170,11 @@
                 index->custom_flags = NULL;
 	}
 
+	if (index->custom_flags_dir != NULL) {
+		i_free(index->custom_flags_dir);
+                index->custom_flags_dir = NULL;
+	}
+
 	if (index->error != NULL) {
 		i_free(index->error);
 		index->error = NULL;
@@ -946,11 +951,8 @@
 		return mmap_verify(index);
 	}
 
-	if (file_set_size(index->fd, (off_t)pos) < 0) {
-		if (errno == ENOSPC)
-			index->nodiskspace = TRUE;
+	if (file_set_size(index->fd, (off_t)pos) < 0)
 		return index_set_syscall_error(index, "file_set_size()");
-	}
 
 	/* file size changed, let others know about it too by changing
 	   sync_id in header. */

Index: mail-index.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index.h,v
retrieving revision 1.67
retrieving revision 1.68
diff -u -d -r1.67 -r1.68
--- mail-index.h	12 Feb 2003 12:07:51 -0000	1.67
+++ mail-index.h	23 Feb 2003 21:06:57 -0000	1.68
@@ -9,6 +9,18 @@
 
 #define INDEX_FILE_PREFIX ".imap.index"
 
+enum mail_index_open_flags {
+	/* Create index if it doesn't exist */
+	MAIL_INDEX_OPEN_FLAG_CREATE		= 0x01,
+	/* Update \Recent flag counters */
+	MAIL_INDEX_OPEN_FLAG_UPDATE_RECENT	= 0x02,
+	/* Compressing and cache updates are not performed */
+	MAIL_INDEX_OPEN_FLAG_FAST		= 0x04,
+
+	/* internal: we're creating the index */
+	_MAIL_INDEX_OPEN_FLAG_CREATING		= 0x10
+};
+
 enum mail_index_header_compat {
 	MAIL_INDEX_COMPAT_LITTLE_ENDIAN	= 0x01
 };
@@ -174,14 +186,11 @@
         (SIZEOF_MAIL_INDEX_DATA + (rec)->full_field_size)
 
 struct mail_index {
-	/* If fast is TRUE, compressing and cache updates are not performed.
-	   Note that opening same index twice in the same process is a bad
+	/* Note that opening same index twice in the same process is a bad
 	   idea since they share the same file locks. As soon one of the
 	   indexes is closed, the locks in second index are dropped which
 	   especially hurts modify log since it keeps locks all the time. */
-	int (*open)(struct mail_index *index, int update_recent, int fast);
-	int (*open_or_create)(struct mail_index *index,
-			      int update_recent, int fast);
+	int (*open)(struct mail_index *index, enum mail_index_open_flags flags);
 
 	/* Free index from memory. */
 	void (*free)(struct mail_index *index);
@@ -358,6 +367,7 @@
 	char *dir; /* directory where to place the index files */
 	char *filepath; /* index file path */
 	char *mailbox_path; /* file/directory for mailbox location */
+	char *custom_flags_dir; /* destination for .customflags file */
 	enum mail_data_field default_cache_fields, never_cache_fields;
 	unsigned int indexid;
 	unsigned int sync_id;
@@ -407,6 +417,7 @@
 	unsigned int inconsistent:1;
 	unsigned int nodiskspace:1;
 	unsigned int index_lock_timeout:1;
+	unsigned int allow_new_custom_flags:1;
 	unsigned int mailbox_lock_timeout:1;
 };
 
@@ -420,16 +431,14 @@
    members.. */
 #define MAIL_INDEX_PRIVATE_FILL \
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-	0, 0, 0, 0, 0, { 0, 0, 0 }, 0, 0, 0, \
+	0, 0, 0, 0, 0, 0, { 0, 0, 0 }, 0, 0, \
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-	0, 0
+	0, 0, 0, 0
 #endif
 
 /* defaults - same as above but prefixed with mail_index_. */
-int mail_index_open(struct mail_index *index, int update_recent, int fast);
-int mail_index_open_or_create(struct mail_index *index,
-			      int update_recent, int fast);
+int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags);
 int mail_index_set_lock(struct mail_index *index,
 			enum mail_lock_type lock_type);
 int mail_index_try_lock(struct mail_index *index,
@@ -566,5 +575,8 @@
 #define MAIL_LOCK_TO_FLOCK(lock_type) \
         ((lock_type) == MAIL_LOCK_EXCLUSIVE ? F_WRLCK : \
 		(lock_type) == MAIL_LOCK_SHARED ? F_RDLCK : F_UNLCK)
+
+#define INDEX_IS_IN_MEMORY(index) \
+	((index)->anon_mmap)
 
 #endif

Index: mail-modifylog.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-modifylog.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- mail-modifylog.c	23 Jan 2003 18:51:20 -0000	1.42
+++ mail-modifylog.c	23 Feb 2003 21:06:57 -0000	1.43
@@ -72,6 +72,11 @@
 {
 	i_assert(function != NULL);
 
+	if (errno == ENOSPC) {
+		file->log->index->nodiskspace = TRUE;
+		return FALSE;
+	}
+
 	index_set_error(file->log->index,
 			"%s failed with modify log file %s: %m",
 			function, file->filepath);
@@ -318,25 +323,15 @@
 
 static int mail_modifylog_init_fd(struct modify_log_file *file, int fd)
 {
-	struct mail_index *index = file->log->index;
         struct modify_log_header hdr;
 
         mail_modifylog_init_header(file->log, &hdr);
-	if (write_full(fd, &hdr, sizeof(hdr)) < 0) {
-		if (errno == ENOSPC)
-			index->nodiskspace = TRUE;
 
-		modifylog_set_syscall_error(file, "write_full()");
-		return FALSE;
-	}
-
-	if (file_set_size(fd, MODIFY_LOG_INITIAL_SIZE) < 0) {
-		if (errno == ENOSPC)
-			index->nodiskspace = TRUE;
+	if (write_full(fd, &hdr, sizeof(hdr)) < 0)
+		return modifylog_set_syscall_error(file, "write_full()");
 
-		modifylog_set_syscall_error(file, "file_set_size()");
-		return FALSE;
-	}
+	if (file_set_size(fd, MODIFY_LOG_INITIAL_SIZE) < 0)
+		return modifylog_set_syscall_error(file, "file_set_size()");
 
 	return TRUE;
 }
@@ -372,14 +367,11 @@
 	struct mail_index *index = file->log->index;
 	int fd, ret;
 
-	if (index->nodiskspace)
+	if (INDEX_IS_IN_MEMORY(index))
 		return -1;
 
 	fd = open(file->filepath, O_RDWR | O_CREAT, 0660);
 	if (fd == -1) {
-		if (errno == ENOSPC)
-			index->nodiskspace = TRUE;
-
 		modifylog_set_syscall_error(file, "open()");
 		return -1;
 	}
@@ -532,7 +524,8 @@
 	file->synced_position = file->mmap_used_length;
 
 	file->anon_mmap = TRUE;
-	file->filepath = i_strdup("(in-memory modify log)");
+	file->filepath = i_strdup_printf("(in-memory modify log for %s)",
+					 file->log->index->mailbox_path);
 }
 
 int mail_modifylog_create(struct mail_index *index)
@@ -544,7 +537,7 @@
 
 	log = mail_modifylog_new(index);
 
-	if (index->nodiskspace)
+	if (INDEX_IS_IN_MEMORY(index))
 		modifylog_create_anon(&log->file1);
 	else {
 		ret = modifylog_reuse_or_create_file(&log->file1);
@@ -687,11 +680,8 @@
 		return TRUE;
 	}
 
-	if (file_set_size(file->fd, (off_t)new_fsize) < 0) {
-		if (errno == ENOSPC)
-			file->log->index->nodiskspace = TRUE;
+	if (file_set_size(file->fd, (off_t)new_fsize) < 0)
 		return modifylog_set_syscall_error(file, "file_set_size()");
-	}
 
 	if (!mmap_update(file, TRUE))
 		return FALSE;

Index: mail-tree.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-tree.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- mail-tree.c	9 Jan 2003 12:35:16 -0000	1.14
+++ mail-tree.c	23 Feb 2003 21:06:57 -0000	1.15
@@ -19,6 +19,11 @@
 {
 	i_assert(function != NULL);
 
+	if (errno == ENOSPC) {
+		tree->index->nodiskspace = TRUE;
+		return FALSE;
+	}
+
 	index_set_error(tree->index, "%s failed with binary tree file %s: %m",
 			function, tree->filepath);
 	return FALSE;
@@ -153,9 +158,6 @@
 	path = t_strconcat(index->filepath, ".tree", NULL);
 	fd = open(path, O_RDWR | O_CREAT, 0660);
 	if (fd == -1) {
-		if (errno == ENOSPC)
-			index->nodiskspace = TRUE;
-
 		index_file_set_syscall_error(index, path, "open()");
 		return NULL;
 	}
@@ -177,7 +179,8 @@
 	tree->anon_mmap = TRUE;
 	tree->fd = -1;
 	tree->index = index;
-	tree->filepath = i_strdup("(in-memory tree)");
+	tree->filepath = i_strdup_printf("(in-memory tree index for %s)",
+					 index->mailbox_path);
 
 	index->tree = tree;
 	return tree;
@@ -189,7 +192,7 @@
 
 	i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE);
 
-	tree = !index->nodiskspace ? mail_tree_open(index) :
+	tree = !INDEX_IS_IN_MEMORY(index) ? mail_tree_open(index) :
 		mail_tree_create_anon(index);
 	if (tree == NULL)
 		return FALSE;
@@ -306,19 +309,11 @@
 	if (lseek(tree->fd, 0, SEEK_SET) < 0)
 		return tree_set_syscall_error(tree, "lseek()");
 
-	if (write_full(tree->fd, &hdr, sizeof(hdr)) < 0) {
-		if (errno == ENOSPC)
-			tree->index->nodiskspace = TRUE;
-
+	if (write_full(tree->fd, &hdr, sizeof(hdr)) < 0)
 		return tree_set_syscall_error(tree, "write_full()");
-	}
-
-	if (file_set_size(tree->fd, MAIL_TREE_MIN_SIZE) < 0) {
-		if (errno == ENOSPC)
-			tree->index->nodiskspace = TRUE;
 
+	if (file_set_size(tree->fd, MAIL_TREE_MIN_SIZE) < 0)
 		return tree_set_syscall_error(tree, "file_set_size()");
-	}
 
 	return TRUE;
 }
@@ -398,11 +393,8 @@
 		return mmap_verify(tree);
 	}
 
-	if (file_set_size(tree->fd, (off_t)new_fsize) < 0) {
-		if (errno == ENOSPC)
-			tree->index->nodiskspace = TRUE;
+	if (file_set_size(tree->fd, (off_t)new_fsize) < 0)
 		return tree_set_syscall_error(tree, "file_set_size()");
-	}
 
 	/* file size changed, let others know about it too by changing
 	   sync_id in header. */

--- mail-lockdir.c DELETED ---

--- mail-lockdir.h DELETED ---




More information about the dovecot-cvs mailing list