우선 이러한 종류의 문제에 대해 수수께끼를 짓는 것은 혼자가 아닙니다 .
이는 NFSv4 에만 국한된 것이 tmpfs
아니라 우려되는 사항입니다
.
응용 프로그램이 스파 스 파일에서 '구멍'을 읽으면 파일 시스템은 빈 블록을 0으로 채워진 "실제"블록으로 변환하여 응용 프로그램으로 반환합니다.
md5sum
파일을 스캔하려고 시도 할 때 md5sum이 수행하려는 작업에 따라 많은 의미를 갖는 순차적 순서 로이를 수행하도록 명시 적으로 선택합니다
.
파일에 근본적으로 "구멍"이 있기 때문에,이 순차적 인 읽기는 (일부 상황에서) 쓰기와 같은 복사 작업으로 인해 파일을 채우게됩니다. 이것은 fallocate()
파일 시스템에서 구현 된대로 지원 되는지 여부와 관련하여 더 심오한 문제가됩니다 FALLOC_FL_PUNCH_HOLE
.
다행히도 tmpfs
이를 지원할뿐만 아니라 구멍을 "발굴"하는 메커니즘이 있습니다.
CLI 유틸리티를 사용하여 fallocate
이러한 구멍을 성공적으로 감지하고 재 발굴 할 수 있습니다.
에 따라 man 1 fallocate
:
-d, --dig-holes
Detect and dig holes. This makes the file sparse in-place, without
using extra disk space. The minimum size of the hole depends on
filesystem I/O block size (usually 4096 bytes). Also, when using
this option, --keep-size is implied. If no range is specified by
--offset and --length, then the entire file is analyzed for holes.
You can think of this option as doing a "cp --sparse" and then
renaming the destination file to the original, without the need for
extra disk space.
See --punch-hole for a list of supported filesystems.
fallocate
파일 수준 에서 작동 하지만 블록 장치md5sum
에 대해 실행 중일 때 (순차 읽기 요청) syscall 작동 방법 사이의 정확한 간격을 넘어서고 있습니다. 우리는 이것을 실제로 볼 수 있습니다 :fallocate()
실제로 예제를 사용하여 다음을 볼 수 있습니다.
$ fs=$(mktemp -d)
$ echo ${fs}
/tmp/tmp.ONTGAS8L06
$ dd if=/dev/zero of=${fs}/sparse100M conv=sparse seek=$((100*2*1024-1)) count=1 2>/dev/null
$ echo "Before:" "$(ls ${fs}/sparse100M -s)"
Before: 0 /tmp/tmp.ONTGAS8L06/sparse100M
$ sudo losetup /dev/loop0 ${fs}/sparse100M
$ sudo md5sum /dev/loop0
2f282b84e7e608d5852449ed940bfc51 /dev/loop0
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 102400 /tmp/tmp.ONTGAS8L06/sparse100M
$ fallocate -d ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 0 /tmp/tmp.ONTGAS8L06/sparse100M
자 ... 기본 질문에 대답합니다. 내 일반적인 좌우명은 "이상 해져"더 깊이 파고 들었습니다.
$ fs=$(mktemp -d)
$ echo ${fs}
/tmp/tmp.ZcAxvW32GY
$ dd if=/dev/zero of=${fs}/sparse100M conv=sparse seek=$((100*2*1024-1)) count=1 2>/dev/null
$ echo "Before:" "$(ls ${fs}/sparse100M -s)"
Before: 0 /tmp/tmp.ZcAxvW32GY/sparse100M
$ sudo losetup /dev/loop0 ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 1036 /tmp/tmp.ZcAxvW32GY/sparse100M
$ sudo md5sum ${fs}/sparse100M
2f282b84e7e608d5852449ed940bfc51 /tmp/tmp.ZcAxvW32GY/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 1036 /tmp/tmp.ZcAxvW32GY/sparse100M
$ fallocate -d ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 520 /tmp/tmp.ZcAxvW32GY/sparse100M
$ sudo md5sum ${fs}/sparse100M
2f282b84e7e608d5852449ed940bfc51 /tmp/tmp.ZcAxvW32GY/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 520 /tmp/tmp.ZcAxvW32GY/sparse100M
$ fallocate -d ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 516 /tmp/tmp.ZcAxvW32GY/sparse100M
$ fallocate -d ${fs}/sparse100M
$ sudo md5sum ${fs}/sparse100M
2f282b84e7e608d5852449ed940bfc51 /tmp/tmp.ZcAxvW32GY/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 512 /tmp/tmp.ZcAxvW32GY/sparse100M
$ fallocate -d ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 0 /tmp/tmp.ZcAxvW32GY/sparse100M
$ sudo md5sum ${fs}/sparse100M
2f282b84e7e608d5852449ed940bfc51 /tmp/tmp.ZcAxvW32GY/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 0 /tmp/tmp.ZcAxvW32GY/sparse100M
스파 스 파일의 크기를 변경하는 작업 만 수행 할 수 losetup
있습니다. 따라서 이것은 tmpfs
, HOLE_PUNCH 메커니즘 fallocate
및 블록 장치가 교차 하는 흥미로운 조합이됩니다 .