* [PATCH 0/2] nolibc: Add fallocate()
@ 2026-04-15 14:32 Daniel Palmer
2026-04-15 14:32 ` [PATCH 1/2] tools/nolibc: fcntl: " Daniel Palmer
2026-04-15 14:32 ` [PATCH 2/2] selftests/nolibc: Add a very basic test for fallocate() Daniel Palmer
0 siblings, 2 replies; 5+ messages in thread
From: Daniel Palmer @ 2026-04-15 14:32 UTC (permalink / raw)
To: w, linux; +Cc: linux-kernel, Daniel Palmer
While poking around with my "static PIE for nommu" series I found
I needed fallocate(). Implementing it turned out a bit more
interesting than I thought it would be due to how the offset and
size need to be passed on 32bit machines.
I have ran the tests on m68k, arm, arm64, riscv[32|64], x86_64,
i386, x32. I probably missed something, maybe there is a better
way to do this. Maybe it can't actually pass an offset or size
>4GB on x32?
Daniel Palmer (2):
tools/nolibc: fcntl: Add fallocate()
selftests/nolibc: Add a very basic test for fallocate()
tools/include/nolibc/fcntl.h | 30 ++++++++++++++++++
tools/testing/selftests/nolibc/nolibc-test.c | 33 ++++++++++++++++++++
2 files changed, 63 insertions(+)
--
2.51.0
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 1/2] tools/nolibc: fcntl: Add fallocate() 2026-04-15 14:32 [PATCH 0/2] nolibc: Add fallocate() Daniel Palmer @ 2026-04-15 14:32 ` Daniel Palmer 2026-04-15 15:56 ` Thomas Weißschuh 2026-04-15 14:32 ` [PATCH 2/2] selftests/nolibc: Add a very basic test for fallocate() Daniel Palmer 1 sibling, 1 reply; 5+ messages in thread From: Daniel Palmer @ 2026-04-15 14:32 UTC (permalink / raw) To: w, linux; +Cc: linux-kernel, Daniel Palmer 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@thingy.jp> --- 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]) + +static __attribute__((unused)) +int sys_fallocate(int fd, int mode, off_t offset, off_t size) +{ +#if defined(__x86_64__) && defined(__ILP32__) + const bool offsetsz_two_args = false; +#else + const bool offsetsz_two_args = sizeof(long) != sizeof(off_t); +#endif + + 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 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] tools/nolibc: fcntl: Add fallocate() 2026-04-15 14:32 ` [PATCH 1/2] tools/nolibc: fcntl: " Daniel Palmer @ 2026-04-15 15:56 ` Thomas Weißschuh 0 siblings, 0 replies; 5+ messages in thread From: Thomas Weißschuh @ 2026-04-15 15:56 UTC (permalink / raw) To: Daniel Palmer; +Cc: w, linux-kernel 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@thingy.jp> > --- > 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@google.com/ > + > + 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 > ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] selftests/nolibc: Add a very basic test for fallocate() 2026-04-15 14:32 [PATCH 0/2] nolibc: Add fallocate() Daniel Palmer 2026-04-15 14:32 ` [PATCH 1/2] tools/nolibc: fcntl: " Daniel Palmer @ 2026-04-15 14:32 ` Daniel Palmer 2026-04-15 15:59 ` Thomas Weißschuh 1 sibling, 1 reply; 5+ messages in thread From: Daniel Palmer @ 2026-04-15 14:32 UTC (permalink / raw) To: w, linux; +Cc: linux-kernel, Daniel Palmer Create a tmp file, fallocate() to make it a bit bigger, check the size is what was expected. Signed-off-by: Daniel Palmer <daniel@thingy.jp> --- tools/testing/selftests/nolibc/nolibc-test.c | 33 ++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c index d3c4facb54c0..066f436561e7 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -896,6 +896,38 @@ int test_getpagesize(void) return !c; } +int test_fallocate(void) +{ + struct stat st; + int fd, r; + + /* Create a new tmp file */ + fd = open("/tmp", O_TMPFILE | O_RDWR, 0644); + if (fd == -1) + return -1; + + /* Expand it to 42 bytes */ + r = fallocate(fd, 0, 0, 42); + if (r) + goto close_tmpfile; + + /* Get the new stat */ + r = fstat(fd, &st); + if (r) + goto close_tmpfile; + + /* It should be 42 bytes long */ + if (st.st_size != 42) { + r = -1; + goto close_tmpfile; + } + +close_tmpfile: + close(fd); + + return r; +} + int test_file_stream(void) { FILE *f; @@ -1442,6 +1474,7 @@ int run_syscall(int min, int max) CASE_TEST(dup3_0); tmp = dup3(0, 100, 0); EXPECT_SYSNE(1, tmp, -1); close(tmp); break; CASE_TEST(dup3_m1); tmp = dup3(-1, 100, 0); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break; CASE_TEST(execve_root); EXPECT_SYSER(1, execve("/", (char*[]){ [0] = "/", [1] = NULL }, NULL), -1, EACCES); break; + CASE_TEST(fallocate); EXPECT_SYSZR(1, test_fallocate()); break; CASE_TEST(fchdir_stdin); EXPECT_SYSER(1, fchdir(STDIN_FILENO), -1, ENOTDIR); break; CASE_TEST(fchdir_badfd); EXPECT_SYSER(1, fchdir(-1), -1, EBADF); break; CASE_TEST(file_stream); EXPECT_SYSZR(1, test_file_stream()); break; -- 2.51.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] selftests/nolibc: Add a very basic test for fallocate() 2026-04-15 14:32 ` [PATCH 2/2] selftests/nolibc: Add a very basic test for fallocate() Daniel Palmer @ 2026-04-15 15:59 ` Thomas Weißschuh 0 siblings, 0 replies; 5+ messages in thread From: Thomas Weißschuh @ 2026-04-15 15:59 UTC (permalink / raw) To: Daniel Palmer; +Cc: w, linux-kernel On 2026-04-15 23:32:25+0900, Daniel Palmer wrote: > Create a tmp file, fallocate() to make it a bit bigger, check the > size is what was expected. > > Signed-off-by: Daniel Palmer <daniel@thingy.jp> > --- > tools/testing/selftests/nolibc/nolibc-test.c | 33 ++++++++++++++++++++ > 1 file changed, 33 insertions(+) > > diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c > index d3c4facb54c0..066f436561e7 100644 > --- a/tools/testing/selftests/nolibc/nolibc-test.c > +++ b/tools/testing/selftests/nolibc/nolibc-test.c > @@ -896,6 +896,38 @@ int test_getpagesize(void) > return !c; > } > > +int test_fallocate(void) > +{ > + struct stat st; > + int fd, r; > + > + /* Create a new tmp file */ > + fd = open("/tmp", O_TMPFILE | O_RDWR, 0644); > + if (fd == -1) > + return -1; > + > + /* Expand it to 42 bytes */ > + r = fallocate(fd, 0, 0, 42); > + if (r) > + goto close_tmpfile; > + > + /* Get the new stat */ > + r = fstat(fd, &st); > + if (r) > + goto close_tmpfile; > + > + /* It should be 42 bytes long */ > + if (st.st_size != 42) { > + r = -1; > + goto close_tmpfile; > + } This should also check that full 64-bit values are passed through. > + > +close_tmpfile: > + close(fd); > + > + return r; > +} (...) ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-04-15 15:59 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-04-15 14:32 [PATCH 0/2] nolibc: Add fallocate() Daniel Palmer 2026-04-15 14:32 ` [PATCH 1/2] tools/nolibc: fcntl: " Daniel Palmer 2026-04-15 15:56 ` Thomas Weißschuh 2026-04-15 14:32 ` [PATCH 2/2] selftests/nolibc: Add a very basic test for fallocate() Daniel Palmer 2026-04-15 15:59 ` Thomas Weißschuh
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox