]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
quota-maildir: Improve error_r strings
authorMartti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
Mon, 16 Oct 2017 12:55:16 +0000 (15:55 +0300)
committerTimo Sirainen <tss@dovecot.fi>
Thu, 19 Oct 2017 13:43:45 +0000 (16:43 +0300)
src/plugins/quota/quota-maildir.c

index 876dc60b22692049df8fa082e192578e51366903..b2fd96d38ef8381647e7cdf632441b220c9de95f 100644 (file)
@@ -54,7 +54,7 @@ static struct dotlock_settings dotlock_settings = {
 };
 
 static int maildir_sum_dir(const char *dir, uint64_t *total_bytes,
-                          uint64_t *total_count)
+                          uint64_t *total_count, const char **error_r)
 {
        DIR *dirp;
        struct dirent *dp;
@@ -68,7 +68,7 @@ static int maildir_sum_dir(const char *dir, uint64_t *total_bytes,
        if (dirp == NULL) {
                if (errno == ENOENT || errno == ESTALE)
                        return 0;
-               i_error("opendir(%s) failed: %m", dir);
+               *error_r = t_strdup_printf("opendir(%s) failed: %m", dir);
                return -1;
        }
 
@@ -107,14 +107,15 @@ static int maildir_sum_dir(const char *dir, uint64_t *total_bytes,
                                *total_bytes += st.st_size;
                                *total_count += 1;
                        } else if (errno != ENOENT && errno != ESTALE) {
-                               i_error("stat(%s) failed: %m", str_c(path));
+                               *error_r = t_strdup_printf(
+                                       "stat(%s) failed: %m", str_c(path));
                                ret = -1;
                        }
                }
        }
 
        if (closedir(dirp) < 0) {
-               i_error("closedir(%s) failed: %m", dir);
+               *error_r = t_strdup_printf("closedir(%s) failed: %m", dir);
                return -1;
        }
        return ret;
@@ -196,9 +197,14 @@ maildir_list_next(struct maildir_list_context *ctx, time_t *mtime_r)
        return str_c(ctx->path);
 }
 
-static int maildir_list_deinit(struct maildir_list_context *ctx)
+static int maildir_list_deinit(struct maildir_list_context *ctx,
+                              const char **error_r)
 {
        int ret = mailbox_list_iter_deinit(&ctx->iter);
+       if (ret < 0)
+               *error_r = t_strdup(
+                       mailbox_list_get_last_internal_error(ctx->iter->list,
+                                                            NULL));
 
        str_free(&ctx->path);
        i_free(ctx);
@@ -207,7 +213,8 @@ static int maildir_list_deinit(struct maildir_list_context *ctx)
 
 static int
 maildirs_check_have_changed(struct maildir_quota_root *root,
-                           struct mail_namespace *ns, time_t latest_mtime)
+                           struct mail_namespace *ns, time_t latest_mtime,
+                           const char **error_r)
 {
        struct maildir_list_context *ctx;
        time_t mtime;
@@ -220,7 +227,7 @@ maildirs_check_have_changed(struct maildir_quota_root *root,
                        break;
                }
        }
-       if (maildir_list_deinit(ctx) < 0)
+       if (maildir_list_deinit(ctx, error_r) < 0)
                return -1;
        return ret;
 }
@@ -319,7 +326,8 @@ static void maildirsize_recalculate_init(struct maildir_quota_root *root)
 }
 
 static int maildirsize_recalculate_namespace(struct maildir_quota_root *root,
-                                            struct mail_namespace *ns)
+                                            struct mail_namespace *ns,
+                                            const char **error_r)
 {
        struct maildir_list_context *ctx;
        const char *dir;
@@ -332,10 +340,10 @@ static int maildirsize_recalculate_namespace(struct maildir_quota_root *root,
                        root->recalc_last_stamp = mtime;
 
                if (maildir_sum_dir(dir, &root->total_bytes,
-                                   &root->total_count) < 0)
+                                   &root->total_count, error_r) < 0)
                        ret = -1;
        }
-       if (maildir_list_deinit(ctx) < 0)
+       if (maildir_list_deinit(ctx, error_r) < 0)
                ret = -1;
 
        return ret;
@@ -366,7 +374,8 @@ static int maildirsize_recalculate_finish(struct maildir_quota_root *root,
        return ret;
 }
 
-static int maildirsize_recalculate(struct maildir_quota_root *root)
+static int maildirsize_recalculate(struct maildir_quota_root *root,
+                                  const char **error_r)
 {
        struct mail_namespace *const *namespaces;
        unsigned int i, count;
@@ -380,7 +389,7 @@ static int maildirsize_recalculate(struct maildir_quota_root *root)
                if (!quota_root_is_namespace_visible(&root->root, namespaces[i]))
                        continue;
 
-               if (maildirsize_recalculate_namespace(root, namespaces[i]) < 0) {
+               if (maildirsize_recalculate_namespace(root, namespaces[i], error_r) < 0) {
                        ret = -1;
                        break;
                }
@@ -394,7 +403,8 @@ static int maildirsize_recalculate(struct maildir_quota_root *root)
                                continue;
 
                        ret = maildirs_check_have_changed(root, namespaces[i],
-                                               root->recalc_last_stamp);
+                                               root->recalc_last_stamp,
+                                               error_r);
                        if (ret != 0)
                                break;
                }
@@ -518,7 +528,8 @@ static int maildirsize_parse(struct maildir_quota_root *root,
        return 1;
 }
 
-static int maildirsize_open(struct maildir_quota_root *root)
+static int maildirsize_open(struct maildir_quota_root *root,
+                           const char **error_r)
 {
        i_close_fd_path(&root->fd, root->maildirsize_path);
 
@@ -526,7 +537,8 @@ static int maildirsize_open(struct maildir_quota_root *root)
        if (root->fd == -1) {
                if (errno == ENOENT)
                        return 0;
-               i_error("open(%s) failed: %m", root->maildirsize_path);
+               *error_r = t_strdup_printf(
+                       "open(%s) failed: %m", root->maildirsize_path);
                return -1;
        }
        return 1;
@@ -553,7 +565,8 @@ static bool maildirsize_has_changed(struct maildir_quota_root *root)
                !CMP_DEV_T(st1.st_dev, st2.st_dev);
 }
 
-static int maildirsize_read(struct maildir_quota_root *root, bool *retry)
+static int maildirsize_read(struct maildir_quota_root *root, bool *retry,
+                           const char **error_r)
 {
        char buf[5120+1];
        unsigned int i, size;
@@ -565,7 +578,7 @@ static int maildirsize_read(struct maildir_quota_root *root, bool *retry)
        if (!maildirsize_has_changed(root))
                return 1;
 
-       if ((ret = maildirsize_open(root)) <= 0)
+       if ((ret = maildirsize_open(root, error_r)) <= 0)
                return ret;
 
        /* @UNSAFE */
@@ -576,7 +589,8 @@ static int maildirsize_read(struct maildir_quota_root *root, bool *retry)
                                *retry = TRUE;
                                break;
                        }
-                       i_error("read(%s) failed: %m", root->maildirsize_path);
+                       *error_r = t_strdup_printf(
+                               "read(%s) failed: %m", root->maildirsize_path);
                        break;
                }
                size += ret;
@@ -660,7 +674,8 @@ static bool maildirquota_limits_init(struct maildir_quota_root *root)
        return TRUE;
 }
 
-static int maildirquota_read_limits(struct maildir_quota_root *root)
+static int maildirquota_read_limits(struct maildir_quota_root *root,
+                                   const char **error_r)
 {
        bool retry = TRUE;
        int ret, n = 0;
@@ -671,20 +686,21 @@ static int maildirquota_read_limits(struct maildir_quota_root *root)
        do {
                if (n == NFS_ESTALE_RETRY_COUNT)
                        retry = FALSE;
-               ret = maildirsize_read(root, &retry);
+               ret = maildirsize_read(root, &retry, error_r);
                n++;
        } while (ret == -1 && retry);
        return ret;
 }
 
 static int
-maildirquota_refresh(struct maildir_quota_root *root, bool *recalculated_r)
+maildirquota_refresh(struct maildir_quota_root *root, bool *recalculated_r,
+                    const char **error_r)
 {
        int ret;
 
        *recalculated_r = FALSE;
 
-       ret = maildirquota_read_limits(root);
+       ret = maildirquota_read_limits(root, error_r);
        if (ret == 0) {
                if (root->root.bytes_limit == 0 &&
                    root->root.count_limit == 0 &&
@@ -697,7 +713,7 @@ maildirquota_refresh(struct maildir_quota_root *root, bool *recalculated_r)
                           updated even if it's not enforced. */
                }
 
-               ret = maildirsize_recalculate(root);
+               ret = maildirsize_recalculate(root, error_r);
                if (ret == 0)
                        *recalculated_r = TRUE;
        }
@@ -775,7 +791,9 @@ maildir_quota_parse_rule(struct quota_root_settings *root_set ATTR_UNUSED,
                bytes = 0;
                count = 0;
        } else if (!maildir_parse_limit(str, &bytes, &count)) {
-               *error_r = "Invalid Maildir++ quota rule";
+               *error_r = t_strdup_printf(
+                       "quota-maildir: Invalid Maildir++ quota rule \"%s\"",
+                       str);
                return FALSE;
        }
 
@@ -788,9 +806,11 @@ static int maildir_quota_init_limits(struct quota_root *_root,
                                     const char **error_r)
 {
        struct maildir_quota_root *root = (struct maildir_quota_root *)_root;
+       const char *error;
 
-       if (maildirquota_read_limits(root) < 0) {
-               *error_r = "Failed to read maildir quota limits";
+       if (maildirquota_read_limits(root, &error) < 0) {
+               *error_r = t_strdup_printf(
+                       "quota-maildir: Failed to read limits: %s", error);
                return -1;
        }
        return 0;
@@ -840,9 +860,11 @@ maildir_quota_get_resource(struct quota_root *_root, const char *name,
 {
        struct maildir_quota_root *root = (struct maildir_quota_root *)_root;
        bool recalculated;
+       const char *error;
 
-       if (maildirquota_refresh(root, &recalculated) < 0) {
-               *error_r = "quota-maildir failed";
+       if (maildirquota_refresh(root, &recalculated, &error) < 0) {
+               *error_r = t_strdup_printf(
+                       "quota-maildir: Failed to get %s: %s", name, error);
                return -1;
        }
 
@@ -862,6 +884,7 @@ maildir_quota_update(struct quota_root *_root,
 {
        struct maildir_quota_root *root = (struct maildir_quota_root *)_root;
        bool recalculated;
+       const char *error;
 
        if (!maildirquota_limits_init(root)) {
                /* no limits */
@@ -872,19 +895,23 @@ maildir_quota_update(struct quota_root *_root,
           we do want to make sure the header gets updated if the limits have
           changed. also this makes sure the maildirsize file is created if
           it doesn't exist. */
-       if (maildirquota_refresh(root, &recalculated) < 0) {
-               *error_r = "Failed to refresh maildir quota";
+       if (maildirquota_refresh(root, &recalculated, &error) < 0) {
+               *error_r = t_strdup_printf(
+                       "quota-maildir: Could not update storage usage data: %s",
+                       error);
                return -1;
        }
 
        if (recalculated) {
                /* quota was just recalculated and it already contains the changes
                   we wanted to do. */
-       } else if (root->fd == -1)
-               (void)maildirsize_recalculate(root);
-       else if (ctx->recalculate != QUOTA_RECALCULATE_DONT) {
+       } else if (root->fd == -1) {
+               if (maildirsize_recalculate(root, &error) < 0)
+                       i_error("quota-maildir: %s", error);
+       } else if (ctx->recalculate != QUOTA_RECALCULATE_DONT) {
                i_close_fd(&root->fd);
-               (void)maildirsize_recalculate(root);
+               if (maildirsize_recalculate(root, &error) < 0)
+                       i_error("quota-maildir: %s", error);
        } else if (maildirsize_update(root, ctx->count_used, ctx->bytes_used) < 0) {
                i_close_fd(&root->fd);
                maildirsize_rebuild_later(root);