2016-08-02 3 views

답변

2

stat() 파일을 사용하여 파일 크기와 디스크 블록 수를 얻고 비교적 적은 수의 디스크 블록을 파일 끝까지 검색하고 알려진 수의 블록을 작성한 다음 파일을 다시 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는 따라서 회전이에 대한 변경을 기다리고, 신속하게 파일의 메타 데이터를 업데이트하지 않는 것 나타나다.

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 
: asdf (ZFS 파일 시스템은 압축 사용) 파일 /tmp/asdf (파일 시스템의 tmpfs)을 사용하여 Solaris 11 상자에서 실행

/var/tmp/asdf은 (ZFS, 아니 압축), 그 코드는 다음과 같은 출력을 생성

출력 결과에서 희박한 파일을 지원하지 않는 파일 시스템에 /tmp/asdf이 있고 해당 파일을 지원하는 파일 시스템에 /var/tmp/asdf이 있다는 것이 분명해야합니다.

평야 asdf은 128KB의 데이터 쓰기로 9 개의 512 바이트 디스크 블록을 모두 추가하는 완전히 다른 것입니다. 그로부터 파일 시스템에서 어떤 종류의 압축이 진행되고 있다고 추측 할 수 있습니다. Offhand, 나는 네이티브 압축을 지원하는 어떤 파일 시스템도 스파 스 파일을 지원할 것이라고 가정하는 것이 안전하다고 생각합니다. 파일의 파일 이름 또는 열린 파일 기술자가 파일 기술자에 파일 이름이나 fstat()stat()를 호출하는 것입니다이의 struct stat에서 st_fstype 필드를 얻을주고, 비교할 때 파일 시스템이 스파 스 파일을 지원하는 경우

그리고 가장 빠른 방법

결정하기 위해 파일 시스템 유형을 스파 스 (sparse) 파일을 지원하는 것으로 알려진 파일 시스템 유형의 문자열 집합으로 변환합니다.