전체 복사와 기록 중 복사 "복사본"을 제어 하는 cp
옵션 이 있다는 것을 알고 있습니다 .--reflink
ls
btrfs에서 파일이 다른 파일과 일부 저장소를 공유하는지(기록 중 복사 의미에서) 확인하기 위해 (또는 다른 명령)을 사용할 수 있습니까 ?
편집: @StéphaneChazelas가 나에게 지적했지만 filefrag
실패했습니다.
root@void:/tmp/mount# mount | tail -1
/tmp/back on /tmp/mount type btrfs (rw,relatime,space_cache)
root@void:/tmp/mount# df -h | tail -1
/dev/loop0 32M 13M 20M 38% /tmp/mount
root@void:/tmp/mount# ls -lh
total 8.0M
-rw-r--r-- 1 root root 8.0M Jan 19 08:43 one
root@void:/tmp/mount# cp --reflink=always one two
root@void:/tmp/mount# sync
root@void:/tmp/mount# ls -lh
total 16M
-rw-r--r-- 1 root root 8.0M Jan 19 08:43 one
-rw-r--r-- 1 root root 8.0M Jan 19 08:45 two
root@void:/tmp/mount# df -h | tail -1
/dev/loop0 32M 13M 20M 38% /tmp/mount
root@void:/tmp/mount# filefrag -kvx one
Filesystem type is: 9123683e
File size of one is 8388608 (8192 blocks of 1024 bytes)
FIEMAP failed with unknown flags 2
one: FIBMAP unsupported
root@void:/tmp/mount# uname -a
Linux void 4.1.7+ #817 PREEMPT Sat Sep 19 15:25:36 BST 2015 armv6l GNU/Linux
답변1
업데이트(2021년 1월):@bitinerant의 의견을 참조하세요."btrfs-debug-tree는 이제 더 이상 사용되지 않습니다. btrfs inform-internal dump-tree를 사용하세요."
명령을 통해 찾는 방법을 모르겠습니다 ls
. 하지만 정말로 원한다면 사용할 수 있습니다btrfs-progs/btrfs-디버그-트리.
그리고인용링크=항상, 파일은 공통 데이터 블록을 공유합니다. 이 공통 데이터 블록(확장이라고도 함)에 대한 참조 수가 1을 초과합니다.
먼저 파일 1과 파일 2의 objectid를 찾아야 합니다.
#./btrfs-debug-tree /dev/xvdc (Check under FS_TREE) <snip> item 8 key (256 DIR_INDEX 4) itemoff 15842 itemsize 33 location key (259 INODE_ITEM 0) type FILE namelen 3 datalen 0 name: one item 9 key (256 DIR_INDEX 5) itemoff 15809 itemsize 33 location key (260 INODE_ITEM 0) type FILE namelen 3 datalen 0 name: two </snip>
위에서 우리는 그것을 볼 수 있습니다259(1)그리고260 (2).
이제 해당 참조를 찾으십시오. 범위 나무에서. 다음 명령은 두 파일 간에 공유되는 데이터 블록을 찾습니다.
# ./btrfs-debug-tree /dev/xvdc | grep -A2 "refs 2" extent refs 2 gen 9 flags DATA extent data backref root 5 objectid 260 offset 0 count 1 extent data backref root 5 objectid 259 offset 0 count 1
보너스: 다른 참조를 생성하세요.
# cp --reflink=always one three
참조 횟수가 1씩 증가하는지 확인합니다.
# ./btrfs-debug-tree /dev/xvdc | grep -A3 "refs 3"
extent refs 3 gen 9 flags DATA
extent data backref root 5 objectid 260 offset 0 count 1
extent data backref root 5 objectid 261 offset 0 count 1
extent data backref root 5 objectid 259 offset 0 count 1
이 데이터 블록은 objectid가 가리키는 세 개의 파일 간에 공유됩니다.259,260,261.
답변2
그냥 사용:
$ btrfs filesystem du .
Total Exclusive Set shared Filename
1.11GiB 1.11GiB - ./file1
1.12GiB 1.12GiB - ./file2
1.31GiB 0.00B - ./file3
3.54GiB 2.23GiB 1.31GiB .
이 예에서 "file3"은 전용 공간을 차지하지 않으므로 참조 링크 복사본입니다.
답변3
@pwaller답변두 파일이 동일한 범위를 공유하는지 확인하기 위해 각 파일에 대해 비교할 수 있는 데이터 범위 목록을 표시합니다. 이것은 (거의) 포장 filefrag
에서 가능합니다. FILE1과 FILE2의 범위가 동일한지 여부가 표시되며, 이 경우 서로 재링크됩니다.e2fsprogs
filefrag -v FILE1 FILE2
filefrag
파일 이름이 출력되기 때문에 스크립트에서 프로그래밍 방식으로 이 작업을 수행하는 것이 더 어렵습니다 . 이를 위해 filefrag
두 가지 변경 사항이 포함된 패치 사본이 있습니다.
- 출력 장치 ID
- 파일 이름을 하나만 지정하면 파일 이름이 출력되지 않습니다.
filefrag
이러한 변경을 통해 두 호출의 출력을 비교할 수 있습니다. 동일한 경우 두 파일은 서로에 대한 참조 링크입니다.
마지막 경고: ` 출력이 filefrag
regex 와 일치 하면 inline|unknown_loc|delalloc
파일에 데이터 블록이 없기 때문에 파일을 다시 연결할 수 없습니다. 이를 처리하기 위해 패턴을 확인 filefrag
하고 패턴이 발견되면 파일 이름 자체를 출력에 추가하여 패치를 래핑했습니다(다른 파일 이름 일치의 출력과 다르지 않도록 출력을 각 파일 이름에 대해 고유하게 만들기 위해). ). @StéphaneChazelas의 댓글 보기여기자세한 내용은.
나는 끌어오기 요청을 제출했습니다(https://github.com/tytso/e2fsprogs/pull/87) 및 질문(https://github.com/tytso/e2fsprogs/issues/88) 이를 위해.
답변4
최소한 xfs
파일이 변경되지 않은 경우 filefrag
플래그 shared
가 설정됩니다.
예를 들어:
>filefrag -e foobar
Filesystem type is: 58465342
File size of filesystems.docker is 1344 (1 block of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 0: 348117738.. 348117738: 1: last,eof
foo: 1 extent found
>cp --reflink=auto foo bar
>filefrag -e foo
Filesystem type is: 58465342
File size of filesystems.docker is 1344 (1 block of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 0: 348117738.. 348117738: 1: last,shared,eof
foo: 1 extent found
경고: 파일의 일부가 변경되어 일부 블록만 공개되면 어떻게 될지 잘 모르겠습니다.
경고 2: 이것이 btrfs에 적용되는지 모르겠습니다(해당되는 경우 댓글을 달거나 편집해 주세요)