From: Yann Sionneau ysionneau@kalray.eu
Define fstatat64 as a wrapper of statx if the kernel does not support fstatat64 syscall This is the case for non-legacy architectures that don't define __ARCH_WANT_NEW_STAT in their linux arch/xxx/include/asm/unistd.h
Signed-off-by: Yann Sionneau ysionneau@kalray.eu
--- libc/sysdeps/linux/common/fstatat64.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/libc/sysdeps/linux/common/fstatat64.c b/libc/sysdeps/linux/common/fstatat64.c index 711521a6a..836ed4114 100644 --- a/libc/sysdeps/linux/common/fstatat64.c +++ b/libc/sysdeps/linux/common/fstatat64.c @@ -43,5 +43,28 @@ int fstatat64(int fd, const char *file, struct stat64 *buf, int flag) } libc_hidden_def(fstatat64) #else + +#if defined(__NR_statx) && defined(__UCLIBC_HAVE_STATX__) +# include <sys/stat.h> +# include <statx_cp.h> +# include <fcntl.h> // for AT_NO_AUTOMOUNT + +int fstatat64(int fd, const char *file, struct stat64 *buf, int flag) +{ + struct statx tmp; + + int r = INLINE_SYSCALL(statx, 5, fd, file, AT_NO_AUTOMOUNT | flag, + STATX_BASIC_STATS, &tmp); + + if (r != 0) + return r; + + __cp_stat_statx ((struct stat *)buf, &tmp); + + return 0; +} +libc_hidden_def(fstatat64) +#endif + /* should add emulation with fstat64() and /proc/self/fd/ ... */ #endif
From: Yann Sionneau ysionneau@kalray.eu
Add missing return value statement to fstat for the statx wrapping case.
Signed-off-by: Yann Sionneau ysionneau@kalray.eu
--- libc/sysdeps/linux/common/fstat.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/libc/sysdeps/linux/common/fstat.c b/libc/sysdeps/linux/common/fstat.c index 0b2798ad4..86c24bff6 100644 --- a/libc/sysdeps/linux/common/fstat.c +++ b/libc/sysdeps/linux/common/fstat.c @@ -40,6 +40,8 @@ int fstat(int fd, struct stat *buf) STATX_BASIC_STATS, &tmp); if (rc == 0) __cp_stat_statx ((struct stat *)buf, &tmp); + + return rc; } libc_hidden_def(fstat)
From: Yann Sionneau ysionneau@kalray.eu
Those must have the recent prlimit64 syscall which exists since Linux 3.2.
This patch is necessary for non-legacy architectures that wish to remove support for legacy setrlimit/getrlimit syscalls.
The non-legacy arch are those who opt-out via non defining __ARCH_WANT_SET_GET_RLIMIT in their arch/xxx/include/uapi/asm/unistd.h
setrlimit and getrlimit are then emulated via the new prlimit64 syscall.
Signed-off-by: Yann Sionneau ysionneau@kalray.eu
--- libc/sysdeps/linux/common/getrlimit.c | 23 +++++++++++++++---- libc/sysdeps/linux/common/setrlimit.c | 32 +++++++++++++++++++-------- 2 files changed, 42 insertions(+), 13 deletions(-)
diff --git a/libc/sysdeps/linux/common/getrlimit.c b/libc/sysdeps/linux/common/getrlimit.c index 26d3d2946..ad3f4a0e4 100644 --- a/libc/sysdeps/linux/common/getrlimit.c +++ b/libc/sysdeps/linux/common/getrlimit.c @@ -9,10 +9,11 @@ #include <sys/syscall.h> #include <sys/resource.h> #include <bits/wordsize.h> +#include <stddef.h> // needed for NULL to be defined
/* Only wrap getrlimit if the new ugetrlimit is not present and getrlimit sucks */
-#if defined __NR_ugetrlimit +#if defined(__NR_ugetrlimit)
/* just call ugetrlimit() */ # define __NR___syscall_ugetrlimit __NR_ugetrlimit @@ -24,16 +25,25 @@ int getrlimit(__rlimit_resource_t resource, struct rlimit *rlimits) return __syscall_ugetrlimit(resource, rlimits); }
-#elif !defined(__UCLIBC_HANDLE_OLDER_RLIMIT__) +#else + +# if !defined(__UCLIBC_HANDLE_OLDER_RLIMIT__)
+# if defined(__NR_prlimit64) +int getrlimit(__rlimit_resource_t resource, struct rlimit *rlimits) +{ + return INLINE_SYSCALL (prlimit64, 4, 0, resource, NULL, rlimits); +} +# else /* We don't need to wrap getrlimit() */ _syscall2(int, getrlimit, __rlimit_resource_t, resource, struct rlimit *, rlim) +# endif
-#else +# else
/* we have to handle old style getrlimit() */ -# define __NR___syscall_getrlimit __NR_getrlimit +# define __NR___syscall_getrlimit __NR_getrlimit static __always_inline _syscall2(int, __syscall_getrlimit, int, resource, struct rlimit *, rlim)
@@ -41,7 +51,11 @@ int getrlimit(__rlimit_resource_t resource, struct rlimit *rlimits) { int result;
+# if defined(__NR_prlimit64) + result = INLINE_SYSCALL (prlimit64, 4, 0, resource, NULL, rlimits); +# else result = __syscall_getrlimit(resource, rlimits); +# endif
if (result == -1) return result; @@ -54,6 +68,7 @@ int getrlimit(__rlimit_resource_t resource, struct rlimit *rlimits) rlimits->rlim_max = RLIM_INFINITY; return result; } +# endif #endif libc_hidden_def(getrlimit)
diff --git a/libc/sysdeps/linux/common/setrlimit.c b/libc/sysdeps/linux/common/setrlimit.c index 8f4973b72..8381afc61 100644 --- a/libc/sysdeps/linux/common/setrlimit.c +++ b/libc/sysdeps/linux/common/setrlimit.c @@ -9,36 +9,45 @@ #include <sys/syscall.h> #include <sys/resource.h> #include <bits/wordsize.h> +#include <stddef.h> // needed for NULL to be defined
/* Only wrap setrlimit if the new usetrlimit is not present and setrlimit sucks */
#if defined(__NR_usetrlimit) - /* just call usetrlimit() */ # define __NR___syscall_usetrlimit __NR_usetrlimit static __always_inline _syscall2(int, __syscall_usetrlimit, enum __rlimit_resource, resource, const struct rlimit *, rlim) -int setrlimit(__rlimit_resource_t resource, struct rlimit *rlimits) +int setrlimit(__rlimit_resource_t resource, const struct rlimit *rlimits) { return __syscall_usetrlimit(resource, rlimits); }
-#elif !defined(__UCLIBC_HANDLE_OLDER_RLIMIT__) +#else + +# if !defined(__UCLIBC_HANDLE_OLDER_RLIMIT__)
+# if defined(__NR_prlimit64) +int setrlimit(__rlimit_resource_t resource, const struct rlimit *rlimits) +{ + return INLINE_SYSCALL (prlimit64, 4, 0, resource, rlimits, NULL); +} +# else /* We don't need to wrap setrlimit() */ _syscall2(int, setrlimit, __rlimit_resource_t, resource, const struct rlimit *, rlim) +# endif
-#else +# else
-# define __need_NULL -# include <stddef.h> -# include <errno.h> -# include <sys/param.h> +# define __need_NULL +# include <stddef.h> +# include <errno.h> +# include <sys/param.h>
/* we have to handle old style setrlimit() */ -# define __NR___syscall_setrlimit __NR_setrlimit +# define __NR___syscall_setrlimit __NR_setrlimit static __always_inline _syscall2(int, __syscall_setrlimit, int, resource, const struct rlimit *, rlim)
@@ -57,8 +66,13 @@ int setrlimit(__rlimit_resource_t resource, const struct rlimit *rlimits) RLIM_INFINITY >> 1); rlimits_small.rlim_max = MIN((unsigned long int) rlimits->rlim_max, RLIM_INFINITY >> 1); +# if defined(__NR_prlimit64) + return INLINE_SYSCALL (prlimit64, 4, 0, resource, &rlimits_small, NULL); +# else return __syscall_setrlimit(resource, &rlimits_small); +# endif } +# endif #endif libc_hidden_def(setrlimit)
From: Yann Sionneau ysionneau@kalray.eu
Add fstatat wrapper that uses statx for non-legacy arch.
This allows non-legacy arch to opt-out from defining the old stat* syscalls by not defining __ARCH_WANT_NEW_STAT in their arch/xxx/include/asm/unistd.h
Signed-off-by: Yann Sionneau ysionneau@kalray.eu
--- libc/sysdeps/linux/common/fstatat.c | 39 +++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
diff --git a/libc/sysdeps/linux/common/fstatat.c b/libc/sysdeps/linux/common/fstatat.c index 13673d76c..db4a8327f 100644 --- a/libc/sysdeps/linux/common/fstatat.c +++ b/libc/sysdeps/linux/common/fstatat.c @@ -31,5 +31,44 @@ int fstatat(int fd, const char *file, struct stat *buf, int flag) } libc_hidden_def(fstatat) #else + +#if defined(__NR_statx) +#include <sys/sysmacros.h> // for makedev + +int fstatat(int fd, const char *file, struct stat *buf, int flag) +{ + int ret; + struct statx tmp; + + ret = INLINE_SYSCALL(statx, 5, fd, file, flag, + STATX_BASIC_STATS, &tmp); + if (ret != 0) + return ret; + + *buf = (struct stat) { + .st_dev = makedev(tmp.stx_dev_major, tmp.stx_dev_minor), + .st_ino = tmp.stx_ino, + .st_mode = tmp.stx_mode, + .st_nlink = tmp.stx_nlink, + .st_uid = tmp.stx_uid, + .st_gid = tmp.stx_gid, + .st_rdev = makedev(tmp.stx_rdev_major, tmp.stx_rdev_minor), + .st_size = tmp.stx_size, + .st_blksize = tmp.stx_blksize, + .st_blocks = tmp.stx_blocks, + .st_atim.tv_sec = tmp.stx_atime.tv_sec, + .st_atim.tv_nsec = tmp.stx_atime.tv_nsec, + .st_mtim.tv_sec = tmp.stx_mtime.tv_sec, + .st_mtim.tv_nsec = tmp.stx_mtime.tv_nsec, + .st_ctim.tv_sec = tmp.stx_ctime.tv_sec, + .st_ctim.tv_nsec = tmp.stx_ctime.tv_nsec, + }; + + return ret; +} +libc_hidden_def(fstatat) + +#endif + /* should add emulation with fstat() and /proc/self/fd/ ... */ #endif
Hi Yann, yann@sionneau.net wrote,
From: Yann Sionneau ysionneau@kalray.eu
Define fstatat64 as a wrapper of statx if the kernel does not support fstatat64 syscall This is the case for non-legacy architectures that don't define __ARCH_WANT_NEW_STAT in their linux arch/xxx/include/asm/unistd.h
Signed-off-by: Yann Sionneau ysionneau@kalray.eu
Series applied and pushed, best regards Waldemar
Hi Yann,
it seems I haven't tested this series good enough. It breaks mips64n32 build with following error:
libc/sysdeps/linux/common/fstatat.c: In function 'fstatat': libc/sysdeps/linux/common/fstatat.c:41:22: error: storage size of 'tmp' isn't known 41 | struct statx tmp; | ^~~ In file included from ./include/sys/syscall.h:33, from libc/sysdeps/linux/common/fstatat.c:9: ./include/bits/syscalls.h:290:48: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] 290 | register ARG_TYPE __a1 __asm__("$5") = (ARG_TYPE) arg2; \ | ^ ./include/bits/syscalls.h:49:9: note: in expansion of macro 'internal_syscall5' 49 | internal_syscall##nr (, "li\t$2, %2\t\t\t# " #name "\n\t", \ | ^~~~~~~~~~~~~~~~ ./include/bits/syscalls.h:24:24: note: in expansion of macro 'INTERNAL_SYSCALL' 24 | long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ | ^~~~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:43:15: note: in expansion of macro 'INLINE_SYSCALL' 43 | ret = INLINE_SYSCALL(statx, 5, fd, file, flag, | ^~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:44:30: error: 'STATX_BASIC_STATS' undeclared (first use in this function) 44 | STATX_BASIC_STATS, &tmp); | ^~~~~~~~~~~~~~~~~ ./include/bits/syscalls.h:292:59: note: in definition of macro 'internal_syscall5' 292 | register ARG_TYPE __a3 __asm__("$7") = (ARG_TYPE) arg4; \ | ^~~~ ./include/bits/syscalls.h:24:24: note: in expansion of macro 'INTERNAL_SYSCALL' 24 | long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ | ^~~~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:43:15: note: in expansion of macro 'INLINE_SYSCALL' 43 | ret = INLINE_SYSCALL(statx, 5, fd, file, flag, | ^~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:44:30: note: each undeclared identifier is reported only once for each function it appears in 44 | STATX_BASIC_STATS, &tmp); | ^~~~~~~~~~~~~~~~~ ./include/bits/syscalls.h:292:59: note: in definition of macro 'internal_syscall5' 292 | register ARG_TYPE __a3 __asm__("$7") = (ARG_TYPE) arg4; \ | ^~~~ ./include/bits/syscalls.h:24:24: note: in expansion of macro 'INTERNAL_SYSCALL' 24 | long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ | ^~~~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:43:15: note: in expansion of macro 'INLINE_SYSCALL' 43 | ret = INLINE_SYSCALL(statx, 5, fd, file, flag, | ^~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:41:22: warning: unused variable 'tmp' [-Wunused-variable] 41 | struct statx tmp; | ^~~ gmake[6]: *** [Makerules:369: libc/sysdeps/linux/common/fstatat.os] Error 1
Any idea?
It is with uClibc-ng current git.
Thanks in advance Waldemar
yann@sionneau.net wrote,
From: Yann Sionneau ysionneau@kalray.eu
Define fstatat64 as a wrapper of statx if the kernel does not support fstatat64 syscall This is the case for non-legacy architectures that don't define __ARCH_WANT_NEW_STAT in their linux arch/xxx/include/asm/unistd.h
Signed-off-by: Yann Sionneau ysionneau@kalray.eu
libc/sysdeps/linux/common/fstatat64.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/libc/sysdeps/linux/common/fstatat64.c b/libc/sysdeps/linux/common/fstatat64.c index 711521a6a..836ed4114 100644 --- a/libc/sysdeps/linux/common/fstatat64.c +++ b/libc/sysdeps/linux/common/fstatat64.c @@ -43,5 +43,28 @@ int fstatat64(int fd, const char *file, struct stat64 *buf, int flag) } libc_hidden_def(fstatat64) #else
+#if defined(__NR_statx) && defined(__UCLIBC_HAVE_STATX__) +# include <sys/stat.h> +# include <statx_cp.h> +# include <fcntl.h> // for AT_NO_AUTOMOUNT
+int fstatat64(int fd, const char *file, struct stat64 *buf, int flag) +{
- struct statx tmp;
- int r = INLINE_SYSCALL(statx, 5, fd, file, AT_NO_AUTOMOUNT | flag,
STATX_BASIC_STATS, &tmp);
- if (r != 0)
return r;
- __cp_stat_statx ((struct stat *)buf, &tmp);
- return 0;
+} +libc_hidden_def(fstatat64) +#endif
/* should add emulation with fstat64() and /proc/self/fd/ ... */
#endif
2.42.0
devel mailing list -- devel@uclibc-ng.org To unsubscribe send an email to devel-leave@uclibc-ng.org
Hi Waldemar,
Oopsy Daisy!
I will try to have a look on monday!
Sorry about that.
Regards,
Yann
Le 21/10/2023 à 07:50, Waldemar Brodkorb a écrit :
Hi Yann,
it seems I haven't tested this series good enough. It breaks mips64n32 build with following error:
libc/sysdeps/linux/common/fstatat.c: In function 'fstatat': libc/sysdeps/linux/common/fstatat.c:41:22: error: storage size of 'tmp' isn't known 41 | struct statx tmp; | ^~~ In file included from ./include/sys/syscall.h:33, from libc/sysdeps/linux/common/fstatat.c:9: ./include/bits/syscalls.h:290:48: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] 290 | register ARG_TYPE __a1 __asm__("$5") = (ARG_TYPE) arg2; \ | ^ ./include/bits/syscalls.h:49:9: note: in expansion of macro 'internal_syscall5' 49 | internal_syscall##nr (, "li\t$2, %2\t\t\t# " #name "\n\t", \ | ^~~~~~~~~~~~~~~~ ./include/bits/syscalls.h:24:24: note: in expansion of macro 'INTERNAL_SYSCALL' 24 | long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ | ^~~~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:43:15: note: in expansion of macro 'INLINE_SYSCALL' 43 | ret = INLINE_SYSCALL(statx, 5, fd, file, flag, | ^~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:44:30: error: 'STATX_BASIC_STATS' undeclared (first use in this function) 44 | STATX_BASIC_STATS, &tmp); | ^~~~~~~~~~~~~~~~~ ./include/bits/syscalls.h:292:59: note: in definition of macro 'internal_syscall5' 292 | register ARG_TYPE __a3 __asm__("$7") = (ARG_TYPE) arg4; \ | ^~~~ ./include/bits/syscalls.h:24:24: note: in expansion of macro 'INTERNAL_SYSCALL' 24 | long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ | ^~~~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:43:15: note: in expansion of macro 'INLINE_SYSCALL' 43 | ret = INLINE_SYSCALL(statx, 5, fd, file, flag, | ^~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:44:30: note: each undeclared identifier is reported only once for each function it appears in 44 | STATX_BASIC_STATS, &tmp); | ^~~~~~~~~~~~~~~~~ ./include/bits/syscalls.h:292:59: note: in definition of macro 'internal_syscall5' 292 | register ARG_TYPE __a3 __asm__("$7") = (ARG_TYPE) arg4; \ | ^~~~ ./include/bits/syscalls.h:24:24: note: in expansion of macro 'INTERNAL_SYSCALL' 24 | long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ | ^~~~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:43:15: note: in expansion of macro 'INLINE_SYSCALL' 43 | ret = INLINE_SYSCALL(statx, 5, fd, file, flag, | ^~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:41:22: warning: unused variable 'tmp' [-Wunused-variable] 41 | struct statx tmp; | ^~~ gmake[6]: *** [Makerules:369: libc/sysdeps/linux/common/fstatat.os] Error 1
Any idea?
It is with uClibc-ng current git.
Thanks in advance Waldemar
yann@sionneau.net wrote,
From: Yann Sionneau ysionneau@kalray.eu
Define fstatat64 as a wrapper of statx if the kernel does not support fstatat64 syscall This is the case for non-legacy architectures that don't define __ARCH_WANT_NEW_STAT in their linux arch/xxx/include/asm/unistd.h
Signed-off-by: Yann Sionneau ysionneau@kalray.eu
libc/sysdeps/linux/common/fstatat64.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/libc/sysdeps/linux/common/fstatat64.c b/libc/sysdeps/linux/common/fstatat64.c index 711521a6a..836ed4114 100644 --- a/libc/sysdeps/linux/common/fstatat64.c +++ b/libc/sysdeps/linux/common/fstatat64.c @@ -43,5 +43,28 @@ int fstatat64(int fd, const char *file, struct stat64 *buf, int flag) } libc_hidden_def(fstatat64) #else
+#if defined(__NR_statx) && defined(__UCLIBC_HAVE_STATX__) +# include <sys/stat.h> +# include <statx_cp.h> +# include <fcntl.h> // for AT_NO_AUTOMOUNT
+int fstatat64(int fd, const char *file, struct stat64 *buf, int flag) +{
- struct statx tmp;
- int r = INLINE_SYSCALL(statx, 5, fd, file, AT_NO_AUTOMOUNT | flag,
STATX_BASIC_STATS, &tmp);
- if (r != 0)
return r;
- __cp_stat_statx ((struct stat *)buf, &tmp);
- return 0;
+} +libc_hidden_def(fstatat64) +#endif
- /* should add emulation with fstat64() and /proc/self/fd/ ... */ #endif
-- 2.42.0
devel mailing list -- devel@uclibc-ng.org To unsubscribe send an email to devel-leave@uclibc-ng.org
Hi Waldemar,
This is due to statx structure being defined in statx.h
statx.h being included in sys/stat.h conditionally to __UCLIBC_HAVE_STATX__ being defined. Which is not, for mips arch.
defining __UCLIBC_HAVE_STATX__ in libc/sysdeps/linux/mips/bits/uClibc_arch_features.h does the job and everything compiles OK.
BUT, I'm not sure if this is the best way of fixing things...
I am wondering why we use this __UCLIBC_HAVE_STATX__ macro in the libc instead of testing the existence of the syscall in the kernel like for every other syscall by doing `#if defined(__NR_statx)` ?
Or maybe __UCLIBC_HAVE_STATX__ means something else? Maybe it means we want to expose a real statx() function wrapper to userspace?
If this is the case, that would mean fstatat.c would need to include directly bits/statx.h instead of sys/stat.h BUT it's explicitly forbidden:
```
#ifndef _SYS_STAT_H # error Never include <bits/statx.h> directly, include <sys/stat.h> instead. #endif
```
So... I'm a bit hesitant here on what's the correct thing to do.
Any thoughts on the list?
Regards,
Yann
Le 21/10/2023 à 07:50, Waldemar Brodkorb a écrit :
Hi Yann,
it seems I haven't tested this series good enough. It breaks mips64n32 build with following error:
libc/sysdeps/linux/common/fstatat.c: In function 'fstatat': libc/sysdeps/linux/common/fstatat.c:41:22: error: storage size of 'tmp' isn't known 41 | struct statx tmp; | ^~~ In file included from ./include/sys/syscall.h:33, from libc/sysdeps/linux/common/fstatat.c:9: ./include/bits/syscalls.h:290:48: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] 290 | register ARG_TYPE __a1 __asm__("$5") = (ARG_TYPE) arg2; \ | ^ ./include/bits/syscalls.h:49:9: note: in expansion of macro 'internal_syscall5' 49 | internal_syscall##nr (, "li\t$2, %2\t\t\t# " #name "\n\t", \ | ^~~~~~~~~~~~~~~~ ./include/bits/syscalls.h:24:24: note: in expansion of macro 'INTERNAL_SYSCALL' 24 | long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ | ^~~~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:43:15: note: in expansion of macro 'INLINE_SYSCALL' 43 | ret = INLINE_SYSCALL(statx, 5, fd, file, flag, | ^~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:44:30: error: 'STATX_BASIC_STATS' undeclared (first use in this function) 44 | STATX_BASIC_STATS, &tmp); | ^~~~~~~~~~~~~~~~~ ./include/bits/syscalls.h:292:59: note: in definition of macro 'internal_syscall5' 292 | register ARG_TYPE __a3 __asm__("$7") = (ARG_TYPE) arg4; \ | ^~~~ ./include/bits/syscalls.h:24:24: note: in expansion of macro 'INTERNAL_SYSCALL' 24 | long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ | ^~~~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:43:15: note: in expansion of macro 'INLINE_SYSCALL' 43 | ret = INLINE_SYSCALL(statx, 5, fd, file, flag, | ^~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:44:30: note: each undeclared identifier is reported only once for each function it appears in 44 | STATX_BASIC_STATS, &tmp); | ^~~~~~~~~~~~~~~~~ ./include/bits/syscalls.h:292:59: note: in definition of macro 'internal_syscall5' 292 | register ARG_TYPE __a3 __asm__("$7") = (ARG_TYPE) arg4; \ | ^~~~ ./include/bits/syscalls.h:24:24: note: in expansion of macro 'INTERNAL_SYSCALL' 24 | long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ | ^~~~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:43:15: note: in expansion of macro 'INLINE_SYSCALL' 43 | ret = INLINE_SYSCALL(statx, 5, fd, file, flag, | ^~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:41:22: warning: unused variable 'tmp' [-Wunused-variable] 41 | struct statx tmp; | ^~~ gmake[6]: *** [Makerules:369: libc/sysdeps/linux/common/fstatat.os] Error 1
Any idea?
It is with uClibc-ng current git.
Thanks in advance Waldemar
yann@sionneau.net wrote,
From: Yann Sionneau ysionneau@kalray.eu
Define fstatat64 as a wrapper of statx if the kernel does not support fstatat64 syscall This is the case for non-legacy architectures that don't define __ARCH_WANT_NEW_STAT in their linux arch/xxx/include/asm/unistd.h
Signed-off-by: Yann Sionneau ysionneau@kalray.eu
libc/sysdeps/linux/common/fstatat64.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/libc/sysdeps/linux/common/fstatat64.c b/libc/sysdeps/linux/common/fstatat64.c index 711521a6a..836ed4114 100644 --- a/libc/sysdeps/linux/common/fstatat64.c +++ b/libc/sysdeps/linux/common/fstatat64.c @@ -43,5 +43,28 @@ int fstatat64(int fd, const char *file, struct stat64 *buf, int flag) } libc_hidden_def(fstatat64) #else
+#if defined(__NR_statx) && defined(__UCLIBC_HAVE_STATX__) +# include <sys/stat.h> +# include <statx_cp.h> +# include <fcntl.h> // for AT_NO_AUTOMOUNT
+int fstatat64(int fd, const char *file, struct stat64 *buf, int flag) +{
- struct statx tmp;
- int r = INLINE_SYSCALL(statx, 5, fd, file, AT_NO_AUTOMOUNT | flag,
STATX_BASIC_STATS, &tmp);
- if (r != 0)
return r;
- __cp_stat_statx ((struct stat *)buf, &tmp);
- return 0;
+} +libc_hidden_def(fstatat64) +#endif
- /* should add emulation with fstat64() and /proc/self/fd/ ... */ #endif
-- 2.42.0
devel mailing list -- devel@uclibc-ng.org To unsubscribe send an email to devel-leave@uclibc-ng.org
Hi Yann,
I added __UCLIBC_HAVE_STATX__ for c-sky when I first added statx support. What you think about attached patch to fix the mips64 n32 issue? It showed no further regressions while testing.
best regards Waldemar
Yann Sionneau wrote,
Hi Waldemar,
This is due to statx structure being defined in statx.h
statx.h being included in sys/stat.h conditionally to __UCLIBC_HAVE_STATX__ being defined. Which is not, for mips arch.
defining __UCLIBC_HAVE_STATX__ in libc/sysdeps/linux/mips/bits/uClibc_arch_features.h does the job and everything compiles OK.
BUT, I'm not sure if this is the best way of fixing things...
I am wondering why we use this __UCLIBC_HAVE_STATX__ macro in the libc instead of testing the existence of the syscall in the kernel like for every other syscall by doing `#if defined(__NR_statx)` ?
Or maybe __UCLIBC_HAVE_STATX__ means something else? Maybe it means we want to expose a real statx() function wrapper to userspace?
If this is the case, that would mean fstatat.c would need to include directly bits/statx.h instead of sys/stat.h BUT it's explicitly forbidden:
#ifndef _SYS_STAT_H # error Never include <bits/statx.h> directly, include <sys/stat.h> instead. #endif
So... I'm a bit hesitant here on what's the correct thing to do.
Any thoughts on the list?
Regards,
Yann
Le 21/10/2023 à 07:50, Waldemar Brodkorb a écrit :
Hi Yann,
it seems I haven't tested this series good enough. It breaks mips64n32 build with following error:
libc/sysdeps/linux/common/fstatat.c: In function 'fstatat': libc/sysdeps/linux/common/fstatat.c:41:22: error: storage size of 'tmp' isn't known 41 | struct statx tmp; | ^~~ In file included from ./include/sys/syscall.h:33, from libc/sysdeps/linux/common/fstatat.c:9: ./include/bits/syscalls.h:290:48: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] 290 | register ARG_TYPE __a1 __asm__("$5") = (ARG_TYPE) arg2; \ | ^ ./include/bits/syscalls.h:49:9: note: in expansion of macro 'internal_syscall5' 49 | internal_syscall##nr (, "li\t$2, %2\t\t\t# " #name "\n\t", \ | ^~~~~~~~~~~~~~~~ ./include/bits/syscalls.h:24:24: note: in expansion of macro 'INTERNAL_SYSCALL' 24 | long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ | ^~~~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:43:15: note: in expansion of macro 'INLINE_SYSCALL' 43 | ret = INLINE_SYSCALL(statx, 5, fd, file, flag, | ^~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:44:30: error: 'STATX_BASIC_STATS' undeclared (first use in this function) 44 | STATX_BASIC_STATS, &tmp); | ^~~~~~~~~~~~~~~~~ ./include/bits/syscalls.h:292:59: note: in definition of macro 'internal_syscall5' 292 | register ARG_TYPE __a3 __asm__("$7") = (ARG_TYPE) arg4; \ | ^~~~ ./include/bits/syscalls.h:24:24: note: in expansion of macro 'INTERNAL_SYSCALL' 24 | long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ | ^~~~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:43:15: note: in expansion of macro 'INLINE_SYSCALL' 43 | ret = INLINE_SYSCALL(statx, 5, fd, file, flag, | ^~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:44:30: note: each undeclared identifier is reported only once for each function it appears in 44 | STATX_BASIC_STATS, &tmp); | ^~~~~~~~~~~~~~~~~ ./include/bits/syscalls.h:292:59: note: in definition of macro 'internal_syscall5' 292 | register ARG_TYPE __a3 __asm__("$7") = (ARG_TYPE) arg4; \ | ^~~~ ./include/bits/syscalls.h:24:24: note: in expansion of macro 'INTERNAL_SYSCALL' 24 | long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ | ^~~~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:43:15: note: in expansion of macro 'INLINE_SYSCALL' 43 | ret = INLINE_SYSCALL(statx, 5, fd, file, flag, | ^~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:41:22: warning: unused variable 'tmp' [-Wunused-variable] 41 | struct statx tmp; | ^~~ gmake[6]: *** [Makerules:369: libc/sysdeps/linux/common/fstatat.os] Error 1
Any idea?
It is with uClibc-ng current git.
Thanks in advance Waldemar
yann@sionneau.net wrote,
From: Yann Sionneau ysionneau@kalray.eu
Define fstatat64 as a wrapper of statx if the kernel does not support fstatat64 syscall This is the case for non-legacy architectures that don't define __ARCH_WANT_NEW_STAT in their linux arch/xxx/include/asm/unistd.h
Signed-off-by: Yann Sionneau ysionneau@kalray.eu
libc/sysdeps/linux/common/fstatat64.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/libc/sysdeps/linux/common/fstatat64.c b/libc/sysdeps/linux/common/fstatat64.c index 711521a6a..836ed4114 100644 --- a/libc/sysdeps/linux/common/fstatat64.c +++ b/libc/sysdeps/linux/common/fstatat64.c @@ -43,5 +43,28 @@ int fstatat64(int fd, const char *file, struct stat64 *buf, int flag) } libc_hidden_def(fstatat64) #else
+#if defined(__NR_statx) && defined(__UCLIBC_HAVE_STATX__) +# include <sys/stat.h> +# include <statx_cp.h> +# include <fcntl.h> // for AT_NO_AUTOMOUNT
+int fstatat64(int fd, const char *file, struct stat64 *buf, int flag) +{
- struct statx tmp;
- int r = INLINE_SYSCALL(statx, 5, fd, file, AT_NO_AUTOMOUNT | flag,
STATX_BASIC_STATS, &tmp);
- if (r != 0)
return r;
- __cp_stat_statx ((struct stat *)buf, &tmp);
- return 0;
+} +libc_hidden_def(fstatat64) +#endif
- /* should add emulation with fstat64() and /proc/self/fd/ ... */ #endif
-- 2.42.0
devel mailing list -- devel@uclibc-ng.org To unsubscribe send an email to devel-leave@uclibc-ng.org
Hi Waldemar,
It's just not clear to me what __UCLIBC_HAVE_STATX__ is supposed to mean.
Does it mean the kernel supports the syscall?
Or does it mean the arch want to expose some "statx" function which wraps the statx syscall? (because statx is non POSIX and is Linux specific)
In the first scenario I would think that it seems redundant with just checking __NR_statx
In the second scenario I would think that even if the arch does not want to expose a statx() function in the libc, the arch would still want to wrap the "old" functions (fstatat, stat, etc) around the new statx syscall, right?
In any case I am interested in understanding which of the 2 scenario is correct: what does __UCLIBC_HAVE_STATX__ mean?
Also, indeed I can see that in other files the check is done like this `#if defined __NR_statx && defined __UCLIBC_HAVE_STATX__` but maybe we need to make sure this is correct, and if it's not, fix this.
I hope I'm helping and not making this more complex than it's already is :)
Cheers,
Yann
Le 27/10/2023 à 15:46, Waldemar Brodkorb a écrit :
Hi Yann,
I added __UCLIBC_HAVE_STATX__ for c-sky when I first added statx support. What you think about attached patch to fix the mips64 n32 issue? It showed no further regressions while testing.
best regards Waldemar
Yann Sionneau wrote,
Hi Waldemar,
This is due to statx structure being defined in statx.h
statx.h being included in sys/stat.h conditionally to __UCLIBC_HAVE_STATX__ being defined. Which is not, for mips arch.
defining __UCLIBC_HAVE_STATX__ in libc/sysdeps/linux/mips/bits/uClibc_arch_features.h does the job and everything compiles OK.
BUT, I'm not sure if this is the best way of fixing things...
I am wondering why we use this __UCLIBC_HAVE_STATX__ macro in the libc instead of testing the existence of the syscall in the kernel like for every other syscall by doing `#if defined(__NR_statx)` ?
Or maybe __UCLIBC_HAVE_STATX__ means something else? Maybe it means we want to expose a real statx() function wrapper to userspace?
If this is the case, that would mean fstatat.c would need to include directly bits/statx.h instead of sys/stat.h BUT it's explicitly forbidden:
#ifndef _SYS_STAT_H # error Never include <bits/statx.h> directly, include <sys/stat.h> instead. #endif
So... I'm a bit hesitant here on what's the correct thing to do.
Any thoughts on the list?
Regards,
Yann
Le 21/10/2023 à 07:50, Waldemar Brodkorb a écrit :
Hi Yann,
it seems I haven't tested this series good enough. It breaks mips64n32 build with following error:
libc/sysdeps/linux/common/fstatat.c: In function 'fstatat': libc/sysdeps/linux/common/fstatat.c:41:22: error: storage size of 'tmp' isn't known 41 | struct statx tmp; | ^~~ In file included from ./include/sys/syscall.h:33, from libc/sysdeps/linux/common/fstatat.c:9: ./include/bits/syscalls.h:290:48: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] 290 | register ARG_TYPE __a1 __asm__("$5") = (ARG_TYPE) arg2; \ | ^ ./include/bits/syscalls.h:49:9: note: in expansion of macro 'internal_syscall5' 49 | internal_syscall##nr (, "li\t$2, %2\t\t\t# " #name "\n\t", \ | ^~~~~~~~~~~~~~~~ ./include/bits/syscalls.h:24:24: note: in expansion of macro 'INTERNAL_SYSCALL' 24 | long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ | ^~~~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:43:15: note: in expansion of macro 'INLINE_SYSCALL' 43 | ret = INLINE_SYSCALL(statx, 5, fd, file, flag, | ^~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:44:30: error: 'STATX_BASIC_STATS' undeclared (first use in this function) 44 | STATX_BASIC_STATS, &tmp); | ^~~~~~~~~~~~~~~~~ ./include/bits/syscalls.h:292:59: note: in definition of macro 'internal_syscall5' 292 | register ARG_TYPE __a3 __asm__("$7") = (ARG_TYPE) arg4; \ | ^~~~ ./include/bits/syscalls.h:24:24: note: in expansion of macro 'INTERNAL_SYSCALL' 24 | long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ | ^~~~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:43:15: note: in expansion of macro 'INLINE_SYSCALL' 43 | ret = INLINE_SYSCALL(statx, 5, fd, file, flag, | ^~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:44:30: note: each undeclared identifier is reported only once for each function it appears in 44 | STATX_BASIC_STATS, &tmp); | ^~~~~~~~~~~~~~~~~ ./include/bits/syscalls.h:292:59: note: in definition of macro 'internal_syscall5' 292 | register ARG_TYPE __a3 __asm__("$7") = (ARG_TYPE) arg4; \ | ^~~~ ./include/bits/syscalls.h:24:24: note: in expansion of macro 'INTERNAL_SYSCALL' 24 | long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ | ^~~~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:43:15: note: in expansion of macro 'INLINE_SYSCALL' 43 | ret = INLINE_SYSCALL(statx, 5, fd, file, flag, | ^~~~~~~~~~~~~~ libc/sysdeps/linux/common/fstatat.c:41:22: warning: unused variable 'tmp' [-Wunused-variable] 41 | struct statx tmp; | ^~~ gmake[6]: *** [Makerules:369: libc/sysdeps/linux/common/fstatat.os] Error 1
Any idea?
It is with uClibc-ng current git.
Thanks in advance Waldemar
yann@sionneau.net wrote,
From: Yann Sionneauysionneau@kalray.eu
Define fstatat64 as a wrapper of statx if the kernel does not support fstatat64 syscall This is the case for non-legacy architectures that don't define __ARCH_WANT_NEW_STAT in their linux arch/xxx/include/asm/unistd.h
Signed-off-by: Yann Sionneauysionneau@kalray.eu
libc/sysdeps/linux/common/fstatat64.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/libc/sysdeps/linux/common/fstatat64.c b/libc/sysdeps/linux/common/fstatat64.c index 711521a6a..836ed4114 100644 --- a/libc/sysdeps/linux/common/fstatat64.c +++ b/libc/sysdeps/linux/common/fstatat64.c @@ -43,5 +43,28 @@ int fstatat64(int fd, const char *file, struct stat64 *buf, int flag) } libc_hidden_def(fstatat64) #else
+#if defined(__NR_statx) && defined(__UCLIBC_HAVE_STATX__) +# include <sys/stat.h> +# include <statx_cp.h> +# include <fcntl.h> // for AT_NO_AUTOMOUNT
+int fstatat64(int fd, const char *file, struct stat64 *buf, int flag) +{
- struct statx tmp;
- int r = INLINE_SYSCALL(statx, 5, fd, file, AT_NO_AUTOMOUNT | flag,
STATX_BASIC_STATS, &tmp);
- if (r != 0)
return r;
- __cp_stat_statx ((struct stat *)buf, &tmp);
- return 0;
+} +libc_hidden_def(fstatat64) +#endif
- /* should add emulation with fstat64() and /proc/self/fd/ ... */ #endif
-- 2.42.0
devel mailing list --devel@uclibc-ng.org To unsubscribe send an email todevel-leave@uclibc-ng.org
Hi Yann, Yann Sionneau wrote,
Hi Waldemar,
It's just not clear to me what __UCLIBC_HAVE_STATX__ is supposed to mean.
Does it mean the kernel supports the syscall?
I would say yes. It is for newer architectures which only support statx like c-sky. At least that is the reason it was introduced. The old functions are not available for c-sky. Now it is also used by kvx.
Or does it mean the arch want to expose some "statx" function which wraps the statx syscall? (because statx is non POSIX and is Linux specific)
In the first scenario I would think that it seems redundant with just checking __NR_statx
It seems not to be redundant, as you can see it breaks some architectures which in newer kernels define __NR_statx, but the old functions still are available and working fine like mips64 n32.
In the second scenario I would think that even if the arch does not want to expose a statx() function in the libc, the arch would still want to wrap the "old" functions (fstatat, stat, etc) around the new statx syscall, right?
In any case I am interested in understanding which of the 2 scenario is correct: what does __UCLIBC_HAVE_STATX__ mean?
Also, indeed I can see that in other files the check is done like this `#if defined __NR_statx && defined __UCLIBC_HAVE_STATX__` but maybe we need to make sure this is correct, and if it's not, fix this.
I at least hope this is correct, yes.
I hope I'm helping and not making this more complex than it's already is :)
Is it now sufficiently explained? Can I push the change?
best regards Waldemar
Hi Waldemar,
Le 27/10/2023 à 18:02, Waldemar Brodkorb a écrit :
Hi Yann, Yann Sionneau wrote,
Hi Waldemar,
It's just not clear to me what __UCLIBC_HAVE_STATX__ is supposed to mean.
Does it mean the kernel supports the syscall?
I would say yes. It is for newer architectures which only support statx like c-sky. At least that is the reason it was introduced. The old functions are not available for c-sky. Now it is also used by kvx.
Or does it mean the arch want to expose some "statx" function which wraps the statx syscall? (because statx is non POSIX and is Linux specific)
In the first scenario I would think that it seems redundant with just checking __NR_statx
It seems not to be redundant, as you can see it breaks some architectures which in newer kernels define __NR_statx, but the old functions still are available and working fine like mips64 n32.
In the second scenario I would think that even if the arch does not want to expose a statx() function in the libc, the arch would still want to wrap the "old" functions (fstatat, stat, etc) around the new statx syscall, right?
In any case I am interested in understanding which of the 2 scenario is correct: what does __UCLIBC_HAVE_STATX__ mean?
Also, indeed I can see that in other files the check is done like this `#if defined __NR_statx && defined __UCLIBC_HAVE_STATX__` but maybe we need to make sure this is correct, and if it's not, fix this.
I at least hope this is correct, yes.
Ok
I hope I'm helping and not making this more complex than it's already is :)
Is it now sufficiently explained? Can I push the change?
I wanted to spend some time to think about this more, but I must confess that I don't have the time right now ... I'm a bit swamped.
I don't want to delay the fix any longer so let's push it if you think it's the correct fix :)
Sorry for delaying!
Regards,