From d478ab951593086a7c935bda3ecd9aefa38b2a52 Mon Sep 17 00:00:00 2001 From: Maurus Decimus <11444311+mdecimus@users.noreply.github.com> Date: Mon, 4 May 2026 19:23:19 +0200 Subject: [PATCH] Fix quota: Include Sieve scripts in quota recalculations --- CHANGELOG.md | 1 + crates/common/src/storage/quota.rs | 4 ++-- crates/jmap/src/quota/get.rs | 2 +- crates/services/src/task_manager/maintenance.rs | 5 +++++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a490f99d..b4c457c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If - Import tool fails to restore registry entries. - FDB: Allow multiple FoundationDB instances in the same process. - Autoconfig: Return `%EMAILADDRESS%` when no email address is provided. +- Quota: Include Sieve scripts in quota recalculations. ## [0.16.3] - 2026-04-30 diff --git a/crates/common/src/storage/quota.rs b/crates/common/src/storage/quota.rs index 2b9af10d..b2223f4b 100644 --- a/crates/common/src/storage/quota.rs +++ b/crates/common/src/storage/quota.rs @@ -55,7 +55,7 @@ impl Server { item_size: u64, ) -> trc::Result<()> { if account.quota_disk != 0 { - let used_quota = self.get_used_quota_account(account.id).await? as u64; + let used_quota = self.get_used_quota_account(account.id).await?.max(0) as u64; if used_quota + item_size > account.quota_disk { return Err(trc::LimitEvent::Quota @@ -76,7 +76,7 @@ impl Server { let tenant = self.tenant(tenant_id).await.caused_by(trc::location!())?; if tenant.quota_disk != 0 { - let used_quota = self.get_used_quota_tenant(tenant_id).await? as u64; + let used_quota = self.get_used_quota_tenant(tenant_id).await?.max(0) as u64; if used_quota + item_size > tenant.quota_disk { return Err(trc::LimitEvent::TenantQuota diff --git a/crates/jmap/src/quota/get.rs b/crates/jmap/src/quota/get.rs index 475292f7..d4a1f89f 100644 --- a/crates/jmap/src/quota/get.rs +++ b/crates/jmap/src/quota/get.rs @@ -81,7 +81,7 @@ impl QuotaGet for Server { QuotaProperty::Id => Value::Element(id.into()), QuotaProperty::ResourceType => "octets".to_string().into(), QuotaProperty::Used => { - (self.get_used_quota_account(account_id).await? as u64).into() + (self.get_used_quota_account(account_id).await?.max(0) as u64).into() } QuotaProperty::HardLimit => account.as_ref().disk_quota().into(), QuotaProperty::Scope => "account".to_string().into(), diff --git a/crates/services/src/task_manager/maintenance.rs b/crates/services/src/task_manager/maintenance.rs index 66b833aa..08fc5af9 100644 --- a/crates/services/src/task_manager/maintenance.rs +++ b/crates/services/src/task_manager/maintenance.rs @@ -20,6 +20,7 @@ use common::{ use email::{ cache::MessageCacheFetch, message::{delete::EmailDeletion, ingest::EmailIngest, metadata::MessageData}, + sieve::SieveScript, }; use groupware::{ calendar::{Calendar, CalendarEvent, CalendarEventNotification}, @@ -450,6 +451,7 @@ async fn recalculate_quota(server: &Server, account_id: u32) -> trc::Result<()> Collection::AddressBook, Collection::ContactCard, Collection::FileNode, + Collection::SieveScript, ] { server .archives(account_id, collection, &(), |_, archive| { @@ -475,6 +477,9 @@ async fn recalculate_quota(server: &Server, account_id: u32) -> trc::Result<()> Collection::FileNode => { quota += archive.unarchive::()?.size() as i64; } + Collection::SieveScript => { + quota += u32::from(archive.unarchive::()?.size) as i64; + } _ => {} } Ok(true)