Home > development > More headaches with 2 GiB I/O

More headaches with 2 GiB I/O

July 11th, 2014

There are quite a few headaches when updating ROMIO and MPICH to be 64 bit clean. Once you’ve gone through all the hurdles to promote types and squash that last overflowing integer parameter, you are not done yet!
Take a look at what happens on OS X (Darwin) when you pass 2147483648 (231) bytes to the write system call:
http://opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/kern/sys_generic.c

dofilewrite(vfs_context_t ctx, struct fileproc *fp, user_addr_t bufp, user_size_t nbyte, off_t offset, int flags,user_ssize_t *retval)
{
    uio_t auio;
    long error = 0;
    user_ssize_t bytecnt;
    char uio_buf[ UIO_SIZEOF(1) ];
    if (nbyte > INT_MAX)
        return (EINVAL);
    ...
}

It’s entirely within the standard for write or read to return less than
requested, but this is not what darwin is doing: it’s straight-out erroring.
FreeBSD 9.2 and 10.0 exhibit similar behavior, which you can see in sys/kern/sys_generic.c

int
sys_read(td, uap)
        struct thread *td;
        struct read_args *uap;
{
        struct uio auio;
        struct iovec aiov;
        int error;
        if (uap->nbyte > IOSIZE_MAX)
                return (EINVAL);
        ...

So in commit 5b674543 I simply ensure no write is larger than a signed 32 bit integer can hold.

development

Comments are closed.