Skip to content

statx requires <sys/stat.h> include file#18316

Open
wbx-github wants to merge 2 commits intoopenzfs:masterfrom
wbx-github:statx-test-fix
Open

statx requires <sys/stat.h> include file#18316
wbx-github wants to merge 2 commits intoopenzfs:masterfrom
wbx-github:statx-test-fix

Conversation

@wbx-github
Copy link

For usage of statx() function you need to include <sys/stat.h>.

When compiling the testsuite with uClibc-ng >= 1.0.57 you get following gcc error:

tests/zfs-tests/cmd/statx.c:58:1: error: conflicting types for 'statx'; have 'int(int, const char *, int, unsigned int, void *)'
58 | statx(int, const char *, int, unsigned int, void *)
| ^~~~~
In file included from /home/wbx/buildroot/br2-zfs/TestZfsUclibc/host/aarch64-buildroot-linux-uclibc/sysroot/usr/include/sys/stat.h:381,
from ./lib/libspl/include/os/linux/sys/stat.h:30,
from /home/wbx/buildroot/br2-zfs/TestZfsUclibc/host/aarch64-buildroot-linux-uclibc/sysroot/usr/include/fcntl.h:37,
from tests/zfs-tests/cmd/statx.c:29:
/home/wbx/buildroot/br2-zfs/TestZfsUclibc/host/aarch64-buildroot-linux-uclibc/sysroot/usr/include/bits/statx.h:98:5: note: previous declaration of 'statx' with type 'int(int, const char * restrict, int, unsigned int, struct statx * restrict)'
98 | int statx (int __dirfd, const char *__restrict __path, int __flags,
| ^~~~~

The reason is that uClibc-ng before 1.0.56 did not expose statx(). With uClibc-ng 1.0.57 there is a mismatch when <fcntl.h> is included, because uClibc-ng has a transient dependency on <sys/stat.h>. Glibc does not include <sys/stat.h>, but <bits/stat.h> in fcntl.h so the error does not happen here, but not the real statx() from glibc is used in this case.

To make both C libraries happy, only define statx() locally, when no statx is recognized via configure and include the correct header.

The test failure was found by the Buildroot project:
https://gitlab.com/jolivain/buildroot/-/jobs/13308829775#L237
See here this thread for the discussion:
https://lists.buildroot.org/pipermail/buildroot/2026-March/797844.html

For usage of statx() function you need to include <sys/stat.h>.

When compiling the testsuite with uClibc-ng >= 1.0.57 you get following
gcc error:

tests/zfs-tests/cmd/statx.c:58:1: error: conflicting types for 'statx'; have 'int(int,  const char *, int,  unsigned int,  void *)'
   58 | statx(int, const char *, int, unsigned int, void *)
      | ^~~~~
In file included from /home/wbx/buildroot/br2-zfs/TestZfsUclibc/host/aarch64-buildroot-linux-uclibc/sysroot/usr/include/sys/stat.h:381,
                 from ./lib/libspl/include/os/linux/sys/stat.h:30,
                 from /home/wbx/buildroot/br2-zfs/TestZfsUclibc/host/aarch64-buildroot-linux-uclibc/sysroot/usr/include/fcntl.h:37,
                 from tests/zfs-tests/cmd/statx.c:29:
/home/wbx/buildroot/br2-zfs/TestZfsUclibc/host/aarch64-buildroot-linux-uclibc/sysroot/usr/include/bits/statx.h:98:5: note: previous declaration of 'statx' with type
'int(int,  const char * restrict,  int,  unsigned int,  struct statx * restrict)'
   98 | int statx (int __dirfd, const char *__restrict __path, int __flags,
      |     ^~~~~

The reason is that uClibc-ng before 1.0.56 did not expose statx().
With uClibc-ng 1.0.57 there is a mismatch when <fcntl.h> is included,
because uClibc-ng has a transient dependency on <sys/stat.h>.
Glibc does not include <sys/stat.h>, but <bits/stat.h> in fcntl.h
so the error does not happen here, but not the real statx() from glibc
is used in this case.

To make both C libraries happy, only define statx() locally, when
no statx is recognized via configure and include the correct header.
@behlendorf
Copy link
Contributor

behlendorf commented Mar 12, 2026

Unfortunately, this seems to break the build with glibc.

  tests/zfs-tests/cmd/statx.c: In function '_statx':
  tests/zfs-tests/cmd/statx.c:67:6: error: the address of 'statx' will always evaluate as 'true' [-Werror=address]
    if (statx)
        ^~~~~
    CC       tests/zfs-tests/cmd/zed_fd_spill-zedlet.o
  cc1: all warnings being treated as errors
  make[4]: *** [Makefile:9121: tests/zfs-tests/cmd/statx.o] Error 1

@behlendorf behlendorf added the Status: Code Review Needed Ready for review and testing label Mar 12, 2026
@wbx-github
Copy link
Author

Sorry, I only tested with Buildroot. It seems the patch needs more work for older glibc. Any idea why my patch breaks?

@jolivain
Copy link

Hi,

For info, on my side, I tried to workaround this issue with the following patch:
jolivain@d363aaf

I am not sure at the moment it is the best fix for zfs.

It is working in Buildroot in all our cases (Glibc with statx, uclibc < 1.0.57 without statx and 1.0.57 with statx, and musl libc without statx). I tested with:

utils/docker-run support/testing/run-tests \
    -d dl -o output_folder tests.package.test_zfs

Note: Buildroot is not running the zfs tests but is rather checking we can use a zfs partition.

@robn
Copy link
Member

robn commented Mar 15, 2026

Does this build run configure? If so, this is probably best done by checking for statx there, and not building the test binary if it doesn't exist. And then make the test driver SKIP if it can't find the program.

@robn
Copy link
Member

robn commented Mar 15, 2026

Oh maybe never mind, I commented "from the hip" and then saw @jolivain's solution, which is similar but better than what I suggested. I'll have a look later today.

arnout pushed a commit to buildroot/buildroot that referenced this pull request Mar 16, 2026
uclibc 1.0.57 added a statx() syscall wrapper in upstream commit [1].

zfs fail to build with uclibc 1.0.57 (not yet in Buildroot), because:
1. uclibc <fcntl.h> internally includes <sys/stat.h>, and
2. a zfs test redefines a statx() wrapper with a slightly different
   prototype.

In that case, zfs fails to compile with error:

    tests/zfs-tests/cmd/statx.c:58:1: error: conflicting types for 'statx'; have 'int(int,  const char *, int,  unsigned int,  void *)'

Issue has been reported upstream at [2].

This commit adds a package patch to fix that issue.

[1] wbx-github/uclibc-ng@d3a819a
[2] openzfs/zfs#18316

Signed-off-by: Julien Olivain <ju.o@free.fr>
@behlendorf
Copy link
Contributor

@jolivain your fix makes good sense to me. Would you mind opening a PR with it.

jolivain added a commit to jolivain/zfs that referenced this pull request Mar 18, 2026
With some libc, such as uclibc >= 1.0.57, the libc defines the statx()
function, while also internally including <sys/stat.h> (from <fcntl.h>
for example), the compilation results to an error due to conflicting
types, with the message:

    tests/zfs-tests/cmd/statx.c:58:1: error: conflicting types for 'statx'; have 'int(int,  const char *, int,  unsigned int,  void *)'
       58 | statx(int, const char *, int, unsigned int, void *)
          | ^~~~~
    In file included from /TestZfsUclibc/host/aarch64-buildroot-linux-uclibc/sysroot/usr/include/sys/stat.h:381,
                     from ./lib/libspl/include/os/linux/sys/stat.h:30,
                     from /TestZfsUclibc/host/aarch64-buildroot-linux-uclibc/sysroot/usr/include/fcntl.h:37,
                     from tests/zfs-tests/cmd/statx.c:29:
    /TestZfsUclibc/host/aarch64-buildroot-linux-uclibc/sysroot/usr/include/bits/statx.h:88:5: note: previous declaration of 'statx' with type 'int(int,  const char * restrict,  int,  unsigned int,  struct statx * restrict)'
       88 | int statx (int __dirfd, const char *__restrict __path, int __flags,
          |     ^~~~~

This is because the zfs statx test inconditionally defines a statx()
function with a slightly different prototype [1], compared to Glibc [2]
and uClibc [3].

The error does not happen with Glibc because its <fcntl.h> header does
not include <sys/stat.h> and the zfs-tests/cmd/statx.c does not include
<sys/stat.h> either. So the conflict does not happen.

This commit fixes the issue by only defining the statx() prototype only
if the libc was detected not to have a working statx() wrapper, and
explicitly include the <sys/stat.h> otherwise.

Note: the issue was found in Linux Buildroot [4], while updating
uclibc-ng to version 1.0.57. See: [5] [6]. The issue was also
reported in [7].

[1] https://github.com/openzfs/zfs/blob/zfs-2.4.1/tests/zfs-tests/cmd/statx.c#L58
[2] https://sourceware.org/git/?p=glibc.git;a=blob;f=io/bits/statx-generic.h;h=9bb9701dc67eccad968b338aeb15d87378fe65cd;hb=ea37298b65bd67f94c3c2640e91ec5865a5019ad#l66
[3] https://github.com/wbx-github/uclibc-ng/blob/v1.0.57/libc/sysdeps/linux/common/bits/statx.h#L88
[4] https://buildroot.org/
[5] https://lore.kernel.org/buildroot/054ee3804bf26bee3dadf8425e0f723c@free.fr/
[6] https://gitlab.com/jolivain/buildroot/-/jobs/13308829775#L237
[7] openzfs#18316

Signed-off-by: Julien Olivain <ju.o@free.fr>
@jolivain
Copy link

Hi, I rebased my proposed patch, added more info in the commit log, and sent a PR in #18345
Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Status: Code Review Needed Ready for review and testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants