I was always curious about the effect of file deletion on memory mapped file.
I've looked in the documentation and saw that as long as the mapped file doesn't have any dirty ranges in memory, it can be deleted. However, what if I try to read some on-disk file range (which doesn't reside on the memory) after it was deleted ?
An experiment showed that the file is readable even after deletion :
map = (char *) mmap(0, fileInfo.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
remove(fd);
for (int i = 0; i < fileInfo.st_size/4; i++)
{
printf("%lu", map[i]);
}
My question is whether the deletion is waiting for munmap / close before it performed, even though the file already removed from the directory tree.
Yes, the deletion waits for the file to be unmapped.
The file system keeps track of how many links (and references, e.g. from processes) there are to a file. The in-core inode reference count entry registers not only the permanent links from the directory structure, or multiple links a file can have, but also the references made to it from the open files table.
When a file is included in a directory on disk, there is a link from the directory entry to the file. (And you can link a file into multiple directories or in the same with different names, with the ln
command.) When a file is opened, (including opening for memory mapping), the in-core inode ref-count entry is updated with the references from processes, from the open files table entries, which point to the inode, and when the file is unlinked, this makes the number of references to remain at one (because the file is still being used). When the file is finally detached, the count reference drops to 0
, and the file blocks are then freed by the kernel.
Even if then you create a file with the same name, the context will be different (because the old name ceased to exist when the file was unlinked, so there's no conflict) and a completely new file will be created, using different blocks, with no risk for the original mapped file.