This clarifies which fields are settings related.
}
o_stream_destroy(&output);
- if (cache->index->fsync_mode == FSYNC_MODE_ALWAYS) {
+ if (cache->index->set.fsync_mode == FSYNC_MODE_ALWAYS) {
if (fdatasync(fd) < 0) {
mail_cache_set_syscall_error(cache, "fdatasync()");
array_free(ext_offsets);
if (mail_cache_append(cache, buffer->data, buffer->used, &offset) < 0)
return -1;
- if (cache->index->fsync_mode == FSYNC_MODE_ALWAYS) {
+ if (cache->index->set.fsync_mode == FSYNC_MODE_ALWAYS) {
if (fdatasync(cache->fd) < 0) {
mail_cache_set_syscall_error(cache, "fdatasync()");
return -1;
cache->dotlock_settings.nfs_flush =
(index->flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0;
cache->dotlock_settings.timeout =
- I_MIN(MAIL_CACHE_LOCK_TIMEOUT, index->max_lock_timeout_secs);
+ I_MIN(MAIL_CACHE_LOCK_TIMEOUT, index->set.max_lock_timeout_secs);
cache->dotlock_settings.stale_timeout = MAIL_CACHE_LOCK_CHANGE_TIMEOUT;
if (!MAIL_INDEX_IS_IN_MEMORY(index) &&
}
i_assert(cache->file_lock == NULL);
- if (cache->index->lock_method != FILE_LOCK_METHOD_DOTLOCK) {
+ if (cache->index->set.lock_method != FILE_LOCK_METHOD_DOTLOCK) {
timeout_secs = I_MIN(MAIL_CACHE_LOCK_TIMEOUT,
- cache->index->max_lock_timeout_secs);
+ cache->index->set.max_lock_timeout_secs);
ret = mail_index_lock_fd(cache->index, cache->filepath,
cache->fd, F_WRLCK,
if (MAIL_CACHE_IS_UNUSABLE(cache)) {
/* we found it to be broken during the lock. just clean up. */
cache->hdr_modified = FALSE;
- } else if (cache->index->fsync_mode == FSYNC_MODE_ALWAYS) {
+ } else if (cache->index->set.fsync_mode == FSYNC_MODE_ALWAYS) {
if (fdatasync(cache->fd) < 0)
mail_cache_set_syscall_error(cache, "fdatasync()");
}
return 1;
}
- return file_wait_lock(fd, path, lock_type, index->lock_method,
+ return file_wait_lock(fd, path, lock_type, index->set.lock_method,
timeout_secs, lock_r);
}
/* Assume flock() is emulated with fcntl(), because that's how most
OSes work nowadays. */
if (locked &&
- (index->lock_method == FILE_LOCK_METHOD_FCNTL ||
- index->lock_method == FILE_LOCK_METHOD_FLOCK)) {
+ (index->set.lock_method == FILE_LOCK_METHOD_FCNTL ||
+ index->set.lock_method == FILE_LOCK_METHOD_FLOCK)) {
nfs_flush_read_cache_locked(path, fd);
} else {
nfs_flush_read_cache_unlocked(path, fd);
struct mail_index_module_register *reg;
};
+struct mail_index_settings {
+ /* Directory path for .cache file. Set via
+ mail_index_set_cache_dir(). */
+ char *cache_dir;
+
+ /* fsyncing behavior. Set via mail_index_set_fsync_mode(). */
+ enum fsync_mode fsync_mode;
+ enum mail_index_fsync_mask fsync_mask;
+
+ /* Index file permissions. Set via mail_index_set_permissions(). */
+ mode_t mode;
+ gid_t gid;
+ char *gid_origin;
+
+ /* Lock settings. Set via mail_index_set_lock_method(). */
+ enum file_lock_method lock_method;
+ unsigned int max_lock_timeout_secs;
+
+ /* Initial extension added to newly created indexes. Set via
+ mail_index_set_ext_init_data(). */
+ uint32_t ext_hdr_init_id;
+ void *ext_hdr_init_data;
+};
+
struct mail_index {
char *dir, *prefix;
- char *cache_dir;
struct event *event;
struct mail_cache *cache;
unsigned int open_count;
enum mail_index_open_flags flags;
- enum fsync_mode fsync_mode;
- enum mail_index_fsync_mask fsync_mask;
- mode_t mode;
- gid_t gid;
- char *gid_origin;
+ struct mail_index_settings set;
struct mail_index_optimization_settings optimization_set;
uint32_t pending_log2_rotate_time;
pool_t extension_pool;
ARRAY(struct mail_index_registered_ext) extensions;
- uint32_t ext_hdr_init_id;
- void *ext_hdr_init_data;
-
ARRAY(mail_index_sync_lost_handler_t *) sync_lost_handlers;
char *filepath;
/* syncing will update this if non-NULL */
struct mail_index_transaction_commit_result *sync_commit_result;
- enum file_lock_method lock_method;
- unsigned int max_lock_timeout_secs;
-
pool_t keywords_pool;
ARRAY_TYPE(keywords) keywords;
HASH_TABLE(char *, void *) keywords_hash; /* name -> unsigned int idx */
str = t_str_new(256);
str_append(str, strmap->path);
- fd = safe_mkstemp_hostpid_group(str, view->view->index->mode,
- view->view->index->gid,
- view->view->index->gid_origin);
+ fd = safe_mkstemp_hostpid_group(str, view->view->index->set.mode,
+ view->view->index->set.gid,
+ view->view->index->set.gid_origin);
temp_path = str_c(str);
if (fd == -1) {
i_assert(strmap->fd != -1);
- if (strmap->index->lock_method != FILE_LOCK_METHOD_DOTLOCK) {
+ if (strmap->index->set.lock_method != FILE_LOCK_METHOD_DOTLOCK) {
i_assert(strmap->file_lock == NULL);
timeout_secs = I_MIN(MAIL_INDEX_STRMAP_TIMEOUT_SECS,
- strmap->index->max_lock_timeout_secs);
+ strmap->index->set.max_lock_timeout_secs);
ret = file_wait_lock(strmap->fd, strmap->path, F_WRLCK,
- strmap->index->lock_method, timeout_secs,
+ strmap->index->set.lock_method, timeout_secs,
&strmap->file_lock);
if (ret <= 0) {
mail_index_strmap_set_syscall_error(strmap,
append_ctx->index_sync_transaction = t->sync_transaction;
append_ctx->tail_offset_changed = t->tail_offset_changed;
append_ctx->want_fsync =
- (t->view->index->fsync_mask & change_mask) != 0 ||
+ (t->view->index->set.fsync_mask & change_mask) != 0 ||
(t->flags & MAIL_INDEX_TRANSACTION_FLAG_FSYNC) != 0;
}
}
o_stream_destroy(&output);
- if (ret == 0 && index->fsync_mode != FSYNC_MODE_NEVER) {
+ if (ret == 0 && index->set.fsync_mode != FSYNC_MODE_NEVER) {
if (fdatasync(fd) < 0) {
mail_index_file_set_syscall_error(index, path,
"fdatasync()");
i_array_init(&index->module_contexts,
I_MIN(5, mail_index_module_register.id));
- index->mode = 0600;
- index->gid = (gid_t)-1;
- index->lock_method = FILE_LOCK_METHOD_FCNTL;
- index->max_lock_timeout_secs = UINT_MAX;
+ index->set.mode = 0600;
+ index->set.gid = (gid_t)-1;
+ index->set.lock_method = FILE_LOCK_METHOD_FCNTL;
+ index->set.max_lock_timeout_secs = UINT_MAX;
index->optimization_set = default_optimization_set;
index->keywords_ext_id =
array_free(&index->module_contexts);
event_unref(&index->event);
- i_free(index->cache_dir);
- i_free(index->ext_hdr_init_data);
- i_free(index->gid_origin);
+ i_free(index->set.cache_dir);
+ i_free(index->set.ext_hdr_init_data);
+ i_free(index->set.gid_origin);
i_free(index->error);
i_free(index->dir);
i_free(index->prefix);
void mail_index_set_cache_dir(struct mail_index *index, const char *dir)
{
- i_free(index->cache_dir);
- index->cache_dir = i_strdup(dir);
+ i_free(index->set.cache_dir);
+ index->set.cache_dir = i_strdup(dir);
}
void mail_index_set_fsync_mode(struct mail_index *index,
enum fsync_mode mode,
enum mail_index_fsync_mask mask)
{
- index->fsync_mode = mode;
- index->fsync_mask = mask;
+ index->set.fsync_mode = mode;
+ index->set.fsync_mask = mask;
}
bool mail_index_use_existing_permissions(struct mail_index *index)
return FALSE;
}
- index->mode = st.st_mode & 0666;
+ index->set.mode = st.st_mode & 0666;
if (S_ISDIR(st.st_mode) && (st.st_mode & S_ISGID) != 0) {
/* directory's GID is used automatically for new files */
- index->gid = (gid_t)-1;
+ index->set.gid = (gid_t)-1;
} else if ((st.st_mode & 0070) >> 3 == (st.st_mode & 0007)) {
/* group has same permissions as world, so don't bother
changing it */
- index->gid = (gid_t)-1;
+ index->set.gid = (gid_t)-1;
} else if (getegid() == st.st_gid) {
/* using our own gid, no need to change it */
- index->gid = (gid_t)-1;
+ index->set.gid = (gid_t)-1;
} else {
- index->gid = st.st_gid;
+ index->set.gid = st.st_gid;
}
- i_free(index->gid_origin);
- if (index->gid != (gid_t)-1)
- index->gid_origin = i_strdup("preserved existing GID");
+ i_free(index->set.gid_origin);
+ if (index->set.gid != (gid_t)-1)
+ index->set.gid_origin = i_strdup("preserved existing GID");
return TRUE;
}
void mail_index_set_permissions(struct mail_index *index,
mode_t mode, gid_t gid, const char *gid_origin)
{
- index->mode = mode & 0666;
- index->gid = gid;
+ index->set.mode = mode & 0666;
+ index->set.gid = gid;
- i_free(index->gid_origin);
- index->gid_origin = i_strdup(gid_origin);
+ i_free(index->set.gid_origin);
+ index->set.gid_origin = i_strdup(gid_origin);
}
void mail_index_set_lock_method(struct mail_index *index,
enum file_lock_method lock_method,
unsigned int max_timeout_secs)
{
- index->lock_method = lock_method;
- index->max_lock_timeout_secs = max_timeout_secs;
+ index->set.lock_method = lock_method;
+ index->set.max_lock_timeout_secs = max_timeout_secs;
}
void mail_index_set_optimization_settings(struct mail_index *index,
{
const struct mail_index_registered_ext *rext;
- i_assert(index->ext_hdr_init_data == NULL ||
- index->ext_hdr_init_id == ext_id);
+ i_assert(index->set.ext_hdr_init_data == NULL ||
+ index->set.ext_hdr_init_id == ext_id);
rext = array_idx(&index->extensions, ext_id);
i_assert(rext->hdr_size == size);
- index->ext_hdr_init_id = ext_id;
- i_free(index->ext_hdr_init_data);
- index->ext_hdr_init_data = i_malloc(size);
- memcpy(index->ext_hdr_init_data, data, size);
+ index->set.ext_hdr_init_id = ext_id;
+ i_free(index->set.ext_hdr_init_data);
+ index->set.ext_hdr_init_data = i_malloc(size);
+ memcpy(index->set.ext_hdr_init_data, data, size);
}
uint32_t mail_index_ext_register(struct mail_index *index, const char *name,
path = *path_r = t_strconcat(path_prefix, ".tmp", NULL);
old_mask = umask(0);
- fd = open(path, O_RDWR|O_CREAT|O_EXCL, index->mode);
+ fd = open(path, O_RDWR|O_CREAT|O_EXCL, index->set.mode);
umask(old_mask);
if (fd == -1 && errno == EEXIST) {
/* stale temp file. unlink and recreate rather than overwriting,
if (i_unlink(path) < 0)
return -1;
old_mask = umask(0);
- fd = open(path, O_RDWR|O_CREAT|O_EXCL, index->mode);
+ fd = open(path, O_RDWR|O_CREAT|O_EXCL, index->set.mode);
umask(old_mask);
}
if (fd == -1) {
{
const char *dir;
- if (index->cache_dir != NULL)
- dir = index->cache_dir;
+ if (index->set.cache_dir != NULL)
+ dir = index->set.cache_dir;
else if (index->dir != NULL)
dir = index->dir;
else
event_unset_forced_debug(index->event);
if ((flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0 &&
- index->fsync_mode != FSYNC_MODE_ALWAYS)
+ index->set.fsync_mode != FSYNC_MODE_ALWAYS)
i_fatal("nfs flush requires mail_fsync=always");
if ((flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0 &&
(flags & MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE) == 0)
{
mode_t mode;
- if (index->gid == (gid_t)-1) {
+ if (index->set.gid == (gid_t)-1) {
/* no gid changing */
return;
- } else if (fchown(fd, (uid_t)-1, index->gid) == 0) {
+ } else if (fchown(fd, (uid_t)-1, index->set.gid) == 0) {
/* success */
return;
- } if ((index->mode & 0060) >> 3 == (index->mode & 0006)) {
+ } if ((index->set.mode & 0060) >> 3 == (index->set.mode & 0006)) {
/* group and world permissions are the same, so group doesn't
really matter. ignore silently. */
return;
mail_index_file_set_syscall_error(index, path, "fchown()");
else {
mail_index_set_error(index, "%s",
- eperm_error_get_chgrp("fchown", path, index->gid,
- index->gid_origin));
+ eperm_error_get_chgrp("fchown", path, index->set.gid,
+ index->set.gid_origin));
}
/* continue, but change permissions so that only the common
subset of group and world is used. this makes sure no one
gets any extra permissions. */
- mode = ((index->mode & 0060) >> 3) & (index->mode & 0006);
- mode |= (mode << 3) | (index->mode & 0600);
+ mode = ((index->set.mode & 0060) >> 3) & (index->set.mode & 0006);
+ mode |= (mode << 3) | (index->set.mode & 0600);
if (fchmod(fd, mode) < 0)
mail_index_file_set_syscall_error(index, path, "fchmod()");
}
file->max_tail_offset);
if ((ctx->want_fsync &&
- file->log->index->fsync_mode != FSYNC_MODE_NEVER) ||
- file->log->index->fsync_mode == FSYNC_MODE_ALWAYS) {
+ file->log->index->set.fsync_mode != FSYNC_MODE_NEVER) ||
+ file->log->index->set.fsync_mode == FSYNC_MODE_ALWAYS) {
if (fdatasync(file->fd) < 0) {
mail_index_file_set_syscall_error(ctx->log->index,
file->filepath,
return 0;
}
- if (file->log->index->lock_method == FILE_LOCK_METHOD_DOTLOCK)
+ if (file->log->index->set.lock_method == FILE_LOCK_METHOD_DOTLOCK)
return mail_transaction_log_file_dotlock(file);
if (file->log->index->readonly) {
i_assert(file->file_lock == NULL);
lock_timeout_secs = I_MIN(MAIL_TRANSACTION_LOG_LOCK_TIMEOUT,
- file->log->index->max_lock_timeout_secs);
+ file->log->index->set.max_lock_timeout_secs);
ret = mail_index_lock_fd(file->log->index, file->filepath, file->fd,
F_WRLCK, lock_timeout_secs,
&file->file_lock);
"Timeout (%us) while waiting for lock for "
"transaction log file %s%s",
lock_timeout_secs, file->filepath,
- file_lock_find(file->fd, file->log->index->lock_method, F_WRLCK));
+ file_lock_find(file->fd, file->log->index->set.lock_method, F_WRLCK));
file->log->index->index_lock_timeout = TRUE;
return -1;
}
file->filepath, lock_time, lock_reason);
}
- if (file->log->index->lock_method == FILE_LOCK_METHOD_DOTLOCK) {
+ if (file->log->index->set.lock_method == FILE_LOCK_METHOD_DOTLOCK) {
(void)mail_transaction_log_file_undotlock(file);
return;
}
struct mail_transaction_ext_hdr_update *ext_hdr;
unsigned int hdr_offset;
- rext = array_idx(&index->extensions, index->ext_hdr_init_id);
+ rext = array_idx(&index->extensions, index->set.ext_hdr_init_id);
/* introduce the extension */
hdr_offset = buf->used;
ext_hdr = buffer_append_space_unsafe(buf, sizeof(*ext_hdr));
ext_hdr->size = rext->hdr_size;
- buffer_append(buf, index->ext_hdr_init_data, rext->hdr_size);
+ buffer_append(buf, index->set.ext_hdr_init_data, rext->hdr_size);
hdr = buffer_get_space_unsafe(buf, hdr_offset, sizeof(*hdr));
hdr->size = mail_index_uint32_to_offset(buf->used - hdr_offset);
writebuf = t_buffer_create(128);
buffer_append(writebuf, &file->hdr, sizeof(file->hdr));
- if (index->ext_hdr_init_data != NULL && reset)
+ if (index->set.ext_hdr_init_data != NULL && reset)
log_write_ext_hdr_init_data(index, writebuf);
if (write_full(new_fd, writebuf->data, writebuf->used) < 0) {
log_file_set_syscall_error(file, "write_full()");
return -1;
}
- if (file->log->index->fsync_mode == FSYNC_MODE_ALWAYS) {
+ if (file->log->index->set.fsync_mode == FSYNC_MODE_ALWAYS) {
/* the header isn't important, so don't bother calling
fdatasync() unless it's required */
if (fdatasync(new_fd) < 0) {
/* With dotlocking we might already have path.lock created, so this
filename has to be different. */
- old_mask = umask(index->mode ^ 0666);
+ old_mask = umask(index->set.mode ^ 0666);
fd = file_dotlock_open(&new_dotlock_set, file->filepath, 0, &dotlock);
umask(old_mask);
mail_index_set_error(log->index,
"Transaction log %s was recreated while we had it locked - "
"locking is broken (lock_method=%s)", path,
- file_lock_method_to_str(log->index->lock_method));
+ file_lock_method_to_str(log->index->set.lock_method));
mail_transaction_log_file_free(&file);
return -1;
}
i_zero(set_r);
set_r->timeout = I_MIN(MAIL_TRANSACTION_LOG_LOCK_TIMEOUT,
- index->max_lock_timeout_secs);
+ index->set.max_lock_timeout_secs);
set_r->stale_timeout = MAIL_TRANSACTION_LOG_LOCK_CHANGE_TIMEOUT;
set_r->nfs_flush = (index->flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0;
set_r->use_excl_lock =