xref: /llvm-project/libc/src/sys/stat/linux/kernel_statx.h (revision 91bf0a073951aa1ca4c357967ed5aff891941785)
1e310f8bdSSiva Chandra Reddy //===-- Wrapper over SYS_statx syscall ------------------------------------===//
2e310f8bdSSiva Chandra Reddy //
3e310f8bdSSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e310f8bdSSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information.
5e310f8bdSSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e310f8bdSSiva Chandra Reddy //
7e310f8bdSSiva Chandra Reddy //===----------------------------------------------------------------------===//
8e310f8bdSSiva Chandra Reddy 
9270547f3SGuillaume Chatelet #ifndef LLVM_LIBC_SRC_SYS_STAT_LINUX_KERNEL_STATX_H
10270547f3SGuillaume Chatelet #define LLVM_LIBC_SRC_SYS_STAT_LINUX_KERNEL_STATX_H
11e310f8bdSSiva Chandra Reddy 
12e310f8bdSSiva Chandra Reddy #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
1305d9cc47SSiva Chandra Reddy #include "src/__support/common.h"
145ff3ff33SPetr Hosek #include "src/__support/macros/config.h"
15e310f8bdSSiva Chandra Reddy 
16e310f8bdSSiva Chandra Reddy #include <stdint.h>
17e310f8bdSSiva Chandra Reddy #include <sys/stat.h>
18e310f8bdSSiva Chandra Reddy #include <sys/syscall.h> // For syscall numbers.
19e310f8bdSSiva Chandra Reddy 
20e310f8bdSSiva Chandra Reddy // It is safe to include this kernel header as it is designed to be
21e310f8bdSSiva Chandra Reddy // included from user programs without causing any name pollution.
22e310f8bdSSiva Chandra Reddy #include <linux/kdev_t.h>
23e310f8bdSSiva Chandra Reddy 
24e310f8bdSSiva Chandra Reddy namespace {
25e310f8bdSSiva Chandra Reddy 
26e310f8bdSSiva Chandra Reddy // The type definitions in the internal namespace match kernel's definition of
27e310f8bdSSiva Chandra Reddy // the statx_timestamp and statx types in linux/stat.h. We define equivalent
28e310f8bdSSiva Chandra Reddy // types here instead of including that header file to avoid name mixup between
29e310f8bdSSiva Chandra Reddy // linux/stat.h and the libc's stat.h.
30e310f8bdSSiva Chandra Reddy struct statx_timestamp {
31e310f8bdSSiva Chandra Reddy   int64_t tv_sec;
32e310f8bdSSiva Chandra Reddy   uint32_t tv_nsec;
33e310f8bdSSiva Chandra Reddy   int32_t __reserved;
34e310f8bdSSiva Chandra Reddy };
35e310f8bdSSiva Chandra Reddy 
36e310f8bdSSiva Chandra Reddy struct statx_buf {
37e310f8bdSSiva Chandra Reddy   uint32_t stx_mask;       // What results were written
38e310f8bdSSiva Chandra Reddy   uint32_t stx_blksize;    // Preferred general I/O size
39e310f8bdSSiva Chandra Reddy   uint64_t stx_attributes; // Flags conveying information about the file
40e310f8bdSSiva Chandra Reddy   uint32_t stx_nlink;      // Number of hard links
41e310f8bdSSiva Chandra Reddy   uint32_t stx_uid;        // User ID of owner
42e310f8bdSSiva Chandra Reddy   uint32_t stx_gid;        // Group ID of owner
43e310f8bdSSiva Chandra Reddy   uint16_t stx_mode;       // File mode
44e310f8bdSSiva Chandra Reddy   uint16_t __spare0[1];
45e310f8bdSSiva Chandra Reddy   uint64_t stx_ino;                 // Inode number
46e310f8bdSSiva Chandra Reddy   uint64_t stx_size;                // File size
47e310f8bdSSiva Chandra Reddy   uint64_t stx_blocks;              // Number of 512-byte blocks allocated
48e310f8bdSSiva Chandra Reddy   uint64_t stx_attributes_mask;     // Mask to show what's supported in
49e310f8bdSSiva Chandra Reddy                                     // stx_attributes
50e310f8bdSSiva Chandra Reddy   struct statx_timestamp stx_atime; // Last access time
51e310f8bdSSiva Chandra Reddy   struct statx_timestamp stx_btime; // File creation time
52e310f8bdSSiva Chandra Reddy   struct statx_timestamp stx_ctime; // Last attribute change time
53e310f8bdSSiva Chandra Reddy   struct statx_timestamp stx_mtime; // Last data modification time
54e310f8bdSSiva Chandra Reddy   uint32_t stx_rdev_major;          // Device ID of special file
55e310f8bdSSiva Chandra Reddy   uint32_t stx_rdev_minor;
56e310f8bdSSiva Chandra Reddy   uint32_t stx_dev_major; // ID of device containing file
57e310f8bdSSiva Chandra Reddy   uint32_t stx_dev_minor;
58e310f8bdSSiva Chandra Reddy   uint64_t stx_mnt_id;
59e310f8bdSSiva Chandra Reddy   uint64_t __spare2;
60e310f8bdSSiva Chandra Reddy   uint64_t __spare3[12]; // Spare space for future expansion
61e310f8bdSSiva Chandra Reddy };
62e310f8bdSSiva Chandra Reddy 
63e310f8bdSSiva Chandra Reddy // The below mask value is based on the definition of a similarly
64e310f8bdSSiva Chandra Reddy // named macro in linux/stat.h. When this flag is passed for the
65e310f8bdSSiva Chandra Reddy // mask argument to the statx syscall, all fields except the
66e310f8bdSSiva Chandra Reddy // stx_btime field will be filled in.
67e310f8bdSSiva Chandra Reddy constexpr unsigned int STATX_BASIC_STATS_MASK = 0x7FF;
68e310f8bdSSiva Chandra Reddy 
69e310f8bdSSiva Chandra Reddy } // Anonymous namespace
70e310f8bdSSiva Chandra Reddy 
715ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL {
72e310f8bdSSiva Chandra Reddy 
7305d9cc47SSiva Chandra Reddy LIBC_INLINE int statx(int dirfd, const char *__restrict path, int flags,
74e310f8bdSSiva Chandra Reddy                       struct stat *__restrict statbuf) {
75e310f8bdSSiva Chandra Reddy   // We make a statx syscall and copy out the result into the |statbuf|.
76e310f8bdSSiva Chandra Reddy   ::statx_buf xbuf;
77b6bc9d72SGuillaume Chatelet   int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_statx, dirfd, path, flags,
781801c356SMichael Jones                                               ::STATX_BASIC_STATS_MASK, &xbuf);
7955612b8eSSiva Chandra Reddy   if (ret < 0)
8055612b8eSSiva Chandra Reddy     return -ret;
81e310f8bdSSiva Chandra Reddy 
82e310f8bdSSiva Chandra Reddy   statbuf->st_dev = MKDEV(xbuf.stx_dev_major, xbuf.stx_dev_minor);
83*91bf0a07SMikhail R. Gadelha   statbuf->st_ino = static_cast<decltype(statbuf->st_ino)>(xbuf.stx_ino);
84e310f8bdSSiva Chandra Reddy   statbuf->st_mode = xbuf.stx_mode;
85e310f8bdSSiva Chandra Reddy   statbuf->st_nlink = xbuf.stx_nlink;
86e310f8bdSSiva Chandra Reddy   statbuf->st_uid = xbuf.stx_uid;
87e310f8bdSSiva Chandra Reddy   statbuf->st_gid = xbuf.stx_gid;
88e310f8bdSSiva Chandra Reddy   statbuf->st_rdev = MKDEV(xbuf.stx_rdev_major, xbuf.stx_rdev_minor);
89e310f8bdSSiva Chandra Reddy   statbuf->st_size = xbuf.stx_size;
90e310f8bdSSiva Chandra Reddy   statbuf->st_atim.tv_sec = xbuf.stx_atime.tv_sec;
91e310f8bdSSiva Chandra Reddy   statbuf->st_atim.tv_nsec = xbuf.stx_atime.tv_nsec;
92e310f8bdSSiva Chandra Reddy   statbuf->st_mtim.tv_sec = xbuf.stx_mtime.tv_sec;
93e310f8bdSSiva Chandra Reddy   statbuf->st_mtim.tv_nsec = xbuf.stx_mtime.tv_nsec;
94e310f8bdSSiva Chandra Reddy   statbuf->st_ctim.tv_sec = xbuf.stx_ctime.tv_sec;
95e310f8bdSSiva Chandra Reddy   statbuf->st_ctim.tv_nsec = xbuf.stx_ctime.tv_nsec;
96e310f8bdSSiva Chandra Reddy   statbuf->st_blksize = xbuf.stx_blksize;
97*91bf0a07SMikhail R. Gadelha   statbuf->st_blocks =
98*91bf0a07SMikhail R. Gadelha       static_cast<decltype(statbuf->st_blocks)>(xbuf.stx_blocks);
99e310f8bdSSiva Chandra Reddy 
100e310f8bdSSiva Chandra Reddy   return 0;
101e310f8bdSSiva Chandra Reddy }
102e310f8bdSSiva Chandra Reddy 
1035ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL
104e310f8bdSSiva Chandra Reddy 
105270547f3SGuillaume Chatelet #endif // LLVM_LIBC_SRC_SYS_STAT_LINUX_KERNEL_STATX_H
106