Lines Matching refs:file
1 /* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
257 struct fs_file *file;
264 file = fs->v.file_alloc();
265 file->fs = fs;
266 file->flags = mode_flags & ~FS_OPEN_MODE_MASK;
267 file->event = fs_create_event(fs, event);
268 fs->v.file_init(file, path, mode_flags & FS_OPEN_MODE_MASK,
273 DLLIST_PREPEND(&fs->files, file);
275 fs_set_metadata(file, FS_METADATA_ORIG_PATH, path);
276 return file;
281 struct fs_file *file = *_file;
282 struct event *event = file->event;
283 pool_t metadata_pool = file->metadata_pool;
285 i_assert(file->fs->files_open_count > 0);
289 fs_file_close(file);
291 DLLIST_REMOVE(&file->fs->files, file);
292 file->fs->files_open_count--;
294 file->fs->v.file_deinit(file);
302 void fs_file_close(struct fs_file *file)
304 i_assert(!file->writing_stream);
305 i_assert(file->output == NULL);
307 if (file->pending_read_input != NULL)
308 i_stream_unref(&file->pending_read_input);
309 if (file->seekable_input != NULL)
310 i_stream_unref(&file->seekable_input);
312 if (file->copy_input != NULL) {
313 i_stream_unref(&file->copy_input);
314 fs_write_stream_abort_error(file, &file->copy_output, "fs_file_close(%s)",
315 o_stream_get_name(file->copy_output));
317 i_free_and_null(file->write_digest);
318 if (file->fs->v.file_close != NULL) T_BEGIN {
319 file->fs->v.file_close(file);
325 i_assert(!file->istream_open);
333 void fs_metadata_init(struct fs_file *file)
335 if (file->metadata_pool == NULL) {
336 i_assert(!array_is_created(&file->metadata));
337 file->metadata_pool = pool_alloconly_create("fs metadata", 1024);
338 p_array_init(&file->metadata, file->metadata_pool, 8);
342 void fs_metadata_init_or_clear(struct fs_file *file)
344 if (file->metadata_pool == NULL)
345 fs_metadata_init(file);
351 array_foreach(&file->metadata, md) {
356 array_clear(&file->metadata);
357 array_append_array(&file->metadata, &internal_metadata);
374 void fs_default_set_metadata(struct fs_file *file,
379 fs_metadata_init(file);
380 metadata = fs_metadata_find_md(&file->metadata, key);
382 metadata = array_append_space(&file->metadata);
383 metadata->key = p_strdup(file->metadata_pool, key);
385 metadata->value = p_strdup(file->metadata_pool, value);
400 void fs_set_metadata(struct fs_file *file, const char *key, const char *value)
405 if (file->fs->v.set_metadata != NULL) T_BEGIN {
406 file->fs->v.set_metadata(file, key, value);
411 file->metadata_changed = TRUE;
416 static void fs_file_timing_start(struct fs_file *file, enum fs_op op)
418 if (!file->fs->set.enable_timing)
420 if (file->timing_start[op].tv_sec == 0) {
421 if (gettimeofday(&file->timing_start[op], NULL) < 0)
443 void fs_file_timing_end(struct fs_file *file, enum fs_op op)
445 if (!file->fs->set.enable_timing || file->timing_start[op].tv_sec == 0)
448 fs_timing_end(&file->fs->stats.timings[op], &file->timing_start[op]);
450 file->timing_start[op].tv_sec = 0;
453 int fs_get_metadata(struct fs_file *file,
458 if (file->fs->v.get_metadata == NULL) {
459 fs_set_error(file->fs, "Metadata not supported by backend");
462 if (!file->read_or_prefetch_counted &&
463 !file->lookup_metadata_counted) {
464 file->lookup_metadata_counted = TRUE;
465 file->fs->stats.lookup_metadata_count++;
466 fs_file_timing_start(file, FS_OP_METADATA);
469 ret = file->fs->v.get_metadata(file, metadata_r);
472 fs_file_timing_end(file, FS_OP_METADATA);
476 int fs_lookup_metadata(struct fs_file *file, const char *key,
481 if (fs_get_metadata(file, &metadata) < 0)
487 const char *fs_file_path(struct fs_file *file)
489 return file->fs->v.get_path == NULL ? file->path :
490 file->fs->v.get_path(file);
493 struct fs *fs_file_fs(struct fs_file *file)
495 return file->fs;
498 struct event *fs_file_event(struct fs_file *file)
500 return file->event;
526 const char *fs_file_last_error(struct fs_file *file)
528 return fs_last_error(file->fs);
531 bool fs_prefetch(struct fs_file *file, uoff_t length)
535 if (!file->read_or_prefetch_counted) {
536 file->read_or_prefetch_counted = TRUE;
537 file->fs->stats.prefetch_count++;
538 fs_file_timing_start(file, FS_OP_PREFETCH);
541 ret = file->fs->v.prefetch(file, length);
543 fs_file_timing_end(file, FS_OP_PREFETCH);
547 ssize_t fs_read_via_stream(struct fs_file *file, void *buf, size_t size)
555 if (file->pending_read_input == NULL)
556 file->pending_read_input = fs_read_stream(file, size+1);
557 ret = i_stream_read_bytes(file->pending_read_input, &data,
560 fs_set_error_async(file->fs);
563 if (ret < 0 && file->pending_read_input->stream_errno != 0) {
564 fs_set_error(file->fs, "read(%s) failed: %s",
565 i_stream_get_name(file->pending_read_input),
566 i_stream_get_error(file->pending_read_input));
571 i_stream_unref(&file->pending_read_input);
575 ssize_t fs_read(struct fs_file *file, void *buf, size_t size)
579 if (!file->read_or_prefetch_counted) {
580 file->read_or_prefetch_counted = TRUE;
581 file->fs->stats.read_count++;
582 fs_file_timing_start(file, FS_OP_READ);
585 if (file->fs->v.read != NULL) {
587 ret = file->fs->v.read(file, buf, size);
590 fs_file_timing_end(file, FS_OP_READ);
596 return fs_read_via_stream(file, buf, size);
599 static void fs_file_istream_destroyed(struct fs_file *file)
601 i_assert(file->istream_open);
603 file->istream_open = FALSE;
606 struct istream *fs_read_stream(struct fs_file *file, size_t max_buffer_size)
614 if (!file->read_or_prefetch_counted) {
615 file->read_or_prefetch_counted = TRUE;
616 file->fs->stats.read_count++;
617 fs_file_timing_start(file, FS_OP_READ);
620 if (file->seekable_input != NULL) {
622 input = i_stream_create_limit(file->seekable_input, (uoff_t)-1);
626 i_assert(!file->istream_open);
628 input = file->fs->v.read_stream(file, max_buffer_size);
632 fs_file_timing_end(file, FS_OP_READ);
635 if (file->fs->set.enable_timing) {
636 struct istream *input2 = i_stream_create_fs_stats(input, file);
642 if ((file->flags & FS_OPEN_FLAG_SEEKABLE) != 0)
644 else if ((file->flags & FS_OPEN_FLAG_ASYNC) == 0 && !input->blocking)
652 file->fs->temp_path_prefix);
656 file->seekable_input = input;
657 i_stream_ref(file->seekable_input);
659 if ((file->flags & FS_OPEN_FLAG_ASYNC) == 0 && !input->blocking) {
664 fs_wait_async(file->fs);
668 file->istream_open = TRUE;
669 i_stream_add_destroy_callback(input, fs_file_istream_destroyed, file);
673 int fs_write_via_stream(struct fs_file *file, const void *data, size_t size)
679 if (!file->write_pending) {
680 output = fs_write_stream(file);
683 fs_write_stream_abort_error(file, &output, "fs_write(%s) failed: %s",
690 ret = fs_write_stream_finish(file, &output);
692 ret = fs_write_stream_finish_async(file);
695 fs_set_error_async(file->fs);
696 file->write_pending = TRUE;
699 file->write_pending = FALSE;
703 int fs_write(struct fs_file *file, const void *data, size_t size)
707 if (file->fs->v.write != NULL) {
708 fs_file_timing_start(file, FS_OP_WRITE);
710 ret = file->fs->v.write(file, data, size);
713 file->fs->stats.write_count++;
714 file->fs->stats.write_bytes += size;
715 fs_file_timing_end(file, FS_OP_WRITE);
722 return fs_write_via_stream(file, data, size);
725 struct ostream *fs_write_stream(struct fs_file *file)
727 i_assert(!file->writing_stream);
728 i_assert(file->output == NULL);
730 file->writing_stream = TRUE;
731 file->fs->stats.write_count++;
733 file->fs->v.write_stream(file);
735 i_assert(file->output != NULL);
736 o_stream_cork(file->output);
737 return file->output;
740 static int fs_write_stream_finish_int(struct fs_file *file, bool success)
744 i_assert(file->writing_stream);
746 fs_file_timing_start(file, FS_OP_WRITE);
748 ret = file->fs->v.write_stream_finish(file, success);
751 fs_file_timing_end(file, FS_OP_WRITE);
752 file->metadata_changed = FALSE;
759 i_assert(file->output == NULL);
760 file->writing_stream = FALSE;
765 int fs_write_stream_finish(struct fs_file *file, struct ostream **output)
770 i_assert(*output == file->output || *output == NULL);
771 i_assert(output != &file->output);
774 if (file->output != NULL) {
775 o_stream_uncork(file->output);
776 if ((ret = o_stream_finish(file->output)) <= 0) {
778 fs_set_error(file->fs, "write(%s) failed: %s",
779 o_stream_get_name(file->output),
780 o_stream_get_error(file->output));
783 file->fs->stats.write_bytes += file->output->offset;
785 return fs_write_stream_finish_int(file, success);
788 int fs_write_stream_finish_async(struct fs_file *file)
790 return fs_write_stream_finish_int(file, TRUE);
793 static void fs_write_stream_abort(struct fs_file *file, struct ostream **output)
797 i_assert(*output == file->output);
798 i_assert(file->output != NULL);
799 i_assert(output != &file->output);
802 o_stream_abort(file->output);
804 ret = fs_write_stream_finish_int(file, FALSE);
808 void fs_write_stream_abort_error(struct fs_file *file, struct ostream **output, const char *error_fmt, ...)
812 fs_set_verror(file->fs, error_fmt, args);
813 fs_write_stream_abort(file, output);
817 void fs_write_stream_abort_parent(struct fs_file *file, struct ostream **output)
819 i_assert(file->parent != NULL);
820 i_assert(fs_file_last_error(file->parent) != NULL);
821 fs_write_stream_abort(file->parent, output);
824 void fs_write_set_hash(struct fs_file *file, const struct hash_method *method,
827 file->write_digest_method = method;
829 i_free(file->write_digest);
830 file->write_digest = i_malloc(method->digest_size);
831 memcpy(file->write_digest, digest, method->digest_size);
834 void fs_file_set_async_callback(struct fs_file *file,
838 if (file->fs->v.set_async_callback != NULL)
839 file->fs->v.set_async_callback(file, callback, context);
871 int fs_lock(struct fs_file *file, unsigned int secs, struct fs_lock **lock_r)
876 ret = file->fs->v.lock(file, secs, lock_r);
887 lock->file->fs->v.unlock(lock);
891 int fs_exists(struct fs_file *file)
896 if (file->fs->v.exists == NULL) {
898 if (fs_stat(file, &st) == 0)
903 fs_file_timing_start(file, FS_OP_EXISTS);
905 ret = file->fs->v.exists(file);
908 file->fs->stats.exists_count++;
909 fs_file_timing_end(file, FS_OP_EXISTS);
914 int fs_stat(struct fs_file *file, struct stat *st_r)
918 if (file->fs->v.stat == NULL) {
919 fs_set_error(file->fs, "fs_stat() not supported");
923 if (!file->read_or_prefetch_counted &&
924 !file->lookup_metadata_counted && !file->stat_counted) {
925 file->stat_counted = TRUE;
926 file->fs->stats.stat_count++;
927 fs_file_timing_start(file, FS_OP_STAT);
930 ret = file->fs->v.stat(file, st_r);
933 fs_file_timing_end(file, FS_OP_STAT);
937 int fs_get_nlinks(struct fs_file *file, nlink_t *nlinks_r)
941 if (file->fs->v.get_nlinks == NULL) {
944 if (fs_stat(file, &st) < 0)
950 if (!file->read_or_prefetch_counted &&
951 !file->lookup_metadata_counted && !file->stat_counted) {
952 file->stat_counted = TRUE;
953 file->fs->stats.stat_count++;
954 fs_file_timing_start(file, FS_OP_STAT);
957 ret = file->fs->v.get_nlinks(file, nlinks_r);
960 fs_file_timing_end(file, FS_OP_STAT);
1073 int fs_delete(struct fs_file *file)
1077 i_assert(!file->writing_stream);
1079 fs_file_timing_start(file, FS_OP_DELETE);
1081 ret = file->fs->v.delete_file(file);
1084 file->fs->stats.delete_count++;
1085 fs_file_timing_end(file, FS_OP_DELETE);