【问题标题】:Inserting pages into large mmap() files without copying data将页面插入大型 mmap() 文件而不复制数据
【发布时间】:2011-04-16 14:43:41
【问题描述】:

我想知道是否有办法在我用 mmap() 打开的大型(多 GB)文件的开头附近插入空白页。显然可以在末尾添加一两页,然后使用 memcpy() 将所有内容向前移动,但这会弄脏每一页,并且在最终刷新到磁盘时需要很长时间。

我猜测解决方案需要在自定义文件系统和页表手动操作之间进行一些复杂的协调:向 inode 添加一个块,以某种方式更新 VMM 中的缓存页以反映这一点,然后以某种方式调整要匹配的页表。这听起来不简单,这让我想知道是否有更好的方法。

这是一个关于 Linux 上的内存和文件操作的有点深奥的问题,尽管我很高兴听到如何在其他系统中完成此操作。我对涉及提高复制效率的解决方法不是特别感兴趣,尽管需要重新映射但避免磁盘 IO 的技术将是一个好的开始。

【问题讨论】:

  • 我预见到很多极端情况 - 例如。该文件的文件句柄偏移量会发生什么变化?其他进程中的文件句柄呢?
  • 在不知道你在做什么的情况下,这可能是一个愚蠢的建议,但你可以在映射之前用 X 页填充物理文件吗?在第一页中保留一个索引/指针/位移到真实数据的开始位置,并根据需要进行更改。周围还有更多工作,但您似乎愿意不遗余力地完成这项工作。
  • @Duck:我没有固定的目标。在处理用于全文搜索的大型倒排索引以及寻找制作更好 B-Tree 的方法时,我想要这样的东西。从一个非常稀疏的文件开始是一个有趣的想法,但不能解决一般情况。
  • @caf:我敢肯定会有问题,但他们并不担心我。如果可以使其适用于多个 mmap() 实例,那么其余的似乎都可以解决。我真正的希望是有人会说“ZFS 的最新测试版支持这个”或“mmap_insert_page() 是在 2.6.X 中添加的”。
  • @Nathan Kurz:知道ftruncate() 引起的错误、极端情况和毛茸茸的问题的数量,我倾向于怀疑这样的东西出现在主线内核中的前景......

标签: linux shared-memory mmap tlb inode


【解决方案1】:

在您的文件中嵌入一个简单的 FAT。例如,文件的前 4k 将是 FAT 页。数据将在以下页面中。随着文件的增长,第一个 FAT 页面可能会链接到其他 FAT 页面。 FAT 中的每个条目将是一个数据页索引和下一个 FAT 条目的索引。 FAT 条目将是 FAT 的页面和条目本身的该页面上的索引。我想你应该已经明白了。 FAT 条目是一个链表。 FAT 页是一个链表。 FAT 条目链接数据页。这应该是足够的信息来使用remap_file_pages() 使您的文件在内存中看起来是连续的,即使它在磁盘上不连续。

【讨论】:

    猜你喜欢
    • 2018-12-31
    • 1970-01-01
    • 2011-11-30
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    相关资源
    最近更新 更多