2012-05-25 35 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的配置。 –