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;