[Bug 238700] mmap bug when using file-systems with small blocks and seeking randomly to read from the file descriptor before mapping

I've been hacking on the FreeBSD kernel and I believe I've discovered a rare bug with the mmap syscall. I've spent quite some time trying to understand exactly what the cause is, and at this point I think I've got a pretty good idea, logically, what's wrong. I'm not experienced enough to find the problem in the code, so I'll just have to give my best description of the problem. I'm using Ext2 with 1KiB Blocks to store some files. This is important because a block size smaller than the system's page size is necessary to cause the bug. I do not know if the bug is exclusive to Ext, however. I have a file that is 13773 bytes long stored on this file-system. That means four 4KiB pages would be needed to map its 14 blocks of data. What I've noticed is that if I open the file and use the file descriptor to mmap the entire contents, then read the entire contents, I trigger four separate page faults to load in that data. Demand paging. Makes sense so far. I've also noticed that if I use the read syscall to read data from the file before using the mmap syscall on the same file descriptor, I will not trigger the same number of page faults after mapping the file in. Reading four bytes from the start (a typical magic number check) seems to pre-fetch two full pages worth of data from the file, and somehow stores that data in a way that makes the first two page faults unnecessary. A cool bit of optimization that still makes perfect sense. If, before calling mmap I seek to 128 bytes from the end of the file and read from there something unexpected happens. As I read the mapped memory I do not trigger ..

Support the originator by clicking the read the rest link below.