From: David Timber Date: Fri, 20 Mar 2026 02:30:52 +0000 (+0900) Subject: fallocate: give up when SEEK_HOLE/DATA misbehaves X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fcd142c3a72a357c73222f59816135844a97478e;p=thirdparty%2Futil-linux.git fallocate: give up when SEEK_HOLE/DATA misbehaves There's a bug in Linux kernel that renders fallocate in an infinite loop. drivers/char/mem.c: static loff_t null_lseek(struct file *file, loff_t offset, int orig) { return file->f_pos = 0; } This is caused by lseek() of /dev/null and /dev/zero always returning 0 regardless of whence. If fallocate is run on /dev/zero or /dev/null with the option -d or -z, the length to skip in the main loop logic in dig_holes() is always calculated as zero. A conforming VFS never behaves like this so it's safe to assume that the SEEK_DATA and SEEK_HOLE behaviour is broken. Signed-off-by: David Timber --- diff --git a/sys-utils/fallocate.c b/sys-utils/fallocate.c index c71dda214..bb056b7ad 100644 --- a/sys-utils/fallocate.c +++ b/sys-utils/fallocate.c @@ -298,7 +298,7 @@ static void dig_holes(int fd, off_t file_off, off_t len) if (file_end && end > file_end) end = file_end; - if (off < 0 || end < 0) + if (off < 0 || end < 0 || off == end) break; #if defined(POSIX_FADV_SEQUENTIAL) && defined(HAVE_POSIX_FADVISE)