public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 1/2] y2038: linux: Provide __utimensat64 implementation
@ 2019-10-29 12:04 Lukasz Majewski
  2019-10-29 12:04 ` [PATCH v2 2/2] y2038: linux: Provide __futimens64 implementation Lukasz Majewski
  2019-11-01 21:36 ` [PATCH v2 1/2] y2038: linux: Provide __utimensat64 implementation Joseph Myers
  0 siblings, 2 replies; 4+ messages in thread
From: Lukasz Majewski @ 2019-10-29 12:04 UTC (permalink / raw)
  To: Joseph Myers, Paul Eggert
  Cc: Alistair Francis, Alistair Francis, GNU C Library,
	Adhemerval Zanella, Florian Weimer, Florian Weimer,
	Zack Weinberg, Lukasz Majewski

This patch provides new __utimensat64 explicit 64 bit function for
setting access and modification time of a file. Moreover, a 32 bit version
- __utimensat has been refactored to internally use __utimensat64.

The __utimensat is now supposed to be used on systems still supporting
32 bit time (__TIMESIZE != 64) - hence the necessary conversions to 64 bit
struct __timespec64.
When pointer to struct __timespec64 is NULL - the file access and modification
time is set to the current one and no conversions from struct timespec to
__timespec64 are performed.

The new utimensat_time64 syscall available from Linux 5.1+ has been used,
when applicable.
The new helper function - __utimensat64_helper - has been introduced to
facilitate code re-usage on function providing futimens syscall handling.
The Linux kernel checks if passed tv_nsec value overflows, so there is no
need to repeat it in glibc.
When utimensat syscall on systems supporting 32 bit time ABI is used,
the check is performed if passed data (which may have 64 bit tv_sec) fits
into 32 bit range.

Build tests:
- The code has been tested on x86_64/x86 (native compilation):
make PARALLELMFLAGS="-j8" && make xcheck PARALLELMFLAGS="-j8"

- The glibc has been build tested (make PARALLELMFLAGS="-j8") for
x86 (i386), x86_64-x32, and armv7

Run-time tests:
- Run specific tests on ARM/x86 32bit systems (qemu):
https://github.com/lmajewski/meta-y2038 and run tests:
https://github.com/lmajewski/y2038-tests/commits/master

- Use of cross-test-ssh.sh for ARM (armv7):
make PARALLELMFLAGS="-j8" test-wrapper='./cross-test-ssh.sh root@192.168.7.2' xcheck

Linux kernel, headers and minimal kernel version for glibc build test
matrix:
- Linux v5.1 (with utimensat_time64) and glibc build with v5.1 as
minimal kernel version (--enable-kernel="5.1.0")
The __ASSUME_TIME64_SYSCALLS flag defined.

- Linux v5.1 and default minimal kernel version
The __ASSUME_TIME64_SYSCALLS not defined, but kernel supports utimensat_time64
syscall.

- Linux v4.19 (no utimensat_time64 support) with default minimal kernel
version for contemporary glibc
This kernel doesn't support utimensat_time64 syscall, so the fallback
to utimensat is tested.

The above tests were performed with Y2038 redirection applied as well as
without (so the __TIMESIZE != 64 execution path is checked as well).

No regressions were observed.
---
Changes for v2:
- Remove check for valid value in the nanoseconds field (tv_nsec) of
struct __timespec64 in the __utimensat64_helper function.
This check is performed (and proper error code is returned) in the Linux
kernel during serving the utimensat syscall.
---
 include/time.h                      | 12 ++++++
 sysdeps/unix/sysv/linux/utimensat.c | 65 +++++++++++++++++++++++++++--
 2 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/include/time.h b/include/time.h
index de660f7f57..432489ae29 100644
--- a/include/time.h
+++ b/include/time.h
@@ -141,6 +141,18 @@ extern int __clock_getres64 (clockid_t clock_id,
 libc_hidden_proto (__clock_getres64);
 #endif
 
+#if __TIMESIZE == 64
+# define __utimensat64 __utimensat
+#else
+extern int __utimensat64 (int fd, const char *file,
+                          const struct __timespec64 tsp[2], int flags);
+libc_hidden_proto (__utimensat64);
+#endif
+
+extern int __utimensat64_helper (int fd, const char *file,
+                                 const struct __timespec64 tsp[2], int flags);
+libc_hidden_proto (__utimensat64_helper);
+
 /* Compute the `struct tm' representation of T,
    offset OFFSET seconds east of UTC,
    and store year, yday, mon, mday, wday, hour, min, sec into *TP.
diff --git a/sysdeps/unix/sysv/linux/utimensat.c b/sysdeps/unix/sysv/linux/utimensat.c
index 3bffa7d22a..1515749f05 100644
--- a/sysdeps/unix/sysv/linux/utimensat.c
+++ b/sysdeps/unix/sysv/linux/utimensat.c
@@ -19,18 +19,75 @@
 #include <errno.h>
 #include <sys/stat.h>
 #include <sysdep.h>
+#include <time.h>
+#include <kernel-features.h>
 
+/* Helper function defined for easy reusage of the code which calls utimensat
+   and utimensat_time64 syscall.  */
+int
+__utimensat64_helper (int fd, const char *file,
+                      const struct __timespec64 tsp64[2], int flags)
+{
+#ifdef __ASSUME_TIME64_SYSCALLS
+# ifndef __NR_utimensat_time64
+#  define __NR_utimensat_time64 __NR_utimensat
+# endif
+  return INLINE_SYSCALL (utimensat_time64, 4, fd, file, &tsp64[0], flags);
+#else
+# ifdef __NR_utimensat_time64
+  int ret = INLINE_SYSCALL (utimensat_time64, 4, fd, file, &tsp64[0], flags);
+  if (ret == 0 || errno != ENOSYS)
+    return ret;
+# endif
+  if (tsp64
+      && (! in_time_t_range (tsp64[0].tv_sec)
+          || ! in_time_t_range (tsp64[1].tv_sec)))
+    {
+      __set_errno (EOVERFLOW);
+      return -1;
+    }
+
+  struct timespec tsp32[2];
+  if (tsp64)
+    {
+      tsp32[0] = valid_timespec64_to_timespec (tsp64[0]);
+      tsp32[1] = valid_timespec64_to_timespec (tsp64[1]);
+    }
+
+  return INLINE_SYSCALL (utimensat, 4, fd, file, tsp64 ? &tsp32[0] : NULL,
+                         flags);
+#endif
+
+}
+libc_hidden_def (__utimensat64_helper)
 
 /* Change the access time of FILE to TSP[0] and
    the modification time of FILE to TSP[1].
 
    Starting with 2.6.22 the Linux kernel has the utimensat syscall.  */
 int
-utimensat (int fd, const char *file, const struct timespec tsp[2],
-	   int flags)
+__utimensat64 (int fd, const char *file, const struct __timespec64 tsp64[2],
+               int flags)
 {
   if (file == NULL)
     return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
-  /* Avoid implicit array coercion in syscall macros.  */
-  return INLINE_SYSCALL (utimensat, 4, fd, file, &tsp[0], flags);
+
+  return __utimensat64_helper (fd, file, &tsp64[0], flags);
+}
+
+#if __TIMESIZE != 64
+int
+__utimensat (int fd, const char *file, const struct timespec tsp[2],
+             int flags)
+{
+  struct __timespec64 tsp64[2];
+  if (tsp)
+    {
+      tsp64[0] = valid_timespec_to_timespec64 (tsp[0]);
+      tsp64[1] = valid_timespec_to_timespec64 (tsp[1]);
+    }
+
+  return __utimensat64 (fd, file, tsp ? &tsp64[0] : NULL, flags);
 }
+#endif
+weak_alias (__utimensat, utimensat)
-- 
2.20.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 2/2] y2038: linux: Provide __futimens64 implementation
  2019-10-29 12:04 [PATCH v2 1/2] y2038: linux: Provide __utimensat64 implementation Lukasz Majewski
@ 2019-10-29 12:04 ` Lukasz Majewski
  2019-11-01 21:38   ` Joseph Myers
  2019-11-01 21:36 ` [PATCH v2 1/2] y2038: linux: Provide __utimensat64 implementation Joseph Myers
  1 sibling, 1 reply; 4+ messages in thread
From: Lukasz Majewski @ 2019-10-29 12:04 UTC (permalink / raw)
  To: Joseph Myers, Paul Eggert
  Cc: Alistair Francis, Alistair Francis, GNU C Library,
	Adhemerval Zanella, Florian Weimer, Florian Weimer,
	Zack Weinberg, Lukasz Majewski

This patch provides new __futimens64 explicit 64 bit function for
setting access and modification time of file (by using its file descriptor).
Moreover, a 32 bit version - __futimens has been refactored to internally use
__futimens64.

The __futimens is now supposed to be used on systems still supporting
32 bit time (__TIMESIZE != 64) - hence the necessary conversions to 64 bit
struct __timespec64.
When pointer to struct __timespec64 is NULL - the file access and modification
time is set to the current one (by the kernel) and no conversions from struct
timespec to __timespec64 are performed.

The __futimens64 reuses __utimensat64_helper defined for __utimensat64.

The test procedure for __futimens64 is the same as for __utimensat64 conversion
patch.
---
 include/time.h                     |  7 +++++++
 sysdeps/unix/sysv/linux/futimens.c | 22 +++++++++++++++++++---
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/include/time.h b/include/time.h
index 432489ae29..0ec6528d78 100644
--- a/include/time.h
+++ b/include/time.h
@@ -153,6 +153,13 @@ extern int __utimensat64_helper (int fd, const char *file,
                                  const struct __timespec64 tsp[2], int flags);
 libc_hidden_proto (__utimensat64_helper);
 
+#if __TIMESIZE == 64
+# define __futimens64 __futimens
+#else
+extern int __futimens64 (int fd, const struct __timespec64 tsp[2]);
+libc_hidden_proto (__futimens64);
+#endif
+
 /* Compute the `struct tm' representation of T,
    offset OFFSET seconds east of UTC,
    and store year, yday, mon, mday, wday, hour, min, sec into *TP.
diff --git a/sysdeps/unix/sysv/linux/futimens.c b/sysdeps/unix/sysv/linux/futimens.c
index 1f233d1246..15fc43b69c 100644
--- a/sysdeps/unix/sysv/linux/futimens.c
+++ b/sysdeps/unix/sysv/linux/futimens.c
@@ -29,10 +29,26 @@
    Starting with 2.6.22 the Linux kernel has the utimensat syscall which
    can be used to implement futimens.  */
 int
-futimens (int fd, const struct timespec tsp[2])
+__futimens64 (int fd, const struct __timespec64 tsp64[2])
 {
   if (fd < 0)
     return INLINE_SYSCALL_ERROR_RETURN_VALUE (EBADF);
-  /* Avoid implicit array coercion in syscall macros.  */
-  return INLINE_SYSCALL (utimensat, 4, fd, NULL, &tsp[0], 0);
+
+  return __utimensat64_helper (fd, NULL, &tsp64[0], 0);
+}
+
+#if __TIMESIZE != 64
+int
+__futimens (int fd, const struct timespec tsp[2])
+{
+  struct __timespec64 tsp64[2];
+  if (tsp)
+    {
+      tsp64[0] = valid_timespec_to_timespec64 (tsp[0]);
+      tsp64[1] = valid_timespec_to_timespec64 (tsp[1]);
+    }
+
+  return __futimens64 (fd, tsp ? &tsp64[0] : NULL);
 }
+#endif
+weak_alias (__futimens, futimens)
-- 
2.20.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 1/2] y2038: linux: Provide __utimensat64 implementation
  2019-10-29 12:04 [PATCH v2 1/2] y2038: linux: Provide __utimensat64 implementation Lukasz Majewski
  2019-10-29 12:04 ` [PATCH v2 2/2] y2038: linux: Provide __futimens64 implementation Lukasz Majewski
@ 2019-11-01 21:36 ` Joseph Myers
  1 sibling, 0 replies; 4+ messages in thread
From: Joseph Myers @ 2019-11-01 21:36 UTC (permalink / raw)
  To: Lukasz Majewski
  Cc: Paul Eggert, Alistair Francis, Alistair Francis, GNU C Library,
	Adhemerval Zanella, Florian Weimer, Florian Weimer,
	Zack Weinberg

On Tue, 29 Oct 2019, Lukasz Majewski wrote:

> Changes for v2:
> - Remove check for valid value in the nanoseconds field (tv_nsec) of
> struct __timespec64 in the __utimensat64_helper function.
> This check is performed (and proper error code is returned) in the Linux
> kernel during serving the utimensat syscall.

This patch version is OK.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 2/2] y2038: linux: Provide __futimens64 implementation
  2019-10-29 12:04 ` [PATCH v2 2/2] y2038: linux: Provide __futimens64 implementation Lukasz Majewski
@ 2019-11-01 21:38   ` Joseph Myers
  0 siblings, 0 replies; 4+ messages in thread
From: Joseph Myers @ 2019-11-01 21:38 UTC (permalink / raw)
  To: Lukasz Majewski
  Cc: Paul Eggert, Alistair Francis, Alistair Francis, GNU C Library,
	Adhemerval Zanella, Florian Weimer, Florian Weimer,
	Zack Weinberg

This patch is OK.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-11-01 21:38 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-29 12:04 [PATCH v2 1/2] y2038: linux: Provide __utimensat64 implementation Lukasz Majewski
2019-10-29 12:04 ` [PATCH v2 2/2] y2038: linux: Provide __futimens64 implementation Lukasz Majewski
2019-11-01 21:38   ` Joseph Myers
2019-11-01 21:36 ` [PATCH v2 1/2] y2038: linux: Provide __utimensat64 implementation Joseph Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).