]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-fs: posix fs backend now closes the fd after reads are finished.
authorTimo Sirainen <tss@iki.fi>
Sun, 7 Apr 2013 20:26:52 +0000 (23:26 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 7 Apr 2013 20:26:52 +0000 (23:26 +0300)
This allows keeping more fs_file structs open than there are available fds.

src/lib-fs/fs-posix.c

index 4e66825e02902a1662ad8ef40ebbcfb60b0d871e..04ffd05949c113885bef5d889e26585038b33fbe 100644 (file)
@@ -252,6 +252,16 @@ fs_posix_file_init(struct fs *_fs, const char *path,
        return &file->file;
 }
 
+static void fs_posix_file_close(struct posix_fs_file *file)
+{
+       if (file->fd != -1 && file->file.output == NULL) {
+               if (close(file->fd) < 0) {
+                       fs_set_critical(file->file.fs, "close(%s) failed: %m",
+                                       file->file.path);
+               }
+       }
+}
+
 static void fs_posix_file_deinit(struct fs_file *_file)
 {
        struct posix_fs_file *file = (struct posix_fs_file *)_file;
@@ -275,12 +285,7 @@ static void fs_posix_file_deinit(struct fs_file *_file)
                break;
        }
 
-       if (file->fd != -1) {
-               if (close(file->fd) < 0) {
-                       fs_set_critical(_file->fs, "close(%s) failed: %m",
-                                       _file->path);
-               }
-       }
+       fs_posix_file_close(file);
        i_free(file->temp_path);
        i_free(file->file.path);
        i_free(file);
@@ -327,6 +332,7 @@ static ssize_t fs_posix_read(struct fs_file *_file, void *buf, size_t size)
        ret = read(file->fd, buf, size);
        if (ret < 0)
                fs_set_error(_file->fs, "read(%s) failed: %m", _file->path);
+       fs_posix_file_close(file);
        return ret;
 }
 
@@ -336,14 +342,14 @@ fs_posix_read_stream(struct fs_file *_file, size_t max_buffer_size)
        struct posix_fs_file *file = (struct posix_fs_file *)_file;
        struct istream *input;
 
-       if (file->fd == -1) {
-               if (fs_posix_open(file) < 0) {
-                       input = i_stream_create_error(errno);
-                       i_stream_set_name(input, _file->path);
-                       return input;
-               }
+       if (file->fd == -1 && fs_posix_open(file) < 0) {
+               input = i_stream_create_error(errno);
+               i_stream_set_name(input, _file->path);
+       } else {
+               input = i_stream_create_fd(file->fd, max_buffer_size, FALSE);
        }
-       return i_stream_create_fd(file->fd, max_buffer_size, FALSE);
+       i_stream_add_destroy_callback(input, fs_posix_file_close, file);
+       return input;
 }
 
 static int fs_posix_write_finish(struct posix_fs_file *file)