From: Timo Sirainen Date: Tue, 24 Feb 2009 23:12:32 +0000 (-0500) Subject: o_stream_send_istream(): Don't do backwards copying if the area doesn't really overlap. X-Git-Tag: 2.0.alpha1~1038^2~81 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=52b34f874a22615c67a9e1a1ee1679153559e377;p=thirdparty%2Fdovecot%2Fcore.git o_stream_send_istream(): Don't do backwards copying if the area doesn't really overlap. --HG-- branch : HEAD --- diff --git a/src/lib/ostream-file.c b/src/lib/ostream-file.c index 6f94563381..187648a5cb 100644 --- a/src/lib/ostream-file.c +++ b/src/lib/ostream-file.c @@ -776,7 +776,7 @@ static off_t o_stream_file_send_istream(struct ostream_private *outstream, { struct file_ostream *foutstream = (struct file_ostream *)outstream; const struct stat *st; - off_t ret; + off_t in_abs_offset, ret; int in_fd; in_fd = i_stream_get_fd(instream); @@ -791,16 +791,17 @@ static off_t o_stream_file_send_istream(struct ostream_private *outstream, } i_assert(instream->v_offset <= (uoff_t)st->st_size); - ret = (off_t)outstream->ostream.offset - - (off_t)(instream->real_stream->abs_start_offset + - instream->v_offset); + in_abs_offset = instream->real_stream->abs_start_offset + + instream->v_offset; + ret = (off_t)outstream->ostream.offset - in_abs_offset; if (ret == 0) { /* copying data over itself. we don't really need to do that, just fake it. */ return st->st_size - instream->v_offset; } - if (ret > 0) { + if (ret > 0 && st->st_size > ret) { /* overlapping */ + i_assert(instream->seekable); return io_stream_copy_backwards(outstream, instream, st->st_size); }