diff options
Diffstat (limited to 'base/sys_info_posix.cc')
-rw-r--r-- | base/sys_info_posix.cc | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/base/sys_info_posix.cc b/base/sys_info_posix.cc index 5d1c450139..cbdfa3f7a9 100644 --- a/base/sys_info_posix.cc +++ b/base/sys_info_posix.cc @@ -28,6 +28,11 @@ #include <sys/statvfs.h> #endif +#if defined(OS_LINUX) +#include <linux/magic.h> +#include <sys/vfs.h> +#endif + namespace { #if !defined(OS_OPENBSD) @@ -73,6 +78,23 @@ base::LazyInstance< base::internal::LazySysInfoValue<int64_t, AmountOfVirtualMemory>>::Leaky g_lazy_virtual_memory = LAZY_INSTANCE_INITIALIZER; +#if defined(OS_LINUX) +bool IsStatsZeroIfUnlimited(const base::FilePath& path) { + struct statfs stats; + + if (HANDLE_EINTR(statfs(path.value().c_str(), &stats)) != 0) + return false; + + switch (static_cast<uint32_t>(stats.f_type)) { + case TMPFS_MAGIC: + case HUGETLBFS_MAGIC: + case RAMFS_MAGIC: + return true; + } + return false; +} +#endif + bool GetDiskSpaceInfo(const base::FilePath& path, int64_t* available_bytes, int64_t* total_bytes) { @@ -80,10 +102,25 @@ bool GetDiskSpaceInfo(const base::FilePath& path, if (HANDLE_EINTR(statvfs(path.value().c_str(), &stats)) != 0) return false; - if (available_bytes) - *available_bytes = static_cast<int64_t>(stats.f_bavail) * stats.f_frsize; - if (total_bytes) - *total_bytes = static_cast<int64_t>(stats.f_blocks) * stats.f_frsize; +#if defined(OS_LINUX) + const bool zero_size_means_unlimited = + stats.f_blocks == 0 && IsStatsZeroIfUnlimited(path); +#else + const bool zero_size_means_unlimited = false; +#endif + + if (available_bytes) { + *available_bytes = + zero_size_means_unlimited + ? std::numeric_limits<int64_t>::max() + : static_cast<int64_t>(stats.f_bavail) * stats.f_frsize; + } + + if (total_bytes) { + *total_bytes = zero_size_means_unlimited + ? std::numeric_limits<int64_t>::max() + : static_cast<int64_t>(stats.f_blocks) * stats.f_frsize; + } return true; } |