tmpfs의 이상한 스파 스 파일 처리를 설명 할 수있는 것은 무엇입니까?


14

ext4파일 시스템 파티션에서 다음 코드를 실행할 수 있습니다.

fs="/mnt/ext4"

#create sparse 100M file on ${fs}
dd if=/dev/zero \
   of=${fs}/sparse100M conv=sparse seek=$((100*2*1024-1)) count=1 2> /dev/null

#show its actual used size before
echo "Before:"
ls ${fs}/sparse100M -s

#setting the sparse file up as loopback and run md5sum on loopback
losetup /dev/loop0 ${fs}/sparse100M 
md5sum /dev/loop0

#show its actual used size afterwards
echo "After:"
ls ${fs}/sparse100M -s

#release loopback and remove file
losetup -d /dev/loop0
rm ${fs}/sparse100M

생산량

Before:
0 sparse100M
2f282b84e7e608d5852449ed940bfc51  /dev/loop0
After:
0 sparse100M

tmpfs에서도 다음과 같은 작업을 수행합니다.

fs="/tmp"

수확량

Before:
0 /tmp/sparse100M
2f282b84e7e608d5852449ed940bfc51  /dev/loop0
After:
102400 /tmp/sparse100M

이것은 기본적으로 데이터를 읽는 것으로 예상되는 것으로 스파 스 파일이 "풍선처럼 터졌다"는 것을 의미합니까?

파일 tmpfs시스템 에서 스파 스 파일을 완벽하게 지원 하지 못하고, 특히 FIEMAP ioctl이 누락 되었기 때문에이 동작이 어떤 원인인지 잘 모르겠습니다. 말해 줄래?


흠. 예를 들어 스파 스 페이지를 mmap ()해야 할 때 사용할 수있는 공유 (쓰기시 복사) 제로 페이지가 있습니다. 따라서 희소 한 tmpfs 파일에서 어떤 유형의 읽기가 실제 메모리를 할당해야하는지 잘 모르겠습니다. lwn.net/Articles/517465 . 이것이 직접 IO를 사용하도록 루프를 변환 할 때 부작용이 있는지 궁금했지만 tmpfs에서 새로운 유형의 루프를 사용하려고 할 때 아무런 차이가 없어야합니다. spinics.net/lists/linux-fsdevel/msg60337.html
sourcejedi

어쩌면 이것이 답변이 되었습니까? 그냥 생각

1
/ tmp의 출력에는 Before / After 파일이 다릅니다. 오타입니까? 전 : 0 / tmp / sparse100 (끝에 M 없음) 후 : 102400 / tmp / sparse100M (후행 M)
YoMismo

@YoMismo, 그렇습니다. 오타 일뿐입니다
인류

답변:


4

우선 이러한 종류의 문제에 대해 수수께끼를 짓는 것은 혼자가 아닙니다 .

이는 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및 블록 장치가 교차 하는 흥미로운 조합이됩니다 .


2
답변 주셔서 감사합니다. tmpfs스파 스 파일과 punch_hole을 지원 한다는 것을 알고 있습니다. 그것이 그렇게 혼란스럽게 만드는 이유입니다 - 이것을 tmpfs 지원 합니다. 왜 루프 장치를 읽을 때 스파 스 구멍을 채우고 채우는가? losetup파일 크기는 변경하지 않지만 대부분의 시스템에서 다음과 같은 내용을 검색하는 블록 장치를 만듭니다. 파티션 테이블이 있습니까? UUID가있는 파일 시스템이 있습니까? / dev / disk / by-uuid / symlink를 만들어야합니까? 그리고 이러한 읽기로 인해 스파 스 파일의 일부가 이미 할당되었습니다. 신비한 이유로 tmpfs는 (일부) 읽기에 구멍을 채 웁니다.
frostschutz

1
" 일부 상황에서 순차적 읽기가 쓰기와 같은 작업시 복사를 유발할 것 "임을 알 수 있습니까 ? 읽기 작업이 쓰기시 복사 작업을 트리거하는 방법을 이해하고 싶습니다. 감사!
roaima

이상하다. 내 시스템에서 수동으로 스크립트가 아닌 동일한 단계를 수행했습니다. 먼저 OP와 같은 100M 파일을 수행했습니다. 그런 다음 10MB 파일로 단계를 반복했습니다. 첫 번째 결과 : ls -s sparse100M은 102400입니다. 그러나 10MB 파일의 ls -s는 328 블록에 불과했습니다. ??
Patrick Taylor

1
@PatrickTaylor ~ 328K는 UUID 스캐너가 제공된 후 사용되는 것에 관한 것이지만 전체 읽기를 위해 루프 장치를 cat / md5sum하지 않았습니다.
frostschutz

1
나는 루프 커널 (에서 모듈의 소스를 통해 발굴 된 loop.c이 있음)와 톱 이 개 관련 기능 : lo_read_simple& lo_read_transfer. 저수준 메모리 할당을 수행하는 방법에는 약간의 차이 lo_read_transfer가 있습니다. 실제로 호출 을 수행하는 동안 slab.h( GFP_NOIO) 에서 비 차단 IO를 alloc_page()요청하고 있습니다. lo_read_simple()다른 한편으로는 수행하고 있지 않습니다 alloc_page().
Brian Redbeard
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.