[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