Browse Source

unix: add Statx on Linux

statx(2) allows to get enhanced file status information (not currently
available through the existing stat syscalls), lightweight stat,
heavyweight stat. The Statx_t type used by Statx has consistent field
sizes on all arches (with year-2038-capable timestamps) and is closer to
the BSD implementation of Stat_t.

See http://man7.org/linux/man-pages/man2/statx.2.html for details. The
syscall was added in Linux kernel 4.11.

See https://github.com/tklauser/statx for an example of how this
function and types can be used to report stat(1)-like file status
information.

Change-Id: I9e9642b5b42a393f94fd532453888ce9ba4f0003
Reviewed-on: https://go-review.googlesource.com/87555
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Tobias Klauser 8 years ago
parent
commit
fff93fa7cd

+ 30 - 4
unix/linux/types.go

@@ -47,11 +47,12 @@ package unix
 #include <sys/utsname.h>
 #include <sys/wait.h>
 #include <linux/filter.h>
+#include <linux/icmpv6.h>
 #include <linux/keyctl.h>
 #include <linux/netlink.h>
 #include <linux/perf_event.h>
 #include <linux/rtnetlink.h>
-#include <linux/icmpv6.h>
+#include <linux/stat.h>
 #include <asm/termbits.h>
 #include <asm/ptrace.h>
 #include <time.h>
@@ -116,6 +117,21 @@ struct stat {
 
 #endif
 
+// These are defined in linux/fcntl.h, but including it globally causes
+// conflicts with fcntl.h
+#ifndef AT_STATX_SYNC_TYPE
+# define AT_STATX_SYNC_TYPE	0x6000	// Type of synchronisation required from statx()
+#endif
+#ifndef AT_STATX_SYNC_AS_STAT
+# define AT_STATX_SYNC_AS_STAT	0x0000	// - Do whatever stat() does
+#endif
+#ifndef AT_STATX_FORCE_SYNC
+# define AT_STATX_FORCE_SYNC	0x2000	// - Force the attributes to be sync'd with the server
+#endif
+#ifndef AT_STATX_DONT_SYNC
+# define AT_STATX_DONT_SYNC	0x4000	// - Don't sync attributes with the server
+#endif
+
 #ifdef TCSETS2
 // On systems that have "struct termios2" use this as type Termios.
 typedef struct termios2 termios_t;
@@ -249,6 +265,10 @@ type Stat_t C.struct_stat
 
 type Statfs_t C.struct_statfs
 
+type StatxTimestamp C.struct_statx_timestamp
+
+type Statx_t C.struct_statx
+
 type Dirent C.struct_dirent
 
 type Fsid C.fsid_t
@@ -513,9 +533,15 @@ type Ustat_t C.struct_ustat
 type EpollEvent C.struct_my_epoll_event
 
 const (
-	AT_FDCWD            = C.AT_FDCWD
-	AT_NO_AUTOMOUNT     = C.AT_NO_AUTOMOUNT
-	AT_REMOVEDIR        = C.AT_REMOVEDIR
+	AT_EMPTY_PATH   = C.AT_EMPTY_PATH
+	AT_FDCWD        = C.AT_FDCWD
+	AT_NO_AUTOMOUNT = C.AT_NO_AUTOMOUNT
+	AT_REMOVEDIR    = C.AT_REMOVEDIR
+
+	AT_STATX_SYNC_AS_STAT = C.AT_STATX_SYNC_AS_STAT
+	AT_STATX_FORCE_SYNC   = C.AT_STATX_FORCE_SYNC
+	AT_STATX_DONT_SYNC    = C.AT_STATX_DONT_SYNC
+
 	AT_SYMLINK_FOLLOW   = C.AT_SYMLINK_FOLLOW
 	AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW
 )

+ 2 - 0
unix/mkerrors.sh

@@ -187,6 +187,7 @@ struct ltchars {
 #include <linux/vm_sockets.h>
 #include <linux/taskstats.h>
 #include <linux/genetlink.h>
+#include <linux/stat.h>
 #include <linux/watchdog.h>
 #include <net/route.h>
 #include <asm/termbits.h>
@@ -428,6 +429,7 @@ ccflags="$@"
 		$2 ~ /^(TASKSTATS|TS)_/ ||
 		$2 ~ /^CGROUPSTATS_/ ||
 		$2 ~ /^GENL_/ ||
+		$2 ~ /^STATX_/ ||
 		$2 ~ /^UTIME_/ ||
 		$2 ~ /^XATTR_(CREATE|REPLACE)/ ||
 		$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||

+ 4 - 0
unix/mkpost.go

@@ -61,6 +61,10 @@ func main() {
 	convertUtsnameRegex := regexp.MustCompile(`((Sys|Node|Domain)name|Release|Version|Machine)(\s+)\[(\d+)\]u?int8`)
 	b = convertUtsnameRegex.ReplaceAll(b, []byte("$1$3[$4]byte"))
 
+	// Remove spare fields (e.g. in Statx_t)
+	spareFieldsRegex := regexp.MustCompile(`X__spare\S*`)
+	b = spareFieldsRegex.ReplaceAll(b, []byte("_"))
+
 	// We refuse to export private fields on s390x
 	if goarch == "s390x" && goos == "linux" {
 		// Remove cgo padding fields

+ 1 - 0
unix/syscall_linux.go

@@ -1318,6 +1318,7 @@ func Setgid(uid int) (err error) {
 
 //sys	Setpriority(which int, who int, prio int) (err error)
 //sys	Setxattr(path string, attr string, data []byte, flags int) (err error)
+//sys	Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error)
 //sys	Sync()
 //sys	Syncfs(fd int) (err error)
 //sysnb	Sysinfo(info *Sysinfo_t) (err error)

+ 90 - 0
unix/syscall_linux_test.go

@@ -314,6 +314,96 @@ func TestSchedSetaffinity(t *testing.T) {
 	}
 }
 
+func TestStatx(t *testing.T) {
+	var stx unix.Statx_t
+	err := unix.Statx(unix.AT_FDCWD, ".", 0, 0, &stx)
+	if err == unix.ENOSYS {
+		t.Skip("statx syscall is not available, skipping test")
+	} else if err != nil {
+		t.Fatalf("Statx: %v", err)
+	}
+
+	defer chtmpdir(t)()
+	touch(t, "file1")
+
+	var st unix.Stat_t
+	err = unix.Stat("file1", &st)
+	if err != nil {
+		t.Fatalf("Stat: %v", err)
+	}
+
+	flags := unix.AT_STATX_SYNC_AS_STAT
+	err = unix.Statx(unix.AT_FDCWD, "file1", flags, unix.STATX_ALL, &stx)
+	if err != nil {
+		t.Fatalf("Statx: %v", err)
+	}
+
+	if uint32(stx.Mode) != st.Mode {
+		t.Errorf("Statx: returned stat mode does not match Stat")
+	}
+
+	atime := unix.StatxTimestamp{Sec: int64(st.Atim.Sec), Nsec: uint32(st.Atim.Nsec)}
+	ctime := unix.StatxTimestamp{Sec: int64(st.Ctim.Sec), Nsec: uint32(st.Ctim.Nsec)}
+	mtime := unix.StatxTimestamp{Sec: int64(st.Mtim.Sec), Nsec: uint32(st.Mtim.Nsec)}
+
+	if stx.Atime != atime {
+		t.Errorf("Statx: returned stat atime does not match Stat")
+	}
+	if stx.Ctime != ctime {
+		t.Errorf("Statx: returned stat ctime does not match Stat")
+	}
+	if stx.Mtime != mtime {
+		t.Errorf("Statx: returned stat mtime does not match Stat")
+	}
+
+	err = os.Symlink("file1", "symlink1")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = unix.Lstat("symlink1", &st)
+	if err != nil {
+		t.Fatalf("Lstat: %v", err)
+	}
+
+	err = unix.Statx(unix.AT_FDCWD, "symlink1", flags, unix.STATX_BASIC_STATS, &stx)
+	if err != nil {
+		t.Fatalf("Statx: %v", err)
+	}
+
+	// follow symlink, expect a regulat file
+	if stx.Mode&unix.S_IFREG == 0 {
+		t.Errorf("Statx: didn't follow symlink")
+	}
+
+	err = unix.Statx(unix.AT_FDCWD, "symlink1", flags|unix.AT_SYMLINK_NOFOLLOW, unix.STATX_ALL, &stx)
+	if err != nil {
+		t.Fatalf("Statx: %v", err)
+	}
+
+	// follow symlink, expect a symlink
+	if stx.Mode&unix.S_IFLNK == 0 {
+		t.Errorf("Statx: unexpectedly followed symlink")
+	}
+	if uint32(stx.Mode) != st.Mode {
+		t.Errorf("Statx: returned stat mode does not match Lstat")
+	}
+
+	atime = unix.StatxTimestamp{Sec: int64(st.Atim.Sec), Nsec: uint32(st.Atim.Nsec)}
+	ctime = unix.StatxTimestamp{Sec: int64(st.Ctim.Sec), Nsec: uint32(st.Ctim.Nsec)}
+	mtime = unix.StatxTimestamp{Sec: int64(st.Mtim.Sec), Nsec: uint32(st.Mtim.Nsec)}
+
+	if stx.Atime != atime {
+		t.Errorf("Statx: returned stat atime does not match Lstat")
+	}
+	if stx.Ctime != ctime {
+		t.Errorf("Statx: returned stat ctime does not match Lstat")
+	}
+	if stx.Mtime != mtime {
+		t.Errorf("Statx: returned stat mtime does not match Lstat")
+	}
+}
+
 // utilities taken from os/os_test.go
 
 func touch(t *testing.T, name string) {

+ 21 - 0
unix/zerrors_linux_386.go

@@ -1638,6 +1638,27 @@ const (
 	SPLICE_F_MORE                        = 0x4
 	SPLICE_F_MOVE                        = 0x1
 	SPLICE_F_NONBLOCK                    = 0x2
+	STATX_ALL                            = 0xfff
+	STATX_ATIME                          = 0x20
+	STATX_ATTR_APPEND                    = 0x20
+	STATX_ATTR_AUTOMOUNT                 = 0x1000
+	STATX_ATTR_COMPRESSED                = 0x4
+	STATX_ATTR_ENCRYPTED                 = 0x800
+	STATX_ATTR_IMMUTABLE                 = 0x10
+	STATX_ATTR_NODUMP                    = 0x40
+	STATX_BASIC_STATS                    = 0x7ff
+	STATX_BLOCKS                         = 0x400
+	STATX_BTIME                          = 0x800
+	STATX_CTIME                          = 0x80
+	STATX_GID                            = 0x10
+	STATX_INO                            = 0x100
+	STATX_MODE                           = 0x2
+	STATX_MTIME                          = 0x40
+	STATX_NLINK                          = 0x4
+	STATX_SIZE                           = 0x200
+	STATX_TYPE                           = 0x1
+	STATX_UID                            = 0x8
+	STATX__RESERVED                      = 0x80000000
 	S_BLKSIZE                            = 0x200
 	S_IEXEC                              = 0x40
 	S_IFBLK                              = 0x6000

+ 21 - 0
unix/zerrors_linux_amd64.go

@@ -1639,6 +1639,27 @@ const (
 	SPLICE_F_MORE                        = 0x4
 	SPLICE_F_MOVE                        = 0x1
 	SPLICE_F_NONBLOCK                    = 0x2
+	STATX_ALL                            = 0xfff
+	STATX_ATIME                          = 0x20
+	STATX_ATTR_APPEND                    = 0x20
+	STATX_ATTR_AUTOMOUNT                 = 0x1000
+	STATX_ATTR_COMPRESSED                = 0x4
+	STATX_ATTR_ENCRYPTED                 = 0x800
+	STATX_ATTR_IMMUTABLE                 = 0x10
+	STATX_ATTR_NODUMP                    = 0x40
+	STATX_BASIC_STATS                    = 0x7ff
+	STATX_BLOCKS                         = 0x400
+	STATX_BTIME                          = 0x800
+	STATX_CTIME                          = 0x80
+	STATX_GID                            = 0x10
+	STATX_INO                            = 0x100
+	STATX_MODE                           = 0x2
+	STATX_MTIME                          = 0x40
+	STATX_NLINK                          = 0x4
+	STATX_SIZE                           = 0x200
+	STATX_TYPE                           = 0x1
+	STATX_UID                            = 0x8
+	STATX__RESERVED                      = 0x80000000
 	S_BLKSIZE                            = 0x200
 	S_IEXEC                              = 0x40
 	S_IFBLK                              = 0x6000

+ 21 - 0
unix/zerrors_linux_arm.go

@@ -1643,6 +1643,27 @@ const (
 	SPLICE_F_MORE                        = 0x4
 	SPLICE_F_MOVE                        = 0x1
 	SPLICE_F_NONBLOCK                    = 0x2
+	STATX_ALL                            = 0xfff
+	STATX_ATIME                          = 0x20
+	STATX_ATTR_APPEND                    = 0x20
+	STATX_ATTR_AUTOMOUNT                 = 0x1000
+	STATX_ATTR_COMPRESSED                = 0x4
+	STATX_ATTR_ENCRYPTED                 = 0x800
+	STATX_ATTR_IMMUTABLE                 = 0x10
+	STATX_ATTR_NODUMP                    = 0x40
+	STATX_BASIC_STATS                    = 0x7ff
+	STATX_BLOCKS                         = 0x400
+	STATX_BTIME                          = 0x800
+	STATX_CTIME                          = 0x80
+	STATX_GID                            = 0x10
+	STATX_INO                            = 0x100
+	STATX_MODE                           = 0x2
+	STATX_MTIME                          = 0x40
+	STATX_NLINK                          = 0x4
+	STATX_SIZE                           = 0x200
+	STATX_TYPE                           = 0x1
+	STATX_UID                            = 0x8
+	STATX__RESERVED                      = 0x80000000
 	S_BLKSIZE                            = 0x200
 	S_IEXEC                              = 0x40
 	S_IFBLK                              = 0x6000

+ 21 - 0
unix/zerrors_linux_arm64.go

@@ -1629,6 +1629,27 @@ const (
 	SPLICE_F_MORE                        = 0x4
 	SPLICE_F_MOVE                        = 0x1
 	SPLICE_F_NONBLOCK                    = 0x2
+	STATX_ALL                            = 0xfff
+	STATX_ATIME                          = 0x20
+	STATX_ATTR_APPEND                    = 0x20
+	STATX_ATTR_AUTOMOUNT                 = 0x1000
+	STATX_ATTR_COMPRESSED                = 0x4
+	STATX_ATTR_ENCRYPTED                 = 0x800
+	STATX_ATTR_IMMUTABLE                 = 0x10
+	STATX_ATTR_NODUMP                    = 0x40
+	STATX_BASIC_STATS                    = 0x7ff
+	STATX_BLOCKS                         = 0x400
+	STATX_BTIME                          = 0x800
+	STATX_CTIME                          = 0x80
+	STATX_GID                            = 0x10
+	STATX_INO                            = 0x100
+	STATX_MODE                           = 0x2
+	STATX_MTIME                          = 0x40
+	STATX_NLINK                          = 0x4
+	STATX_SIZE                           = 0x200
+	STATX_TYPE                           = 0x1
+	STATX_UID                            = 0x8
+	STATX__RESERVED                      = 0x80000000
 	S_BLKSIZE                            = 0x200
 	S_IEXEC                              = 0x40
 	S_IFBLK                              = 0x6000

+ 21 - 0
unix/zerrors_linux_mips.go

@@ -1641,6 +1641,27 @@ const (
 	SPLICE_F_MORE                        = 0x4
 	SPLICE_F_MOVE                        = 0x1
 	SPLICE_F_NONBLOCK                    = 0x2
+	STATX_ALL                            = 0xfff
+	STATX_ATIME                          = 0x20
+	STATX_ATTR_APPEND                    = 0x20
+	STATX_ATTR_AUTOMOUNT                 = 0x1000
+	STATX_ATTR_COMPRESSED                = 0x4
+	STATX_ATTR_ENCRYPTED                 = 0x800
+	STATX_ATTR_IMMUTABLE                 = 0x10
+	STATX_ATTR_NODUMP                    = 0x40
+	STATX_BASIC_STATS                    = 0x7ff
+	STATX_BLOCKS                         = 0x400
+	STATX_BTIME                          = 0x800
+	STATX_CTIME                          = 0x80
+	STATX_GID                            = 0x10
+	STATX_INO                            = 0x100
+	STATX_MODE                           = 0x2
+	STATX_MTIME                          = 0x40
+	STATX_NLINK                          = 0x4
+	STATX_SIZE                           = 0x200
+	STATX_TYPE                           = 0x1
+	STATX_UID                            = 0x8
+	STATX__RESERVED                      = 0x80000000
 	S_BLKSIZE                            = 0x200
 	S_IEXEC                              = 0x40
 	S_IFBLK                              = 0x6000

+ 21 - 0
unix/zerrors_linux_mips64.go

@@ -1641,6 +1641,27 @@ const (
 	SPLICE_F_MORE                        = 0x4
 	SPLICE_F_MOVE                        = 0x1
 	SPLICE_F_NONBLOCK                    = 0x2
+	STATX_ALL                            = 0xfff
+	STATX_ATIME                          = 0x20
+	STATX_ATTR_APPEND                    = 0x20
+	STATX_ATTR_AUTOMOUNT                 = 0x1000
+	STATX_ATTR_COMPRESSED                = 0x4
+	STATX_ATTR_ENCRYPTED                 = 0x800
+	STATX_ATTR_IMMUTABLE                 = 0x10
+	STATX_ATTR_NODUMP                    = 0x40
+	STATX_BASIC_STATS                    = 0x7ff
+	STATX_BLOCKS                         = 0x400
+	STATX_BTIME                          = 0x800
+	STATX_CTIME                          = 0x80
+	STATX_GID                            = 0x10
+	STATX_INO                            = 0x100
+	STATX_MODE                           = 0x2
+	STATX_MTIME                          = 0x40
+	STATX_NLINK                          = 0x4
+	STATX_SIZE                           = 0x200
+	STATX_TYPE                           = 0x1
+	STATX_UID                            = 0x8
+	STATX__RESERVED                      = 0x80000000
 	S_BLKSIZE                            = 0x200
 	S_IEXEC                              = 0x40
 	S_IFBLK                              = 0x6000

+ 21 - 0
unix/zerrors_linux_mips64le.go

@@ -1641,6 +1641,27 @@ const (
 	SPLICE_F_MORE                        = 0x4
 	SPLICE_F_MOVE                        = 0x1
 	SPLICE_F_NONBLOCK                    = 0x2
+	STATX_ALL                            = 0xfff
+	STATX_ATIME                          = 0x20
+	STATX_ATTR_APPEND                    = 0x20
+	STATX_ATTR_AUTOMOUNT                 = 0x1000
+	STATX_ATTR_COMPRESSED                = 0x4
+	STATX_ATTR_ENCRYPTED                 = 0x800
+	STATX_ATTR_IMMUTABLE                 = 0x10
+	STATX_ATTR_NODUMP                    = 0x40
+	STATX_BASIC_STATS                    = 0x7ff
+	STATX_BLOCKS                         = 0x400
+	STATX_BTIME                          = 0x800
+	STATX_CTIME                          = 0x80
+	STATX_GID                            = 0x10
+	STATX_INO                            = 0x100
+	STATX_MODE                           = 0x2
+	STATX_MTIME                          = 0x40
+	STATX_NLINK                          = 0x4
+	STATX_SIZE                           = 0x200
+	STATX_TYPE                           = 0x1
+	STATX_UID                            = 0x8
+	STATX__RESERVED                      = 0x80000000
 	S_BLKSIZE                            = 0x200
 	S_IEXEC                              = 0x40
 	S_IFBLK                              = 0x6000

+ 21 - 0
unix/zerrors_linux_mipsle.go

@@ -1641,6 +1641,27 @@ const (
 	SPLICE_F_MORE                        = 0x4
 	SPLICE_F_MOVE                        = 0x1
 	SPLICE_F_NONBLOCK                    = 0x2
+	STATX_ALL                            = 0xfff
+	STATX_ATIME                          = 0x20
+	STATX_ATTR_APPEND                    = 0x20
+	STATX_ATTR_AUTOMOUNT                 = 0x1000
+	STATX_ATTR_COMPRESSED                = 0x4
+	STATX_ATTR_ENCRYPTED                 = 0x800
+	STATX_ATTR_IMMUTABLE                 = 0x10
+	STATX_ATTR_NODUMP                    = 0x40
+	STATX_BASIC_STATS                    = 0x7ff
+	STATX_BLOCKS                         = 0x400
+	STATX_BTIME                          = 0x800
+	STATX_CTIME                          = 0x80
+	STATX_GID                            = 0x10
+	STATX_INO                            = 0x100
+	STATX_MODE                           = 0x2
+	STATX_MTIME                          = 0x40
+	STATX_NLINK                          = 0x4
+	STATX_SIZE                           = 0x200
+	STATX_TYPE                           = 0x1
+	STATX_UID                            = 0x8
+	STATX__RESERVED                      = 0x80000000
 	S_BLKSIZE                            = 0x200
 	S_IEXEC                              = 0x40
 	S_IFBLK                              = 0x6000

+ 21 - 0
unix/zerrors_linux_ppc64.go

@@ -1696,6 +1696,27 @@ const (
 	SPLICE_F_MORE                        = 0x4
 	SPLICE_F_MOVE                        = 0x1
 	SPLICE_F_NONBLOCK                    = 0x2
+	STATX_ALL                            = 0xfff
+	STATX_ATIME                          = 0x20
+	STATX_ATTR_APPEND                    = 0x20
+	STATX_ATTR_AUTOMOUNT                 = 0x1000
+	STATX_ATTR_COMPRESSED                = 0x4
+	STATX_ATTR_ENCRYPTED                 = 0x800
+	STATX_ATTR_IMMUTABLE                 = 0x10
+	STATX_ATTR_NODUMP                    = 0x40
+	STATX_BASIC_STATS                    = 0x7ff
+	STATX_BLOCKS                         = 0x400
+	STATX_BTIME                          = 0x800
+	STATX_CTIME                          = 0x80
+	STATX_GID                            = 0x10
+	STATX_INO                            = 0x100
+	STATX_MODE                           = 0x2
+	STATX_MTIME                          = 0x40
+	STATX_NLINK                          = 0x4
+	STATX_SIZE                           = 0x200
+	STATX_TYPE                           = 0x1
+	STATX_UID                            = 0x8
+	STATX__RESERVED                      = 0x80000000
 	S_BLKSIZE                            = 0x200
 	S_IEXEC                              = 0x40
 	S_IFBLK                              = 0x6000

+ 21 - 0
unix/zerrors_linux_ppc64le.go

@@ -1696,6 +1696,27 @@ const (
 	SPLICE_F_MORE                        = 0x4
 	SPLICE_F_MOVE                        = 0x1
 	SPLICE_F_NONBLOCK                    = 0x2
+	STATX_ALL                            = 0xfff
+	STATX_ATIME                          = 0x20
+	STATX_ATTR_APPEND                    = 0x20
+	STATX_ATTR_AUTOMOUNT                 = 0x1000
+	STATX_ATTR_COMPRESSED                = 0x4
+	STATX_ATTR_ENCRYPTED                 = 0x800
+	STATX_ATTR_IMMUTABLE                 = 0x10
+	STATX_ATTR_NODUMP                    = 0x40
+	STATX_BASIC_STATS                    = 0x7ff
+	STATX_BLOCKS                         = 0x400
+	STATX_BTIME                          = 0x800
+	STATX_CTIME                          = 0x80
+	STATX_GID                            = 0x10
+	STATX_INO                            = 0x100
+	STATX_MODE                           = 0x2
+	STATX_MTIME                          = 0x40
+	STATX_NLINK                          = 0x4
+	STATX_SIZE                           = 0x200
+	STATX_TYPE                           = 0x1
+	STATX_UID                            = 0x8
+	STATX__RESERVED                      = 0x80000000
 	S_BLKSIZE                            = 0x200
 	S_IEXEC                              = 0x40
 	S_IFBLK                              = 0x6000

+ 21 - 0
unix/zerrors_linux_s390x.go

@@ -1700,6 +1700,27 @@ const (
 	SPLICE_F_MORE                        = 0x4
 	SPLICE_F_MOVE                        = 0x1
 	SPLICE_F_NONBLOCK                    = 0x2
+	STATX_ALL                            = 0xfff
+	STATX_ATIME                          = 0x20
+	STATX_ATTR_APPEND                    = 0x20
+	STATX_ATTR_AUTOMOUNT                 = 0x1000
+	STATX_ATTR_COMPRESSED                = 0x4
+	STATX_ATTR_ENCRYPTED                 = 0x800
+	STATX_ATTR_IMMUTABLE                 = 0x10
+	STATX_ATTR_NODUMP                    = 0x40
+	STATX_BASIC_STATS                    = 0x7ff
+	STATX_BLOCKS                         = 0x400
+	STATX_BTIME                          = 0x800
+	STATX_CTIME                          = 0x80
+	STATX_GID                            = 0x10
+	STATX_INO                            = 0x100
+	STATX_MODE                           = 0x2
+	STATX_MTIME                          = 0x40
+	STATX_NLINK                          = 0x4
+	STATX_SIZE                           = 0x200
+	STATX_TYPE                           = 0x1
+	STATX_UID                            = 0x8
+	STATX__RESERVED                      = 0x80000000
 	S_BLKSIZE                            = 0x200
 	S_IEXEC                              = 0x40
 	S_IFBLK                              = 0x6000

+ 15 - 0
unix/zsyscall_linux_386.go

@@ -1238,6 +1238,21 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() {
 	SyscallNoError(SYS_SYNC, 0, 0, 0)
 	return

+ 15 - 0
unix/zsyscall_linux_amd64.go

@@ -1238,6 +1238,21 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() {
 	SyscallNoError(SYS_SYNC, 0, 0, 0)
 	return

+ 15 - 0
unix/zsyscall_linux_arm.go

@@ -1238,6 +1238,21 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() {
 	SyscallNoError(SYS_SYNC, 0, 0, 0)
 	return

+ 15 - 0
unix/zsyscall_linux_arm64.go

@@ -1238,6 +1238,21 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() {
 	SyscallNoError(SYS_SYNC, 0, 0, 0)
 	return

+ 15 - 0
unix/zsyscall_linux_mips.go

@@ -1238,6 +1238,21 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() {
 	SyscallNoError(SYS_SYNC, 0, 0, 0)
 	return

+ 15 - 0
unix/zsyscall_linux_mips64.go

@@ -1238,6 +1238,21 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() {
 	SyscallNoError(SYS_SYNC, 0, 0, 0)
 	return

+ 15 - 0
unix/zsyscall_linux_mips64le.go

@@ -1238,6 +1238,21 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() {
 	SyscallNoError(SYS_SYNC, 0, 0, 0)
 	return

+ 15 - 0
unix/zsyscall_linux_mipsle.go

@@ -1238,6 +1238,21 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() {
 	SyscallNoError(SYS_SYNC, 0, 0, 0)
 	return

+ 15 - 0
unix/zsyscall_linux_ppc64.go

@@ -1238,6 +1238,21 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() {
 	SyscallNoError(SYS_SYNC, 0, 0, 0)
 	return

+ 15 - 0
unix/zsyscall_linux_ppc64le.go

@@ -1238,6 +1238,21 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() {
 	SyscallNoError(SYS_SYNC, 0, 0, 0)
 	return

+ 15 - 0
unix/zsyscall_linux_s390x.go

@@ -1238,6 +1238,21 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() {
 	SyscallNoError(SYS_SYNC, 0, 0, 0)
 	return

+ 39 - 3
unix/ztypes_linux_386.go

@@ -131,6 +131,36 @@ type Statfs_t struct {
 	Spare   [4]int32
 }
 
+type StatxTimestamp struct {
+	Sec         int64
+	Nsec        uint32
+	X__reserved int32
+}
+
+type Statx_t struct {
+	Mask            uint32
+	Blksize         uint32
+	Attributes      uint64
+	Nlink           uint32
+	Uid             uint32
+	Gid             uint32
+	Mode            uint16
+	_               [1]uint16
+	Ino             uint64
+	Size            uint64
+	Blocks          uint64
+	Attributes_mask uint64
+	Atime           StatxTimestamp
+	Btime           StatxTimestamp
+	Ctime           StatxTimestamp
+	Mtime           StatxTimestamp
+	Rdev_major      uint32
+	Rdev_minor      uint32
+	Dev_major       uint32
+	Dev_minor       uint32
+	_               [14]uint64
+}
+
 type Dirent struct {
 	Ino       uint64
 	Off       int64
@@ -643,9 +673,15 @@ type EpollEvent struct {
 }
 
 const (
-	AT_FDCWD            = -0x64
-	AT_NO_AUTOMOUNT     = 0x800
-	AT_REMOVEDIR        = 0x200
+	AT_EMPTY_PATH   = 0x1000
+	AT_FDCWD        = -0x64
+	AT_NO_AUTOMOUNT = 0x800
+	AT_REMOVEDIR    = 0x200
+
+	AT_STATX_SYNC_AS_STAT = 0x0
+	AT_STATX_FORCE_SYNC   = 0x2000
+	AT_STATX_DONT_SYNC    = 0x4000
+
 	AT_SYMLINK_FOLLOW   = 0x400
 	AT_SYMLINK_NOFOLLOW = 0x100
 )

+ 39 - 3
unix/ztypes_linux_amd64.go

@@ -131,6 +131,36 @@ type Statfs_t struct {
 	Spare   [4]int64
 }
 
+type StatxTimestamp struct {
+	Sec         int64
+	Nsec        uint32
+	X__reserved int32
+}
+
+type Statx_t struct {
+	Mask            uint32
+	Blksize         uint32
+	Attributes      uint64
+	Nlink           uint32
+	Uid             uint32
+	Gid             uint32
+	Mode            uint16
+	_               [1]uint16
+	Ino             uint64
+	Size            uint64
+	Blocks          uint64
+	Attributes_mask uint64
+	Atime           StatxTimestamp
+	Btime           StatxTimestamp
+	Ctime           StatxTimestamp
+	Mtime           StatxTimestamp
+	Rdev_major      uint32
+	Rdev_minor      uint32
+	Dev_major       uint32
+	Dev_minor       uint32
+	_               [14]uint64
+}
+
 type Dirent struct {
 	Ino       uint64
 	Off       int64
@@ -661,9 +691,15 @@ type EpollEvent struct {
 }
 
 const (
-	AT_FDCWD            = -0x64
-	AT_NO_AUTOMOUNT     = 0x800
-	AT_REMOVEDIR        = 0x200
+	AT_EMPTY_PATH   = 0x1000
+	AT_FDCWD        = -0x64
+	AT_NO_AUTOMOUNT = 0x800
+	AT_REMOVEDIR    = 0x200
+
+	AT_STATX_SYNC_AS_STAT = 0x0
+	AT_STATX_FORCE_SYNC   = 0x2000
+	AT_STATX_DONT_SYNC    = 0x4000
+
 	AT_SYMLINK_FOLLOW   = 0x400
 	AT_SYMLINK_NOFOLLOW = 0x100
 )

+ 39 - 3
unix/ztypes_linux_arm.go

@@ -133,6 +133,36 @@ type Statfs_t struct {
 	Pad_cgo_0 [4]byte
 }
 
+type StatxTimestamp struct {
+	Sec         int64
+	Nsec        uint32
+	X__reserved int32
+}
+
+type Statx_t struct {
+	Mask            uint32
+	Blksize         uint32
+	Attributes      uint64
+	Nlink           uint32
+	Uid             uint32
+	Gid             uint32
+	Mode            uint16
+	_               [1]uint16
+	Ino             uint64
+	Size            uint64
+	Blocks          uint64
+	Attributes_mask uint64
+	Atime           StatxTimestamp
+	Btime           StatxTimestamp
+	Ctime           StatxTimestamp
+	Mtime           StatxTimestamp
+	Rdev_major      uint32
+	Rdev_minor      uint32
+	Dev_major       uint32
+	Dev_minor       uint32
+	_               [14]uint64
+}
+
 type Dirent struct {
 	Ino       uint64
 	Off       int64
@@ -632,9 +662,15 @@ type EpollEvent struct {
 }
 
 const (
-	AT_FDCWD            = -0x64
-	AT_NO_AUTOMOUNT     = 0x800
-	AT_REMOVEDIR        = 0x200
+	AT_EMPTY_PATH   = 0x1000
+	AT_FDCWD        = -0x64
+	AT_NO_AUTOMOUNT = 0x800
+	AT_REMOVEDIR    = 0x200
+
+	AT_STATX_SYNC_AS_STAT = 0x0
+	AT_STATX_FORCE_SYNC   = 0x2000
+	AT_STATX_DONT_SYNC    = 0x4000
+
 	AT_SYMLINK_FOLLOW   = 0x400
 	AT_SYMLINK_NOFOLLOW = 0x100
 )

+ 39 - 3
unix/ztypes_linux_arm64.go

@@ -132,6 +132,36 @@ type Statfs_t struct {
 	Spare   [4]int64
 }
 
+type StatxTimestamp struct {
+	Sec         int64
+	Nsec        uint32
+	X__reserved int32
+}
+
+type Statx_t struct {
+	Mask            uint32
+	Blksize         uint32
+	Attributes      uint64
+	Nlink           uint32
+	Uid             uint32
+	Gid             uint32
+	Mode            uint16
+	_               [1]uint16
+	Ino             uint64
+	Size            uint64
+	Blocks          uint64
+	Attributes_mask uint64
+	Atime           StatxTimestamp
+	Btime           StatxTimestamp
+	Ctime           StatxTimestamp
+	Mtime           StatxTimestamp
+	Rdev_major      uint32
+	Rdev_minor      uint32
+	Dev_major       uint32
+	Dev_minor       uint32
+	_               [14]uint64
+}
+
 type Dirent struct {
 	Ino       uint64
 	Off       int64
@@ -640,9 +670,15 @@ type EpollEvent struct {
 }
 
 const (
-	AT_FDCWD            = -0x64
-	AT_NO_AUTOMOUNT     = 0x800
-	AT_REMOVEDIR        = 0x200
+	AT_EMPTY_PATH   = 0x1000
+	AT_FDCWD        = -0x64
+	AT_NO_AUTOMOUNT = 0x800
+	AT_REMOVEDIR    = 0x200
+
+	AT_STATX_SYNC_AS_STAT = 0x0
+	AT_STATX_FORCE_SYNC   = 0x2000
+	AT_STATX_DONT_SYNC    = 0x4000
+
 	AT_SYMLINK_FOLLOW   = 0x400
 	AT_SYMLINK_NOFOLLOW = 0x100
 )

+ 39 - 3
unix/ztypes_linux_mips.go

@@ -132,6 +132,36 @@ type Statfs_t struct {
 	Pad_cgo_1 [4]byte
 }
 
+type StatxTimestamp struct {
+	Sec         int64
+	Nsec        uint32
+	X__reserved int32
+}
+
+type Statx_t struct {
+	Mask            uint32
+	Blksize         uint32
+	Attributes      uint64
+	Nlink           uint32
+	Uid             uint32
+	Gid             uint32
+	Mode            uint16
+	_               [1]uint16
+	Ino             uint64
+	Size            uint64
+	Blocks          uint64
+	Attributes_mask uint64
+	Atime           StatxTimestamp
+	Btime           StatxTimestamp
+	Ctime           StatxTimestamp
+	Mtime           StatxTimestamp
+	Rdev_major      uint32
+	Rdev_minor      uint32
+	Dev_major       uint32
+	Dev_minor       uint32
+	_               [14]uint64
+}
+
 type Dirent struct {
 	Ino       uint64
 	Off       int64
@@ -637,9 +667,15 @@ type EpollEvent struct {
 }
 
 const (
-	AT_FDCWD            = -0x64
-	AT_NO_AUTOMOUNT     = 0x800
-	AT_REMOVEDIR        = 0x200
+	AT_EMPTY_PATH   = 0x1000
+	AT_FDCWD        = -0x64
+	AT_NO_AUTOMOUNT = 0x800
+	AT_REMOVEDIR    = 0x200
+
+	AT_STATX_SYNC_AS_STAT = 0x0
+	AT_STATX_FORCE_SYNC   = 0x2000
+	AT_STATX_DONT_SYNC    = 0x4000
+
 	AT_SYMLINK_FOLLOW   = 0x400
 	AT_SYMLINK_NOFOLLOW = 0x100
 )

+ 39 - 3
unix/ztypes_linux_mips64.go

@@ -132,6 +132,36 @@ type Statfs_t struct {
 	Spare   [5]int64
 }
 
+type StatxTimestamp struct {
+	Sec         int64
+	Nsec        uint32
+	X__reserved int32
+}
+
+type Statx_t struct {
+	Mask            uint32
+	Blksize         uint32
+	Attributes      uint64
+	Nlink           uint32
+	Uid             uint32
+	Gid             uint32
+	Mode            uint16
+	_               [1]uint16
+	Ino             uint64
+	Size            uint64
+	Blocks          uint64
+	Attributes_mask uint64
+	Atime           StatxTimestamp
+	Btime           StatxTimestamp
+	Ctime           StatxTimestamp
+	Mtime           StatxTimestamp
+	Rdev_major      uint32
+	Rdev_minor      uint32
+	Dev_major       uint32
+	Dev_minor       uint32
+	_               [14]uint64
+}
+
 type Dirent struct {
 	Ino       uint64
 	Off       int64
@@ -642,9 +672,15 @@ type EpollEvent struct {
 }
 
 const (
-	AT_FDCWD            = -0x64
-	AT_NO_AUTOMOUNT     = 0x800
-	AT_REMOVEDIR        = 0x200
+	AT_EMPTY_PATH   = 0x1000
+	AT_FDCWD        = -0x64
+	AT_NO_AUTOMOUNT = 0x800
+	AT_REMOVEDIR    = 0x200
+
+	AT_STATX_SYNC_AS_STAT = 0x0
+	AT_STATX_FORCE_SYNC   = 0x2000
+	AT_STATX_DONT_SYNC    = 0x4000
+
 	AT_SYMLINK_FOLLOW   = 0x400
 	AT_SYMLINK_NOFOLLOW = 0x100
 )

+ 39 - 3
unix/ztypes_linux_mips64le.go

@@ -132,6 +132,36 @@ type Statfs_t struct {
 	Spare   [5]int64
 }
 
+type StatxTimestamp struct {
+	Sec         int64
+	Nsec        uint32
+	X__reserved int32
+}
+
+type Statx_t struct {
+	Mask            uint32
+	Blksize         uint32
+	Attributes      uint64
+	Nlink           uint32
+	Uid             uint32
+	Gid             uint32
+	Mode            uint16
+	_               [1]uint16
+	Ino             uint64
+	Size            uint64
+	Blocks          uint64
+	Attributes_mask uint64
+	Atime           StatxTimestamp
+	Btime           StatxTimestamp
+	Ctime           StatxTimestamp
+	Mtime           StatxTimestamp
+	Rdev_major      uint32
+	Rdev_minor      uint32
+	Dev_major       uint32
+	Dev_minor       uint32
+	_               [14]uint64
+}
+
 type Dirent struct {
 	Ino       uint64
 	Off       int64
@@ -642,9 +672,15 @@ type EpollEvent struct {
 }
 
 const (
-	AT_FDCWD            = -0x64
-	AT_NO_AUTOMOUNT     = 0x800
-	AT_REMOVEDIR        = 0x200
+	AT_EMPTY_PATH   = 0x1000
+	AT_FDCWD        = -0x64
+	AT_NO_AUTOMOUNT = 0x800
+	AT_REMOVEDIR    = 0x200
+
+	AT_STATX_SYNC_AS_STAT = 0x0
+	AT_STATX_FORCE_SYNC   = 0x2000
+	AT_STATX_DONT_SYNC    = 0x4000
+
 	AT_SYMLINK_FOLLOW   = 0x400
 	AT_SYMLINK_NOFOLLOW = 0x100
 )

+ 39 - 3
unix/ztypes_linux_mipsle.go

@@ -132,6 +132,36 @@ type Statfs_t struct {
 	Pad_cgo_1 [4]byte
 }
 
+type StatxTimestamp struct {
+	Sec         int64
+	Nsec        uint32
+	X__reserved int32
+}
+
+type Statx_t struct {
+	Mask            uint32
+	Blksize         uint32
+	Attributes      uint64
+	Nlink           uint32
+	Uid             uint32
+	Gid             uint32
+	Mode            uint16
+	_               [1]uint16
+	Ino             uint64
+	Size            uint64
+	Blocks          uint64
+	Attributes_mask uint64
+	Atime           StatxTimestamp
+	Btime           StatxTimestamp
+	Ctime           StatxTimestamp
+	Mtime           StatxTimestamp
+	Rdev_major      uint32
+	Rdev_minor      uint32
+	Dev_major       uint32
+	Dev_minor       uint32
+	_               [14]uint64
+}
+
 type Dirent struct {
 	Ino       uint64
 	Off       int64
@@ -637,9 +667,15 @@ type EpollEvent struct {
 }
 
 const (
-	AT_FDCWD            = -0x64
-	AT_NO_AUTOMOUNT     = 0x800
-	AT_REMOVEDIR        = 0x200
+	AT_EMPTY_PATH   = 0x1000
+	AT_FDCWD        = -0x64
+	AT_NO_AUTOMOUNT = 0x800
+	AT_REMOVEDIR    = 0x200
+
+	AT_STATX_SYNC_AS_STAT = 0x0
+	AT_STATX_FORCE_SYNC   = 0x2000
+	AT_STATX_DONT_SYNC    = 0x4000
+
 	AT_SYMLINK_FOLLOW   = 0x400
 	AT_SYMLINK_NOFOLLOW = 0x100
 )

+ 39 - 3
unix/ztypes_linux_ppc64.go

@@ -133,6 +133,36 @@ type Statfs_t struct {
 	Spare   [4]int64
 }
 
+type StatxTimestamp struct {
+	Sec         int64
+	Nsec        uint32
+	X__reserved int32
+}
+
+type Statx_t struct {
+	Mask            uint32
+	Blksize         uint32
+	Attributes      uint64
+	Nlink           uint32
+	Uid             uint32
+	Gid             uint32
+	Mode            uint16
+	_               [1]uint16
+	Ino             uint64
+	Size            uint64
+	Blocks          uint64
+	Attributes_mask uint64
+	Atime           StatxTimestamp
+	Btime           StatxTimestamp
+	Ctime           StatxTimestamp
+	Mtime           StatxTimestamp
+	Rdev_major      uint32
+	Rdev_minor      uint32
+	Dev_major       uint32
+	Dev_minor       uint32
+	_               [14]uint64
+}
+
 type Dirent struct {
 	Ino       uint64
 	Off       int64
@@ -650,9 +680,15 @@ type EpollEvent struct {
 }
 
 const (
-	AT_FDCWD            = -0x64
-	AT_NO_AUTOMOUNT     = 0x800
-	AT_REMOVEDIR        = 0x200
+	AT_EMPTY_PATH   = 0x1000
+	AT_FDCWD        = -0x64
+	AT_NO_AUTOMOUNT = 0x800
+	AT_REMOVEDIR    = 0x200
+
+	AT_STATX_SYNC_AS_STAT = 0x0
+	AT_STATX_FORCE_SYNC   = 0x2000
+	AT_STATX_DONT_SYNC    = 0x4000
+
 	AT_SYMLINK_FOLLOW   = 0x400
 	AT_SYMLINK_NOFOLLOW = 0x100
 )

+ 39 - 3
unix/ztypes_linux_ppc64le.go

@@ -133,6 +133,36 @@ type Statfs_t struct {
 	Spare   [4]int64
 }
 
+type StatxTimestamp struct {
+	Sec         int64
+	Nsec        uint32
+	X__reserved int32
+}
+
+type Statx_t struct {
+	Mask            uint32
+	Blksize         uint32
+	Attributes      uint64
+	Nlink           uint32
+	Uid             uint32
+	Gid             uint32
+	Mode            uint16
+	_               [1]uint16
+	Ino             uint64
+	Size            uint64
+	Blocks          uint64
+	Attributes_mask uint64
+	Atime           StatxTimestamp
+	Btime           StatxTimestamp
+	Ctime           StatxTimestamp
+	Mtime           StatxTimestamp
+	Rdev_major      uint32
+	Rdev_minor      uint32
+	Dev_major       uint32
+	Dev_minor       uint32
+	_               [14]uint64
+}
+
 type Dirent struct {
 	Ino       uint64
 	Off       int64
@@ -650,9 +680,15 @@ type EpollEvent struct {
 }
 
 const (
-	AT_FDCWD            = -0x64
-	AT_NO_AUTOMOUNT     = 0x800
-	AT_REMOVEDIR        = 0x200
+	AT_EMPTY_PATH   = 0x1000
+	AT_FDCWD        = -0x64
+	AT_NO_AUTOMOUNT = 0x800
+	AT_REMOVEDIR    = 0x200
+
+	AT_STATX_SYNC_AS_STAT = 0x0
+	AT_STATX_FORCE_SYNC   = 0x2000
+	AT_STATX_DONT_SYNC    = 0x4000
+
 	AT_SYMLINK_FOLLOW   = 0x400
 	AT_SYMLINK_NOFOLLOW = 0x100
 )

+ 39 - 3
unix/ztypes_linux_s390x.go

@@ -132,6 +132,36 @@ type Statfs_t struct {
 	_       [4]byte
 }
 
+type StatxTimestamp struct {
+	Sec  int64
+	Nsec uint32
+	_    int32
+}
+
+type Statx_t struct {
+	Mask            uint32
+	Blksize         uint32
+	Attributes      uint64
+	Nlink           uint32
+	Uid             uint32
+	Gid             uint32
+	Mode            uint16
+	_               [1]uint16
+	Ino             uint64
+	Size            uint64
+	Blocks          uint64
+	Attributes_mask uint64
+	Atime           StatxTimestamp
+	Btime           StatxTimestamp
+	Ctime           StatxTimestamp
+	Mtime           StatxTimestamp
+	Rdev_major      uint32
+	Rdev_minor      uint32
+	Dev_major       uint32
+	Dev_minor       uint32
+	_               [14]uint64
+}
+
 type Dirent struct {
 	Ino    uint64
 	Off    int64
@@ -667,9 +697,15 @@ type EpollEvent struct {
 }
 
 const (
-	AT_FDCWD            = -0x64
-	AT_NO_AUTOMOUNT     = 0x800
-	AT_REMOVEDIR        = 0x200
+	AT_EMPTY_PATH   = 0x1000
+	AT_FDCWD        = -0x64
+	AT_NO_AUTOMOUNT = 0x800
+	AT_REMOVEDIR    = 0x200
+
+	AT_STAT_ = 0x0
+	AT_STAT_ = 0x2000
+	AT_STAT_ = 0x4000
+
 	AT_SYMLINK_FOLLOW   = 0x400
 	AT_SYMLINK_NOFOLLOW = 0x100
 )