Messages in this thread Patch in this message | | | From | chris.chenfeiyang@gmail ... | Subject | [PATCH 1/3] nolibc: Add statx() support to implement sys_stat() | Date | Tue, 7 Feb 2023 10:09:40 +0800 |
| |
From: Feiyang Chen <chenfeiyang@loongson.cn>
Neither __NR_newfstatat nor __NR_stat is defined on new architecture like LoongArch, but we can use statx() to implement sys_stat().
Signed-off-by: Feiyang Chen <chenfeiyang@loongson.cn> --- tools/include/nolibc/sys.h | 36 +++++++++++++++++++++++++--- tools/include/nolibc/types.h | 46 ++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 3 deletions(-)
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h index b5f8cd35c03b..7ff9b401008a 100644 --- a/tools/include/nolibc/sys.h +++ b/tools/include/nolibc/sys.h @@ -1054,6 +1054,7 @@ pid_t setsid(void) * Warning: the struct stat's layout is arch-dependent. */ +#if defined(__NR_newfstatat) || defined(__NR_stat) static __attribute__((unused)) int sys_stat(const char *path, struct stat *buf) { @@ -1063,10 +1064,8 @@ int sys_stat(const char *path, struct stat *buf) #ifdef __NR_newfstatat /* only solution for arm64 */ ret = my_syscall4(__NR_newfstatat, AT_FDCWD, path, &stat, 0); -#elif defined(__NR_stat) +#else /* __NR_stat */ ret = my_syscall2(__NR_stat, path, &stat); -#else -#error Neither __NR_newfstatat nor __NR_stat defined, cannot implement sys_stat() #endif buf->st_dev = stat.st_dev; buf->st_ino = stat.st_ino; @@ -1083,6 +1082,37 @@ int sys_stat(const char *path, struct stat *buf) buf->st_ctime = stat.st_ctime; return ret; } +#elif defined(__NR_statx) +/* only solution for loongarch */ +static __attribute__((unused)) +int sys_stat(const char *path, struct stat *buf) +{ + struct statx statx; + long ret; + + ret = my_syscall5(__NR_statx, AT_FDCWD, path, 0, STATX_BASIC_STATS, &statx); + buf->st_dev = ((statx.stx_dev_minor & 0xff) + | (statx.stx_dev_major << 8) + | ((statx.stx_dev_minor & ~0xff) << 12)); + buf->st_ino = statx.stx_ino; + buf->st_mode = statx.stx_mode; + buf->st_nlink = statx.stx_nlink; + buf->st_uid = statx.stx_uid; + buf->st_gid = statx.stx_gid; + buf->st_rdev = ((statx.stx_rdev_minor & 0xff) + | (statx.stx_rdev_major << 8) | + ((statx.stx_rdev_minor & ~0xff) << 12)); + buf->st_size = statx.stx_size; + buf->st_blksize = statx.stx_blksize; + buf->st_blocks = statx.stx_blocks; + buf->st_atime = statx.stx_atime.tv_sec; + buf->st_mtime = statx.stx_mtime.tv_sec; + buf->st_ctime = statx.stx_ctime.tv_sec; + return ret; +} +#else +#error None of __NR_newfstatat, __NR_stat, nor __NR_statx defined, cannot implement sys_stat() +#endif static __attribute__((unused)) int stat(const char *path, struct stat *buf) diff --git a/tools/include/nolibc/types.h b/tools/include/nolibc/types.h index fbbc0e68c001..9b244af1ec2c 100644 --- a/tools/include/nolibc/types.h +++ b/tools/include/nolibc/types.h @@ -193,6 +193,52 @@ struct stat { time_t st_ctime; /* time of last status change */ }; +/* for statx() */ +#ifndef STATX_BASIC_STATS +#define STATX_BASIC_STATS (0x000007ffU) +#endif + +struct statx_timestamp { + __s64 tv_sec; + __u32 tv_nsec; + __s32 __reserved; +}; + +struct statx { + /* 0x00 */ + __u32 stx_mask; /* What results were written [uncond] */ + __u32 stx_blksize; /* Preferred general I/O size [uncond] */ + __u64 stx_attributes; /* Flags conveying information about the file [uncond] */ + /* 0x10 */ + __u32 stx_nlink; /* Number of hard links */ + __u32 stx_uid; /* User ID of owner */ + __u32 stx_gid; /* Group ID of owner */ + __u16 stx_mode; /* File mode */ + __u16 __spare0[1]; + /* 0x20 */ + __u64 stx_ino; /* Inode number */ + __u64 stx_size; /* File size */ + __u64 stx_blocks; /* Number of 512-byte blocks allocated */ + __u64 stx_attributes_mask; /* Mask to show what's supported in stx_attributes */ + /* 0x40 */ + struct statx_timestamp stx_atime; /* Last access time */ + struct statx_timestamp stx_btime; /* File creation time */ + struct statx_timestamp stx_ctime; /* Last attribute change time */ + struct statx_timestamp stx_mtime; /* Last data modification time */ + /* 0x80 */ + __u32 stx_rdev_major; /* Device ID of special file [if bdev/cdev] */ + __u32 stx_rdev_minor; + __u32 stx_dev_major; /* ID of device containing file [uncond] */ + __u32 stx_dev_minor; + /* 0x90 */ + __u64 stx_mnt_id; + __u32 stx_dio_mem_align; /* Memory buffer alignment for direct I/O */ + __u32 stx_dio_offset_align; /* File offset alignment for direct I/O */ + /* 0xa0 */ + __u64 __spare3[12]; /* Spare space for future expansion */ + /* 0x100 */ +}; + /* WARNING, it only deals with the 4096 first majors and 256 first minors */ #define makedev(major, minor) ((dev_t)((((major) & 0xfff) << 8) | ((minor) & 0xff))) #define major(dev) ((unsigned int)(((dev) >> 8) & 0xfff)) -- 2.39.0
| |