jnr / jnr-posix

Java Posix layer
Other
241 stars 91 forks source link

Struct layout for `LinuxFileStatAARCH64` does not match that on Amazon Graviton2 nodes #164

Closed robbavey closed 3 years ago

robbavey commented 3 years ago

Looking at the struct layout defined here in LinuxFileStatAARCH64, it does not match stat struct on Amazon Graviton2 nodes:

pahole -C stat /usr/lib/debug/lib64/libc.so.6.debug 

struct stat {
    __dev_t                    st_dev;               /*     0     8 */
    __ino_t                    st_ino;               /*     8     8 */
    __mode_t                   st_mode;              /*    16     4 */
    __nlink_t                  st_nlink;             /*    20     4 */
    __uid_t                    st_uid;               /*    24     4 */
    __gid_t                    st_gid;               /*    28     4 */
    __dev_t                    st_rdev;              /*    32     8 */
    __dev_t                    __pad1;               /*    40     8 */
    __off_t                    st_size;              /*    48     8 */
    __blksize_t                st_blksize;           /*    56     4 */
    int                        __pad2;               /*    60     4 */
    /* --- cacheline 1 boundary (64 bytes) --- */
    __blkcnt_t                 st_blocks;            /*    64     8 */
    struct timespec            st_atim;              /*    72    16 */
    struct timespec            st_mtim;              /*    88    16 */
    struct timespec            st_ctim;              /*   104    16 */
    int                        __glibc_reserved[2];  /*   120     8 */

    /* size: 128, cachelines: 2, members: 16 */
};
        public final dev_t st_dev = new dev_t();
        public final ino_t st_ino = new ino_t();
        public final mode_t st_mode = new mode_t();
        public final nlink_t st_nlink = new nlink_t();
        public final uid_t st_uid = new uid_t();
        public final gid_t st_gid = new gid_t();
        public final dev_t st_rdev = new dev_t();
        public final off_t st_size = new off_t();
        public final blksize_t st_blksize = new blksize_t();
        public final blkcnt_t st_blocks = new blkcnt_t();
        public final time_t st_atime = new time_t();             // Time of last access
        public final SignedLong st_atimensec = new SignedLong(); // Time of last access (nanoseconds)
        public final time_t st_mtime = new time_t();             // Last data modification time
        public final SignedLong st_mtimensec = new SignedLong(); // Last data modification time (nanoseconds)
        public final time_t st_ctime = new time_t();             // Time of last status change
        public final SignedLong st_ctimensec = new SignedLong(); // Time of last status change (nanoseconds)
        public final Signed64 __unused4 = new Signed64();

which manifests itself in File.stat running on jruby-9.2.17.0 presenting incorrect results on these nodes.

There are a few issues here:

https://github.com/jnr/jnr-ffi/blob/master/src/main/java/jnr/ffi/provider/jffi/platform/aarch64/linux/TypeAliases.java#L52:

m.put(TypeAlias.nlink_t, NativeType.ULONG);
/usr/include/bits/stat.h:    __nlink_t st_nlink;        /* Link count.  */
/usr/include/bits/types.h:__STD_TYPE __NLINK_T_TYPE __nlink_t;  /* Type of file link counts.  */
/usr/include/bits/typesizes.h:#define __NLINK_T_TYPE        __U32_TYPE

And

https://github.com/jnr/jnr-ffi/blob/master/src/main/java/jnr/ffi/provider/jffi/platform/aarch64/linux/TypeAliases.java#L44

m.put(TypeAlias.blksize_t, NativeType.SLONG);

vs:

/usr/include/bits/stat.h:    __blksize_t st_blksize;    /* Optimal block size for I/O.  */
/usr/include/bits/types.h:__STD_TYPE __BLKSIZE_T_TYPE __blksize_t;
/usr/include/bits/typesizes.h:#define __BLKSIZE_T_TYPE  __S32_TYPE