diff --git a/Doc/library/os.rst b/Doc/library/os.rst index ef08e1bfa51a6f..50f6886c89df9e 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3566,9 +3566,9 @@ features: STATX_WRITE_ATOMIC STATX_DIO_READ_ALIGN - Bitflags for use in the *mask* parameter to :func:`os.statx`. Flags - including and after :const:`!STATX_MNT_ID` are only available when their - corresponding members in :class:`statx_result` are available. + Bitflags for use in the *mask* parameter to :func:`os.statx`. Some of these + flags may be available even when their corresponding members in + :class:`statx_result` are not available. .. availability:: Linux >= 4.11 with glibc >= 2.28. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 1cfb068680cc4b..d0b9eed8c8208b 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -3364,15 +3364,15 @@ static PyMemberDef pystatx_result_members[] = { STATX_GET_UINT(st_uid, stx_uid, STATX_UID) STATX_GET_UINT(st_gid, stx_gid, STATX_GID) STATX_GET_UINT(st_nlink, stx_nlink, STATX_NLINK) -#ifdef STATX_DIOALIGN +#ifdef HAVE_STRUCT_STATX_STX_DIO_MEM_ALIGN STATX_GET_UINT(stx_dio_mem_align, stx_dio_mem_align, STATX_DIOALIGN) STATX_GET_UINT(stx_dio_offset_align, stx_dio_offset_align, STATX_DIOALIGN) #endif -#ifdef STATX_DIO_READ_ALIGN +#ifdef HAVE_STRUCT_STATX_STX_DIO_READ_OFFSET_ALIGN STATX_GET_UINT(stx_dio_read_offset_align, stx_dio_read_offset_align, STATX_DIO_READ_ALIGN) #endif -#ifdef STATX_WRITE_ATOMIC +#ifdef HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MIN STATX_GET_UINT(stx_atomic_write_unit_min, stx_atomic_write_unit_min, STATX_WRITE_ATOMIC) STATX_GET_UINT(stx_atomic_write_unit_max, stx_atomic_write_unit_max, @@ -3401,10 +3401,10 @@ STATX_GET_UINT(stx_atomic_write_unit_max_opt, stx_atomic_write_unit_max_opt, STATX_GET_ULONGLONG(st_blocks, stx_blocks, STATX_BLOCKS) STATX_GET_ULONGLONG(st_ino, stx_ino, STATX_INO) STATX_GET_ULONGLONG(st_size, stx_size, STATX_SIZE) -#ifdef STATX_MNT_ID +#ifdef HAVE_STRUCT_STATX_STX_MNT_ID STATX_GET_ULONGLONG(stx_mnt_id, stx_mnt_id, STATX_MNT_ID) #endif -#ifdef STATX_SUBVOL +#ifdef HAVE_STRUCT_STATX_STX_SUBVOL STATX_GET_ULONGLONG(stx_subvol, stx_subvol, STATX_SUBVOL) #endif @@ -3463,17 +3463,17 @@ static PyGetSetDef pystatx_result_getset[] = { G(st_ctime_ns, "time of last change in nanoseconds"), G(st_mtime, "time of last modification"), G(st_mtime_ns, "time of last modification in nanoseconds"), -#ifdef STATX_MNT_ID +#ifdef HAVE_STRUCT_STATX_STX_MNT_ID G(stx_mnt_id, "mount ID"), #endif -#ifdef STATX_DIOALIGN +#ifdef HAVE_STRUCT_STATX_STX_DIO_MEM_ALIGN G(stx_dio_mem_align, "direct I/O memory buffer alignment"), G(stx_dio_offset_align, "direct I/O file offset alignment"), #endif -#ifdef STATX_SUBVOL +#ifdef HAVE_STRUCT_STATX_STX_SUBVOL G(stx_subvol, "subvolume ID"), #endif -#ifdef STATX_WRITE_ATOMIC +#ifdef HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MIN G(stx_atomic_write_unit_min, "minimum size for direct I/O with torn-write protection"), G(stx_atomic_write_unit_max, @@ -3481,7 +3481,7 @@ static PyGetSetDef pystatx_result_getset[] = { G(stx_atomic_write_segments_max, "maximum iovecs for direct I/O with torn-write protection"), #endif -#ifdef STATX_DIO_READ_ALIGN +#ifdef HAVE_STRUCT_STATX_STX_DIO_READ_OFFSET_ALIGN G(stx_dio_read_offset_align, "direct I/O file offset alignment for reads"), #endif #ifdef HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MAX_OPT diff --git a/configure b/configure index 95e231f406a9a3..2fd3ca210b6305 100755 --- a/configure +++ b/configure @@ -25139,6 +25139,57 @@ fi if test "$ac_cv_func_statx" = yes; then + # Some systems have the definitions of the mask bits without having the + # corresponding members in struct statx. Check for members added after Linux + # 4.11 (when statx itself was added). + ac_fn_c_check_member "$LINENO" "struct statx" "stx_mnt_id" "ac_cv_member_struct_statx_stx_mnt_id" "$ac_includes_default" +if test "x$ac_cv_member_struct_statx_stx_mnt_id" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STATX_STX_MNT_ID 1" >>confdefs.h + + +fi + + ac_fn_c_check_member "$LINENO" "struct statx" "stx_dio_mem_align" "ac_cv_member_struct_statx_stx_dio_mem_align" "$ac_includes_default" +if test "x$ac_cv_member_struct_statx_stx_dio_mem_align" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STATX_STX_DIO_MEM_ALIGN 1" >>confdefs.h + + +fi + + # stx_dio_offset_align was added together with stx_dio_mem_align + ac_fn_c_check_member "$LINENO" "struct statx" "stx_subvol" "ac_cv_member_struct_statx_stx_subvol" "$ac_includes_default" +if test "x$ac_cv_member_struct_statx_stx_subvol" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STATX_STX_SUBVOL 1" >>confdefs.h + + +fi + + ac_fn_c_check_member "$LINENO" "struct statx" "stx_atomic_write_unit_min" "ac_cv_member_struct_statx_stx_atomic_write_unit_min" "$ac_includes_default" +if test "x$ac_cv_member_struct_statx_stx_atomic_write_unit_min" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MIN 1" >>confdefs.h + + +fi + + # stx_atomic_write_unit_max and stx_atomic_write_segments_max were added + # together with stx_atomic_write_unit_min + ac_fn_c_check_member "$LINENO" "struct statx" "stx_dio_read_offset_align" "ac_cv_member_struct_statx_stx_dio_read_offset_align" "$ac_includes_default" +if test "x$ac_cv_member_struct_statx_stx_dio_read_offset_align" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STATX_STX_DIO_READ_OFFSET_ALIGN 1" >>confdefs.h + + +fi + # stx_atomic_write_unit_max_opt was added in Linux 6.16, but is controlled by # the STATX_WRITE_ATOMIC mask bit added in Linux 6.11, so having the mask bit # doesn't imply having the member. diff --git a/configure.ac b/configure.ac index 65c37579633754..1606941d88d0b2 100644 --- a/configure.ac +++ b/configure.ac @@ -5826,6 +5826,17 @@ AC_CHECK_MEMBERS([struct passwd.pw_gecos, struct passwd.pw_passwd], [], [], [[ AC_CHECK_MEMBERS([siginfo_t.si_band], [], [], [[@%:@include ]]) if test "$ac_cv_func_statx" = yes; then + # Some systems have the definitions of the mask bits without having the + # corresponding members in struct statx. Check for members added after Linux + # 4.11 (when statx itself was added). + AC_CHECK_MEMBERS([struct statx.stx_mnt_id]) + AC_CHECK_MEMBERS([struct statx.stx_dio_mem_align]) + # stx_dio_offset_align was added together with stx_dio_mem_align + AC_CHECK_MEMBERS([struct statx.stx_subvol]) + AC_CHECK_MEMBERS([struct statx.stx_atomic_write_unit_min]) + # stx_atomic_write_unit_max and stx_atomic_write_segments_max were added + # together with stx_atomic_write_unit_min + AC_CHECK_MEMBERS([struct statx.stx_dio_read_offset_align]) # stx_atomic_write_unit_max_opt was added in Linux 6.16, but is controlled by # the STATX_WRITE_ATOMIC mask bit added in Linux 6.11, so having the mask bit # doesn't imply having the member. diff --git a/pyconfig.h.in b/pyconfig.h.in index 092f96e7152e11..fb12079bafa95e 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1334,6 +1334,23 @@ statx'. */ #undef HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MAX_OPT +/* Define to 1 if 'stx_atomic_write_unit_min' is a member of 'struct statx'. + */ +#undef HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MIN + +/* Define to 1 if 'stx_dio_mem_align' is a member of 'struct statx'. */ +#undef HAVE_STRUCT_STATX_STX_DIO_MEM_ALIGN + +/* Define to 1 if 'stx_dio_read_offset_align' is a member of 'struct statx'. + */ +#undef HAVE_STRUCT_STATX_STX_DIO_READ_OFFSET_ALIGN + +/* Define to 1 if 'stx_mnt_id' is a member of 'struct statx'. */ +#undef HAVE_STRUCT_STATX_STX_MNT_ID + +/* Define to 1 if 'stx_subvol' is a member of 'struct statx'. */ +#undef HAVE_STRUCT_STATX_STX_SUBVOL + /* Define to 1 if 'st_birthtime' is a member of 'struct stat'. */ #undef HAVE_STRUCT_STAT_ST_BIRTHTIME