brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · 8ee4de2 Raw
98 lines · c
1//===-- Convert Statfs to Statvfs -------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIBC_SRC_SYS_STATVFS_LINUX_STATFS_TO_STATVFS_H10#define LLVM_LIBC_SRC_SYS_STATVFS_LINUX_STATFS_TO_STATVFS_H11 12#include "include/llvm-libc-types/struct_statvfs.h"13#include "src/__support/CPP/optional.h"14#include "src/__support/OSUtil/syscall.h"15#include "src/__support/libc_errno.h"16#include "src/__support/macros/attributes.h"17#include "src/__support/macros/config.h"18#include <asm/statfs.h>19#include <sys/syscall.h>20namespace LIBC_NAMESPACE_DECL {21 22namespace statfs_utils {23#ifdef SYS_statfs6424using LinuxStatFs = statfs64;25#else26using LinuxStatFs = statfs;27#endif28 29// Linux kernel set an additional flag to f_flags. Libc should mask it out.30LIBC_INLINE_VAR constexpr decltype(LinuxStatFs::f_flags) ST_VALID = 0x0020;31 32LIBC_INLINE cpp::optional<LinuxStatFs> linux_statfs(const char *path) {33  // The kernel syscall routine checks the validity of the path before filling34  // the statfs structure. So, it is possible that the result is not initialized35  // after the syscall. Since the struct is trvial, the compiler will generate36  // pattern filling for the struct.37  LinuxStatFs result;38  // On 32-bit platforms, original statfs cannot handle large file systems.39  // In such cases, SYS_statfs64 is defined and should be used.40#ifdef SYS_statfs6441  int ret = syscall_impl<int>(SYS_statfs64, path, sizeof(result), &result);42#else43  int ret = syscall_impl<int>(SYS_statfs, path, &result);44#endif45  if (ret < 0) {46    libc_errno = -ret;47    return cpp::nullopt;48  }49  result.f_flags &= ~ST_VALID;50  return result;51}52 53LIBC_INLINE cpp::optional<LinuxStatFs> linux_fstatfs(int fd) {54  // The kernel syscall routine checks the validity of the path before filling55  // the statfs structure. So, it is possible that the result is not initialized56  // after the syscall. Since the struct is trvial, the compiler will generate57  // pattern filling for the struct.58  LinuxStatFs result;59  // On 32-bit platforms, original fstatfs cannot handle large file systems.60  // In such cases, SYS_fstatfs64 is defined and should be used.61#ifdef SYS_fstatfs6462  int ret = syscall_impl<int>(SYS_fstatfs64, fd, sizeof(result), &result);63#else64  int ret = syscall_impl<int>(SYS_fstatfs, fd, &result);65#endif66  if (ret < 0) {67    libc_errno = -ret;68    return cpp::nullopt;69  }70  result.f_flags &= ~ST_VALID;71  return result;72}73 74// must use 'struct' tag to refer to type 'statvfs' in this scope. There will be75// a function in the same namespace with the same name. For consistency, we use76// struct prefix for all statvfs/statfs related types.77LIBC_INLINE struct statvfs statfs_to_statvfs(const LinuxStatFs &in) {78  struct statvfs out;79  out.f_bsize = in.f_bsize;80  out.f_frsize = in.f_frsize;81  out.f_blocks = static_cast<decltype(out.f_blocks)>(in.f_blocks);82  out.f_bfree = static_cast<decltype(out.f_bfree)>(in.f_bfree);83  out.f_bavail = static_cast<decltype(out.f_bavail)>(in.f_bavail);84  out.f_files = static_cast<decltype(out.f_files)>(in.f_files);85  out.f_ffree = static_cast<decltype(out.f_ffree)>(in.f_ffree);86  out.f_favail = static_cast<decltype(out.f_favail)>(in.f_ffree);87  out.f_fsid = in.f_fsid.val[0];88  if constexpr (sizeof(decltype(out.f_fsid)) == sizeof(uint64_t))89    out.f_fsid |= static_cast<decltype(out.f_fsid)>(in.f_fsid.val[1]) << 32;90  out.f_flag = in.f_flags;91  out.f_namemax = in.f_namelen;92  return out;93}94} // namespace statfs_utils95} // namespace LIBC_NAMESPACE_DECL96 97#endif // LLVM_LIBC_SRC_SYS_STATVFS_LINUX_STATFS_TO_STATVFS_H98