Re: [PATCH 1/2] tools/nolibc: fcntl: Add fallocate()

From: Thomas Weißschuh

Date: Wed Apr 15 2026 - 11:57:31 EST


Hi Daniel!

thanks for the patches.

On 2026-04-15 23:32:24+0900, Daniel Palmer wrote:
> Add fallocate(), some special care is needed to
> put the offset and size into the syscall parameters
> for 32bit machines and for x32.
>
> Signed-off-by: Daniel Palmer <daniel@xxxxxxxxx>
> ---
> tools/include/nolibc/fcntl.h | 30 ++++++++++++++++++++++++++++++
> 1 file changed, 30 insertions(+)
>
> diff --git a/tools/include/nolibc/fcntl.h b/tools/include/nolibc/fcntl.h
> index ed2f5553c65a..0ebfdb7bc792 100644
> --- a/tools/include/nolibc/fcntl.h
> +++ b/tools/include/nolibc/fcntl.h
> @@ -66,4 +66,34 @@ int open(const char *path, int flags, ...)
> return __sysret(_sys_open(path, flags, mode));
> }
>
> +/*
> + * int fallocate(int fd, int mode, off_t offset, off_t size);
> + */
> +
> +#define __NOLIBC_LLARGPART(_arg, _part) \
> + (((union { long long ll; long l[2]; }) { .ll = _arg }).l[_part])

This should go into sys.h, as it is fairly generic.

> +static __attribute__((unused))
> +int sys_fallocate(int fd, int mode, off_t offset, off_t size)

This should be _sys_fallocate() to avoid clashing with user symbols.

> +{
> +#if defined(__x86_64__) && defined(__ILP32__)
> + const bool offsetsz_two_args = false;
> +#else
> + const bool offsetsz_two_args = sizeof(long) != sizeof(off_t);
> +#endif

We try to avoid architecture-specific logic in the generic files.
x32 would be covered with sizeof(__kernel_long_t). But MIPS N32 is also
detected incorrectly here. In my opinion the best solution would be to
have an override mechansim like for _sys_mmap and override it for x32
and N32 in arch-x86.h and arch-mips.h.

Maybe also look at the recent proposal for ftruncate() which is somewhat
related:

https://git.kernel.org/pub/scm/linux/kernel/git/thomas.weissschuh/linux.git/commit/?h=b4/nolibc-ftruncate
https://lore.kernel.org/lkml/20260303010039.2969125-2-jordanrichards@xxxxxxxxxx/

> +
> + if (offsetsz_two_args)
> + return __nolibc_syscall6(__NR_fallocate, fd, mode,
> + __NOLIBC_LLARGPART(offset, 0), __NOLIBC_LLARGPART(offset, 1),
> + __NOLIBC_LLARGPART(size, 0), __NOLIBC_LLARGPART(size, 1));
> + else
> + return __nolibc_syscall4(__NR_fallocate, fd, mode, offset, size);
> +}
> +
> +static __attribute__((unused))
> +int fallocate(int fd, int mode, off_t offset, off_t size)
> +{
> + return __sysret(sys_fallocate(fd, mode, offset, size));
> +}
> +
> #endif /* _NOLIBC_FCNTL_H */
> --
> 2.51.0
>