comparison src/plugins/trash/trash-plugin.c @ 5158:aa9b1fec1c21 HEAD

Although messages were expunged, the expunges weren't counted in that same transaction and the APPEND failed.
author Timo Sirainen <tss@iki.fi>
date Fri, 16 Feb 2007 20:31:33 +0200
parents df22aec605b7
children 24f4a959a24c
comparison
equal deleted inserted replaced
5157:df22aec605b7 5158:aa9b1fec1c21
88 88
89 *received_time_r = mail_get_received_date(trash->mail); 89 *received_time_r = mail_get_received_date(trash->mail);
90 return 1; 90 return 1;
91 } 91 }
92 92
93 static int trash_try_clean_mails(uint64_t size_needed) 93 static int trash_try_clean_mails(struct quota_transaction_context *ctx,
94 uint64_t size_needed)
94 { 95 {
95 struct trash_mailbox *trashes; 96 struct trash_mailbox *trashes;
96 unsigned int i, j, count, oldest_idx; 97 unsigned int i, j, count, oldest_idx;
97 time_t oldest, received; 98 time_t oldest, received;
98 uint64_t size; 99 uint64_t size, size_expunged = 0, expunged_count = 0;
99 int ret = 0; 100 int ret = 0;
100 101
101 trashes = array_get_modifiable(&trash_boxes, &count); 102 trashes = array_get_modifiable(&trash_boxes, &count);
102 for (i = 0; i < count; ) { 103 for (i = 0; i < count; ) {
103 if (trashes[i].storage == NULL) { 104 if (trashes[i].storage == NULL) {
128 } 129 }
129 } 130 }
130 } 131 }
131 132
132 if (oldest_idx < count) { 133 if (oldest_idx < count) {
134 size = mail_get_physical_size(trashes[oldest_idx].mail);
135 if (size == (uoff_t)-1) {
136 /* maybe expunged already? */
137 trashes[oldest_idx].mail_set = FALSE;
138 continue;
139 }
140
133 if (mail_expunge(trashes[oldest_idx].mail) < 0) 141 if (mail_expunge(trashes[oldest_idx].mail) < 0)
134 break; 142 break;
135 143
136 size = mail_get_physical_size(trashes[oldest_idx].mail); 144 expunged_count++;
137 if (size >= size_needed) { 145 size_expunged += size;
138 size_needed = 0; 146 if (size_expunged >= size_needed)
139 break; 147 break;
140 }
141 trashes[oldest_idx].mail_set = FALSE; 148 trashes[oldest_idx].mail_set = FALSE;
142
143 size_needed -= size;
144 } else { 149 } else {
145 /* find more mails from next priority's mailbox */ 150 /* find more mails from next priority's mailbox */
146 i = j; 151 i = j;
147 } 152 }
148 } 153 }
156 161
157 trash->mail_set = FALSE; 162 trash->mail_set = FALSE;
158 mail_free(&trash->mail); 163 mail_free(&trash->mail);
159 (void)mailbox_search_deinit(&trash->search_ctx); 164 (void)mailbox_search_deinit(&trash->search_ctx);
160 165
161 if (size_needed == 0) { 166 if (size_expunged >= size_needed) {
162 (void)mailbox_transaction_commit(&trash->trans, 167 (void)mailbox_transaction_commit(&trash->trans,
163 MAILBOX_SYNC_FLAG_FULL_WRITE); 168 MAILBOX_SYNC_FLAG_FULL_WRITE);
164 } else { 169 } else {
165 /* couldn't get enough space, don't expunge anything */ 170 /* couldn't get enough space, don't expunge anything */
166 mailbox_transaction_rollback(&trash->trans); 171 mailbox_transaction_rollback(&trash->trans);
167 } 172 }
168 173
169 mailbox_close(&trash->box); 174 mailbox_close(&trash->box);
170 } 175 }
171 return size_needed == 0; 176
177 if (size_expunged < size_needed)
178 return FALSE;
179
180 ctx->bytes_used = ctx->bytes_used > (int64_t)size_expunged ?
181 ctx->bytes_used - size_expunged : 0;
182 ctx->count_used = ctx->count_used > (int64_t)expunged_count ?
183 ctx->count_used - expunged_count : 0;
184 return TRUE;
172 } 185 }
173 186
174 static int 187 static int
175 trash_quota_test_alloc(struct quota_transaction_context *ctx, 188 trash_quota_test_alloc(struct quota_transaction_context *ctx,
176 uoff_t size, bool *too_large_r) 189 uoff_t size, bool *too_large_r)
189 that was needed.. */ 202 that was needed.. */
190 break; 203 break;
191 } 204 }
192 205
193 /* not enough space. try deleting some from mailbox. */ 206 /* not enough space. try deleting some from mailbox. */
194 ret = trash_try_clean_mails(size); 207 ret = trash_try_clean_mails(ctx, size);
195 if (ret <= 0) 208 if (ret <= 0)
196 return 0; 209 return 0;
197 } 210 }
198 211
199 return 0; 212 return 0;