我对大文件ftruncate和fsync操作感到惊讶。我写了一个程序,在Linux64位系统上创建一个空文件,将其截断为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;
}发布于 2012-05-25 15:58:57
我写了一个程序,在Linux64位系统上创建一个空文件,将其截断为0xffffffff字节,然后对其进行fsync。
除非你写了一些东西,否则这个文件极有可能包含漏洞。
来自TLPI:
如果程序查找超出文件末尾,然后执行I/O,会发生什么情况?调用read()将返回0,表示文件结束。有些令人惊讶的是,可以在文件末尾之后的任意位置写入字节。
在文件的前一端和新写入的字节之间的空间被称为文件孔。从编程的角度来看,洞中的字节是存在的,从洞中读取会返回一个包含0(空字节)的字节缓冲区。
然而,文件孔不会占用任何磁盘空间。文件系统不会为空洞分配任何磁盘块,直到稍后将数据写入该空洞。
发布于 2012-05-25 16:23:54
您有哪个Linux内核版本、哪个文件系统以及哪些挂载选项(特别是启用了屏障?)?
在Linux2.6.3264位的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: 330https://stackoverflow.com/questions/10750655
复制相似问题