This will help removing fs_set_error() calls.
struct fs_vfuncs {
struct fs *(*alloc)(void);
int (*init)(struct fs *fs, const char *args,
- const struct fs_settings *set);
+ const struct fs_settings *set, const char **error_r);
void (*deinit)(struct fs *fs);
enum fs_properties (*get_properties)(struct fs *fs);
const struct fs_settings *set, struct fs **fs_r, const char **error_r)
{
struct fs *fs;
+ const char *temp_error;
+ char *error = NULL;
int ret;
fs = fs_class->v.alloc();
i_array_init(&fs->module_contexts, 5);
T_BEGIN {
- ret = fs_class->v.init(fs, args, set);
+ if ((ret = fs_class->v.init(fs, args, set, &temp_error)) < 0)
+ error = i_strdup(temp_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,
- fs_last_error(fs));
+ *error_r = t_strdup_printf("%s: %s", fs_class->name, error);
+ i_free(error);
fs_unref(&fs);
return -1;
}
}
static int
-fs_dict_init(struct fs *_fs, const char *args, const struct fs_settings *set)
+fs_dict_init(struct fs *_fs, const char *args, const struct fs_settings *set,
+ const char **error_r)
{
struct dict_fs *fs = (struct dict_fs *)_fs;
struct dict_settings dict_set;
p = strchr(args, ':');
if (p == NULL) {
- fs_set_error(_fs, "':' missing in args");
+ *error_r = "':' missing in args";
return -1;
}
encoding_str = t_strdup_until(args, p++);
else if (strcmp(encoding_str, "base64") == 0)
fs->encoding = FS_DICT_VALUE_ENCODING_BASE64;
else {
- fs_set_error(_fs, "Unknown value encoding '%s'", encoding_str);
+ *error_r = t_strdup_printf("Unknown value encoding '%s'",
+ encoding_str);
return -1;
}
dict_set.base_dir = set->base_dir;
if (dict_init(p, &dict_set, &fs->dict, &error) < 0) {
- fs_set_error(_fs, "dict_init(%s) failed: %s", args, error);
+ *error_r = t_strdup_printf("dict_init(%s) failed: %s",
+ args, error);
return -1;
}
return 0;
}
static int
-fs_metawrap_init(struct fs *_fs, const char *args, const
- struct fs_settings *set)
+fs_metawrap_init(struct fs *_fs, const char *args,
+ const struct fs_settings *set, const char **error_r)
{
struct metawrap_fs *fs = (struct metawrap_fs *)_fs;
- const char *parent_name, *parent_args, *error;
+ const char *parent_name, *parent_args;
if (*args == '\0') {
- fs_set_error(_fs, "Parent filesystem not given as parameter");
+ *error_r = "Parent filesystem not given as parameter";
return -1;
}
parent_name = t_strdup_until(args, parent_args);
parent_args++;
}
- if (fs_init(parent_name, parent_args, set, &_fs->parent, &error) < 0) {
- fs_set_error(_fs, "%s", error);
+ if (fs_init(parent_name, parent_args, set, &_fs->parent, error_r) < 0)
return -1;
- }
if ((fs_get_properties(_fs->parent) & FS_PROPERTY_METADATA) == 0)
fs->wrap_metadata = TRUE;
return 0;
}
static int
-fs_posix_init(struct fs *_fs, const char *args, const struct fs_settings *set)
+fs_posix_init(struct fs *_fs, const char *args, const struct fs_settings *set,
+ const char **error_r)
{
struct posix_fs *fs = container_of(_fs, struct posix_fs, fs);
const char *const *tmp;
} else if (str_begins(arg, "mode=")) {
unsigned int mode;
if (str_to_uint_oct(arg+5, &mode) < 0) {
- fs_set_error(_fs, "Invalid mode value: %s", arg+5);
+ *error_r = t_strdup_printf("Invalid mode value: %s", arg+5);
return -1;
}
fs->mode = mode & 0666;
if (fs->mode == 0) {
- fs_set_error(_fs, "Invalid mode: %s", arg+5);
+ *error_r = t_strdup_printf("Invalid mode: %s", arg+5);
return -1;
}
} else {
- fs_set_error(_fs, "Unknown arg '%s'", arg);
+ *error_r = t_strdup_printf("Unknown arg '%s'", arg);
return -1;
}
}
static int
fs_randomfail_init(struct fs *_fs, const char *args,
- const struct fs_settings *set)
+ const struct fs_settings *set, const char **error_r)
{
struct randomfail_fs *fs = (struct randomfail_fs *)_fs;
const char *p, *parent_name, *parent_args, *error;
p = strchr(args, ':');
if (p == NULL) {
- fs_set_error(_fs, "Randomfail parameters missing");
+ *error_r = "Randomfail parameters missing";
return -1;
}
if (fs_randomfail_parse_params(fs, t_strdup_until(args, p++), &error) < 0) {
- fs_set_error(_fs, "Invalid randomfail parameters: %s", error);
+ *error_r = t_strdup_printf(
+ "Invalid randomfail parameters: %s", error);
return -1;
}
args = p;
if (*args == '\0') {
- fs_set_error(_fs, "Parent filesystem not given as parameter");
+ *error_r = "Parent filesystem not given as parameter";
return -1;
}
parent_name = t_strdup_until(args, parent_args);
parent_args++;
}
- if (fs_init(parent_name, parent_args, set, &_fs->parent, &error) < 0) {
- fs_set_error(_fs, "%s", error);
+ if (fs_init(parent_name, parent_args, set, &_fs->parent, error_r) < 0)
return -1;
- }
return 0;
}
static int
fs_sis_queue_init(struct fs *_fs, const char *args,
- const struct fs_settings *set)
+ const struct fs_settings *set, const char **error_r)
{
struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
- const char *p, *parent_name, *parent_args, *error;
+ const char *p, *parent_name, *parent_args;
/* <queue_dir>:<parent fs>[:<args>] */
p = strchr(args, ':');
if (p == NULL || p[1] == '\0') {
- fs_set_error(_fs, "Parent filesystem not given as parameter");
+ *error_r = "Parent filesystem not given as parameter";
return -1;
}
parent_args = "";
else
parent_name = t_strdup_until(parent_name, parent_args++);
- if (fs_init(parent_name, parent_args, set, &_fs->parent, &error) < 0) {
- fs_set_error(_fs, "%s", error);
+ if (fs_init(parent_name, parent_args, set, &_fs->parent, error_r) < 0)
return -1;
- }
return 0;
}
}
static int
-fs_sis_init(struct fs *_fs, const char *args, const struct fs_settings *set)
+fs_sis_init(struct fs *_fs, const char *args, const struct fs_settings *set,
+ const char **error_r)
{
enum fs_properties props;
- const char *parent_name, *parent_args, *error;
+ const char *parent_name, *parent_args;
if (*args == '\0') {
- fs_set_error(_fs, "Parent filesystem not given as parameter");
+ *error_r = "Parent filesystem not given as parameter";
return -1;
}
parent_name = t_strdup_until(args, parent_args);
parent_args++;
}
- if (fs_init(parent_name, parent_args, set, &_fs->parent, &error) < 0) {
- fs_set_error(_fs, "%s", error);
+ if (fs_init(parent_name, parent_args, set, &_fs->parent, error_r) < 0)
return -1;
- }
props = fs_get_properties(_fs->parent);
if ((props & FS_SIS_REQUIRED_PROPS) != FS_SIS_REQUIRED_PROPS) {
- fs_set_error(_fs, "%s backend can't be used with SIS",
- parent_name);
+ *error_r = t_strdup_printf("%s backend can't be used with SIS",
+ parent_name);
return -1;
}
return 0;
static int
fs_test_init(struct fs *_fs ATTR_UNUSED, const char *args ATTR_UNUSED,
- const struct fs_settings *set ATTR_UNUSED)
+ const struct fs_settings *set ATTR_UNUSED,
+ const char **error_r ATTR_UNUSED)
{
return 0;
}
}
static int
-fs_compress_init(struct fs *_fs, const char *args, const
- struct fs_settings *set)
+fs_compress_init(struct fs *_fs, const char *args,
+ const struct fs_settings *set, const char **error_r)
{
struct compress_fs *fs = (struct compress_fs *)_fs;
const char *p, *compression_name, *level_str, *error;
p = strchr(args, ':');
if (p == NULL) {
- fs_set_error(_fs, "Compression method not given as parameter");
+ *error_r = "Compression method not given as parameter";
return -1;
}
compression_name = t_strdup_until(args, p++);
/* get compression level */
p = strchr(args, ':');
if (p == NULL || p[1] == '\0') {
- fs_set_error(_fs, "Parent filesystem not given as parameter");
+ *error_r = "Parent filesystem not given as parameter";
return -1;
}
level_str = t_strdup_until(args, p++);
if (str_to_uint(level_str, &fs->compress_level) < 0 ||
fs->compress_level > 9) {
- fs_set_error(_fs, "Invalid compression level parameter '%s'", level_str);
+ *error_r = t_strdup_printf(
+ "Invalid compression level parameter '%s'", level_str);
return -1;
}
args = p;
fs->handler = compression_lookup_handler(compression_name);
if (fs->handler == NULL) {
- fs_set_error(_fs, "Compression method '%s' not support", compression_name);
+ *error_r = t_strdup_printf(
+ "Compression method '%s' not supported", compression_name);
return -1;
}
parent_args++;
}
if (fs_init(parent_name, parent_args, set, &_fs->parent, &error) < 0) {
- fs_set_error(_fs, "%s: %s", parent_name, error);
+ *error_r = t_strdup_printf("%s: %s", parent_name, error);
return -1;
}
return 0;
}
static int
-fs_crypt_init(struct fs *_fs, const char *args, const
- struct fs_settings *set)
+fs_crypt_init(struct fs *_fs, const char *args, const struct fs_settings *set,
+ const char **error_r)
{
struct crypt_fs *fs = (struct crypt_fs *)_fs;
const char *enc_algo, *set_prefix;
for (;;) {
p = strchr(args, ':');
if (p == NULL) {
- fs_set_error(_fs, "Missing parameters");
+ *error_r = "Missing parameters";
return -1;
}
arg = t_strdup_until(args, p);
else if (strcmp(arg, "password") == 0)
password = value;
else {
- fs_set_error(_fs, "Invalid parameter '%s'", arg);
+ *error_r = t_strdup_printf(
+ "Invalid parameter '%s'", arg);
return -1;
}
}
parent_args++;
}
if (fs_init(parent_name, parent_args, set, &_fs->parent, &error) < 0) {
- fs_set_error(_fs, "%s: %s", parent_name, error);
+ *error_r = t_strdup_printf("%s: %s", parent_name, error);
return -1;
}
fs->enc_algo = i_strdup(enc_algo);