[PATCH] D38295: Do not use posix_fallocate because it's slow.
Rafael Avila de Espindola via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 28 09:27:17 PDT 2017
Which filesystems don't have it?
Is the issue just an error message? I thought we would get a hard crash
trying to write to a mmaped area when there is no space available to
flush it to disk.
Cheers,
Rafael
Rui Ueyama via Phabricator <reviews at reviews.llvm.org> writes:
> ruiu created this revision.
> Herald added subscribers: hiraditya, kristof.beyls, aemerson.
>
> posix_fallocate is too slow if your filesystem does not support the
> fallocate system call.
>
> That's still harmless if you are creating relatively small files,
> or the overhead of creating files takes only a small part of an
> entire process, but for lld, the issue is pretty noticeable. lld
> can now link an 1.7 GiB executable in about 7 seconds on my machine,
> and posix_fallocate takes 1 second. Spending a second on every linker
> invocation just to prepare for "disk full" errors doesn't make much
> sense.
>
>
> https://reviews.llvm.org/D38295
>
> Files:
> llvm/lib/Support/Unix/Path.inc
>
>
> Index: llvm/lib/Support/Unix/Path.inc
> ===================================================================
> --- llvm/lib/Support/Unix/Path.inc
> +++ llvm/lib/Support/Unix/Path.inc
> @@ -422,19 +422,16 @@
> }
>
> std::error_code resize_file(int FD, uint64_t Size) {
> -#if defined(HAVE_POSIX_FALLOCATE)
> - // If we have posix_fallocate use it. Unlike ftruncate it always allocates
> - // space, so we get an error if the disk is full.
> - if (int Err = ::posix_fallocate(FD, 0, Size)) {
> - if (Err != EOPNOTSUPP)
> - return std::error_code(Err, std::generic_category());
> - }
> -#endif
> - // Use ftruncate as a fallback. It may or may not allocate space. At least on
> - // OS X with HFS+ it does.
> + // Resize the file using ftruncate. ftruncate may not allocate actual disk
> + // blocks, so even if ftruncate succeeds, subsequent writes may fail due to
> + // "disk full" errors.
> + //
> + // posix_fallocate guarantees that it allocates all disk blocks, but the
> + // function is slow unless your filesystem supports the fallocate system
> + // call. When it falls back, it writes null bytes on each block. So we don't
> + // want to use the function.
> if (::ftruncate(FD, Size) == -1)
> return std::error_code(errno, std::generic_category());
> -
> return std::error_code();
> }
>
>
>
> Index: llvm/lib/Support/Unix/Path.inc
> ===================================================================
> --- llvm/lib/Support/Unix/Path.inc
> +++ llvm/lib/Support/Unix/Path.inc
> @@ -422,19 +422,16 @@
> }
>
> std::error_code resize_file(int FD, uint64_t Size) {
> -#if defined(HAVE_POSIX_FALLOCATE)
> - // If we have posix_fallocate use it. Unlike ftruncate it always allocates
> - // space, so we get an error if the disk is full.
> - if (int Err = ::posix_fallocate(FD, 0, Size)) {
> - if (Err != EOPNOTSUPP)
> - return std::error_code(Err, std::generic_category());
> - }
> -#endif
> - // Use ftruncate as a fallback. It may or may not allocate space. At least on
> - // OS X with HFS+ it does.
> + // Resize the file using ftruncate. ftruncate may not allocate actual disk
> + // blocks, so even if ftruncate succeeds, subsequent writes may fail due to
> + // "disk full" errors.
> + //
> + // posix_fallocate guarantees that it allocates all disk blocks, but the
> + // function is slow unless your filesystem supports the fallocate system
> + // call. When it falls back, it writes null bytes on each block. So we don't
> + // want to use the function.
> if (::ftruncate(FD, Size) == -1)
> return std::error_code(errno, std::generic_category());
> -
> return std::error_code();
> }
>
More information about the llvm-commits
mailing list