dovecot-2.1: mdbox: Delay getting permissions for map/message fi...

dovecot at dovecot.org dovecot at dovecot.org
Sat Sep 22 19:13:49 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.1/rev/c83c70edef35
changeset: 14723:c83c70edef35
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Sep 21 11:44:17 2012 +0200
description:
mdbox: Delay getting permissions for map/message files.
This avoids a stat() if no mailbox is opened.

diffstat:

 src/lib-storage/index/dbox-multi/mdbox-file.c        |  21 ++++++-----
 src/lib-storage/index/dbox-multi/mdbox-map-private.h |  10 +++-
 src/lib-storage/index/dbox-multi/mdbox-map.c         |  36 +++++++++++++++----
 3 files changed, 47 insertions(+), 20 deletions(-)

diffs (155 lines):

diff -r 6908b8875720 -r c83c70edef35 src/lib-storage/index/dbox-multi/mdbox-file.c
--- a/src/lib-storage/index/dbox-multi/mdbox-file.c	Fri Sep 21 09:26:10 2012 +0200
+++ b/src/lib-storage/index/dbox-multi/mdbox-file.c	Fri Sep 21 11:44:17 2012 +0200
@@ -302,11 +302,14 @@
 {
 	struct mdbox_file *mfile = (struct mdbox_file *)file;
 	struct mdbox_map *map = mfile->storage->map;
-	mode_t old_mask;
-	const char *p, *dir, *error;
+	mode_t create_mode, old_mask;
+	gid_t create_gid;
+	const char *create_gid_origin, *p, *dir, *error;
 	int fd;
 
-	old_mask = umask(0666 & ~map->create_mode);
+	mdbox_map_get_create_mode(map, &create_mode, &create_gid,
+				  &create_gid_origin);
+	old_mask = umask(0666 & ~create_mode);
 	fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0666);
 	umask(old_mask);
 	if (fd == -1 && errno == ENOENT && parents &&
@@ -322,25 +325,25 @@
 			return -1;
 		}
 		/* try again */
-		old_mask = umask(0666 & ~map->create_mode);
+		old_mask = umask(0666 & ~create_mode);
 		fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0666);
 		umask(old_mask);
 	}
 	if (fd == -1) {
 		mail_storage_set_critical(&file->storage->storage,
 			"open(%s, O_CREAT) failed: %m", path);
-	} else if (map->create_gid == (gid_t)-1) {
+	} else if (create_gid == (gid_t)-1) {
 		/* no group change */
-	} else if (fchown(fd, (uid_t)-1, map->create_gid) < 0) {
+	} else if (fchown(fd, (uid_t)-1, create_gid) < 0) {
 		if (errno == EPERM) {
 			mail_storage_set_critical(&file->storage->storage, "%s",
 				eperm_error_get_chgrp("fchown", path,
-						      map->create_gid,
-						      map->create_gid_origin));
+						      create_gid,
+						      create_gid_origin));
 		} else {
 			mail_storage_set_critical(&file->storage->storage,
 				"fchown(%s, -1, %ld) failed: %m",
-				path, (long)map->create_gid);
+				path, (long)create_gid);
 		}
 		/* continue anyway */
 	}
diff -r 6908b8875720 -r c83c70edef35 src/lib-storage/index/dbox-multi/mdbox-map-private.h
--- a/src/lib-storage/index/dbox-multi/mdbox-map-private.h	Fri Sep 21 09:26:10 2012 +0200
+++ b/src/lib-storage/index/dbox-multi/mdbox-map-private.h	Fri Sep 21 11:44:17 2012 +0200
@@ -20,11 +20,12 @@
 	uint32_t map_ext_id, ref_ext_id;
 
 	struct mailbox_list *root_list;
-	mode_t create_mode;
-	gid_t create_gid;
-	const char *create_gid_origin;
+	mode_t _create_mode;
+	gid_t _create_gid;
+	char *_create_gid_origin;
 
 	unsigned int verify_existing_file_ids:1;
+	unsigned int create_mode_set:1;
 };
 
 struct mdbox_map_append {
@@ -64,4 +65,7 @@
 			      struct mail_index_view *view, uint32_t seq,
 			      struct dbox_mail_lookup_rec *rec_r);
 
+void mdbox_map_get_create_mode(struct mdbox_map *map, mode_t *mode_r, gid_t *gid_r,
+			       const char **gid_origin_r);
+
 #endif
diff -r 6908b8875720 -r c83c70edef35 src/lib-storage/index/dbox-multi/mdbox-map.c
--- a/src/lib-storage/index/dbox-multi/mdbox-map.c	Fri Sep 21 09:26:10 2012 +0200
+++ b/src/lib-storage/index/dbox-multi/mdbox-map.c	Fri Sep 21 11:44:17 2012 +0200
@@ -50,7 +50,6 @@
 {
 	struct mdbox_map *map;
 	const char *root, *index_root;
-	mode_t dir_mode;
 
 	root = mailbox_list_get_path(root_list, NULL,
 				     MAILBOX_LIST_PATH_TYPE_DIR);
@@ -77,14 +76,26 @@
 				sizeof(uint32_t));
 	map->ref_ext_id = mail_index_ext_register(map->index, "ref", 0,
 				sizeof(uint16_t), sizeof(uint16_t));
+	return map;
+}
 
-	mailbox_list_get_root_permissions(root_list,
-					  &map->create_mode, &dir_mode,
-					  &map->create_gid,
-					  &map->create_gid_origin);
-	mail_index_set_permissions(map->index, map->create_mode,
-				   map->create_gid, map->create_gid_origin);
-	return map;
+void mdbox_map_get_create_mode(struct mdbox_map *map, mode_t *mode_r, gid_t *gid_r,
+			       const char **gid_origin_r)
+{
+	mode_t dir_mode;
+	const char *gid_origin;
+
+	if (!map->create_mode_set) {
+		mailbox_list_get_root_permissions(map->root_list,
+						  &map->_create_mode, &dir_mode,
+						  &map->_create_gid,
+						  &gid_origin);
+		map->_create_gid_origin = i_strdup(gid_origin);
+		map->create_mode_set = TRUE;
+	}
+	*mode_r = map->_create_mode;
+	*gid_r = map->_create_gid;
+	*gid_origin_r = map->_create_gid_origin;
 }
 
 void mdbox_map_deinit(struct mdbox_map **_map)
@@ -98,6 +109,7 @@
 		mail_index_close(map->index);
 	}
 	mail_index_free(&map->index);
+	i_free(map->_create_gid_origin);
 	i_free(map->index_path);
 	i_free(map->path);
 	i_free(map);
@@ -156,6 +168,9 @@
 static int mdbox_map_open_internal(struct mdbox_map *map, bool create_missing)
 {
 	enum mail_index_open_flags open_flags;
+	mode_t create_mode;
+	gid_t create_gid;
+	const char *create_gid_origin;
 	int ret = 0;
 
 	if (map->view != NULL) {
@@ -163,6 +178,11 @@
 		return 1;
 	}
 
+	mdbox_map_get_create_mode(map, &create_mode, &create_gid,
+				  &create_gid_origin);
+	mail_index_set_permissions(map->index, create_mode,
+				   create_gid, create_gid_origin);
+
 	open_flags = MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY |
 		mail_storage_settings_to_index_flags(MAP_STORAGE(map)->set);
 	if (create_missing) {


More information about the dovecot-cvs mailing list