从 C 可执行文件增加 ext4 文件系统 linux 中文件大小而不在文件中创建漏洞的最快方法是什么?

What is the fastest way to increase the size of a file in linux on a ext4 filesystem from a C executable without creating holes in the file?

据我所知,增加文件大小的最快方法是使用 ftruncate() 或 lseek() 到所需大小并写入一个字节。在这种情况下,这不符合我的需要,因为文件中产生的漏洞不会在文件系统中保留 space。

是使用 calloc() 和 write() 的最佳替代方案吗?

int increase_file_size_(int fd, int pages) {
    int pagesize = 4096;
    void* data = calloc(pagesize, 1);
    for(int i = 0; i < pages; ++i) {
       // In a real world program this would handle partial writes and interruptions
       if (write(fd, data, pagesize) != pagesize) {
          return -1;
    }
    return 0;
}

也许使用 writev 可以使这变得更快。 下一个版本应该会更快,因为 calloc 必须零初始化更少的内存,更多的数据适合 CPU 缓存。

int increase_file_size_(int fd, int pages) {
    int pagesize = 4096/16;
    void* data = calloc(pagesize, 1);
    struct iovec iov[16];
    for(int i = 0; i < 16; ++i) {
      iov[i].iov_base = data;
      iov[i].iov_len = pagesize ;
    }
    for(int i = 0; i < pages; ++i) {
       // In a real world program this would handle partial writes and interruptions
       if (writev(fd, data, pagesize) != pagesize * 16) {
          return -1;
    }
    return 0;
}

我可以试验看看哪种方法和哪种页面大小更快。但是,是否有另一种方法被认为是扩展文件的正常最佳实践?我应该对其他方法进行性能测试吗?

谢谢。

看看 posix_fallocate() 函数:它为文件保留 space 而不必写入任何数据来占用 space。分配的 space 有点像一个稀疏文件,即使你没有明确地向它写入任何内容,你也可以从中读取,但与稀疏文件不同的是,它实际上减少了空闲 space 在文件系统中。您可以放心,稍后可以写入文件的该区域,而无需 space.

中的 运行

请注意 posix_fallocate() 似乎无法保证分配的 space 的 内容 如果您在写入之前阅读它。我认为 Linux 实现将 return 所有零字节,类似于稀疏文件,但您可能不应该依赖它。在你写真正的东西之前把它当作垃圾。

另请注意,并非所有文件系统驱动程序都支持 posix_fallocate() 利用的预分配功能,我认为如果预分配不支持,它会退回到实际将数据写入文件(正常方式)不支持。典型的 Linux 文件系统,如 ext4 和 XFS 是可以的,但如果你在 FAT 或 NTFS 之类的系统上尝试,你的程序可能会在 I/O 上阻塞一段时间。