uint64_t bytes_before, uint64_t bytes_current,
uint64_t count_before, uint64_t count_current);
bool quota_transaction_is_over(struct quota_transaction_context *ctx, uoff_t size);
+int quota_transaction_set_limits(struct quota_transaction_context *ctx);
#endif
}
ctx->dest_mail = qt->tmp_mail;
}
+ /* get quota before copying any mails. this avoids .vsize.lock
+ deadlocks with backends that lock mails for expunging/copying. */
+ (void)quota_transaction_set_limits(qt);
if (qbox->module_ctx.super.copy(ctx, mail) < 0)
return -1;
}
ctx->dest_mail = qt->tmp_mail;
}
+ /* get quota before copying any mails. this avoids .vsize.lock
+ deadlocks with backends that lock mails for expunging/copying. */
+ (void)quota_transaction_set_limits(qt);
return qbox->module_ctx.super.save_begin(ctx, input);
}
return ctx;
}
-static int quota_transaction_set_limits(struct quota_transaction_context *ctx)
+int quota_transaction_set_limits(struct quota_transaction_context *ctx)
{
struct quota_root *const *roots;
const char *mailbox_name;
bool use_grace, ignored;
int ret;
+ if (ctx->limits_set)
+ return 0;
ctx->limits_set = TRUE;
mailbox_name = mailbox_get_vname(ctx->box);
/* use quota_grace only for LDA/LMTP */
uoff_t size;
int ret;
- if (!ctx->limits_set) {
- if (quota_transaction_set_limits(ctx) < 0)
- return -1;
- }
+ if (quota_transaction_set_limits(ctx) < 0)
+ return -1;
if (ctx->no_quota_updates)
return 1;
if (ctx->failed)
return -1;
- if (!ctx->limits_set) {
- if (quota_transaction_set_limits(ctx) < 0)
- return -1;
- }
+ if (quota_transaction_set_limits(ctx) < 0)
+ return -1;
if (ctx->no_quota_updates)
return 1;
/* this is a virtual function mainly for trash plugin and similar,