为什么在 btrfs 子卷之间移动文件是一项昂贵的操作?

m.a*_*ini 10 file-transfer btrfs benchmarking

据我了解,btrfs 子卷共享同一个文件系统“存储”,所以我很惊讶地知道在不同子卷之间移动文件是一项昂贵的操作,就像在不同文件系统之间移动(复制 + 删除)一样。

当有人建议这种解决方法时,我特别惊讶:在子卷之间重新链接复制文件,然后删除原始文件。据说这是一种廉价的操作(仅移动元数据)。使用COW时,不同的子卷如何共享数据块,而在移动数据的应该更简单的操作中却无法共享?

Wil*_*own 9

使用COW时,不同的子卷如何共享数据块,而在移动数据的应该更简单的操作中却无法共享?

mv 使用重命名系统调用来尝试移动。btrfs 的内核重命名 impl 检测到跨子卷移动并明确禁止这样做(即使在相同的挂载点下):

/* we only allow rename subvolume link between subvolumes */
if (old_ino != BTRFS_FIRST_FREE_OBJECTID && root != dest)
    return -EXDEV;
Run Code Online (Sandbox Code Playgroud)

这可能与子卷 inode 记帐以及这些操作采用的代码路径有关。reflink-copy 实际上是在创建新的元数据(但数据本身是 CoW),这些元数据在新的子卷中占有一席之地。从理论上讲,他们可能可以通过执行类似于 copy --reflink 后跟 rm source 所做的事情来使重命名“移动”元数据……只是没有人愿意这样做。

  • 子卷在文件系统的任何位置显示为目录条目(又名“子卷链接”)。评论说您只能重命名(也称为移动)子卷之间的子卷目录条目,而不是实际的目录/文件。 (5认同)