btrfs의 파일이 쓰기 중 복사인지 확인하는 방법은 무엇입니까?

btrfs의 파일이 쓰기 중 복사인지 확인하는 방법은 무엇입니까?

전체 복사와 기록 중 복사 "복사본"을 제어 하는 cp​​옵션 이 있다는 것을 알고 있습니다 .--reflink

lsbtrfs에서 파일이 다른 파일과 일부 저장소를 공유하는지(기록 중 복사 의미에서) 확인하기 위해 (또는 다른 명령)을 사용할 수 있습니까 ?

편집: @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. 먼저 파일 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).

  1. 이제 해당 참조를 찾으십시오. 범위 나무에서. 다음 명령은 두 파일 간에 공유되는 데이터 블록을 찾습니다.

     # ./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의 범위가 동일한지 여부가 표시되며, 이 경우 서로 재링크됩니다.e2fsprogsfilefrag -v FILE1 FILE2

filefrag파일 이름이 출력되기 때문에 스크립트에서 프로그래밍 방식으로 이 작업을 수행하는 것이 더 어렵습니다 . 이를 위해 filefrag두 가지 변경 사항이 포함된 패치 사본이 있습니다.

  1. 출력 장치 ID
  2. 파일 이름을 하나만 지정하면 파일 이름이 출력되지 않습니다.

filefrag이러한 변경을 통해 두 호출의 출력을 비교할 수 있습니다. 동일한 경우 두 파일은 서로에 대한 참조 링크입니다.

마지막 경고: ` 출력이 filefragregex 와 일치 하면 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에 적용되는지 모르겠습니다(해당되는 경우 댓글을 달거나 편집해 주세요)

관련 정보