NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/55712: posix_fallocate() is broken



>Number:         55712
>Category:       kern
>Synopsis:       posix_fallocate() is broken
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Oct 10 14:00:00 +0000 2020
>Originator:     Frank Kardel
>Release:        NetBSD 9.99.73
>Organization:
	
>Environment:
	
	
System: NetBSD pip 9.99.73 NetBSD 9.99.73 (PIPGEN) #0: Tue Oct 6 22:46:19 CEST 2020 kardel@pip:/src/NetBSD/cur/src/obj.amd64/sys/arch/amd64/compile/PIPGEN amd64
Architecture: x86_64
Machine: amd64
>Description:
	posix_fallocate() fails to extend a given file in size to
	support the range [offset...offset+length[. This is
	in contrast to the manual page and software trips over
	that.
	ftruncate does work, though.
>How-To-Repeat:
	Run following test program.

#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
	struct stat s;
	long size = 0;
        int fd;
	int errors = 0;

	if (argc < 2) {
		fprintf(stderr, "Usage: %s <size> <file path>\n", argv[0]);
		return 1;
	}

	if (sscanf(argv[1], "%ld", &size) != 1) {
		fprintf(stderr, "not a valid integer %s\n", argv[1]);
		return 1;
	}

	fd = open(argv[2], O_CREAT|O_RDWR, 0600);
	if (fd == -1) {
		perror(argv[2]);
		return 1;
	}

	if (posix_fallocate(fd, 0, size) == -1) {
		perror("posix_falloc");
		goto outunlink;
	}

	if (stat(argv[2], &s) == -1) {
		perror("stat()");
		goto outunlink;
	}

	if (size != s.st_size) {
		printf("ERROR: posix_fallocate() size mismatch expected %ld - actual %ld\n", size, s.st_size);
		errors++;
	} else {
		printf("OK: posix_fallocate() allocated file size %ld\n", size);
	}


	if (ftruncate(fd, size) == -1) {
		perror("ftruncate");
		goto outunlink;
	}

	if (stat(argv[2], &s) == -1) {
		perror("stat()");
		goto outunlink;
	}

	if (size != s.st_size) {
		printf("ERROR: ftruncate() size mismatch expected %ld - actual %ld\n", size, s.st_size);
		errors++;
	} else {
		printf("OK: ftruncate() allocated file size %ld\n", size);
	}

	unlink(argv[2]);

	return errors;

outunlink:
	unlink(argv[2]);

	return 1;
}
>Fix:
	

>Unformatted:
 	
 	


Home | Main Index | Thread Index | Old Index