2016-08-02 28 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啓用壓縮似乎並沒有迅速更新文件元數據,因此紡紗等待變化出現。

當與所述文件asdf(ZFS文件系統,能夠進行壓縮)/tmp/asdf(tmpfs文件系統)在Solaris 11箱運行,並且/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字節的磁盤塊。由此可以推斷文件系統中存在某種壓縮。我認爲假設任何支持這種本地壓縮的文件系統也會支持稀疏文件是非常安全的。

並以最快的方式,以確定是否一個文件系統支持稀疏文件時給文件名或打開文件的描述符是調用stat()上的文件描述符的文件名或fstat(),從struct stat獲得st_fstype領域,比較文件的文件系統類型轉換爲已知支持稀疏文件的一組文件系統類型。