web-dev-qa-db-ja.com

btrfs上のファイルがコピーオンライトであるかどうかを確認するにはどうすればよいですか?

cpには完全なコピーとコピーオンライトの「コピー」を制御するための--reflinkオプションがあることを私は知っています。

Btrfsで、ls(または他のコマンド)を使用して、ファイルが(コピーオンライトの意味で)別のファイルとストレージを共有しているかどうかを確認できますか?

編集:@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
7
not-a-user

lsコマンドで見つける方法がわかりません。ただし、本当に必要な場合は、btrfs-progs/btrfs-debug-treeを使用できます。

reflink = alwaysを使用すると、ファイルは共通のデータブロックを共有します。この共通データブロック(別名エクステント)には、1を超える参照があります。

  1. まず、ファイル1と2のオブジェクトIDを見つける必要があります

    #./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(one)260(two)

  1. 今、その参照を見つけます。エクステントツリーから。以下のコマンドは、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

refcountが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

ここで、データブロックは、objectid259,260,261が指す3つのファイル間で共有されます。

5
webminal.org

ファイルの物理エクステントのSHA1ハッシュを計算する fienode (←リンク)というプログラムをリリースしました。同一のCoWコピーには同じハッシュがあります。

これが必要な理由を説明する、より詳細な回答もここにあります。

ただし、BTRFSは物理的な範囲を自由に変更できることに注意してください。大きなreflinkedファイルが挑発せずに物理エクステントを変更し、物理エクステントの大部分がまだ共有されていても、fienode出力が異なることを確認しました。

1
pwaller