unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] asm-generic ABI: Allow statx syscall despite fstatat64,fstat64
@ 2020-02-24 18:23 Vineet Gupta
  2020-02-24 18:39 ` Florian Weimer
  0 siblings, 1 reply; 12+ messages in thread
From: Vineet Gupta @ 2020-02-24 18:23 UTC (permalink / raw)
  To: libc-alpha, arnd; +Cc: linux-snps-arc, alistair23, lukma, Vineet Gupta

An old version of asm-generic syscall ABI (e.g. ARC 2013) provided
fstat[at]64 syscalls for implementing the stat family.

These sycalls are passthru (no interworking/itemized-copy needed
between kernel and user structs since they are binary comaptible).
However with switch to 64-bit time_t the compatibily goes away so we
need explicit interworking. Luckily such code already exists albeit it
uses the statx syscall.

So this patch reworks the asm-generic based stat functions to use the
statx code-path if the arch so desires. It essentially reworks the commit
6bbfc5c09fc5b5e3 ("Add statx conditionals for wordsize-32 *xstat.c")

This will be used by ARC port for 64-bit time_t. But it has no real
bearing on 64-bit and can just be independently opted-in by an arch port
provided the ABI supports it.

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
 sysdeps/unix/sysv/linux/fxstat64.c                     |  8 ++++----
 sysdeps/unix/sysv/linux/fxstatat64.c                   |  6 +++---
 sysdeps/unix/sysv/linux/generic/kernel_stat.h          |  7 +++++++
 sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c   |  6 +++---
 sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c |  6 +++---
 sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c   | 10 +++++-----
 sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c |  8 ++++----
 sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c    |  6 +++---
 sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c  |  6 +++---
 sysdeps/unix/sysv/linux/statx_cp.c                     |  2 +-
 10 files changed, 36 insertions(+), 29 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/fxstat64.c b/sysdeps/unix/sysv/linux/fxstat64.c
index 9133a0a29b8e..d4da85f7949c 100644
--- a/sysdeps/unix/sysv/linux/fxstat64.c
+++ b/sysdeps/unix/sysv/linux/fxstat64.c
@@ -33,15 +33,15 @@ int
 ___fxstat64 (int vers, int fd, struct stat64 *buf)
 {
   int result;
-#ifdef __NR_fstat64
-  result = INLINE_SYSCALL (fstat64, 2, fd, buf);
-#else
+# if defined(STAT64_IS_NOT_KERNEL_STAT64) || !defined(__NR_fstat64)
   struct statx tmp;
   result = INLINE_SYSCALL (statx, 5, fd, "", AT_EMPTY_PATH, STATX_BASIC_STATS,
                            &tmp);
   if (result == 0)
     __cp_stat64_statx (buf, &tmp);
-#endif
+# else
+  result = INLINE_SYSCALL (fstat64, 2, fd, buf);
+# endif
   return result;
 }
 
diff --git a/sysdeps/unix/sysv/linux/fxstatat64.c b/sysdeps/unix/sysv/linux/fxstatat64.c
index e24b456604ff..eb59c8be845f 100644
--- a/sysdeps/unix/sysv/linux/fxstatat64.c
+++ b/sysdeps/unix/sysv/linux/fxstatat64.c
@@ -38,15 +38,15 @@ __fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
 
   int result;
 
-#ifdef __NR_fstatat64
-  result = INTERNAL_SYSCALL_CALL (fstatat64, fd, file, st, flag);
-#else
+# if defined(STAT64_IS_NOT_KERNEL_STAT64) || !defined(__NR_fstatat64)
   struct statx tmp;
 
   result = INTERNAL_SYSCALL_CALL (statx, fd, file, AT_NO_AUTOMOUNT | flag,
 				  STATX_BASIC_STATS, &tmp);
   if (result == 0)
     __cp_stat64_statx (st, &tmp);
+#else
+  result = INTERNAL_SYSCALL_CALL (fstatat64, fd, file, st, flag);
 #endif
   if (!__glibc_likely (INTERNAL_SYSCALL_ERROR_P (result)))
     return 0;
diff --git a/sysdeps/unix/sysv/linux/generic/kernel_stat.h b/sysdeps/unix/sysv/linux/generic/kernel_stat.h
index 2eed3596c0ed..916deb7ed8c1 100644
--- a/sysdeps/unix/sysv/linux/generic/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/generic/kernel_stat.h
@@ -28,3 +28,10 @@
 #endif
 
 #define STATFS_IS_STATFS64 0
+
+/* Ports define to 1 when glibc struct stat64 is not compatible with
+   kernel stat64. This forces use of statx syscall (and explicit interworking)
+   even when fstat64 syscall is available. For asm-generic ABI this happened
+   with switch to 64-bit time_t.  */
+
+# undef STAT64_IS_NOT_KERNEL_STAT64
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c
index 850450e1e8a1..8ab11c62d1b3 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c
@@ -36,14 +36,14 @@ __fxstat (int vers, int fd, struct stat *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-# ifdef __NR_fstat64
-      int rc = INLINE_SYSCALL (fstat64, 2, fd, buf);
-# else
+# if defined(STAT64_IS_NOT_KERNEL_STAT64) || !defined(__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, fd, "", AT_EMPTY_PATH,
                                STATX_BASIC_STATS, &tmp);
       if (rc == 0)
         __cp_stat64_statx ((struct stat64 *)buf, &tmp);
+# else
+      int rc = INLINE_SYSCALL (fstat64, 2, fd, buf);
 # endif
       return rc ?: stat_overflow (buf);
     }
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c
index 8df65ebea084..19446a6cd917 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c
@@ -36,15 +36,15 @@ __fxstatat (int vers, int fd, const char *file, struct stat *buf, int flag)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-# ifdef __NR_fstatat64
-      int rc = INLINE_SYSCALL (fstatat64, 4, fd, file, buf, flag);
-# else
+# if defined(STAT64_IS_NOT_KERNEL_STAT64) || !defined(__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, fd, file,
                                AT_NO_AUTOMOUNT | flag,
                                STATX_BASIC_STATS, &tmp);
       if (rc == 0)
         __cp_stat64_statx ((struct stat64 *)buf, &tmp);
+# else
+      int rc = INLINE_SYSCALL (fstatat64, 4, fd, file, buf, flag);
 # endif
       return rc ?: stat_overflow (buf);
     }
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c
index bd02631d68cd..63fba924d14e 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c
@@ -35,17 +35,17 @@ __lxstat (int vers, const char *name, struct stat *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-#ifdef __NR_fstatat64
-      int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf,
-                               AT_SYMLINK_NOFOLLOW);
-#else
+# if defined(STAT64_IS_NOT_KERNEL_STAT64) || !defined(__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name,
                                AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW,
                                STATX_BASIC_STATS, &tmp);
       if (rc == 0)
         __cp_stat64_statx ((struct stat64 *)buf, &tmp);
-#endif
+# else
+      int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf,
+                               AT_SYMLINK_NOFOLLOW);
+# endif
       return rc ?: stat_overflow (buf);
     }
   errno = EINVAL;
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c
index 3eab0a184751..5f8361361e04 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c
@@ -40,10 +40,7 @@ __lxstat64 (int vers, const char *name, struct stat64 *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-#ifdef __NR_fstatat64
-      return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf,
-                             AT_SYMLINK_NOFOLLOW);
-#else
+# if defined(STAT64_IS_NOT_KERNEL_STAT64) || !defined(__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name,
                                AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW,
@@ -51,6 +48,9 @@ __lxstat64 (int vers, const char *name, struct stat64 *buf)
       if (rc == 0)
         __cp_stat64_statx (buf, &tmp);
       return rc;
+#else
+      return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf,
+                             AT_SYMLINK_NOFOLLOW);
 #endif
     }
 
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c
index a4a921c1ea6c..43b3e0b7b638 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c
@@ -35,14 +35,14 @@ __xstat (int vers, const char *name, struct stat *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-# ifdef __NR_fstatat64
-      int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
-# else
+# if defined(STAT64_IS_NOT_KERNEL_STAT64) || !defined(__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name, AT_NO_AUTOMOUNT,
                                STATX_BASIC_STATS, &tmp);
       if (rc == 0)
         __cp_stat64_statx ((struct stat64 *)buf, &tmp);
+# else
+      int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
 # endif
       return rc ?: stat_overflow (buf);
     }
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c
index 0848b5a4b4b1..e999bd2ffad5 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c
@@ -40,15 +40,15 @@ __xstat64 (int vers, const char *name, struct stat64 *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-#ifdef __NR_fstatat64
-      return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
-#else
+# if defined(STAT64_IS_NOT_KERNEL_STAT64) || !defined(__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name, AT_NO_AUTOMOUNT,
                                STATX_BASIC_STATS, &tmp);
       if (rc == 0)
         __cp_stat64_statx (buf, &tmp);
       return rc;
+#else
+      return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
 #endif
     }
   errno = EINVAL;
diff --git a/sysdeps/unix/sysv/linux/statx_cp.c b/sysdeps/unix/sysv/linux/statx_cp.c
index cc6e17929ea0..faba286d963c 100644
--- a/sysdeps/unix/sysv/linux/statx_cp.c
+++ b/sysdeps/unix/sysv/linux/statx_cp.c
@@ -22,7 +22,7 @@
 
 #include <statx_cp.h>
 
-#if !defined(__NR_fstat64) || !defined(__NR_fstatat64)
+#if !defined(__NR_fstat64) || !defined(__NR_fstatat64) || defined(STAT64_IS_NOT_KERNEL_STAT64)
 void
 __cp_stat64_statx (struct stat64 *to, struct statx *from)
 {
-- 
2.20.1


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

* Re: [PATCH] asm-generic ABI: Allow statx syscall despite fstatat64,fstat64
  2020-02-24 18:23 [PATCH] asm-generic ABI: Allow statx syscall despite fstatat64,fstat64 Vineet Gupta
@ 2020-02-24 18:39 ` Florian Weimer
  2020-02-24 19:03   ` Vineet Gupta
  0 siblings, 1 reply; 12+ messages in thread
From: Florian Weimer @ 2020-02-24 18:39 UTC (permalink / raw)
  To: Vineet Gupta; +Cc: libc-alpha, arnd, linux-snps-arc, alistair23, lukma

* Vineet Gupta:

> +/* Ports define to 1 when glibc struct stat64 is not compatible with
> +   kernel stat64. This forces use of statx syscall (and explicit interworking)
> +   even when fstat64 syscall is available. For asm-generic ABI this happened
> +   with switch to 64-bit time_t.  */
> +
> +# undef STAT64_IS_NOT_KERNEL_STAT64

Sorry, I think that going forward, we prefer that such macros are always
defined, with values 0 or 1 as appropriate.

Thanks,
Florian


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

* Re: [PATCH] asm-generic ABI: Allow statx syscall despite fstatat64,fstat64
  2020-02-24 18:39 ` Florian Weimer
@ 2020-02-24 19:03   ` Vineet Gupta
  2020-02-24 19:13     ` Florian Weimer
  0 siblings, 1 reply; 12+ messages in thread
From: Vineet Gupta @ 2020-02-24 19:03 UTC (permalink / raw)
  To: Florian Weimer
  Cc: libc-alpha@sourceware.org, arnd@arndb.de,
	linux-snps-arc@lists.infradead.org, alistair23@gmail.com,
	lukma@denx.de

On 2/24/20 10:39 AM, Florian Weimer wrote:
>> +# undef STAT64_IS_NOT_KERNEL_STAT64
>
> Sorry, I think that going forward, we prefer that such macros are always
> defined, with values 0 or 1 as appropriate.

And that means we also need to additionally define this to 0 in all ports which
don't end up including the generic header ?

Thx,
-Vineet

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

* Re: [PATCH] asm-generic ABI: Allow statx syscall despite fstatat64,fstat64
  2020-02-24 19:03   ` Vineet Gupta
@ 2020-02-24 19:13     ` Florian Weimer
  2020-02-24 19:27       ` Vineet Gupta
  0 siblings, 1 reply; 12+ messages in thread
From: Florian Weimer @ 2020-02-24 19:13 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: libc-alpha@sourceware.org, arnd@arndb.de,
	linux-snps-arc@lists.infradead.org, alistair23@gmail.com,
	lukma@denx.de

* Vineet Gupta:

> On 2/24/20 10:39 AM, Florian Weimer wrote:
>>> +# undef STAT64_IS_NOT_KERNEL_STAT64
>>
>> Sorry, I think that going forward, we prefer that such macros are always
>> defined, with values 0 or 1 as appropriate.
>
> And that means we also need to additionally define this to 0 in all
> ports which don't end up including the generic header ?

Yes, or move the definition into its own header, with the default for
*future* architectures (not the majority of the current architectures)
in the header in the sysdeps/unix/sysv/linux directory.

Thanks,
Florian


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

* Re: [PATCH] asm-generic ABI: Allow statx syscall despite fstatat64,fstat64
  2020-02-24 19:13     ` Florian Weimer
@ 2020-02-24 19:27       ` Vineet Gupta
  2020-02-24 19:38         ` Florian Weimer
  0 siblings, 1 reply; 12+ messages in thread
From: Vineet Gupta @ 2020-02-24 19:27 UTC (permalink / raw)
  To: Florian Weimer
  Cc: libc-alpha@sourceware.org, arnd@arndb.de,
	linux-snps-arc@lists.infradead.org, alistair23@gmail.com,
	lukma@denx.de

On 2/24/20 11:13 AM, Florian Weimer wrote:
> * Vineet Gupta:
> 
>> On 2/24/20 10:39 AM, Florian Weimer wrote:
>>>> +# undef STAT64_IS_NOT_KERNEL_STAT64
>>> Sorry, I think that going forward, we prefer that such macros are always
>>> defined, with values 0 or 1 as appropriate.
>>
>> And that means we also need to additionally define this to 0 in all
>> ports which don't end up including the generic header ?
>
> Yes, or move the definition into its own header, with the default for
> *future* architectures (not the majority of the current architectures)
> in the header in the sysdeps/unix/sysv/linux directory.

Adding a new file would seem too kludgy. Adding it to existing arch headers is
still OK but then one needs to know what exact syscall ABI each arch has as even
asm-generic ones differ depending on when the linux port was merged. And the only
way to know that is to do a build for each arch or is there some documentation one
could refer to.

Thx,
-Vineet



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

* Re: [PATCH] asm-generic ABI: Allow statx syscall despite fstatat64,fstat64
  2020-02-24 19:27       ` Vineet Gupta
@ 2020-02-24 19:38         ` Florian Weimer
  2020-02-24 22:15           ` [PATCH v2] " Vineet Gupta
  0 siblings, 1 reply; 12+ messages in thread
From: Florian Weimer @ 2020-02-24 19:38 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: libc-alpha@sourceware.org, arnd@arndb.de,
	linux-snps-arc@lists.infradead.org, alistair23@gmail.com,
	lukma@denx.de

* Vineet Gupta:

> On 2/24/20 11:13 AM, Florian Weimer wrote:
>> * Vineet Gupta:
>> 
>>> On 2/24/20 10:39 AM, Florian Weimer wrote:
>>>>> +# undef STAT64_IS_NOT_KERNEL_STAT64
>>>> Sorry, I think that going forward, we prefer that such macros are always
>>>> defined, with values 0 or 1 as appropriate.
>>>
>>> And that means we also need to additionally define this to 0 in all
>>> ports which don't end up including the generic header ?
>>
>> Yes, or move the definition into its own header, with the default for
>> *future* architectures (not the majority of the current architectures)
>> in the header in the sysdeps/unix/sysv/linux directory.
>
> Adding a new file would seem too kludgy.

I think it's the preferred approach.  Here's a recent discussion that
looks at a few options in this space:

  <https://sourceware.org/ml/libc-alpha/2019-10/msg00030.html>

> Adding it to existing arch headers is still OK but then one needs to
> know what exact syscall ABI each arch has as even asm-generic ones
> differ depending on when the linux port was merged. And the only way
> to know that is to do a build for each arch or is there some
> documentation one could refer to.

In your case, the build should fail somewhere if there is a mismatch and
the #define is incorrect for a particular architecture.  In this case,
you can keep running build-many-glibcs.py and making tweaks to the
failing architectures until all failures are gone.

Thanks,
Florian


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

* [PATCH v2] asm-generic ABI: Allow statx syscall despite fstatat64,fstat64
  2020-02-24 19:38         ` Florian Weimer
@ 2020-02-24 22:15           ` Vineet Gupta
  2020-02-25  0:09             ` Joseph Myers
  0 siblings, 1 reply; 12+ messages in thread
From: Vineet Gupta @ 2020-02-24 22:15 UTC (permalink / raw)
  To: libc-alpha; +Cc: linux-snps-arc, alistair.francis, alistair23, Vineet Gupta

An old version of asm-generic syscall ABI (e.g. ARC 2013) provided
fstat[at]64 syscalls for implementing the stat family.

These sycalls are passthru (no interworking/itemized-copy needed
between kernel and user structs since they are binary comaptible).
However with switch to 64-bit time_t the compatibily goes away so we
need explicit interworking. Luckily such code already exists albeit it
uses the statx syscall.

So this patch reworks the asm-generic based stat functions to use the
statx code-path if the arch so desires. It essentially reworks the commit
6bbfc5c09fc5b5e3 ("Add statx conditionals for wordsize-32 *xstat.c")

This will be used by ARC port for 64-bit time_t. But it has no real
bearing on 64-bit and can just be independently opted-in by an arch port
provided the ABI supports it.

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
Changes since v1
  * make the toggle #if style rather than #ifdef style
  * define to 0 in all arches which don't use it
---
 sysdeps/unix/sysv/linux/alpha/kernel_stat.h            |  1 +
 sysdeps/unix/sysv/linux/fxstat64.c                     |  8 ++++----
 sysdeps/unix/sysv/linux/fxstatat64.c                   |  6 +++---
 sysdeps/unix/sysv/linux/generic/kernel_stat.h          |  7 +++++++
 sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c   |  6 +++---
 sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c |  6 +++---
 sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c   | 10 +++++-----
 sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c |  8 ++++----
 sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c    |  6 +++---
 sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c  |  6 +++---
 sysdeps/unix/sysv/linux/hppa/kernel_stat.h             |  1 +
 sysdeps/unix/sysv/linux/ia64/kernel_stat.h             |  1 +
 sysdeps/unix/sysv/linux/kernel_stat.h                  |  1 +
 sysdeps/unix/sysv/linux/microblaze/kernel_stat.h       |  1 +
 sysdeps/unix/sysv/linux/mips/kernel_stat.h             |  1 +
 .../unix/sysv/linux/powerpc/powerpc32/kernel_stat.h    |  1 +
 .../unix/sysv/linux/powerpc/powerpc64/kernel_stat.h    |  1 +
 sysdeps/unix/sysv/linux/s390/s390-64/kernel_stat.h     |  1 +
 sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h    |  1 +
 sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h    |  1 +
 sysdeps/unix/sysv/linux/statx_cp.c                     |  2 +-
 sysdeps/unix/sysv/linux/x86_64/kernel_stat.h           |  1 +
 22 files changed, 48 insertions(+), 29 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/alpha/kernel_stat.h b/sysdeps/unix/sysv/linux/alpha/kernel_stat.h
index d637e099cfe4..437b56098ecd 100644
--- a/sysdeps/unix/sysv/linux/alpha/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/alpha/kernel_stat.h
@@ -87,3 +87,4 @@ struct glibc21_stat
 
 #define XSTAT_IS_XSTAT64 1
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/fxstat64.c b/sysdeps/unix/sysv/linux/fxstat64.c
index 9133a0a29b8e..93394c450f1c 100644
--- a/sysdeps/unix/sysv/linux/fxstat64.c
+++ b/sysdeps/unix/sysv/linux/fxstat64.c
@@ -33,15 +33,15 @@ int
 ___fxstat64 (int vers, int fd, struct stat64 *buf)
 {
   int result;
-#ifdef __NR_fstat64
-  result = INLINE_SYSCALL (fstat64, 2, fd, buf);
-#else
+# if STAT64_IS_NOT_KERNEL_STAT64 || !defined(__NR_fstat64)
   struct statx tmp;
   result = INLINE_SYSCALL (statx, 5, fd, "", AT_EMPTY_PATH, STATX_BASIC_STATS,
                            &tmp);
   if (result == 0)
     __cp_stat64_statx (buf, &tmp);
-#endif
+# else
+  result = INLINE_SYSCALL (fstat64, 2, fd, buf);
+# endif
   return result;
 }
 
diff --git a/sysdeps/unix/sysv/linux/fxstatat64.c b/sysdeps/unix/sysv/linux/fxstatat64.c
index e24b456604ff..090d4af65988 100644
--- a/sysdeps/unix/sysv/linux/fxstatat64.c
+++ b/sysdeps/unix/sysv/linux/fxstatat64.c
@@ -38,15 +38,15 @@ __fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
 
   int result;
 
-#ifdef __NR_fstatat64
-  result = INTERNAL_SYSCALL_CALL (fstatat64, fd, file, st, flag);
-#else
+# if STAT64_IS_NOT_KERNEL_STAT64 || !defined(__NR_fstatat64)
   struct statx tmp;
 
   result = INTERNAL_SYSCALL_CALL (statx, fd, file, AT_NO_AUTOMOUNT | flag,
 				  STATX_BASIC_STATS, &tmp);
   if (result == 0)
     __cp_stat64_statx (st, &tmp);
+#else
+  result = INTERNAL_SYSCALL_CALL (fstatat64, fd, file, st, flag);
 #endif
   if (!__glibc_likely (INTERNAL_SYSCALL_ERROR_P (result)))
     return 0;
diff --git a/sysdeps/unix/sysv/linux/generic/kernel_stat.h b/sysdeps/unix/sysv/linux/generic/kernel_stat.h
index 2eed3596c0ed..fb97832f213f 100644
--- a/sysdeps/unix/sysv/linux/generic/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/generic/kernel_stat.h
@@ -28,3 +28,10 @@
 #endif
 
 #define STATFS_IS_STATFS64 0
+
+/* Allows asm-generic ABI ports with fstat64 syscall to use statx syscall for
+   implement stat* wrappers. This is needed when glibc stat64 is not compatible
+   with kernel stat64 (due to 64-bit time_t). By default it is off unless
+   arch opts-in.  */
+
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c
index 850450e1e8a1..67194194b632 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c
@@ -36,14 +36,14 @@ __fxstat (int vers, int fd, struct stat *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-# ifdef __NR_fstat64
-      int rc = INLINE_SYSCALL (fstat64, 2, fd, buf);
-# else
+# if STAT64_IS_NOT_KERNEL_STAT64 || !defined(__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, fd, "", AT_EMPTY_PATH,
                                STATX_BASIC_STATS, &tmp);
       if (rc == 0)
         __cp_stat64_statx ((struct stat64 *)buf, &tmp);
+# else
+      int rc = INLINE_SYSCALL (fstat64, 2, fd, buf);
 # endif
       return rc ?: stat_overflow (buf);
     }
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c
index 8df65ebea084..38fd2b7791bc 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c
@@ -36,15 +36,15 @@ __fxstatat (int vers, int fd, const char *file, struct stat *buf, int flag)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-# ifdef __NR_fstatat64
-      int rc = INLINE_SYSCALL (fstatat64, 4, fd, file, buf, flag);
-# else
+# if STAT64_IS_NOT_KERNEL_STAT64 || !defined(__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, fd, file,
                                AT_NO_AUTOMOUNT | flag,
                                STATX_BASIC_STATS, &tmp);
       if (rc == 0)
         __cp_stat64_statx ((struct stat64 *)buf, &tmp);
+# else
+      int rc = INLINE_SYSCALL (fstatat64, 4, fd, file, buf, flag);
 # endif
       return rc ?: stat_overflow (buf);
     }
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c
index bd02631d68cd..fc4998e75c36 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c
@@ -35,17 +35,17 @@ __lxstat (int vers, const char *name, struct stat *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-#ifdef __NR_fstatat64
-      int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf,
-                               AT_SYMLINK_NOFOLLOW);
-#else
+# if STAT64_IS_NOT_KERNEL_STAT64 || !defined(__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name,
                                AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW,
                                STATX_BASIC_STATS, &tmp);
       if (rc == 0)
         __cp_stat64_statx ((struct stat64 *)buf, &tmp);
-#endif
+# else
+      int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf,
+                               AT_SYMLINK_NOFOLLOW);
+# endif
       return rc ?: stat_overflow (buf);
     }
   errno = EINVAL;
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c
index 3eab0a184751..83ea74cd09ed 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c
@@ -40,10 +40,7 @@ __lxstat64 (int vers, const char *name, struct stat64 *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-#ifdef __NR_fstatat64
-      return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf,
-                             AT_SYMLINK_NOFOLLOW);
-#else
+# if STAT64_IS_NOT_KERNEL_STAT64 || !defined(__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name,
                                AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW,
@@ -51,6 +48,9 @@ __lxstat64 (int vers, const char *name, struct stat64 *buf)
       if (rc == 0)
         __cp_stat64_statx (buf, &tmp);
       return rc;
+#else
+      return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf,
+                             AT_SYMLINK_NOFOLLOW);
 #endif
     }
 
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c
index a4a921c1ea6c..9a155ee4a757 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c
@@ -35,14 +35,14 @@ __xstat (int vers, const char *name, struct stat *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-# ifdef __NR_fstatat64
-      int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
-# else
+# if STAT64_IS_NOT_KERNEL_STAT64 || !defined(__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name, AT_NO_AUTOMOUNT,
                                STATX_BASIC_STATS, &tmp);
       if (rc == 0)
         __cp_stat64_statx ((struct stat64 *)buf, &tmp);
+# else
+      int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
 # endif
       return rc ?: stat_overflow (buf);
     }
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c
index 0848b5a4b4b1..1bbcbeefc428 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c
@@ -40,15 +40,15 @@ __xstat64 (int vers, const char *name, struct stat64 *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-#ifdef __NR_fstatat64
-      return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
-#else
+# if STAT64_IS_NOT_KERNEL_STAT64 || !defined(__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name, AT_NO_AUTOMOUNT,
                                STATX_BASIC_STATS, &tmp);
       if (rc == 0)
         __cp_stat64_statx (buf, &tmp);
       return rc;
+#else
+      return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
 #endif
     }
   errno = EINVAL;
diff --git a/sysdeps/unix/sysv/linux/hppa/kernel_stat.h b/sysdeps/unix/sysv/linux/hppa/kernel_stat.h
index a3ac53a1ef2f..93802c4257c0 100644
--- a/sysdeps/unix/sysv/linux/hppa/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/hppa/kernel_stat.h
@@ -32,3 +32,4 @@ struct kernel_stat {
 
 #define XSTAT_IS_XSTAT64 0
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/ia64/kernel_stat.h b/sysdeps/unix/sysv/linux/ia64/kernel_stat.h
index b38bf741d37b..6965d95e9529 100644
--- a/sysdeps/unix/sysv/linux/ia64/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/ia64/kernel_stat.h
@@ -19,3 +19,4 @@
 #define STAT_IS_KERNEL_STAT 1
 #define XSTAT_IS_XSTAT64 1
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/kernel_stat.h b/sysdeps/unix/sysv/linux/kernel_stat.h
index eecc962de390..3ff0882c51a2 100644
--- a/sysdeps/unix/sysv/linux/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/kernel_stat.h
@@ -36,3 +36,4 @@ struct kernel_stat
 
 #define XSTAT_IS_XSTAT64 0
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel_stat.h b/sysdeps/unix/sysv/linux/microblaze/kernel_stat.h
index 765e0dca6763..64d4b11ee6da 100644
--- a/sysdeps/unix/sysv/linux/microblaze/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/microblaze/kernel_stat.h
@@ -50,3 +50,4 @@ struct kernel_stat
 
 #define XSTAT_IS_XSTAT64 0
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/mips/kernel_stat.h b/sysdeps/unix/sysv/linux/mips/kernel_stat.h
index 388df1bfffec..fd221c632fac 100644
--- a/sysdeps/unix/sysv/linux/mips/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/mips/kernel_stat.h
@@ -58,3 +58,4 @@ struct kernel_stat
 
 #define XSTAT_IS_XSTAT64 0
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/kernel_stat.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/kernel_stat.h
index c5948a4d3c1c..4e389cb2ff80 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/kernel_stat.h
@@ -49,3 +49,4 @@ struct kernel_stat
 
 #define XSTAT_IS_XSTAT64 0
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/kernel_stat.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/kernel_stat.h
index 5c10da3356f2..b48dbc15227d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/kernel_stat.h
@@ -19,3 +19,4 @@
 #define STAT_IS_KERNEL_STAT 1
 #define XSTAT_IS_XSTAT64 1
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/kernel_stat.h b/sysdeps/unix/sysv/linux/s390/s390-64/kernel_stat.h
index b38bf741d37b..6965d95e9529 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/kernel_stat.h
@@ -19,3 +19,4 @@
 #define STAT_IS_KERNEL_STAT 1
 #define XSTAT_IS_XSTAT64 1
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h b/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h
index a4416009f1bc..17ac63b753e5 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h
@@ -33,3 +33,4 @@ struct kernel_stat
 
 #define XSTAT_IS_XSTAT64 0
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h b/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h
index 30afb553b9b8..4912a98529a4 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h
@@ -46,3 +46,4 @@ struct kernel_stat64
 
 #define XSTAT_IS_XSTAT64 1
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/statx_cp.c b/sysdeps/unix/sysv/linux/statx_cp.c
index cc6e17929ea0..b68d233a2963 100644
--- a/sysdeps/unix/sysv/linux/statx_cp.c
+++ b/sysdeps/unix/sysv/linux/statx_cp.c
@@ -22,7 +22,7 @@
 
 #include <statx_cp.h>
 
-#if !defined(__NR_fstat64) || !defined(__NR_fstatat64)
+#if !defined(__NR_fstat64) || !defined(__NR_fstatat64) || STAT64_IS_NOT_KERNEL_STAT64
 void
 __cp_stat64_statx (struct stat64 *to, struct statx *from)
 {
diff --git a/sysdeps/unix/sysv/linux/x86_64/kernel_stat.h b/sysdeps/unix/sysv/linux/x86_64/kernel_stat.h
index b38bf741d37b..6965d95e9529 100644
--- a/sysdeps/unix/sysv/linux/x86_64/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/x86_64/kernel_stat.h
@@ -19,3 +19,4 @@
 #define STAT_IS_KERNEL_STAT 1
 #define XSTAT_IS_XSTAT64 1
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
-- 
2.20.1


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

* Re: [PATCH v2] asm-generic ABI: Allow statx syscall despite fstatat64,fstat64
  2020-02-24 22:15           ` [PATCH v2] " Vineet Gupta
@ 2020-02-25  0:09             ` Joseph Myers
  2020-02-25  0:29               ` [PATCH v3] " Vineet Gupta
  0 siblings, 1 reply; 12+ messages in thread
From: Joseph Myers @ 2020-02-25  0:09 UTC (permalink / raw)
  To: Vineet Gupta; +Cc: libc-alpha, linux-snps-arc, alistair.francis, alistair23

On Mon, 24 Feb 2020, Vineet Gupta wrote:

> diff --git a/sysdeps/unix/sysv/linux/fxstat64.c b/sysdeps/unix/sysv/linux/fxstat64.c
> index 9133a0a29b8e..93394c450f1c 100644
> --- a/sysdeps/unix/sysv/linux/fxstat64.c
> +++ b/sysdeps/unix/sysv/linux/fxstat64.c
> @@ -33,15 +33,15 @@ int
>  ___fxstat64 (int vers, int fd, struct stat64 *buf)
>  {
>    int result;
> -#ifdef __NR_fstat64
> -  result = INLINE_SYSCALL (fstat64, 2, fd, buf);
> -#else
> +# if STAT64_IS_NOT_KERNEL_STAT64 || !defined(__NR_fstat64)

I don't think the extra space after "#" is correct here.  We use such 
spaces to indicate the level of nesting inside outer #if conditionals, but 
there is no outer #if conditional around this one in this file, so "#if" 
without the space is correct.

There should be a space before '(' in the "defined" call.

Likewise in other files changed by this patch.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* [PATCH v3] asm-generic ABI: Allow statx syscall despite fstatat64,fstat64
  2020-02-25  0:09             ` Joseph Myers
@ 2020-02-25  0:29               ` Vineet Gupta
  2020-02-25  3:13                 ` [PATCH v3] asm-generic ABI: Allow statx syscall despite fstatat64, fstat64 Vineet Gupta
  0 siblings, 1 reply; 12+ messages in thread
From: Vineet Gupta @ 2020-02-25  0:29 UTC (permalink / raw)
  To: libc-alpha; +Cc: linux-snps-arc, alistair.francis, alistair23, Vineet Gupta

An old version of asm-generic syscall ABI (e.g. ARC 2013) provided
fstat[at]64 syscalls for implementing the stat family.

These sycalls are passthru (no interworking/itemized-copy needed
between kernel and user structs since they are binary comaptible).
However with switch to 64-bit time_t the compatibily goes away so we
need explicit interworking. Luckily such code already exists albeit it
uses the statx syscall.

So this patch reworks the asm-generic based stat functions to use the
statx code-path if the arch so desires. It essentially reworks the commit
6bbfc5c09fc5b5e3 ("Add statx conditionals for wordsize-32 *xstat.c")

This will be used by ARC port for 64-bit time_t. But it has no real
bearing on 64-bit and can just be independently opted-in by an arch port
provided the ABI supports it.

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
Changes since v2
  * Fixup coding style for #if and defined
Changes since v1
  * make the toggle #if style rather than #ifdef style
  * define to 0 in all arches which don't use it
---
 sysdeps/unix/sysv/linux/alpha/kernel_stat.h            |  1 +
 sysdeps/unix/sysv/linux/fxstat64.c                     |  6 +++---
 sysdeps/unix/sysv/linux/fxstatat64.c                   |  6 +++---
 sysdeps/unix/sysv/linux/generic/kernel_stat.h          |  7 +++++++
 sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c   |  6 +++---
 sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c |  6 +++---
 sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c   | 10 +++++-----
 sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c |  8 ++++----
 sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c    |  6 +++---
 sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c  |  6 +++---
 sysdeps/unix/sysv/linux/hppa/kernel_stat.h             |  1 +
 sysdeps/unix/sysv/linux/ia64/kernel_stat.h             |  1 +
 sysdeps/unix/sysv/linux/kernel_stat.h                  |  1 +
 sysdeps/unix/sysv/linux/microblaze/kernel_stat.h       |  1 +
 sysdeps/unix/sysv/linux/mips/kernel_stat.h             |  1 +
 .../unix/sysv/linux/powerpc/powerpc32/kernel_stat.h    |  1 +
 .../unix/sysv/linux/powerpc/powerpc64/kernel_stat.h    |  1 +
 sysdeps/unix/sysv/linux/s390/s390-64/kernel_stat.h     |  1 +
 sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h    |  1 +
 sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h    |  1 +
 sysdeps/unix/sysv/linux/statx_cp.c                     |  2 +-
 sysdeps/unix/sysv/linux/x86_64/kernel_stat.h           |  1 +
 22 files changed, 47 insertions(+), 28 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/alpha/kernel_stat.h b/sysdeps/unix/sysv/linux/alpha/kernel_stat.h
index d637e099cfe4..437b56098ecd 100644
--- a/sysdeps/unix/sysv/linux/alpha/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/alpha/kernel_stat.h
@@ -87,3 +87,4 @@ struct glibc21_stat
 
 #define XSTAT_IS_XSTAT64 1
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/fxstat64.c b/sysdeps/unix/sysv/linux/fxstat64.c
index 9133a0a29b8e..dc0edec4bd8e 100644
--- a/sysdeps/unix/sysv/linux/fxstat64.c
+++ b/sysdeps/unix/sysv/linux/fxstat64.c
@@ -33,14 +33,14 @@ int
 ___fxstat64 (int vers, int fd, struct stat64 *buf)
 {
   int result;
-#ifdef __NR_fstat64
-  result = INLINE_SYSCALL (fstat64, 2, fd, buf);
-#else
+#if STAT64_IS_NOT_KERNEL_STAT64 || !defined (__NR_fstat64)
   struct statx tmp;
   result = INLINE_SYSCALL (statx, 5, fd, "", AT_EMPTY_PATH, STATX_BASIC_STATS,
                            &tmp);
   if (result == 0)
     __cp_stat64_statx (buf, &tmp);
+#else
+  result = INLINE_SYSCALL (fstat64, 2, fd, buf);
 #endif
   return result;
 }
diff --git a/sysdeps/unix/sysv/linux/fxstatat64.c b/sysdeps/unix/sysv/linux/fxstatat64.c
index e24b456604ff..393b2b8ef87f 100644
--- a/sysdeps/unix/sysv/linux/fxstatat64.c
+++ b/sysdeps/unix/sysv/linux/fxstatat64.c
@@ -38,15 +38,15 @@ __fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
 
   int result;
 
-#ifdef __NR_fstatat64
-  result = INTERNAL_SYSCALL_CALL (fstatat64, fd, file, st, flag);
-#else
+#if STAT64_IS_NOT_KERNEL_STAT64 || !defined (__NR_fstatat64)
   struct statx tmp;
 
   result = INTERNAL_SYSCALL_CALL (statx, fd, file, AT_NO_AUTOMOUNT | flag,
 				  STATX_BASIC_STATS, &tmp);
   if (result == 0)
     __cp_stat64_statx (st, &tmp);
+#else
+  result = INTERNAL_SYSCALL_CALL (fstatat64, fd, file, st, flag);
 #endif
   if (!__glibc_likely (INTERNAL_SYSCALL_ERROR_P (result)))
     return 0;
diff --git a/sysdeps/unix/sysv/linux/generic/kernel_stat.h b/sysdeps/unix/sysv/linux/generic/kernel_stat.h
index 2eed3596c0ed..fb97832f213f 100644
--- a/sysdeps/unix/sysv/linux/generic/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/generic/kernel_stat.h
@@ -28,3 +28,10 @@
 #endif
 
 #define STATFS_IS_STATFS64 0
+
+/* Allows asm-generic ABI ports with fstat64 syscall to use statx syscall for
+   implement stat* wrappers. This is needed when glibc stat64 is not compatible
+   with kernel stat64 (due to 64-bit time_t). By default it is off unless
+   arch opts-in.  */
+
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c
index 850450e1e8a1..b20956049a01 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c
@@ -36,14 +36,14 @@ __fxstat (int vers, int fd, struct stat *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-# ifdef __NR_fstat64
-      int rc = INLINE_SYSCALL (fstat64, 2, fd, buf);
-# else
+# if STAT64_IS_NOT_KERNEL_STAT64 || !defined (__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, fd, "", AT_EMPTY_PATH,
                                STATX_BASIC_STATS, &tmp);
       if (rc == 0)
         __cp_stat64_statx ((struct stat64 *)buf, &tmp);
+# else
+      int rc = INLINE_SYSCALL (fstat64, 2, fd, buf);
 # endif
       return rc ?: stat_overflow (buf);
     }
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c
index 8df65ebea084..3a1d01618225 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c
@@ -36,15 +36,15 @@ __fxstatat (int vers, int fd, const char *file, struct stat *buf, int flag)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-# ifdef __NR_fstatat64
-      int rc = INLINE_SYSCALL (fstatat64, 4, fd, file, buf, flag);
-# else
+# if STAT64_IS_NOT_KERNEL_STAT64 || !defined (__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, fd, file,
                                AT_NO_AUTOMOUNT | flag,
                                STATX_BASIC_STATS, &tmp);
       if (rc == 0)
         __cp_stat64_statx ((struct stat64 *)buf, &tmp);
+# else
+      int rc = INLINE_SYSCALL (fstatat64, 4, fd, file, buf, flag);
 # endif
       return rc ?: stat_overflow (buf);
     }
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c
index bd02631d68cd..ccd8816fac51 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c
@@ -35,17 +35,17 @@ __lxstat (int vers, const char *name, struct stat *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-#ifdef __NR_fstatat64
-      int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf,
-                               AT_SYMLINK_NOFOLLOW);
-#else
+# if STAT64_IS_NOT_KERNEL_STAT64 || !defined (__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name,
                                AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW,
                                STATX_BASIC_STATS, &tmp);
       if (rc == 0)
         __cp_stat64_statx ((struct stat64 *)buf, &tmp);
-#endif
+# else
+      int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf,
+                               AT_SYMLINK_NOFOLLOW);
+# endif
       return rc ?: stat_overflow (buf);
     }
   errno = EINVAL;
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c
index 3eab0a184751..152cbf1d126b 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c
@@ -40,10 +40,7 @@ __lxstat64 (int vers, const char *name, struct stat64 *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-#ifdef __NR_fstatat64
-      return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf,
-                             AT_SYMLINK_NOFOLLOW);
-#else
+#if STAT64_IS_NOT_KERNEL_STAT64 || !defined (__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name,
                                AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW,
@@ -51,6 +48,9 @@ __lxstat64 (int vers, const char *name, struct stat64 *buf)
       if (rc == 0)
         __cp_stat64_statx (buf, &tmp);
       return rc;
+#else
+      return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf,
+                             AT_SYMLINK_NOFOLLOW);
 #endif
     }
 
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c
index a4a921c1ea6c..054ceeb79d5d 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c
@@ -35,14 +35,14 @@ __xstat (int vers, const char *name, struct stat *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-# ifdef __NR_fstatat64
-      int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
-# else
+# if STAT64_IS_NOT_KERNEL_STAT64 || !defined (__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name, AT_NO_AUTOMOUNT,
                                STATX_BASIC_STATS, &tmp);
       if (rc == 0)
         __cp_stat64_statx ((struct stat64 *)buf, &tmp);
+# else
+      int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
 # endif
       return rc ?: stat_overflow (buf);
     }
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c
index 0848b5a4b4b1..1c5e9610a1a8 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c
@@ -40,15 +40,15 @@ __xstat64 (int vers, const char *name, struct stat64 *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
-#ifdef __NR_fstatat64
-      return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
-#else
+#if STAT64_IS_NOT_KERNEL_STAT64 || !defined (__NR_fstat64)
       struct statx tmp;
       int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name, AT_NO_AUTOMOUNT,
                                STATX_BASIC_STATS, &tmp);
       if (rc == 0)
         __cp_stat64_statx (buf, &tmp);
       return rc;
+#else
+      return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
 #endif
     }
   errno = EINVAL;
diff --git a/sysdeps/unix/sysv/linux/hppa/kernel_stat.h b/sysdeps/unix/sysv/linux/hppa/kernel_stat.h
index a3ac53a1ef2f..93802c4257c0 100644
--- a/sysdeps/unix/sysv/linux/hppa/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/hppa/kernel_stat.h
@@ -32,3 +32,4 @@ struct kernel_stat {
 
 #define XSTAT_IS_XSTAT64 0
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/ia64/kernel_stat.h b/sysdeps/unix/sysv/linux/ia64/kernel_stat.h
index b38bf741d37b..6965d95e9529 100644
--- a/sysdeps/unix/sysv/linux/ia64/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/ia64/kernel_stat.h
@@ -19,3 +19,4 @@
 #define STAT_IS_KERNEL_STAT 1
 #define XSTAT_IS_XSTAT64 1
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/kernel_stat.h b/sysdeps/unix/sysv/linux/kernel_stat.h
index eecc962de390..3ff0882c51a2 100644
--- a/sysdeps/unix/sysv/linux/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/kernel_stat.h
@@ -36,3 +36,4 @@ struct kernel_stat
 
 #define XSTAT_IS_XSTAT64 0
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel_stat.h b/sysdeps/unix/sysv/linux/microblaze/kernel_stat.h
index 765e0dca6763..64d4b11ee6da 100644
--- a/sysdeps/unix/sysv/linux/microblaze/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/microblaze/kernel_stat.h
@@ -50,3 +50,4 @@ struct kernel_stat
 
 #define XSTAT_IS_XSTAT64 0
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/mips/kernel_stat.h b/sysdeps/unix/sysv/linux/mips/kernel_stat.h
index 388df1bfffec..fd221c632fac 100644
--- a/sysdeps/unix/sysv/linux/mips/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/mips/kernel_stat.h
@@ -58,3 +58,4 @@ struct kernel_stat
 
 #define XSTAT_IS_XSTAT64 0
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/kernel_stat.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/kernel_stat.h
index c5948a4d3c1c..4e389cb2ff80 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/kernel_stat.h
@@ -49,3 +49,4 @@ struct kernel_stat
 
 #define XSTAT_IS_XSTAT64 0
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/kernel_stat.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/kernel_stat.h
index 5c10da3356f2..b48dbc15227d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/kernel_stat.h
@@ -19,3 +19,4 @@
 #define STAT_IS_KERNEL_STAT 1
 #define XSTAT_IS_XSTAT64 1
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/kernel_stat.h b/sysdeps/unix/sysv/linux/s390/s390-64/kernel_stat.h
index b38bf741d37b..6965d95e9529 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/kernel_stat.h
@@ -19,3 +19,4 @@
 #define STAT_IS_KERNEL_STAT 1
 #define XSTAT_IS_XSTAT64 1
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h b/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h
index a4416009f1bc..17ac63b753e5 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h
@@ -33,3 +33,4 @@ struct kernel_stat
 
 #define XSTAT_IS_XSTAT64 0
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h b/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h
index 30afb553b9b8..4912a98529a4 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h
@@ -46,3 +46,4 @@ struct kernel_stat64
 
 #define XSTAT_IS_XSTAT64 1
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
diff --git a/sysdeps/unix/sysv/linux/statx_cp.c b/sysdeps/unix/sysv/linux/statx_cp.c
index cc6e17929ea0..2e43d46f4f99 100644
--- a/sysdeps/unix/sysv/linux/statx_cp.c
+++ b/sysdeps/unix/sysv/linux/statx_cp.c
@@ -22,7 +22,7 @@
 
 #include <statx_cp.h>
 
-#if !defined(__NR_fstat64) || !defined(__NR_fstatat64)
+#if !defined (__NR_fstat64) || !defined (__NR_fstatat64) || STAT64_IS_NOT_KERNEL_STAT64
 void
 __cp_stat64_statx (struct stat64 *to, struct statx *from)
 {
diff --git a/sysdeps/unix/sysv/linux/x86_64/kernel_stat.h b/sysdeps/unix/sysv/linux/x86_64/kernel_stat.h
index b38bf741d37b..6965d95e9529 100644
--- a/sysdeps/unix/sysv/linux/x86_64/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/x86_64/kernel_stat.h
@@ -19,3 +19,4 @@
 #define STAT_IS_KERNEL_STAT 1
 #define XSTAT_IS_XSTAT64 1
 #define STATFS_IS_STATFS64 0
+#define STAT64_IS_NOT_KERNEL_STAT64 0
-- 
2.20.1


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

* Re: [PATCH v3] asm-generic ABI: Allow statx syscall despite fstatat64, fstat64
  2020-02-25  0:29               ` [PATCH v3] " Vineet Gupta
@ 2020-02-25  3:13                 ` Vineet Gupta
  2020-02-25 16:10                   ` Joseph Myers
  0 siblings, 1 reply; 12+ messages in thread
From: Vineet Gupta @ 2020-02-25  3:13 UTC (permalink / raw)
  To: libc-alpha; +Cc: alistair23, linux-snps-arc, alistair.francis

On 2/24/20 4:29 PM, Vineet Gupta wrote:
> An old version of asm-generic syscall ABI (e.g. ARC 2013) provided
> fstat[at]64 syscalls for implementing the stat family.
> 
> These sycalls are passthru (no interworking/itemized-copy needed
> between kernel and user structs since they are binary comaptible).
> However with switch to 64-bit time_t the compatibily goes away so we
> need explicit interworking. Luckily such code already exists albeit it
> uses the statx syscall.
> 
> So this patch reworks the asm-generic based stat functions to use the
> statx code-path if the arch so desires. It essentially reworks the commit
> 6bbfc5c09fc5b5e3 ("Add statx conditionals for wordsize-32 *xstat.c")
> 
> This will be used by ARC port for 64-bit time_t. But it has no real
> bearing on 64-bit and can just be independently opted-in by an arch port
> provided the ABI supports it.

Oh wait. Can we avoid this churn by simply undef __NR_fstat64 and __NR_fstatat64
from ARC sysdep.h ? And it will then automatically fallback to statx code !

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

* Re: [PATCH v3] asm-generic ABI: Allow statx syscall despite fstatat64, fstat64
  2020-02-25  3:13                 ` [PATCH v3] asm-generic ABI: Allow statx syscall despite fstatat64, fstat64 Vineet Gupta
@ 2020-02-25 16:10                   ` Joseph Myers
  2020-02-25 16:55                     ` Vineet Gupta
  0 siblings, 1 reply; 12+ messages in thread
From: Joseph Myers @ 2020-02-25 16:10 UTC (permalink / raw)
  To: Vineet Gupta; +Cc: libc-alpha, alistair23, linux-snps-arc, alistair.francis

On Mon, 24 Feb 2020, Vineet Gupta wrote:

> Oh wait. Can we avoid this churn by simply undef __NR_fstat64 and __NR_fstatat64
> from ARC sysdep.h ? And it will then automatically fallback to statx code !

If all files needing this information include sysdep.h, that might well 
work.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH v3] asm-generic ABI: Allow statx syscall despite fstatat64, fstat64
  2020-02-25 16:10                   ` Joseph Myers
@ 2020-02-25 16:55                     ` Vineet Gupta
  0 siblings, 0 replies; 12+ messages in thread
From: Vineet Gupta @ 2020-02-25 16:55 UTC (permalink / raw)
  To: Joseph Myers
  Cc: libc-alpha@sourceware.org, alistair23@gmail.com,
	linux-snps-arc@lists.infradead.org, alistair.francis@wdc.com

On 2/25/20 8:10 AM, Joseph Myers wrote:
> On Mon, 24 Feb 2020, Vineet Gupta wrote:
> 
>> Oh wait. Can we avoid this churn by simply undef __NR_fstat64 and __NR_fstatat64
>> from ARC sysdep.h ? And it will then automatically fallback to statx code !
>
> If all files needing this information include sysdep.h, that might well 
> work.

I agree that this is a valid concern. If we really want to make it water tight we
could have the build system enforce this with -include or some such ?

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

end of thread, other threads:[~2020-02-25 16:56 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-24 18:23 [PATCH] asm-generic ABI: Allow statx syscall despite fstatat64,fstat64 Vineet Gupta
2020-02-24 18:39 ` Florian Weimer
2020-02-24 19:03   ` Vineet Gupta
2020-02-24 19:13     ` Florian Weimer
2020-02-24 19:27       ` Vineet Gupta
2020-02-24 19:38         ` Florian Weimer
2020-02-24 22:15           ` [PATCH v2] " Vineet Gupta
2020-02-25  0:09             ` Joseph Myers
2020-02-25  0:29               ` [PATCH v3] " Vineet Gupta
2020-02-25  3:13                 ` [PATCH v3] asm-generic ABI: Allow statx syscall despite fstatat64, fstat64 Vineet Gupta
2020-02-25 16:10                   ` Joseph Myers
2020-02-25 16:55                     ` Vineet Gupta

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).