如何确定 btrfs 上的文件是否为写时复制?

not*_*ser 8 linux coreutils 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
Run Code Online (Sandbox Code Playgroud)

web*_*org 5

更新(2021 年 1 月):请参阅 @bitinerant 的评论:“btrfs-debug-tree 现在已过时;使用 btrfs inspect-internal dump-tree”


我不知道如何通过ls命令找到它。但是如果你真的想要它,你可以使用btrfs-progs/btrfs-debug-tree

使用reflink=always,文件将共享一个公共数据块。这个公共数据块(又名范围)的引用超过 1。

  1. 首先你需要找到文件一和二的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>
    
    Run Code Online (Sandbox Code Playgroud)

从上面我们可以看到它的259(one)260(two)

  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
    
    Run Code Online (Sandbox Code Playgroud)

奖励:创建另一个参考:

# cp --reflink=always one three
Run Code Online (Sandbox Code Playgroud)

验证 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
Run Code Online (Sandbox Code Playgroud)

这里的数据块在 objectid 259,260,261指向的三个文件之间共享。

  • `btrfs-debug-tree` 现在已过时;使用`btrfs检查内部转储树` (2认同)