Mercurial > dovecot > original-hg > dovecot-1.2
comparison src/lib-storage/index/maildir/maildir-sync.c @ 1956:d6941cd8afdc HEAD
Added support for setting dirty flags for messages (TODO: undirty..)
s/mail_index_record_flag/mail_cache_record_flag/
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 02 May 2004 22:24:35 +0300 |
parents | 0f0128b4af5d |
children | 4dec6a3d79fd |
comparison
equal
deleted
inserted
replaced
1955:0f0128b4af5d | 1956:d6941cd8afdc |
---|---|
193 int partial; | 193 int partial; |
194 | 194 |
195 struct maildir_uidlist_sync_ctx *uidlist_sync_ctx; | 195 struct maildir_uidlist_sync_ctx *uidlist_sync_ctx; |
196 }; | 196 }; |
197 | 197 |
198 struct maildir_index_sync_context { | |
199 struct index_mailbox *ibox; | |
200 struct mail_index_view *view; | |
201 struct mail_index_sync_ctx *sync_ctx; | |
202 | |
203 struct mail_index_sync_rec sync_rec; | |
204 uint32_t seq; | |
205 }; | |
206 | |
198 static int maildir_expunge(struct index_mailbox *ibox, const char *path, | 207 static int maildir_expunge(struct index_mailbox *ibox, const char *path, |
199 void *context __attr_unused__) | 208 void *context __attr_unused__) |
200 { | 209 { |
201 if (unlink(path) == 0) { | 210 if (unlink(path) == 0) { |
202 ibox->dirty_cur_time = ioloop_time; | 211 ibox->dirty_cur_time = ioloop_time; |
211 } | 220 } |
212 | 221 |
213 static int maildir_sync_flags(struct index_mailbox *ibox, const char *path, | 222 static int maildir_sync_flags(struct index_mailbox *ibox, const char *path, |
214 void *context) | 223 void *context) |
215 { | 224 { |
216 struct mail_index_sync_rec *syncrec = context; | 225 struct maildir_index_sync_context *ctx = context; |
217 const char *newpath; | 226 const char *newpath; |
218 enum mail_flags flags; | 227 enum mail_flags flags; |
219 uint8_t flags8; | 228 uint8_t flags8; |
220 custom_flags_mask_t custom_flags; | 229 custom_flags_mask_t custom_flags; |
221 | 230 |
222 (void)maildir_filename_get_flags(path, &flags, custom_flags); | 231 (void)maildir_filename_get_flags(path, &flags, custom_flags); |
223 | 232 |
224 flags8 = flags; | 233 flags8 = flags; |
225 mail_index_sync_flags_apply(syncrec, &flags8, custom_flags); | 234 mail_index_sync_flags_apply(&ctx->sync_rec, &flags8, custom_flags); |
226 | 235 |
227 newpath = maildir_filename_set_flags(path, flags8, custom_flags); | 236 newpath = maildir_filename_set_flags(path, flags8, custom_flags); |
228 if (rename(path, newpath) == 0) { | 237 if (rename(path, newpath) == 0) { |
229 ibox->dirty_cur_time = ioloop_time; | 238 ibox->dirty_cur_time = ioloop_time; |
230 return 1; | 239 return 1; |
231 } | 240 } |
232 if (errno == ENOENT) | 241 if (errno == ENOENT) |
233 return 0; | 242 return 0; |
234 | 243 |
244 if (ENOSPACE(errno)) { | |
245 if (mail_index_sync_set_dirty(ctx->sync_ctx, ctx->seq) < 0) | |
246 return -1; | |
247 return 1; | |
248 } | |
249 | |
235 mail_storage_set_critical(ibox->box.storage, | 250 mail_storage_set_critical(ibox->box.storage, |
236 "rename(%s, %s) failed: %m", path, newpath); | 251 "rename(%s, %s) failed: %m", path, newpath); |
237 return -1; | 252 return -1; |
238 } | 253 } |
239 | 254 |
240 static int maildir_sync_record(struct index_mailbox *ibox, | 255 static int maildir_sync_record(struct index_mailbox *ibox, |
241 struct mail_index_view *view, | 256 struct maildir_index_sync_context *ctx) |
242 struct mail_index_sync_rec *syncrec) | 257 { |
243 { | 258 struct mail_index_sync_rec *sync_rec = &ctx->sync_rec; |
259 struct mail_index_view *view = ctx->view; | |
244 uint32_t seq, uid; | 260 uint32_t seq, uid; |
245 | 261 |
246 switch (syncrec->type) { | 262 switch (sync_rec->type) { |
247 case MAIL_INDEX_SYNC_TYPE_APPEND: | 263 case MAIL_INDEX_SYNC_TYPE_APPEND: |
248 break; | 264 break; |
249 case MAIL_INDEX_SYNC_TYPE_EXPUNGE: | 265 case MAIL_INDEX_SYNC_TYPE_EXPUNGE: |
250 for (seq = syncrec->seq1; seq <= syncrec->seq2; seq++) { | 266 for (seq = sync_rec->seq1; seq <= sync_rec->seq2; seq++) { |
251 if (mail_index_lookup_uid(view, seq, &uid) < 0) | 267 if (mail_index_lookup_uid(view, seq, &uid) < 0) |
252 return -1; | 268 return -1; |
253 if (maildir_file_do(ibox, uid, maildir_expunge, | 269 if (maildir_file_do(ibox, uid, maildir_expunge, |
254 NULL) < 0) | 270 NULL) < 0) |
255 return -1; | 271 return -1; |
256 } | 272 } |
257 break; | 273 break; |
258 case MAIL_INDEX_SYNC_TYPE_FLAGS: | 274 case MAIL_INDEX_SYNC_TYPE_FLAGS: |
259 for (seq = syncrec->seq1; seq <= syncrec->seq2; seq++) { | 275 ctx->seq = sync_rec->seq1; |
260 if (mail_index_lookup_uid(view, seq, &uid) < 0) | 276 for (; ctx->seq <= sync_rec->seq2; ctx->seq++) { |
277 if (mail_index_lookup_uid(view, ctx->seq, &uid) < 0) | |
261 return -1; | 278 return -1; |
262 if (maildir_file_do(ibox, uid, maildir_sync_flags, | 279 if (maildir_file_do(ibox, uid, maildir_sync_flags, |
263 syncrec) < 0) | 280 ctx) < 0) |
264 return -1; | 281 return -1; |
265 } | 282 } |
266 break; | 283 break; |
267 } | 284 } |
268 | 285 |
269 return 0; | 286 return 0; |
270 } | 287 } |
271 | 288 |
272 int maildir_sync_last_commit(struct index_mailbox *ibox) | 289 int maildir_sync_last_commit(struct index_mailbox *ibox) |
273 { | 290 { |
274 struct mail_index_view *view; | 291 struct maildir_index_sync_context ctx; |
275 struct mail_index_sync_ctx *sync_ctx; | |
276 struct mail_index_sync_rec sync_rec; | |
277 int ret; | 292 int ret; |
278 | 293 |
279 if (ibox->commit_log_file_seq == 0) | 294 if (ibox->commit_log_file_seq == 0) |
280 return 0; | 295 return 0; |
281 | 296 |
282 ret = mail_index_sync_begin(ibox->index, &sync_ctx, &view, | 297 memset(&ctx, 0, sizeof(ctx)); |
298 ctx.ibox = ibox; | |
299 | |
300 ret = mail_index_sync_begin(ibox->index, &ctx.sync_ctx, &ctx.view, | |
283 ibox->commit_log_file_seq, | 301 ibox->commit_log_file_seq, |
284 ibox->commit_log_file_offset); | 302 ibox->commit_log_file_offset); |
285 if (ret > 0) { | 303 if (ret > 0) { |
286 while ((ret = mail_index_sync_next(sync_ctx, &sync_rec)) > 0) { | 304 while ((ret = mail_index_sync_next(ctx.sync_ctx, |
287 if (maildir_sync_record(ibox, view, &sync_rec) < 0) { | 305 &ctx.sync_rec)) > 0) { |
306 if (maildir_sync_record(ibox, &ctx) < 0) { | |
288 ret = -1; | 307 ret = -1; |
289 break; | 308 break; |
290 } | 309 } |
291 } | 310 } |
292 if (mail_index_sync_end(sync_ctx, 0, 0) < 0) | 311 if (mail_index_sync_end(ctx.sync_ctx, 0, 0) < 0) |
293 ret = -1; | 312 ret = -1; |
294 } | 313 } |
295 | 314 |
296 if (ret == 0) { | 315 if (ret == 0) { |
297 ibox->commit_log_file_seq = 0; | 316 ibox->commit_log_file_seq = 0; |
474 } | 493 } |
475 | 494 |
476 static int maildir_sync_index(struct maildir_sync_context *ctx) | 495 static int maildir_sync_index(struct maildir_sync_context *ctx) |
477 { | 496 { |
478 struct index_mailbox *ibox = ctx->ibox; | 497 struct index_mailbox *ibox = ctx->ibox; |
479 struct mail_index_sync_ctx *sync_ctx; | 498 struct maildir_index_sync_context sync_ctx; |
480 struct mail_index_sync_rec sync_rec; | |
481 struct maildir_uidlist_iter_ctx *iter; | 499 struct maildir_uidlist_iter_ctx *iter; |
482 struct mail_index_transaction *trans; | 500 struct mail_index_transaction *trans; |
483 struct mail_index_view *view; | 501 struct mail_index_view *view; |
484 const struct mail_index_header *hdr; | 502 const struct mail_index_header *hdr; |
485 const struct mail_index_record *rec; | 503 const struct mail_index_record *rec; |
489 enum mail_flags flags; | 507 enum mail_flags flags; |
490 custom_flags_mask_t custom_flags; | 508 custom_flags_mask_t custom_flags; |
491 uint32_t sync_stamp; | 509 uint32_t sync_stamp; |
492 int ret; | 510 int ret; |
493 | 511 |
494 if (mail_index_sync_begin(ibox->index, &sync_ctx, &view, | 512 memset(&sync_ctx, 0, sizeof(sync_ctx)); |
513 sync_ctx.ibox = ibox; | |
514 | |
515 if (mail_index_sync_begin(ibox->index, &sync_ctx.sync_ctx, &view, | |
495 (uint32_t)-1, (uoff_t)-1) <= 0) { | 516 (uint32_t)-1, (uoff_t)-1) <= 0) { |
496 mail_storage_set_index_error(ibox); | 517 mail_storage_set_index_error(ibox); |
497 return -1; | 518 return -1; |
498 } | 519 } |
520 sync_ctx.view = view; | |
499 | 521 |
500 ret = mail_index_get_header(view, &hdr); | 522 ret = mail_index_get_header(view, &hdr); |
501 i_assert(ret == 0); /* view is locked, can't happen */ | 523 i_assert(ret == 0); /* view is locked, can't happen */ |
502 | 524 |
503 trans = mail_index_transaction_begin(view, FALSE); | 525 trans = mail_index_transaction_begin(view, FALSE); |
542 mail_index_mark_corrupted(ibox->index); | 564 mail_index_mark_corrupted(ibox->index); |
543 ret = -1; | 565 ret = -1; |
544 break; | 566 break; |
545 } | 567 } |
546 | 568 |
569 if ((rec->flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0) { | |
570 /* we haven't been able to update maildir with this | |
571 record's flag changes. don't sync them. */ | |
572 continue; | |
573 } | |
574 | |
547 maildir_filename_get_flags(filename, &flags, custom_flags); | 575 maildir_filename_get_flags(filename, &flags, custom_flags); |
548 if ((uint8_t)flags != (rec->flags & MAIL_FLAGS_MASK) || | 576 if ((uint8_t)flags != (rec->flags & MAIL_FLAGS_MASK) || |
549 memcmp(custom_flags, rec->custom_flags, | 577 memcmp(custom_flags, rec->custom_flags, |
550 INDEX_CUSTOM_FLAGS_BYTE_COUNT) != 0) { | 578 INDEX_CUSTOM_FLAGS_BYTE_COUNT) != 0) { |
551 mail_index_update_flags(trans, seq, MODIFY_REPLACE, | 579 mail_index_update_flags(trans, seq, MODIFY_REPLACE, |
573 ibox->commit_log_file_offset = offset; | 601 ibox->commit_log_file_offset = offset; |
574 } | 602 } |
575 } | 603 } |
576 | 604 |
577 /* now, sync the index */ | 605 /* now, sync the index */ |
578 while ((ret = mail_index_sync_next(sync_ctx, &sync_rec)) > 0) { | 606 while ((ret = mail_index_sync_next(sync_ctx.sync_ctx, |
579 if (maildir_sync_record(ibox, view, &sync_rec) < 0) { | 607 &sync_ctx.sync_rec)) > 0) { |
608 if (maildir_sync_record(ibox, &sync_ctx) < 0) { | |
580 ret = -1; | 609 ret = -1; |
581 break; | 610 break; |
582 } | 611 } |
583 } | 612 } |
584 | 613 |
585 sync_stamp = ibox->dirty_cur_time != 0 ? 0 : ibox->last_cur_mtime; | 614 sync_stamp = ibox->dirty_cur_time != 0 ? 0 : ibox->last_cur_mtime; |
586 if (mail_index_sync_end(sync_ctx, sync_stamp, 0) < 0) | 615 if (mail_index_sync_end(sync_ctx.sync_ctx, sync_stamp, 0) < 0) |
587 ret = -1; | 616 ret = -1; |
588 | 617 |
589 if (ret == 0) { | 618 if (ret == 0) { |
590 ibox->commit_log_file_seq = 0; | 619 ibox->commit_log_file_seq = 0; |
591 ibox->commit_log_file_offset = 0; | 620 ibox->commit_log_file_offset = 0; |