如何测试是否支持稀疏文件 [英] How to test if sparse file is supported
问题描述
给出一个文件描述符或文件名,我如何知道是否可以写一个任意位置而不必等待中间部分在磁盘上显式清零?
Given a file descriptor or file name, how do I know if I can write to an arbitrary location without waiting for the intervening part be explicitly zeroed out on disk?
推荐答案
您可以stat()
文件获取文件大小和磁盘块数量,在文件末尾查找相对较少数量的磁盘块,然后进行写操作已知数量的块,然后再次统计文件.将磁盘块的原始数量与最终数量进行比较.如果文件系统不支持稀疏文件,那么只需几个磁盘块就不需要花费太多时间.
You can stat()
the file to obtain file size and number of disk blocks, seek a relatively small number of disk blocks past the end of the file, write a known number of blocks, then stat the file again. Compare the original number of disk blocks to the final number. Just a few disk blocks shouldn't take too long to write if the file system doesn't support sparse file.
给出磁盘块的原始数量和最终数量,然后尝试确定文件系统是否支持稀疏文件.我之所以说尝试",是因为某些文件系统可能会很难处理-例如,启用了压缩的ZFS.
Given the original and final number of disk blocks, then try to determine if the file system supports sparse files. I say "try" because some filesystems can make this hard - for example, ZFS with compression enabled.
类似这样的东西:
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
int check( const char *filename )
{
struct stat sb;
long blocksize;
off_t filesize;
blkcnt_t origblocks;
char *buffer;
int fd;
fd = open( filename, O_CREAT | O_RDWR, 0644 );
fstat( fd, &sb );
blocksize = sb.st_blksize;
filesize = sb.st_size;
origblocks = sb.st_blocks;
lseek( fd, 16UL * blocksize, SEEK_END );
buffer = malloc( blocksize );
memset( buffer, 0xAA, blocksize );
write( fd, buffer, blocksize );
fsync( fd );
free( buffer );
// kludge to give ZFS time to update metadata
for ( ;; )
{
stat( filename, &sb );
if ( sb.st_blocks != origblocks )
{
break;
}
}
printf( "file: %s\n filesystem: %s\n blocksize: %d\n size: %zd\n"
" blocks: %zd\n orig blocks: %zd\n disk space: %zd\n",
filename, sb.st_fstype, blocksize, sb.st_size,
( size_t ) sb.st_blocks, ( size_t ) origblocks,
( size_t ) ( 512UL * sb.st_blocks ) );
// return file to original size
ftruncate( fd, filesize );
return( 0 );
}
int main( int argc, char **argv )
{
for ( int ii = 1; ii < argc; ii++ )
{
check( argv[ ii ] );
}
return( 0 );
}
(为清楚起见,省略了错误检查)
(error checking is omitted for clarity)
启用压缩的ZFS似乎无法快速更新文件元数据,因此正在旋转,等待更改出现.
ZFS with compression enabled doesn't seem to update the file metadata quickly, hence the spinning waiting for the changes to appear.
在带有文件asdf
(ZFS文件系统,启用压缩),/tmp/asdf
(tmpfs文件系统)和/var/tmp/asdf
(ZFS,无压缩)的Solaris 11机器上运行时,该代码将产生以下输出:
When run on a Solaris 11 box with the files asdf
(ZFS filesystem, compression enabled) /tmp/asdf
(tmpfs file system), and /var/tmp/asdf
(ZFS, no compression), that code produces the following output:
file: asdf
filesystem: zfs
blocksize: 131072
size: 2228224
blocks: 10
orig blocks: 1
disk space: 5120
file: /tmp/asdf
filesystem: tmpfs
blocksize: 4096
size: 69632
blocks: 136
orig blocks: 0
disk space: 69632
file: /var/tmp/asdf
filesystem: zfs
blocksize: 131072
size: 2228224
blocks: 257
orig blocks: 1
disk space: 131584
从该输出中,很明显/tmp/asdf
在不支持稀疏文件的文件系统上,而/var/tmp/asdf
在不支持此类文件的文件系统中.
From that output, it should be obvious that /tmp/asdf
is on a file system that doesn't support sparse files, and /var/tmp/asdf
is in a file system that does support such files.
和普通的asdf
完全是另外一回事,在其中写入128 kB数据将添加9 512字节磁盘块的全部.由此,您可以推断出文件系统中正在进行某种压缩.暂时,我怀疑假定支持这种本机压缩的任何文件系统也将支持稀疏文件是很安全的.
And plain asdf
is on something else entirely, where writing 128 kB of data adds all of 9 512-byte disk blocks. From that, you can infer that there's some sort of compression going on in the filesystem. Offhand, I suspect it's pretty safe to assume any filesystem that supports such native compression is also going to support sparse files.
提供文件名或打开文件描述符时确定文件系统是否支持稀疏文件的最快方法是调用文件名上的stat()
或文件描述符上的fstat()
,从struct stat
,并将文件的文件系统类型与已知支持稀疏文件的一组文件系统类型字符串进行比较.
And the fastest way to determine if a filesystem supports sparse files when give a filename or open file descriptor is to call stat()
on the filename or fstat()
on the file descriptor, obtain the st_fstype
field from the struct stat
, and compare the file's filesystem type to a set of strings of filesystem types known to support sparse files.
这篇关于如何测试是否支持稀疏文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!