2016-08-02 9 views

答えて

2

stat()ファイルのサイズとディスクブロック数を取得するには、比較的少数のディスクブロックをファイルの最後から検索し、既知の数のブロックを書き込み、ファイルを再度統計します。ディスクブロックの元の数を最終数と比較します。ファイルシステムがスパースファイルをサポートしていない場合、ほんの少数のディスクブロックが書き込みに時間がかかりません。

ディスクブロックの元の数と最終数が指定されている場合、ファイルシステムがスパースファイルをサポートしているかどうかを確認してください。いくつかのファイルシステムは圧縮を有効にしたZFSなど、これを難しくする可能性があるため、私は "試してください"と言います。このような

何か:

#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); 
} 

(エラーチェックを明確にするために省略される)を有効に圧縮して

ZFSは、したがって紡糸への変更を待って、すぐにファイルのメタデータを更新していないようです現れる。

のSolaris 11のファイルasdf(ZFSファイルシステム、圧縮有効)/tmp/asdf(tmpfsのファイルシステム)とボックス、および/var/tmp/asdf(ZFS、圧縮なし)で実行した場合、そのコードは次の出力を生成します。

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が含まれていることが明らかです。

そして、平文asdfは、128kBのデータを書き込むと、9個の512バイトディスクブロックすべてが追加されます。それで、ファイルシステムで何らかの圧縮が行われていると推測できます。オフラインでは、このようなネイティブ圧縮をサポートするファイルシステムがスパースファイルをサポートすると想定するのはかなり安全だと思われます。

とファイル名またはオープンファイルディスクリプタを与えるとき、ファイルシステムは、スパースファイルをサポートしているかどうかを判断する最速の方法は、ファイルディスクリプタ上のファイル名またはfstat()stat()を呼び出すstruct statからst_fstypeフィールドを取得し、ファイルのを比較することですファイルシステムタイプを、スパースファイルをサポートすることが知られているファイルシステムタイプの文字列のセットに置き換えます。

関連する問題