Hello, thank you for your work on Linux. I'm trying to report what looks to me like a kernel issue: the code below, if run on a normal file system prints: After creation: 0/1048576 After read: 0/1048576 but if run on a tmpfs it prints: After creation: 0/1048576 After read: 1048576/1048576 This unexpected allocation happens only when using sendfile(2), not while reading the file with read(2). I observed this behaviour on a range of kernels, from Centos7's 3.10.0 to 4.16 currently running in my machine. This is the code to reproduce it: #include <sys/fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/sendfile.h> #include <unistd.h> #include <stdio.h> int main() { int fd = open("test", O_WRONLY | O_CREAT, 0644); if (fd == -1) { perror("cannot open for writing"); return 1; } if (ftruncate(fd, 1024*1024) == -1) { perror("cannot ftruncate"); return 1; } close(fd); struct stat st; if (stat("test", &st) == -1) { perror("cannot stat after creation"); return 1; } fprintf(stdout, "After creation: %d/%d\n", st.st_blocks * 512, st.st_size); fd = open("test", O_RDONLY); if (fd == -1) { perror("cannot open for reading"); return 1; } int out = open("/dev/null", O_WRONLY); if (out == -1) { perror("cannot open /dev/null"); return 1; } off_t offset = 0; ssize_t res = sendfile(out, fd, &offset, st.st_size); if (res == -1) { perror("cannot sendfile"); return 1; } if (res != st.st_size) fprintf(stderr, "warning: partial sendfile\n"); if (stat("test", &st) == -1) { perror("cannot stat after read"); return 1; } fprintf(stdout, "After read: %d/%d\n", st.st_blocks * 512, st.st_size); close(out); close(fd); unlink("test"); return 0; } Thanks, Enrico
Attachment:
signature.asc
Description: PGP signature