};
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;
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;
}
*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;
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);
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;
break;
}
}
- if (maildir_list_deinit(ctx) < 0)
+ if (maildir_list_deinit(ctx, error_r) < 0)
return -1;
return ret;
}
}
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;
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;
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;
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;
}
continue;
ret = maildirs_check_have_changed(root, namespaces[i],
- root->recalc_last_stamp);
+ root->recalc_last_stamp,
+ error_r);
if (ret != 0)
break;
}
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);
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;
!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;
if (!maildirsize_has_changed(root))
return 1;
- if ((ret = maildirsize_open(root)) <= 0)
+ if ((ret = maildirsize_open(root, error_r)) <= 0)
return ret;
/* @UNSAFE */
*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;
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;
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 &&
updated even if it's not enforced. */
}
- ret = maildirsize_recalculate(root);
+ ret = maildirsize_recalculate(root, error_r);
if (ret == 0)
*recalculated_r = TRUE;
}
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;
}
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;
{
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;
}
{
struct maildir_quota_root *root = (struct maildir_quota_root *)_root;
bool recalculated;
+ const char *error;
if (!maildirquota_limits_init(root)) {
/* no limits */
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);