最近在使用一个cp拷贝一个26G的文件的时候,发现1s就完成了,我的硬盘绝对没有这么快的速度。
测试拷贝一个1.5G的压缩包,只要0.03s就完成了:
$ du -h linux-6.12.y.tar
1.5G linux-6.12.y.tar
$ time cp linux-6.12.y.tar abc
real 0m0.034s
user 0m0.000s
sys 0m0.034s
觉得很神奇,然后使用strace查看:
openat(AT_FDCWD, "linux-6.12.y.tar", O_RDONLY) = 3
openat(AT_FDCWD, "abc", O_WRONLY|O_TRUNC) = 4
ioctl(4, BTRFS_IOC_CLONE or FICLONE, 3) = 0
原来它使用了FICLONE系统调用,而且我的文件系统是btrfs,btrfs是一个cow文件系统。它支持内部快速复制一个文件。相当于两个文件使用同样的文件内容。当其中一个文件变化的时候,就会复制出来,copy on write。
查看cp手册,有一个选项reflink可以控制clone拷贝:
--reflink=<auto|always|never>
control clone/CoW copies. See below
比如,关闭cow,速度就变慢了:
$ time cp --reflink=never linux-6.12.y.tar abc
real 0m1.606s
user 0m0.004s
sys 0m0.903s