Lines Matching refs:file

1 /* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
12 #include "file-lock.h"
13 #include "file-dotlock.h"
43 struct fs_file file;
240 static int fs_posix_create(struct posix_fs_file *file)
242 struct posix_fs *fs = (struct posix_fs *)file->file.fs;
249 i_assert(file->temp_path == NULL);
251 if ((slash = strrchr(file->full_path, '/')) != NULL) {
252 str_append_n(str, file->full_path, slash - file->full_path);
274 file->temp_path = i_strdup(str_c(str));
278 static int fs_posix_open(struct posix_fs_file *file)
280 struct posix_fs *fs = (struct posix_fs *)file->file.fs;
281 const char *path = file->full_path;
283 i_assert(file->fd == -1);
285 switch (file->open_mode) {
287 file->fd = open(path, O_RDONLY);
288 if (file->fd == -1)
292 file->fd = open(path, O_RDWR | O_APPEND);
293 if (file->fd == -1)
300 file->fd = fs_posix_create(file);
304 if (file->fd == -1)
311 struct posix_fs_file *file = i_new(struct posix_fs_file, 1);
312 return &file->file;
319 struct posix_fs_file *file = (struct posix_fs_file *)_file;
324 file->file.path = i_strdup(path);
327 file->file.path = i_strdup_printf("%s/%s", path,
330 file->full_path = fs->path_prefix == NULL ? i_strdup(file->file.path) :
331 i_strconcat(fs->path_prefix, file->file.path, NULL);
332 file->open_mode = mode;
333 file->open_flags = flags;
334 file->fd = -1;
339 struct posix_fs_file *file = (struct posix_fs_file *)_file;
341 if (file->fd != -1 && file->file.output == NULL) {
342 if (close(file->fd) < 0) {
343 fs_set_critical(file->file.fs, "close(%s) failed: %m",
344 file->full_path);
346 file->fd = -1;
352 struct posix_fs_file *file = (struct posix_fs_file *)_file;
356 switch (file->open_mode) {
363 if (file->temp_path == NULL)
365 /* failed to create/replace this. delete the temp file */
366 if (unlink(file->temp_path) < 0) {
368 file->temp_path);
373 i_free(file->temp_path);
374 i_free(file->full_path);
375 i_free(file->file.path);
376 i_free(file);
379 static int fs_posix_open_for_read(struct posix_fs_file *file)
381 i_assert(file->file.output == NULL);
382 i_assert(file->temp_path == NULL);
384 if (file->fd == -1) {
385 if (fs_posix_open(file) < 0)
393 struct posix_fs_file *file = (struct posix_fs_file *)_file;
395 if (fs_posix_open_for_read(file) < 0)
400 if (posix_fadvise(file->fd, 0, length, POSIX_FADV_WILLNEED) < 0) {
401 e_error(_file->event, "posix_fadvise(%s) failed: %m", file->full_path);
410 struct posix_fs_file *file = (struct posix_fs_file *)_file;
413 if (fs_posix_open_for_read(file) < 0)
416 if (file->seek_to_beginning) {
417 file->seek_to_beginning = FALSE;
418 if (lseek(file->fd, 0, SEEK_SET) < 0) {
420 file->full_path);
425 ret = read(file->fd, buf, size);
427 fs_set_error(_file->fs, "read(%s) failed: %m", file->full_path);
435 struct posix_fs_file *file = (struct posix_fs_file *)_file;
438 if (fs_posix_open_for_read(file) < 0)
442 input = i_stream_create_fd_autoclose(&file->fd, max_buffer_size);
444 i_stream_set_name(input, file->full_path);
448 static void fs_posix_write_rename_if_needed(struct posix_fs_file *file)
450 struct posix_fs *fs = (struct posix_fs *)file->file.fs;
453 new_fname = fs_metadata_find(&file->file.metadata, FS_METADATA_WRITE_FNAME);
457 p = strrchr(file->file.path, '/');
461 new_prefix = t_strdup_until(file->file.path, p+1);
462 i_free(file->file.path);
463 file->file.path = i_strconcat(new_prefix, new_fname, NULL);
465 i_free(file->full_path);
466 file->full_path = fs->path_prefix == NULL ? i_strdup(file->file.path) :
467 i_strconcat(fs->path_prefix, file->file.path, NULL);
470 static int fs_posix_write_finish(struct posix_fs_file *file)
472 struct posix_fs *fs = (struct posix_fs *)file->file.fs;
475 if ((file->open_flags & FS_OPEN_FLAG_FSYNC) != 0 &&
477 if (fdatasync(file->fd) < 0) {
478 fs_set_error(file->file.fs, "fdatasync(%s) failed: %m",
479 file->full_path);
484 fs_posix_write_rename_if_needed(file);
485 switch (file->open_mode) {
488 if ((ret = link(file->temp_path, file->full_path)) < 0) {
489 fs_set_error(file->file.fs, "link(%s, %s) failed: %m",
490 file->temp_path, file->full_path);
493 if (unlink(file->temp_path) < 0) {
494 fs_set_error(file->file.fs, "unlink(%s) failed: %m",
495 file->temp_path);
499 fs_posix_file_close(&file->file);
500 i_free_and_null(file->temp_path);
505 if (rename(file->temp_path, file->full_path) < 0) {
506 fs_set_error(file->file.fs, "rename(%s, %s) failed: %m",
507 file->temp_path, file->full_path);
514 i_free_and_null(file->temp_path);
515 file->seek_to_beginning = TRUE;
516 /* allow opening the file after writing to it */
517 file->open_mode = FS_OPEN_MODE_READONLY;
523 struct posix_fs_file *file = (struct posix_fs_file *)_file;
526 if (file->fd == -1) {
527 if (fs_posix_open(file) < 0)
529 i_assert(file->fd != -1);
532 if (file->open_mode != FS_OPEN_MODE_APPEND) {
533 if (write_full(file->fd, data, size) < 0) {
535 file->full_path);
538 return fs_posix_write_finish(file);
542 ret = write(file->fd, data, size);
544 fs_set_error(_file->fs, "write(%s) failed: %m", file->full_path);
550 file->full_path, (size_t)ret, size);
559 struct posix_fs_file *file = (struct posix_fs_file *)_file;
563 if (file->open_mode == FS_OPEN_MODE_APPEND) {
564 file->write_buf = buffer_create_dynamic(default_pool, 1024*32);
565 _file->output = o_stream_create_buffer(file->write_buf);
566 } else if (file->fd == -1 && fs_posix_open(file) < 0) {
570 i_assert(file->fd != -1);
571 _file->output = o_stream_create_fd_file(file->fd,
574 o_stream_set_name(_file->output, file->full_path);
579 struct posix_fs_file *file = (struct posix_fs_file *)_file;
584 switch (file->open_mode) {
587 ret = fs_posix_write(_file, file->write_buf->data,
588 file->write_buf->used);
590 buffer_free(&file->write_buf);
596 ret = fs_posix_write_finish(file);
607 struct posix_fs_file *file = (struct posix_fs_file *)_file;
614 fs_lock.lock.file = _file;
620 "(for file %s)", file->full_path);
623 ret = file_try_lock(file->fd, file->full_path, F_WRLCK,
627 ret = file_wait_lock(file->fd, file->full_path, F_WRLCK,
633 file->full_path);
643 ret = file_dotlock_create(&dotlock_set, file->full_path,
650 file->full_path);
676 struct posix_fs_file *file = (struct posix_fs_file *)_file;
679 if (stat(file->full_path, &st) < 0) {
682 file->full_path);
692 struct posix_fs_file *file = (struct posix_fs_file *)_file;
694 /* in case output != NULL it means that we're still writing to the file
695 and fs_stat() shouldn't stat the unfinished file. this is done by
697 if (file->fd != -1 && _file->output == NULL) {
698 if (fstat(file->fd, st_r) < 0) {
699 fs_set_error(_file->fs, "fstat(%s) failed: %m", file->full_path);
703 if (stat(file->full_path, st_r) < 0) {
704 fs_set_error(_file->fs, "stat(%s) failed: %m", file->full_path);
721 /* destination file already exists - replace it */
766 struct posix_fs_file *file = (struct posix_fs_file *)_file;
769 if (unlink(file->full_path) < 0) {
771 fs_set_error(_file->fs, "unlink(%s) failed: %m", file->full_path);
776 if (rmdir(file->full_path) < 0) {
777 fs_set_error(_file->fs, "rmdir(%s) failed: %m", file->full_path);
781 (void)fs_posix_rmdir_parents(fs, file->full_path);