diff -r 413dbb37b839 src/lib-storage/index/maildir/maildir-mail.c --- a/src/lib-storage/index/maildir/maildir-mail.c Tue Nov 20 04:56:00 2007 +0200 +++ b/src/lib-storage/index/maildir/maildir-mail.c Tue Nov 20 05:37:56 2007 +0200 @@ -43,6 +43,7 @@ maildir_open_mail(struct maildir_mailbox maildir_open_mail(struct maildir_mailbox *mbox, struct mail *mail, bool *deleted_r) { + struct index_mail *imail = (struct index_mail *)mail; const char *path; int fd = -1; @@ -60,6 +61,11 @@ maildir_open_mail(struct maildir_mailbox if (fd == -1) { *deleted_r = TRUE; return NULL; + } + + if ((imail->data.access_part & (READ_BODY|PARSE_BODY)) != 0) { + if (posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL) < 0) + i_error("posix_fadvise() failed: %m"); } return i_stream_create_fd(fd, MAIL_READ_BLOCK_SIZE, TRUE); @@ -386,8 +392,30 @@ static int maildir_mail_get_stream(struc return index_mail_init_stream(mail, hdr_size, body_size, stream_r); } +static void maildir_mail_close(struct mail *_mail) +{ + struct index_mail *mail = (struct index_mail *)_mail; + int fd; + + if (mail->data.stream != NULL && mail->data.stream->v_offset != 0) { + /* drop the data that has been read by the client. with partial + fetches we drop only what has been read so far. + + if we read the mail just to return e.g. virtual size or + bodystructure, v_offset=0 and we don't drop anything since + there's a good chance that the client will soon fetch the + mail body. */ + fd = i_stream_get_fd(mail->data.stream); + if (posix_fadvise(fd, 0, mail->data.stream->v_offset, + POSIX_FADV_DONTNEED) < 0) + i_error("posix_fadvise() failed: %m"); + } + + index_mail_close(_mail); +} + struct mail_vfuncs maildir_mail_vfuncs = { - index_mail_close, + maildir_mail_close, index_mail_free, index_mail_set_seq, index_mail_set_uid, diff -r 413dbb37b839 src/lib-storage/index/maildir/maildir-save.c --- a/src/lib-storage/index/maildir/maildir-save.c Tue Nov 20 04:56:00 2007 +0200 +++ b/src/lib-storage/index/maildir/maildir-save.c Tue Nov 20 05:37:56 2007 +0200 @@ -501,6 +501,13 @@ int maildir_save_finish(struct mail_save ctx->failed = TRUE; } } + if (ctx->cur_dest_mail != NULL && !ctx->mbox->ibox.keep_recent) { + /* if we're not running from deliver (assume so if + keep_recent=TRUE) and we updated cache file, it's unlikely + we're going to need this mail anytime soon */ + if (posix_fadvise(ctx->fd, 0, 0, POSIX_FADV_DONTNEED) < 0) + i_error("posix_fadvise() failed: %m"); + } if (close(ctx->fd) < 0) { mail_storage_set_critical(storage, "close(%s) failed: %m", path);