macOS 中的 mmap 和文件删除

mmap and file deletion in macOS

我一直很好奇文件删除对内存映射文件的影响。

我查看了文档,发现只要映射文件在内存中没有任何脏范围,就可以将其删除。 但是,如果我在删除后尝试读取一些磁盘上的文件范围(不驻留在内存中)怎么办?

一项实验表明,该文件即使在删除后仍可读:

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]);
}

我的问题是删除是否在执行之前等待 munmap / close,即使文件已经从目录树中删除。

是的,删除等待文件取消映射。

文件系统跟踪一个文件有多少 link(以及引用,例如来自进程)。核心 inode 引用计数条目不仅记录了目录结构中的永久 links,或者一个文件可以拥有的多个 links,而且还记录了从打开的文件中对其进行的引用 table.

当文件包含在磁盘上的目录中时,从目录条目到文件有一个 link。 (而且你可以link一个文件到多个目录下或者同一个目录下不同的名字,用ln命令。)当一个文件被打开时,(包括内存映射打开),内核inode ref-count 条目使用来自进程的引用更新,来自打开的文件 table 条目,指向 inode,当文件未被 linked 时,这使得引用的数量保持在一个位置(因为该文件仍在使用中)。当文件最终分离时,计数引用下降到 0,然后文件块被内核释放。

即使你创建了一个同名文件,上下文也会不同(因为旧名称在文件被取消linked 时不复存在,所以没有冲突)和一个完全将使用不同的块创建新文件,对原始映射文件没有风险。