2012-05-25 32 views
0

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

经过所有操作后,文件被正确创建为该长度。

我看到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; 
} 

回答

7

我写了一个Linux 64位系统上创建一个空文件的程序, 截断它为0xffffffff字节后,FSYNC它。

除非你写了一些东西,否则极有可能文件包含漏洞。

从TLPI:

如果某个程序试图过去文件的末尾,然后 执行I/O,会发生什么?对read()的调用将返回0,表示文件结束。有点令人惊讶的是,可以在文件末尾的任意一个点上写入字节。

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

但是,文件孔不占用任何磁盘空间。文件 系统不会为空洞分配任何磁盘块,直到在稍后的点 处将数据写入其中。

+3

也许还应该提到,这个功能通常被称为稀疏文件(http://en.wikipedia.org/wiki/Sparse_file)。 – LiKao

+0

如果你想为所有这些零字节实际保留空间,你需要在文件上调用'posix_fallocate'。 –

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 
+0

Linux 2.6.18-274.el5#1 SMP挂载针对jfs2文件系统的nfs AIX文件系统。没有特殊的安装选项。我不知道有关Barries的配置。 –