Mercurial > dovecot > core-2.2
changeset 15085:8f4ce0932777
lib-fs: fs_init() API changed to allow returning an error.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 17 Sep 2012 18:13:32 +0300 |
parents | 64f556e62025 |
children | 04580a59dc53 |
files | src/lib-fs/fs-api-private.h src/lib-fs/fs-api.c src/lib-fs/fs-api.h src/lib-fs/fs-posix.c src/lib-fs/fs-sis-queue.c src/lib-fs/fs-sis.c src/lib-storage/index/dbox-common/dbox-storage.c |
diffstat | 7 files changed, 110 insertions(+), 58 deletions(-) [+] |
line wrap: on
line diff
--- 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,
--- 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)
--- 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). */
--- 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)
--- 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)
--- 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)
--- 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, + &error) < 0) { + *error_r = t_strdup_printf("mail_attachment_fs: %s", + error); + return -1; + } + } dbox_verify_alt_path(ns->list); return 0;