dovecot-2.2: lib-fs: fs_init() API changed to allow returning an...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Sep 17 18:13:48 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/8f4ce0932777
changeset: 15085:8f4ce0932777
user: Timo Sirainen <tss at iki.fi>
date: Mon Sep 17 18:13:32 2012 +0300
description:
lib-fs: fs_init() API changed to allow returning an error.
diffstat:
src/lib-fs/fs-api-private.h | 3 +-
src/lib-fs/fs-api.c | 38 +++++++++++++++----
src/lib-fs/fs-api.h | 6 ++-
src/lib-fs/fs-posix.c | 44 +++++++++++++----------
src/lib-fs/fs-sis-queue.c | 30 ++++++++++------
src/lib-fs/fs-sis.c | 33 ++++++++++++------
src/lib-storage/index/dbox-common/dbox-storage.c | 14 +++++--
7 files changed, 110 insertions(+), 58 deletions(-)
diffs (truncated from 309 to 300 lines):
diff -r 64f556e62025 -r 8f4ce0932777 src/lib-fs/fs-api-private.h
--- a/src/lib-fs/fs-api-private.h Mon Sep 17 17:51:03 2012 +0300
+++ b/src/lib-fs/fs-api-private.h Mon Sep 17 18:13:32 2012 +0300
@@ -4,7 +4,8 @@
#include "fs-api.h"
struct fs_vfuncs {
- struct fs *(*init)(const char *args, const struct fs_settings *set);
+ int (*init)(const char *args, const struct fs_settings *set,
+ struct fs **fs_r, const char **error_r);
void (*deinit)(struct fs *fs);
int (*open)(struct fs *fs, const char *path, enum fs_open_mode mode,
diff -r 64f556e62025 -r 8f4ce0932777 src/lib-fs/fs-api.c
--- a/src/lib-fs/fs-api.c Mon Sep 17 17:51:03 2012 +0300
+++ b/src/lib-fs/fs-api.c Mon Sep 17 18:13:32 2012 +0300
@@ -10,27 +10,47 @@
&fs_class_sis_queue
};
-static struct fs *
+static int
fs_alloc(const struct fs *fs_class, const char *args,
- const struct fs_settings *set)
+ const struct fs_settings *set, struct fs **fs_r, const char **error_r)
{
struct fs *fs;
+ char *error_dup = NULL;
+ int ret;
- fs = fs_class->v.init(args, set);
+ T_BEGIN {
+ const char *error;
+
+ ret = fs_class->v.init(args, set, fs_r, &error);
+ if (ret < 0)
+ error_dup = i_strdup(error);
+ } T_END;
+ if (ret < 0) {
+ /* a bit kludgy way to allow data stack frame usage in normal
+ conditions but still be able to return error message from
+ data stack. */
+ *error_r = t_strdup_printf("%s: %s", fs_class->name, error_dup);
+ i_free(error_dup);
+ return -1;
+ }
fs->last_error = str_new(default_pool, 64);
- return fs;
+ return 0;
}
-struct fs *fs_init(const char *driver, const char *args,
- const struct fs_settings *set)
+int fs_init(const char *driver, const char *args,
+ const struct fs_settings *set,
+ struct fs **fs_r, const char **error_r)
{
unsigned int i;
for (i = 0; i < N_ELEMENTS(fs_classes); i++) {
- if (strcmp(fs_classes[i]->name, driver) == 0)
- return fs_alloc(fs_classes[i], args, set);
+ if (strcmp(fs_classes[i]->name, driver) == 0) {
+ return fs_alloc(fs_classes[i], args,
+ set, fs_r, error_r);
+ }
}
- i_fatal("Unknown fs driver: %s", driver);
+ *error_r = t_strdup_printf("Unknown fs driver: %s", driver);
+ return -1;
}
void fs_deinit(struct fs **_fs)
diff -r 64f556e62025 -r 8f4ce0932777 src/lib-fs/fs-api.h
--- a/src/lib-fs/fs-api.h Mon Sep 17 17:51:03 2012 +0300
+++ b/src/lib-fs/fs-api.h Mon Sep 17 18:13:32 2012 +0300
@@ -2,6 +2,7 @@
#define FS_API_H
struct stat;
+struct fs;
struct fs_file;
struct fs_lock;
@@ -31,8 +32,9 @@
const char *temp_file_prefix;
};
-struct fs *fs_init(const char *driver, const char *args,
- const struct fs_settings *set);
+int fs_init(const char *driver, const char *args,
+ const struct fs_settings *set,
+ struct fs **fs_r, const char **error_r);
void fs_deinit(struct fs **fs);
/* Returns 0 if opened, -1 if error (errno is set). */
diff -r 64f556e62025 -r 8f4ce0932777 src/lib-fs/fs-posix.c
--- a/src/lib-fs/fs-posix.c Mon Sep 17 17:51:03 2012 +0300
+++ b/src/lib-fs/fs-posix.c Mon Sep 17 18:13:32 2012 +0300
@@ -53,10 +53,12 @@
struct dotlock *dotlock;
};
-static struct fs *
-fs_posix_init(const char *args, const struct fs_settings *set)
+static int
+fs_posix_init(const char *args, const struct fs_settings *set,
+ struct fs **fs_r, const char **error_r)
{
struct posix_fs *fs;
+ const char *const *tmp;
fs = i_new(struct posix_fs, 1);
fs->fs = fs_class_posix;
@@ -66,32 +68,34 @@
fs->lock_method = FS_POSIX_LOCK_METHOD_FLOCK;
fs->mode = FS_DEFAULT_MODE;
- T_BEGIN {
- const char *const *tmp = t_strsplit_spaces(args, " ");
- for (; *tmp != NULL; tmp++) {
- const char *arg = *tmp;
+ tmp = t_strsplit_spaces(args, " ");
+ for (; *tmp != NULL; tmp++) {
+ const char *arg = *tmp;
- if (strcmp(arg, "lock=flock") == 0)
- fs->lock_method = FS_POSIX_LOCK_METHOD_FLOCK;
- else if (strcmp(arg, "lock=dotlock") == 0)
- fs->lock_method = FS_POSIX_LOCK_METHOD_DOTLOCK;
- else if (strncmp(arg, "mode=", 5) == 0) {
- fs->mode = strtoul(arg+5, NULL, 8) & 0666;
- if (fs->mode == 0) {
- i_fatal("fs-posix: Invalid mode: %s",
- arg+5);
- }
- } else
- i_fatal("fs-posix: Unknown arg '%s'", arg);
+ if (strcmp(arg, "lock=flock") == 0)
+ fs->lock_method = FS_POSIX_LOCK_METHOD_FLOCK;
+ else if (strcmp(arg, "lock=dotlock") == 0)
+ fs->lock_method = FS_POSIX_LOCK_METHOD_DOTLOCK;
+ else if (strncmp(arg, "mode=", 5) == 0) {
+ fs->mode = strtoul(arg+5, NULL, 8) & 0666;
+ if (fs->mode == 0) {
+ *error_r = t_strdup_printf("Invalid mode: %s",
+ arg+5);
+ return -1;
+ }
+ } else {
+ *error_r = t_strdup_printf("Unknown arg '%s'", arg);
+ return -1;
}
- } T_END;
+ }
fs->dir_mode = fs->mode;
if ((fs->dir_mode & 0600) != 0) fs->dir_mode |= 0100;
if ((fs->dir_mode & 0060) != 0) fs->dir_mode |= 0010;
if ((fs->dir_mode & 0006) != 0) fs->dir_mode |= 0001;
- return &fs->fs;
+ *fs_r = &fs->fs;
+ return 0;
}
static void fs_posix_deinit(struct fs *_fs)
diff -r 64f556e62025 -r 8f4ce0932777 src/lib-fs/fs-sis-queue.c
--- a/src/lib-fs/fs-sis-queue.c Mon Sep 17 17:51:03 2012 +0300
+++ b/src/lib-fs/fs-sis-queue.c Mon Sep 17 18:13:32 2012 +0300
@@ -30,11 +30,12 @@
fs_sis_queue_copy_error(fs);
}
-static struct fs *
-fs_sis_queue_init(const char *args, const struct fs_settings *set)
+static int
+fs_sis_queue_init(const char *args, const struct fs_settings *set,
+ struct fs **fs_r, const char **error_r)
{
struct sis_queue_fs *fs;
- const char *p, *parent_fs;
+ const char *p, *parent_name, *parent_args, *error;
fs = i_new(struct sis_queue_fs, 1);
fs->fs = fs_class_sis_queue;
@@ -42,18 +43,25 @@
/* <queue_dir>:<parent fs>[:<args>] */
p = strchr(args, ':');
- if (p == NULL || p[1] == '\0')
- i_fatal("fs-sis-queue: Parent filesystem not given as parameter");
+ if (p == NULL || p[1] == '\0') {
+ *error_r = "Parent filesystem not given as parameter";
+ return -1;
+ }
fs->queue_dir = i_strdup_until(args, p);
- parent_fs = p + 1;
+ parent_name = p + 1;
- p = strchr(parent_fs, ':');
- if (p == NULL)
- fs->super = fs_init(parent_fs, "", set);
+ parent_args = strchr(parent_name, ':');
+ if (parent_args == NULL)
+ parent_args = "";
else
- fs->super = fs_init(t_strdup_until(parent_fs, p), p+1, set);
- return &fs->fs;
+ parent_name = t_strdup_until(parent_name, parent_args++);
+ if (fs_init(parent_name, parent_args, set, &fs->super, &error) < 0) {
+ *error_r = t_strdup_printf("%s: %s", parent_name, error);
+ return -1;
+ }
+ *fs_r = &fs->fs;
+ return 0;
}
static void fs_sis_queue_deinit(struct fs *_fs)
diff -r 64f556e62025 -r 8f4ce0932777 src/lib-fs/fs-sis.c
--- a/src/lib-fs/fs-sis.c Mon Sep 17 17:51:03 2012 +0300
+++ b/src/lib-fs/fs-sis.c Mon Sep 17 18:13:32 2012 +0300
@@ -35,24 +35,35 @@
fs_sis_copy_error(fs);
}
-static struct fs *
-fs_sis_init(const char *args, const struct fs_settings *set)
+static int
+fs_sis_init(const char *args, const struct fs_settings *set,
+ struct fs **fs_r, const char **error_r)
{
struct sis_fs *fs;
- const char *p;
+ const char *parent_name, *parent_args, *error;
fs = i_new(struct sis_fs, 1);
fs->fs = fs_class_sis;
- if (*args == '\0')
- i_fatal("fs-sis: Parent filesystem not given as parameter");
+ if (*args == '\0') {
+ *error_r = "Parent filesystem not given as parameter";
+ return -1;
+ }
- p = strchr(args, ':');
- if (p == NULL)
- fs->super = fs_init(args, "", set);
- else
- fs->super = fs_init(t_strdup_until(args, p), p+1, set);
- return &fs->fs;
+ parent_args = strchr(args, ':');
+ if (parent_args == NULL) {
+ parent_name = args;
+ parent_args = "";
+ } else {
+ parent_name = t_strdup_until(args, parent_args);
+ parent_args++;
+ }
+ if (fs_init(parent_name, parent_args, set, &fs->super, &error) < 0) {
+ *error_r = t_strdup_printf("%s: %s", parent_name, error);
+ return -1;
+ }
+ *fs_r = &fs->fs;
+ return 0;
}
static void fs_sis_deinit(struct fs *_fs)
diff -r 64f556e62025 -r 8f4ce0932777 src/lib-storage/index/dbox-common/dbox-storage.c
--- a/src/lib-storage/index/dbox-common/dbox-storage.c Mon Sep 17 17:51:03 2012 +0300
+++ b/src/lib-storage/index/dbox-common/dbox-storage.c Mon Sep 17 18:13:32 2012 +0300
@@ -80,16 +80,17 @@
int dbox_storage_create(struct mail_storage *_storage,
struct mail_namespace *ns,
- const char **error_r ATTR_UNUSED)
+ const char **error_r)
{
struct dbox_storage *storage = (struct dbox_storage *)_storage;
const struct mail_storage_settings *set = _storage->set;
struct fs_settings fs_set;
+ const char *error;
memset(&fs_set, 0, sizeof(fs_set));
fs_set.temp_file_prefix = mailbox_list_get_global_temp_prefix(ns->list);
- if (*set->mail_attachment_fs != '\0') T_BEGIN {
+ if (*set->mail_attachment_fs != '\0') {
const char *name, *args, *dir;
args = strchr(set->mail_attachment_fs, ' ');
@@ -102,8 +103,13 @@
dir = mail_user_home_expand(_storage->user,
set->mail_attachment_dir);
storage->attachment_dir = p_strdup(_storage->pool, dir);
- storage->attachment_fs = fs_init(name, args, &fs_set);
- } T_END;
+ if (fs_init(name, args, &fs_set, &storage->attachment_fs,
More information about the dovecot-cvs
mailing list