Fsync太快了?

时间:2012-05-25 07:56:56

标签: c++ c linux filesystems

我对大文件ftruncatefsync操作感到惊讶。我编写了一个程序,在Linux 64位系统上创建一个空文件,将其截断为0xffffffff字节,然后将其截断为fsync

在所有操作之后,使用此长度正确创建文件。

我发现ftruncate费用大约为1442微秒,fsync费用仅为4微秒。

这种高性能是正常的吗?真的是在光盘上写下所有字节吗?如果没有,我该如何确保同步?

#include <sys/time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <iostream>

static const size_t __tamFile__ = 0xffffffff;

int main(int, char **)
{
    std::string fichero("./testTruncate.dat");

    unlink(fichero.c_str());

    int fd = open(fichero.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    if (fd != -1)
    {
        struct timeval t1, t2;

        timerclear(&t1);
        timerclear(&t2);

        gettimeofday(&t1, NULL);
        ftruncate(fd, __tamFile__);
        gettimeofday(&t2, NULL);

        unsigned long long msecTruncate = static_cast<unsigned long long>((((t2.tv_sec * 1E6) + t2.tv_usec) - ((t1.tv_sec * 1E6) + t1.tv_usec))) ;

        gettimeofday(&t1, NULL);
        fdatasync(fd);
        gettimeofday(&t2, NULL);

        unsigned long long msecFsync = static_cast<unsigned long long>((((t2.tv_sec * 1E6) + t2.tv_usec) - ((t1.tv_sec * 1E6) + t1.tv_usec))) ;

        std::cout << "Total microsec truncate: " << msecTruncate << std::endl;
        std::cout << "Total microsec fsync: " << msecFsync << std::endl;

        close(fd);
    }
    return 0;
}

2 个答案:

答案 0 :(得分:7)

  

我编写了一个在Linux 64位系统上创建空文件的程序,   将其截断为0xffffffff字节,然后将其截断为fsync。

除非你写一些内容,否则该文件极有可能包含漏洞。

来自TLPI:

  

如果程序寻找超过文件末尾会发生什么,然后呢   执行I / O?对read()的调用将返回0,表示文件结束。   有点令人惊讶的是,可以在任意位置写入字节   指向文件末尾。

     

前一个结束之间的空间   文件和新写入的字节被称为文件孔。   从编程的角度来看,孔中的字节存在,和   从空洞读取返回包含0的空字符缓冲区(null   个字节)。

     

但是,文件孔不会占用任何磁盘空间。文件   在某些情况下,系统不会为某个孔分配任何磁盘块   稍后,将数据写入其中。

答案 1 :(得分:0)

您拥有哪个Linux内核版本,哪个文件系统以及哪些挂载选项(特别是启用了屏障?)?

在Linux 2.6.32 64位,ext4启用了屏障(默认),我得到了


$ ~/src/cpptest/truncsync 
Total microsec truncate: 32
Total microsec fsync: 266
Total microsec close: 14

否则相同,但是使用NFS挂载的文件系统,我得到了


$ ./truncsync 
Total microsec truncate: 38297
Total microsec fsync: 6
Total microsec close: 6
$ ./truncsync 
Total microsec truncate: 3454967
Total microsec fsync: 8
Total microsec close: 330