]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added i_stream_get_size(). Use it instead of i_stream_stat() where possible.
authorTimo Sirainen <tss@iki.fi>
Wed, 25 Feb 2009 02:13:29 +0000 (21:13 -0500)
committerTimo Sirainen <tss@iki.fi>
Wed, 25 Feb 2009 02:13:29 +0000 (21:13 -0500)
--HG--
branch : HEAD

src/lib-storage/index/mbox/mbox-sync.c
src/lib/istream-internal.h
src/lib/istream-limit.c
src/lib/istream.c
src/lib/istream.h
src/plugins/quota/quota-storage.c

index 4ae5c99657cecbab932a915c18bf505725dfc4b2..7781e9ec22d74c09a35bf5202a39182c21a7f14e 100644 (file)
@@ -866,22 +866,24 @@ mbox_sync_seek_to_uid(struct mbox_sync_context *sync_ctx, uint32_t uid)
 {
        struct mail_index_view *sync_view = sync_ctx->sync_view;
        uint32_t seq1, seq2;
-       const struct stat *st;
+       uoff_t size;
+       int ret;
 
        i_assert(!sync_ctx->index_reset);
 
        if (!mail_index_lookup_seq_range(sync_view, uid, (uint32_t)-1,
                                         &seq1, &seq2)) {
                /* doesn't exist anymore, seek to end of file */
-               st = i_stream_stat(sync_ctx->file_input, TRUE);
-               if (st == NULL) {
+               ret = i_stream_get_size(sync_ctx->file_input, TRUE, &size);
+               if (ret < 0) {
                        mbox_set_syscall_error(sync_ctx->mbox,
-                                              "i_stream_stat()");
+                                              "i_stream_get_size()");
                        return -1;
                }
+               i_assert(ret != 0);
 
                if (istream_raw_mbox_seek(sync_ctx->mbox->mbox_stream,
-                                         st->st_size) < 0) {
+                                         size) < 0) {
                        mbox_sync_set_critical(sync_ctx,
                                "Error seeking to end of mbox file %s",
                                sync_ctx->mbox->path);
@@ -1218,8 +1220,8 @@ static int mbox_write_pseudo(struct mbox_sync_context *sync_ctx)
 static int mbox_sync_handle_eof_updates(struct mbox_sync_context *sync_ctx,
                                        struct mbox_sync_mail_context *mail_ctx)
 {
-       const struct stat *st;
        uoff_t file_size, offset, padding, trailer_size;
+       int ret;
 
        if (!istream_raw_mbox_is_eof(sync_ctx->input)) {
                i_assert(sync_ctx->need_space_seq == 0);
@@ -1227,17 +1229,16 @@ static int mbox_sync_handle_eof_updates(struct mbox_sync_context *sync_ctx,
                return 0;
        }
 
-       st = i_stream_stat(sync_ctx->file_input, TRUE);
-       if (st == NULL) {
-               mbox_set_syscall_error(sync_ctx->mbox, "i_stream_stat()");
+       ret = i_stream_get_size(sync_ctx->file_input, TRUE, &file_size);
+       if (ret < 0) {
+               mbox_set_syscall_error(sync_ctx->mbox, "i_stream_get_size()");
                return -1;
        }
-       if (st->st_size < 0) {
+       if (ret == 0) {
                /* Not a file - allow anyway */
                return 0;
        }
 
-       file_size = st->st_size;
        if (file_size < sync_ctx->file_input->v_offset) {
                mbox_sync_set_critical(sync_ctx,
                        "file size unexpectedly shrank in mbox file %s "
index e075debc81d0354852bfc0539b2f311883a41b4a..f5f27aa41ff6aa2c2b4f85a9ca822debfea7ef21 100644 (file)
@@ -16,6 +16,7 @@ struct istream_private {
                     uoff_t v_offset, bool mark);
        void (*sync)(struct istream_private *stream);
        const struct stat *(*stat)(struct istream_private *stream, bool exact);
+       int (*get_size)(struct istream_private *stream, bool exact, uoff_t *size_r);
 
 /* data: */
        struct istream istream;
index 454446726740a335fa8234f5ccc45c9e72f09c6a..cc59e0f8f7e425a67890f659fc7f601ed201d4d5 100644 (file)
@@ -112,6 +112,27 @@ i_stream_limit_stat(struct istream_private *stream, bool exact)
        return &stream->statbuf;
 }
 
+static int i_stream_limit_get_size(struct istream_private *stream,
+                                  bool exact, uoff_t *size_r)
+{
+       struct limit_istream *lstream = (struct limit_istream *) stream;
+       const struct stat *st;
+
+       if (lstream->v_size != (uoff_t)-1) {
+               *size_r = lstream->v_size;
+               return 1;
+       }
+
+       st = i_stream_stat(&stream->istream, exact);
+       if (st == NULL)
+               return -1;
+       if (st->st_size == -1)
+               return 0;
+
+       *size_r = st->st_size;
+       return 1;
+}
+
 struct istream *i_stream_create_limit(struct istream *input, uoff_t v_size)
 {
        struct limit_istream *lstream;
@@ -130,6 +151,7 @@ struct istream *i_stream_create_limit(struct istream *input, uoff_t v_size)
        lstream->istream.read = i_stream_limit_read;
        lstream->istream.seek = i_stream_limit_seek;
        lstream->istream.stat = i_stream_limit_stat;
+       lstream->istream.get_size = i_stream_limit_get_size;
 
        lstream->istream.istream.blocking = input->blocking;
        lstream->istream.istream.seekable = input->seekable;
index cf8b7a0cd3f6eea8bb71d03741a8e4ef327dc784..413cae1be3987636c897014199d50b694603e157 100644 (file)
@@ -191,6 +191,16 @@ const struct stat *i_stream_stat(struct istream *stream, bool exact)
        return _stream->stat(_stream, exact);
 }
 
+int i_stream_get_size(struct istream *stream, bool exact, uoff_t *size_r)
+{
+       struct istream_private *_stream = stream->real_stream;
+
+       if (unlikely(stream->closed))
+               return -1;
+
+       return _stream->get_size(_stream, exact, size_r);
+}
+
 bool i_stream_have_bytes_left(const struct istream *stream)
 {
        const struct istream_private *_stream = stream->real_stream;
@@ -429,6 +439,22 @@ i_stream_default_stat(struct istream_private *stream, bool exact ATTR_UNUSED)
        return &stream->statbuf;
 }
 
+static int
+i_stream_default_get_size(struct istream_private *stream,
+                         bool exact, uoff_t *size_r)
+{
+       const struct stat *st;
+
+       st = stream->stat(stream, exact);
+       if (st == NULL)
+               return -1;
+       if (st->st_size == -1)
+               return 0;
+
+       *size_r = st->st_size;
+       return 1;
+}
+
 struct istream *
 i_stream_create(struct istream_private *_stream, struct istream *parent, int fd)
 {
@@ -443,6 +469,8 @@ i_stream_create(struct istream_private *_stream, struct istream *parent, int fd)
 
        if (_stream->stat == NULL)
                _stream->stat = i_stream_default_stat;
+       if (_stream->get_size == NULL)
+               _stream->get_size = i_stream_default_get_size;
        if (_stream->iostream.set_max_buffer_size == NULL) {
                _stream->iostream.set_max_buffer_size =
                        i_stream_default_set_max_buffer_size;
index a48de15fbaa5f315fbb02262f7b284b728403683..607ebf01691eac5c2cc0ebf5565d40827aa1a51e 100644 (file)
@@ -82,6 +82,9 @@ void i_stream_seek_mark(struct istream *stream, uoff_t v_offset);
    returned values can be compared to see if anything had changed (eg. in
    compressed stream st_size could be compressed size) */
 const struct stat *i_stream_stat(struct istream *stream, bool exact);
+/* Similar to i_stream_stat() call. Returns 1 if size was successfully
+   set, 0 if size is unknown, -1 if error. */
+int i_stream_get_size(struct istream *stream, bool exact, uoff_t *size_r);
 /* Returns TRUE if there are any bytes left to be read or in buffer. */
 bool i_stream_have_bytes_left(const struct istream *stream) ATTR_PURE;
 
index fa68242c35604bbd226de0b8d8b971eed259c89b..3a5769178146cd1b6d2f31fa48e1bf87d484ab4f 100644 (file)
@@ -200,11 +200,10 @@ quota_save_begin(struct mail_save_context *ctx, struct istream *input)
        struct mailbox_transaction_context *t = ctx->transaction;
        struct quota_transaction_context *qt = QUOTA_CONTEXT(t);
        struct quota_mailbox *qbox = QUOTA_CONTEXT(t->box);
-       const struct stat *st;
+       uoff_t size;
        int ret;
 
-       st = i_stream_stat(input, TRUE);
-       if (st != NULL && st->st_size != -1) {
+       if (i_stream_get_size(input, TRUE, &size) > 0) {
                /* Input size is known, check for quota immediately. This
                   check isn't perfect, especially because input stream's
                   linefeeds may contain CR+LFs while physical message would
@@ -216,7 +215,7 @@ quota_save_begin(struct mail_save_context *ctx, struct istream *input)
                   full mail. */
                bool too_large;
 
-               ret = quota_test_alloc(qt, st->st_size, &too_large);
+               ret = quota_test_alloc(qt, size, &too_large);
                if (ret == 0) {
                        mail_storage_set_error(t->box->storage,
                                MAIL_ERROR_NOSPACE,