changeset 389:60040a9d243f HEAD

ioloop_create() takes now pool-parameter. io_buffer_create_mmaped() takes start_offset parameter instead of getting it with lseek(). Instead of using offsets to index file, we now use record indexes (first_hole_index, tree file).
author Timo Sirainen <tss@iki.fi>
date Wed, 09 Oct 2002 02:26:08 +0300
parents 792fc5b3daa4
children 0039b676a423
files src/auth/main.c src/imap/main.c src/lib-index/mail-index-compress.c src/lib-index/mail-index-fsck.c src/lib-index/mail-index.c src/lib-index/mail-index.h src/lib-index/mail-tree-redblack.c src/lib-index/mail-tree.h src/lib-index/maildir/maildir-open.c src/lib-index/maildir/maildir-update.c src/lib-index/mbox/mbox-index.c src/lib-index/mbox/mbox-rewrite.c src/lib/iobuffer.c src/lib/iobuffer.h src/lib/ioloop.c src/lib/ioloop.h src/master/main.c
diffstat 17 files changed, 129 insertions(+), 131 deletions(-) [+]
line wrap: on
line diff
--- a/src/auth/main.c	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/auth/main.c	Wed Oct 09 02:26:08 2002 +0300
@@ -88,7 +88,7 @@
 	/* NOTE: we start rooted, so keep the code minimal until
 	   restrict_access_by_env() is called */
 	lib_init();
-	ioloop = io_loop_create();
+	ioloop = io_loop_create(system_pool);
 
 	main_init();
         io_loop_run(ioloop);
--- a/src/imap/main.c	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/imap/main.c	Wed Oct 09 02:26:08 2002 +0300
@@ -98,7 +98,7 @@
 	/* NOTE: we start rooted, so keep the code minimal until
 	   restrict_access_by_env() is called */
 	lib_init();
-	ioloop = io_loop_create();
+	ioloop = io_loop_create(system_pool);
 
 	main_init(argc == 2 && strcmp(argv[1], "-s") == 0);
         io_loop_run(ioloop);
--- a/src/lib-index/mail-index-compress.c	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/lib-index/mail-index-compress.c	Wed Oct 09 02:26:08 2002 +0300
@@ -45,12 +45,12 @@
 int mail_index_compress(MailIndex *index)
 {
 	MailIndexRecord *rec, *hole_rec, *end_rec;
-	uoff_t pos;
+	unsigned int idx;
 
 	if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE))
 		return FALSE;
 
-	if (index->header->first_hole_position == 0) {
+	if (index->header->first_hole_records == 0) {
 		/* we don't need to compress after all. shouldn't happen.. */
 		index->header->flags &= ~MAIL_INDEX_FLAG_COMPRESS;
 		return TRUE;
@@ -69,13 +69,14 @@
 	end_rec = (MailIndexRecord *) ((char *) index->mmap_base +
 				       index->mmap_used_length);
 	hole_rec = (MailIndexRecord *) ((char *) index->mmap_base +
-					index->header->first_hole_position);
+					sizeof(MailIndexHeader)) +
+		index->header->first_hole_index;
 	rec = hole_rec + index->header->first_hole_records;
 	while (rec < end_rec) {
 		if (rec->uid != 0) {
 			memcpy(hole_rec, rec, sizeof(MailIndexRecord));
-			pos = INDEX_FILE_POSITION(index, hole_rec);
-			if (!mail_tree_update(index->tree, rec->uid, pos))
+			idx = INDEX_RECORD_INDEX(index, hole_rec);
+			if (!mail_tree_update(index->tree, rec->uid, idx))
 				return FALSE;
 			hole_rec++;
 		}
@@ -91,7 +92,7 @@
 		return FALSE;
 
 	/* update headers */
-	index->header->first_hole_position = 0;
+	index->header->first_hole_index = 0;
 	index->header->first_hole_records = 0;
 
 	/* make sure the whole file is synced before removing rebuild-flag */
--- a/src/lib-index/mail-index-fsck.c	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/lib-index/mail-index-fsck.c	Wed Oct 09 02:26:08 2002 +0300
@@ -13,10 +13,10 @@
 static void print_differences(MailIndexHeader *old_hdr,
 			      MailIndexHeader *new_hdr)
 {
-	if (old_hdr->first_hole_position != new_hdr->first_hole_position) {
-		i_warning("fsck: first_hole_position %"PRIuUOFF_T
-			  " != %"PRIuUOFF_T, old_hdr->first_hole_position,
-			  new_hdr->first_hole_position);
+	if (old_hdr->first_hole_index != new_hdr->first_hole_index) {
+		i_warning("fsck: first_hole_position %u != %u",
+			  old_hdr->first_hole_index,
+			  new_hdr->first_hole_index);
 	}
 	CHECK(first_hole_records);
 
@@ -51,8 +51,7 @@
 	MailIndexHeader old_hdr;
 	MailIndexHeader *hdr;
 	MailIndexRecord *rec, *end_rec;
-	unsigned int max_uid;
-	uoff_t pos;
+	unsigned int max_uid, pos;
 
 	i_assert(index->lock_type != MAIL_LOCK_SHARED);
 
@@ -62,7 +61,7 @@
 	hdr = index->header;
 	memcpy(&old_hdr, hdr, sizeof(MailIndexHeader));
 
-	hdr->first_hole_position = 0;
+	hdr->first_hole_index = 0;
 	hdr->first_hole_records = 0;
 
 	hdr->messages_count = 0;
@@ -81,13 +80,12 @@
 	for (; rec < end_rec; rec++) {
 		if (rec->uid == 0) {
 			/* expunged message */
-			pos = INDEX_FILE_POSITION(index, rec);
-			if (hdr->first_hole_position == 0) {
-				hdr->first_hole_position = pos;
+			pos = INDEX_RECORD_INDEX(index, rec);
+			if (hdr->first_hole_index == 0) {
+				hdr->first_hole_index = pos;
 				hdr->first_hole_records = 1;
-			} else if (hdr->first_hole_position +
-				   (hdr->first_hole_records *
-				    sizeof(MailIndexRecord)) == pos) {
+			} else if (hdr->first_hole_index +
+				   hdr->first_hole_records == pos) {
 				/* hole continues */
 				hdr->first_hole_records++;
 			}
--- a/src/lib-index/mail-index.c	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/lib-index/mail-index.c	Wed Oct 09 02:26:08 2002 +0300
@@ -399,36 +399,24 @@
 int mail_index_verify_hole_range(MailIndex *index)
 {
 	MailIndexHeader *hdr;
-	unsigned int max_records, first_records;
+	unsigned int max_records;
 
 	hdr = index->header;
-	if (hdr->first_hole_position == 0)
+	if (hdr->first_hole_records == 0)
 		return TRUE;
 
-	/* make sure position is valid */
-	if (hdr->first_hole_position < sizeof(MailIndexHeader) ||
-	    (hdr->first_hole_position -
-	     sizeof(MailIndexHeader)) % sizeof(MailIndexRecord) != 0) {
-		index_set_corrupted(index, "first_hole_position contains "
-				    "invalid value");
+	max_records = MAIL_INDEX_RECORD_COUNT(index);
+	if (hdr->first_hole_index >= max_records) {
+		index_set_corrupted(index,
+				    "first_hole_index points outside file");
 		return FALSE;
 	}
 
-	/* make sure position is in range.. */
-	if (hdr->first_hole_position >= index->mmap_used_length) {
-		index_set_corrupted(index, "first_hole_position points "
-				    "outside file");
-		return FALSE;
-	}
-
-	/* and finally check that first_hole_records is in valid range */
-	max_records = MAIL_INDEX_RECORD_COUNT(index);
-	first_records = (hdr->first_hole_position -
-			 sizeof(MailIndexHeader)) / sizeof(MailIndexRecord);
-	if (index->header->first_hole_records > max_records ||
-	    first_records + index->header->first_hole_records > max_records) {
-		index_set_corrupted(index, "first_hole_records points "
-				    "outside file");
+	/* check that first_hole_records is in valid range */
+	if (hdr->first_hole_records > max_records ||
+	    hdr->first_hole_index + hdr->first_hole_records > max_records) {
+		index_set_corrupted(index,
+				    "first_hole_records points outside file");
 		return FALSE;
 	}
 
@@ -447,7 +435,7 @@
 	MailIndexHeader *hdr;
 	MailIndexRecord *rec;
 	const char *format;
-	uoff_t pos;
+	unsigned int idx;
 
 	i_assert(seq > 0);
 	i_assert(index->lock_type != MAIL_LOCK_UNLOCK);
@@ -467,23 +455,20 @@
 	if (!mail_index_verify_hole_range(index))
 		return NULL;
 
-	pos = sizeof(MailIndexHeader) +
-		(uoff_t)(seq-1) * sizeof(MailIndexRecord);
-	if (hdr->first_hole_position == 0 ||
-	    hdr->first_hole_position > pos) {
+	idx = seq-1;
+	if (hdr->first_hole_records == 0 || hdr->first_hole_index > idx) {
 		/* easy, it's just at the expected index */
-		format = "Invalid first_hole_position in header: %"PRIuUOFF_T;
+		format = "Invalid first_hole_index in header: %"PRIuUOFF_T;
 	} else if (hdr->first_hole_records ==
 		   MAIL_INDEX_RECORD_COUNT(index) - hdr->messages_count) {
 		/* only one hole in file, skip it and we're at
 		   correct position */
-		pos += (size_t)hdr->first_hole_records *
-			sizeof(MailIndexRecord);
+		idx += hdr->first_hole_records;
 		format = "Invalid hole locations in header: %"PRIuUOFF_T;
 	} else {
 		/* find from binary tree */
-		pos = mail_tree_lookup_sequence(index->tree, seq);
-		if (pos == 0) {
+		idx = mail_tree_lookup_sequence(index->tree, seq);
+		if (idx == (unsigned int)-1) {
 			index_set_corrupted(index, "Sequence %u not found from "
 					    "binary tree (%u msgs says header)",
 					    seq, hdr->messages_count);
@@ -492,16 +477,15 @@
 		format = "Invalid offset returned by binary tree: %"PRIuUOFF_T;
 	}
 
-	if (pos < sizeof(MailIndexHeader) ||
-	    pos > index->mmap_used_length - sizeof(MailIndexRecord) ||
-	    (pos - sizeof(MailIndexHeader)) % sizeof(MailIndexRecord) != 0) {
-		index_set_corrupted(index, format, pos);
+	if (idx >= MAIL_INDEX_RECORD_COUNT(index)) {
+		index_set_corrupted(index, format, idx);
 		return NULL;
 	}
 
-	rec = (MailIndexRecord *) ((char *) index->mmap_base + pos);
+	rec = (MailIndexRecord *) ((char *) index->mmap_base +
+				   sizeof(MailIndexHeader)) + idx;
 	if (rec->uid == 0) {
-		index_set_corrupted(index, format, pos);
+		index_set_corrupted(index, format, idx);
 		return NULL;
 	}
 
@@ -537,18 +521,28 @@
 					     unsigned int *seq_r)
 {
 	MailIndexRecord *rec;
-	uoff_t pos;
+	unsigned int idx;
 
 	i_assert(index->lock_type != MAIL_LOCK_UNLOCK);
 	i_assert(first_uid > 0 && last_uid > 0);
 	i_assert(first_uid <= last_uid);
 
-	pos = mail_tree_lookup_uid_range(index->tree, seq_r,
+	idx = mail_tree_lookup_uid_range(index->tree, seq_r,
 					 first_uid, last_uid);
-	if (pos == 0)
+	if (idx == (unsigned int)-1)
 		return NULL;
 
-	rec = (MailIndexRecord *) ((char *) index->mmap_base + pos);
+	if (idx >= MAIL_INDEX_RECORD_COUNT(index)) {
+		index_set_error(index, "Corrupted binary tree for index %s: "
+				"lookup returned index outside range "
+				"(%u >= %u)", index->filepath, idx,
+				MAIL_INDEX_RECORD_COUNT(index));
+		index->set_flags |= MAIL_INDEX_FLAG_REBUILD_TREE;
+		return NULL;
+	}
+
+	rec = (MailIndexRecord *) ((char *) index->mmap_base +
+				   sizeof(MailIndexRecord)) + idx;
 	if (rec->uid < first_uid || rec->uid > last_uid) {
 		index_set_error(index, "Corrupted binary tree for index %s: "
 				"lookup returned offset to wrong UID "
@@ -669,7 +663,8 @@
 
 	/* see if first_hole_records can be grown */
 	rec = (MailIndexRecord *) ((char *) index->mmap_base +
-				   index->header->first_hole_position) +
+				   sizeof(MailIndexHeader)) +
+		index->header->first_hole_index +
 		index->header->first_hole_records;
 	end_rec = (MailIndexRecord *) ((char *) index->mmap_base +
 				       index->mmap_used_length);
@@ -681,9 +676,10 @@
 
 static int mail_index_truncate_hole(MailIndex *index)
 {
-	index->header->used_file_size =
-		(size_t)index->header->first_hole_position;
-	index->header->first_hole_position = 0;
+	index->header->used_file_size = sizeof(MailIndexHeader) +
+		(uoff_t)index->header->first_hole_index *
+		sizeof(MailIndexRecord);
+	index->header->first_hole_index = 0;
 	index->header->first_hole_records = 0;
 
 	index->mmap_used_length = index->header->used_file_size;
@@ -708,8 +704,7 @@
 		       unsigned int seq, int external_change)
 {
 	MailIndexHeader *hdr;
-	unsigned int records;
-	uoff_t pos;
+	unsigned int records, idx;
 
 	i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE);
 	i_assert(seq != 0);
@@ -749,25 +744,24 @@
 	hdr = index->header;
 
 	/* update first hole */
-	pos = INDEX_FILE_POSITION(index, rec);
-	if (hdr->first_hole_position < sizeof(MailIndexRecord)) {
+	idx = INDEX_RECORD_INDEX(index, rec);
+	if (hdr->first_hole_records == 0) {
 		/* first deleted message in index */
-		hdr->first_hole_position = pos;
+		hdr->first_hole_index = idx;
 		hdr->first_hole_records = 1;
-	} else if (hdr->first_hole_position - sizeof(MailIndexRecord) == pos) {
+	} else if (idx == hdr->first_hole_index+1) {
 		/* deleted the previous record before hole */
-		hdr->first_hole_position -= sizeof(MailIndexRecord);
+		hdr->first_hole_index--;
 		hdr->first_hole_records++;
-	} else if (hdr->first_hole_position +
-		   (hdr->first_hole_records * sizeof(MailIndexRecord)) == pos) {
+	} else if (hdr->first_hole_index + hdr->first_hole_records == idx) {
 		/* deleted the next record after hole */
 		hdr->first_hole_records++;
 		update_first_hole_records(index);
 	} else {
 		/* second hole coming to index file */
-		if (hdr->first_hole_position > pos) {
+		if (idx < hdr->first_hole_index) {
 			/* new hole before the old hole */
-			hdr->first_hole_position = pos;
+			hdr->first_hole_index = idx;
 			hdr->first_hole_records = 1;
 		}
 	}
@@ -783,7 +777,7 @@
 	hdr->messages_count--;
 	mail_index_mark_flag_changes(index, rec, rec->msg_flags, 0);
 
-	if ((hdr->first_hole_position - sizeof(MailIndexHeader)) /
+	if ((hdr->first_hole_index - sizeof(MailIndexHeader)) /
 	    sizeof(MailIndexRecord) == hdr->messages_count) {
 		/* the hole reaches end of file, truncate it */
 		(void)mail_index_truncate_hole(index);
@@ -892,12 +886,11 @@
 	i_assert(rec->uid == 0);
 
 	index->header->messages_count++;
-
 	rec->uid = index->header->next_uid++;
 
 	if (index->tree != NULL) {
 		mail_tree_insert(index->tree, rec->uid,
-				 INDEX_FILE_POSITION(index, rec));
+				 INDEX_RECORD_INDEX(index, rec));
 	}
 
 	return TRUE;
--- a/src/lib-index/mail-index.h	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/lib-index/mail-index.h	Wed Oct 09 02:26:08 2002 +0300
@@ -110,7 +110,7 @@
 
 	uoff_t used_file_size;
 
-	uoff_t first_hole_position;
+	unsigned int first_hole_index;
 	unsigned int first_hole_records;
 
 	unsigned int uid_validity;
@@ -433,6 +433,10 @@
 #define INDEX_POSITION_INDEX(pos) \
 	(((pos) - sizeof(MailIndexHeader)) / sizeof(MailIndexRecord))
 
+/* index number for given record */
+#define INDEX_RECORD_INDEX(index, ptr) \
+	INDEX_POSITION_INDEX(INDEX_FILE_POSITION(index, ptr))
+
 /* mark the index corrupted */
 #define INDEX_MARK_CORRUPTED(index) \
 	STMT_START { (index)->set_flags |= MAIL_INDEX_FLAG_REBUILD; } STMT_END
--- a/src/lib-index/mail-tree-redblack.c	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/lib-index/mail-tree-redblack.c	Wed Oct 09 02:26:08 2002 +0300
@@ -619,9 +619,9 @@
 }
 #endif
 
-uoff_t mail_tree_lookup_uid_range(MailTree *tree, unsigned int *seq_r,
-				  unsigned int first_uid,
-				  unsigned int last_uid)
+unsigned int mail_tree_lookup_uid_range(MailTree *tree, unsigned int *seq_r,
+					unsigned int first_uid,
+					unsigned int last_uid)
 {
 	MailTreeNode *node = tree->node_base;
 	unsigned int x, y, seq;
@@ -667,10 +667,10 @@
 			*seq_r = seq+1;
 	}
 
-	return x == RBNULL ? 0 : node[x].value;
+	return x == RBNULL ? (unsigned int)-1 : node[x].value;
 }
 
-uoff_t mail_tree_lookup_sequence(MailTree *tree, unsigned int seq)
+unsigned int mail_tree_lookup_sequence(MailTree *tree, unsigned int seq)
 {
         MailTreeNode *node = tree->node_base;
 	unsigned int x, upleft_nodes, left_nodes;
@@ -698,10 +698,10 @@
 		}
 	}
 
-	return 0;
+	return (unsigned int)-1;
 }
 
-int mail_tree_insert(MailTree *tree, unsigned int uid, uoff_t pos)
+int mail_tree_insert(MailTree *tree, unsigned int uid, unsigned int index)
 {
         MailTreeNode *node = tree->node_base;
 	unsigned int x, z;
@@ -731,7 +731,7 @@
 	node = tree->node_base;
 
 	node[z].key = uid;
-	node[z].value = pos;
+	node[z].value = index;
 	node[z].up = x;
 	node[z].node_count = 1;
 	node[z].left = RBNULL;
@@ -754,7 +754,7 @@
 	return TRUE;
 }
 
-int mail_tree_update(MailTree *tree, unsigned int uid, uoff_t pos)
+int mail_tree_update(MailTree *tree, unsigned int uid, unsigned int index)
 {
 	MailTreeNode *node = tree->node_base;
 	unsigned int x;
@@ -773,7 +773,7 @@
 			x = node[x].right;
 		else {
 			/* found it */
-			node[x].value = pos;
+			node[x].value = index;
 			return TRUE;
 		}
 	}
--- a/src/lib-index/mail-tree.h	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/lib-index/mail-tree.h	Wed Oct 09 02:26:08 2002 +0300
@@ -43,7 +43,7 @@
 	unsigned int node_count;
 
 	unsigned int key;
-	uoff_t value;
+	unsigned int value;
 };
 
 int mail_tree_create(MailIndex *index);
@@ -53,19 +53,19 @@
 int mail_tree_rebuild(MailTree *tree);
 int mail_tree_sync_file(MailTree *tree);
 
-/* Find first existing UID in range. */
-uoff_t mail_tree_lookup_uid_range(MailTree *tree, unsigned int *seq_r,
-				  unsigned int first_uid,
-				  unsigned int last_uid);
+/* Find first existing UID in range. Returns (unsigned int)-1 if not found. */
+unsigned int mail_tree_lookup_uid_range(MailTree *tree, unsigned int *seq_r,
+					unsigned int first_uid,
+					unsigned int last_uid);
 
-/* Find message by sequence number. */
-uoff_t mail_tree_lookup_sequence(MailTree *tree, unsigned int seq);
+/* Find message by sequence number. Returns (unsigned int)-1 if not found. */
+unsigned int mail_tree_lookup_sequence(MailTree *tree, unsigned int seq);
 
 /* Insert a new record in tree. */
-int mail_tree_insert(MailTree *tree, unsigned int uid, uoff_t pos);
+int mail_tree_insert(MailTree *tree, unsigned int uid, unsigned int index);
 
 /* Update existing record in tree. */
-int mail_tree_update(MailTree *tree, unsigned int uid, uoff_t pos);
+int mail_tree_update(MailTree *tree, unsigned int uid, unsigned int index);
 
 /* Delete record from tree. */
 void mail_tree_delete(MailTree *tree, unsigned int uid);
--- a/src/lib-index/maildir/maildir-open.c	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/lib-index/maildir/maildir-open.c	Wed Oct 09 02:26:08 2002 +0300
@@ -36,5 +36,5 @@
 	}
 
 	return io_buffer_create_mmap(fd, default_pool, MAIL_MMAP_BLOCK_SIZE,
-				     0, TRUE);
+				     0, 0, TRUE);
 }
--- a/src/lib-index/maildir/maildir-update.c	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/lib-index/maildir/maildir-update.c	Wed Oct 09 02:26:08 2002 +0300
@@ -11,7 +11,7 @@
 	i_assert(path != NULL);
 
 	inbuf = io_buffer_create_mmap(fd, default_pool,
-				      MAIL_MMAP_BLOCK_SIZE, 0, FALSE);
+				      MAIL_MMAP_BLOCK_SIZE, 0, 0, FALSE);
 	mail_index_update_headers(update, inbuf, 0, NULL, NULL);
 	io_buffer_unref(inbuf);
 	return TRUE;
--- a/src/lib-index/mbox/mbox-index.c	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/lib-index/mbox/mbox-index.c	Wed Oct 09 02:26:08 2002 +0300
@@ -37,13 +37,9 @@
 		}
 	}
 
-	if (lseek(index->mbox_fd, (off_t)offset, SEEK_SET) != (off_t)offset) {
-		mbox_set_syscall_error(index, "lseek()");
-		return NULL;
-	}
-
 	return io_buffer_create_mmap(index->mbox_fd, default_pool,
-				     MAIL_MMAP_BLOCK_SIZE, 0, FALSE);
+				     MAIL_MMAP_BLOCK_SIZE,
+				     (uoff_t)offset, 0, FALSE);
 }
 
 void mbox_file_close(MailIndex *index)
--- a/src/lib-index/mbox/mbox-rewrite.c	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/lib-index/mbox/mbox-rewrite.c	Wed Oct 09 02:26:08 2002 +0300
@@ -359,12 +359,10 @@
 
 	i_assert(out_offset <= OFF_T_MAX);
 
-	if (lseek(in_fd, 0, SEEK_SET) < 0)
-		return -1;
 	if (lseek(out_fd, (off_t)out_offset, SEEK_SET) < 0)
 		return -1;
 
-	inbuf = io_buffer_create_mmap(in_fd, default_pool, 65536, 0, FALSE);
+	inbuf = io_buffer_create_mmap(in_fd, default_pool, 65536, 0, 0, FALSE);
 	outbuf = io_buffer_create_file(out_fd, default_pool, 1024, FALSE);
 
 	ret = io_buffer_send_iobuffer(outbuf, inbuf, inbuf->size);
--- a/src/lib/iobuffer.c	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/lib/iobuffer.c	Wed Oct 09 02:26:08 2002 +0300
@@ -78,10 +78,13 @@
 }
 
 IOBuffer *io_buffer_create_mmap(int fd, Pool pool, size_t block_size,
-				uoff_t size, int autoclose_fd)
+				uoff_t start_offset, uoff_t size,
+				int autoclose_fd)
 {
 	IOBuffer *buf;
-	off_t start_offset, stop_offset;
+	off_t stop_offset;
+
+	i_assert(start_offset < OFF_T_MAX);
 
 	/* block size must be page aligned, and at least two pages long */
 	if (mmap_pagesize == 0) {
@@ -100,19 +103,17 @@
 	buf->mmaped = TRUE;
 	buf->receive = TRUE;
 
-	/* set offsets */
-	start_offset = lseek(fd, 0, SEEK_CUR);
 	stop_offset = lseek(fd, 0, SEEK_END);
-
-	if (start_offset < 0 || stop_offset < 0) {
+	if (stop_offset < 0) {
 		i_error("io_buffer_create_mmap(): lseek() failed: %m");
-		buf->start_offset = buf->size = 0;
+		stop_offset = 0;
+		buf->size = 0;
 	}
 
-	if (start_offset > stop_offset)
+	if (start_offset > (uoff_t)stop_offset)
 		start_offset = stop_offset;
 
-	if (size > (uoff_t) (stop_offset-start_offset)) {
+	if (size > (uoff_t)stop_offset-start_offset) {
 		i_warning("Trying to create IOBuffer with size %"PRIuUOFF_T
 			  " but we have only %"PRIuUOFF_T" bytes available "
 			  "in file", size, stop_offset-start_offset);
@@ -341,6 +342,7 @@
 static int io_buffer_ioloop(IOBuffer *buf, IOBufferBlockContext *ctx,
 			    void (*send_func)(IOBufferBlockContext *ctx))
 {
+	Pool pool;
 	Timeout to;
 	int save_errno;
 
@@ -349,7 +351,8 @@
 		io_remove(buf->io);
 
 	/* create a new I/O loop */
-	ctx->ioloop = io_loop_create();
+	pool = pool_create("io_buffer_ioloop", 1024, FALSE);
+	ctx->ioloop = io_loop_create(pool);
 	ctx->outbuf = buf;
 
 	buf->io = io_add(buf->fd, IO_WRITE, (IOFunc) send_func, ctx);
@@ -379,6 +382,7 @@
 	}
 
 	io_loop_destroy(ctx->ioloop);
+	pool_unref(pool);
 
 	errno = save_errno;
 	return ctx->size > 0 ? -1 : 1;
@@ -829,6 +833,7 @@
 ssize_t io_buffer_read_blocking(IOBuffer *buf)
 {
         IOBufferBlockContext ctx;
+	Pool pool;
 	Timeout to;
 	ssize_t ret;
 
@@ -841,7 +846,8 @@
 
 	/* create a new I/O loop */
 	memset(&ctx, 0, sizeof(ctx));
-	ctx.ioloop = io_loop_create();
+	pool = pool_create("io_buffer_read_blocking", 1024, FALSE);
+	ctx.ioloop = io_loop_create(pool);
 	ctx.inbuf = buf;
 
 	buf->io = io_add(buf->fd, IO_READ, io_read_data, &ctx);
@@ -864,6 +870,7 @@
 	}
 
 	io_loop_destroy(ctx.ioloop);
+	pool_unref(pool);
 
 	return buf->pos > buf->skip ?
 		(ssize_t) (buf->pos-buf->skip) : -1;
--- a/src/lib/iobuffer.h	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/lib/iobuffer.h	Wed Oct 09 02:26:08 2002 +0300
@@ -56,7 +56,8 @@
 /* Read the file by mmap()ing it in blocks. stop_offset specifies where to
    stop reading, or 0 to end of file. */
 IOBuffer *io_buffer_create_mmap(int fd, Pool pool, size_t block_size,
-				uoff_t size, int autoclose_fd);
+				uoff_t start_offset, uoff_t size,
+				int autoclose_fd);
 
 /* Reference counting. References start from 1, so calling io_buffer_unref()
    destroys the buffer if io_buffer_ref() is never used. */
--- a/src/lib/ioloop.c	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/lib/ioloop.c	Wed Oct 09 02:26:08 2002 +0300
@@ -300,7 +300,7 @@
         ioloop->running = TRUE;
 }
 
-IOLoop io_loop_create(void)
+IOLoop io_loop_create(Pool pool)
 {
 	IOLoop ioloop;
 
@@ -308,8 +308,9 @@
 	gettimeofday(&ioloop_timeval, NULL);
 	ioloop_time = ioloop_timeval.tv_sec;
 
-        ioloop = i_new(struct _IOLoop, 1);
-	ioloop->pool = pool_create("I/O loop", 10240, TRUE);
+        ioloop = p_new(pool, struct _IOLoop, 1);
+	pool_ref(pool);
+	ioloop->pool = pool;
 	ioloop->highest_fd = -1;
 
 	io_loop_handler_init(ioloop);
@@ -349,5 +350,4 @@
 	current_ioloop = current_ioloop->prev;
 
 	pool_unref(ioloop->pool);
-        i_free(ioloop);
 }
--- a/src/lib/ioloop.h	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/lib/ioloop.h	Wed Oct 09 02:26:08 2002 +0300
@@ -37,7 +37,7 @@
 void io_loop_set_running(IOLoop ioloop);
 void io_loop_handler_run(IOLoop ioloop);
 
-IOLoop io_loop_create(void);
+IOLoop io_loop_create(Pool pool);
 void io_loop_destroy(IOLoop ioloop);
 
 #endif
--- a/src/master/main.c	Wed Oct 09 02:22:06 2002 +0300
+++ b/src/master/main.c	Wed Oct 09 02:26:08 2002 +0300
@@ -248,7 +248,7 @@
 	if (!foreground)
 		daemonize();
 
-	ioloop = io_loop_create();
+	ioloop = io_loop_create(system_pool);
 
 	main_init();
         io_loop_run(ioloop);