Send stream format 发送流格式
Send stream format represents a linear sequence of commands describing actions
to be performed on the target filesystem (receive side), created on the source
filesystem (send side). The stream is currently used in two ways: to generate a
stream representing a standalone subvolume (full mode) or a difference between
two snapshots of the same subvolume (incremental mode). The stream can be
generated using a set of other subvolumes to look for extent references that
could lead to a more efficient stream by transferring only the references and
not full data.
发送流格式表示一系列命令的线性序列,描述在目标文件系统(接收端)上执行的操作,在源文件系统(发送端)上创建。该流目前以两种方式使用:生成代表独立子卷(完整模式)或同一子卷的两个快照之间差异的流(增量模式)。可以使用一组其他子卷生成流,以查找可能导致更高效流的范围引用,只传输引用而不是完整数据。
The stream format is abstracted from on-disk structures (though it may share
some BTRFS specifics), the stream instructions could be generated by other
means than the send ioctl.
流格式是从磁盘结构中抽象出来的(尽管它可能共享一些 BTRFS 具体信息),流指令可以通过发送 ioctl 以外的其他方式生成。
Data types 数据类型
Raw data types. Integer values are stored in little endian byte order.
原始数据类型。整数值以小端字节顺序存储。
Meaning |
Size |
Name |
---|---|---|
unsigned int 无符号整数 |
8 bit 8 位 |
u8 |
unsigned int 无符号整数 |
16 bit 16 位 |
u16 |
unsigned int 无符号整数 |
32 bit 32 位 |
u32 |
unsigned int 无符号整数 |
64 bit 64 位 |
u64 |
variable length binary data |
variable |
data |
variable length string 可变长度字符串 |
variable |
string |
UUID |
16 bytes 16 字节 |
uuid |
time specification 时间规范 |
64bit seconds, 32bit nanoseconds |
timespec |
Stream structure 流结构
The stream starts with a descriptor bytes btrfs-stream
followed by version
stored as little endian u32. Then the sequence of commands starts. The expected
start is a subvolume or snapshot followed by commands to change the data.
流以描述符字节 btrfs-stream
开始,后跟存储为小端 u32 的版本。然后开始命令序列。预期的起始是子卷或快照,后跟更改数据的命令。
Command structure 命令结构
u32 length u32 长度
u16 command type u16 命令类型
u32 checksum (CRC32C) u32 校验和 (CRC32C)
Note: the checksum initial seed is not 0xFFFFFFFF but 0x0. That is a slight
mistake and not the recommended way, overlooked when the protocol was
implemented. This does not have a big impact though.
注意: 校验和的初始种子不是 0xFFFFFFFF,而是 0x0。这是一个轻微的错误,不是推荐的方式,在实现协议时被忽略了。尽管如此,这并没有太大影响。
Command data are structured as sequence of type-length-value (TLV):
命令数据被构造为类型-长度-值 (TLV) 的序列:
TLV type TLV 类型
TLV length of the data
数据的 TLV 长度raw data 原始数据
The TLVs are stored in the command data sequentially and the order is not
mandatory, expected data for each command is looked up based on the type.
Unrecognized TLV type may be ignored on the receive side. In the following
documentation the TLVs are listed in the order as they’re emitted by kernel
side generating the stream.
TLV 以命令数据的顺序存储,顺序不是强制的,每个命令的预期数据是根据类型查找的。在接收端可能会忽略未识别的 TLV 类型。在以下文档中,TLV 按照由内核侧生成流的顺序列出。
Subvolumes from the source and target filesystems are matched by the UUIDs.
源文件系统和目标文件系统中的子卷通过 UUID 进行匹配。
All file or directory changes are matched by path, inode numbers may be different
on the source and target filesystems but are present in the TLVs.
所有文件或目录更改都通过路径匹配,源文件系统和目标文件系统上的 inode 可能不同,但存在于 TLV 中。
Attributes, TLV types 属性,TLV 类型
The TLV types are also called attributes of the command. The raw data type is
one of the Data types listed above, the actual named type may be a generic one
(like PATH) or specific for set of command (like CLONE_OFFSET).
TLV 类型也被称为命令的属性。原始数据类型是上面列出的数据类型之一,实际命名的类型可能是通用的(如 PATH)或针对一组命令特定的(如 CLONE_OFFSET)。
The attributes represent the same raw data type when used in various commands,
though this is not strictly necessary.
当在不同命令中使用时,属性代表相同的原始数据类型,尽管这并非绝对必要。
Version 1 版本 1
Name |
Number |
Type |
---|---|---|
BTRFS_SEND_A_UNSPEC |
0 |
invalid |
BTRFS_SEND_A_UUID |
1 |
uuid |
BTRFS_SEND_A_CTRANSID |
2 |
u64 |
BTRFS_SEND_A_INO |
3 |
u64 |
BTRFS_SEND_A_SIZE |
4 |
u64 |
BTRFS_SEND_A_MODE |
5 |
u64 |
BTRFS_SEND_A_UID |
6 |
u64 |
BTRFS_SEND_A_GID |
7 |
u64 |
BTRFS_SEND_A_RDEV |
8 |
u64 |
BTRFS_SEND_A_CTIME |
9 |
timespec |
BTRFS_SEND_A_MTIME |
10 |
timespec |
BTRFS_SEND_A_ATIME |
11 |
timespec |
BTRFS_SEND_A_OTIME |
12 |
timespec |
BTRFS_SEND_A_XATTR_NAME |
13 |
string |
BTRFS_SEND_A_XATTR_DATA |
14 |
data |
BTRFS_SEND_A_PATH |
15 |
string |
BTRFS_SEND_A_PATH_TO |
16 |
string |
BTRFS_SEND_A_PATH_LINK |
17 |
string |
BTRFS_SEND_A_FILE_OFFSET |
18 |
u64 |
BTRFS_SEND_A_DATA |
19 |
data |
BTRFS_SEND_A_CLONE_UUID |
20 |
uuid |
BTRFS_SEND_A_CLONE_CTRANSID |
21 |
u64 |
BTRFS_SEND_A_CLONE_PATH |
22 |
string |
BTRFS_SEND_A_CLONE_OFFSET |
23 |
u64 |
BTRFS_SEND_A_CLONE_LEN |
24 |
u64 |
Version 2 版本 2
Name |
Number |
Type |
---|---|---|
BTRFS_SEND_A_FALLOCATE_MODE |
25 |
u32 |
BTRFS_SEND_A_FILEATTR |
26 |
u64 |
BTRFS_SEND_A_UNENCODED_FILE_LEN |
27 |
u64 |
BTRFS_SEND_A_UNENCODED_LEN |
28 |
u64 |
BTRFS_SEND_A_UNENCODED_OFFSET |
29 |
u64 |
BTRFS_SEND_A_COMPRESSION |
30 |
u32 |
BTRFS_SEND_A_ENCRYPTION |
31 |
u32 |
Special cases 特殊情况
File creation (MKFILE) is done in two phases, where first a file with special
name like o-123-45678 is created and then renamed (RENAME) to the target
location.
文件创建(MKFILE)分为两个阶段进行,首先创建一个带有特殊名称(如 o-123-45678)的文件,然后将其重命名(RENAME)到目标位置。
Parent directory where file changes are currently done gets update of times
(UTIMES) after each operation that affects it. This is not optimal as only the
last one would be needed.
当前进行文件更改的父目录在每次影响它的操作之后都会更新时间(UTIMES)。这并不是最佳的做法,因为只需要最后一个操作的时间。
Raw data type is processed in a different way in protocol version 1 and 2. In 1
the maximum size of the TLV is 64KiB as the size is stored in u16. This is not
sufficient for encoded write (ENCODED_WRITE) command. In 2 the data length is
up to 4GiB (using the type u32) but the TLV must be last and the actual
length is calculated as the delta between the whole command and the TLV (i.e.
ignoring the TLV header length).
在协议版本 1 和 2 中,原始数据类型以不同的方式处理。在版本 1 中,TLV 的最大大小为 64KiB,因为大小存储在 u16 中。这对于编码写(ENCODED_WRITE)命令是不够的。在版本 2 中,数据长度最多为 4GiB(使用类型 u32),但 TLV 必须是最后一个,并且实际长度是整个命令和 TLV 之间的增量计算得出的(即忽略 TLV 头长度)。
Stream version 1 流版本 1
BTRFS_SEND_C_UNSPEC (0)
BTRFS_SEND_C_UNSPEC (0)
Placeholder, invalid or ignored command.
占位符,无效或被忽略的命令。
BTRFS_SEND_C_SUBVOL (1)
Type |
Name |
Description |
---|---|---|
string |
path |
relative path of the subvolume |
uuid |
uuid |
UUID of the sent subvolume |
u64 |
ctransid |
creation transaction 创建事务 |
BTRFS_SEND_C_SNAPSHOT (2)
Start of commands of a given snapshot.
特定快照的命令开始。
Type |
Name |
Description |
---|---|---|
string |
path |
relative path of the subvolume |
uuid |
uuid |
UUID of the sent subvolume |
u64 |
ctransid |
creation transaction 创建事务 |
uuid |
clone_uuid |
|
u64 |
clone_ctransid |
BTRFS_SEND_C_MKFILE (3)
Create regular file. See also section Special cases.
创建常规文件。另请参阅特殊情况部分。
Type |
Name |
Description |
---|---|---|
string |
path |
relative file path to create |
u64 |
ino |
inode number inode 编号 |
BTRFS_SEND_C_MKDIR (4)
Create a directory. 创建一个目录。
Type |
Name |
Description |
---|---|---|
string |
path |
relative directory path to create |
u64 |
ino |
inode number inode 号 |
File creation is done in two commands, the first one contains a special file name
that is later renamed to the final name. (WHY)
文件创建分为两个命令,第一个包含一个特殊的文件名,稍后将其重命名为最终名称。(为什么)
BTRFS_SEND_C_MKNOD (5)
Create a special file of type device node (mknod).
创建一个特殊类型的设备节点文件(mknod)。
Type |
Name |
Description |
---|---|---|
string |
path |
relative file path to create |
u64 |
mode |
file mode parameter of mknod(2) |
u64 |
rdev |
rdev parameter of mknod(2) |
BTRFS_SEND_C_MKFIFO (6)
Create a special file of type FIFO (mkfifo).
创建一个 FIFO 类型的特殊文件(mkfifo)。
Type |
Name |
Description |
---|---|---|
string |
path |
relative file path to create |
u64 |
ino |
inode number inode 号码 |
BTRFS_SEND_C_MKSOCK (7)
Create a special file of type socket (mknod S_IFSOCK).
创建一个特殊类型为套接字的文件(mknod S_IFSOCK)。
Type |
Name |
Description |
---|---|---|
string |
path |
relative file path to create |
u64 |
ino |
inode number inode 号码 |
BTRFS_SEND_C_SYMLINK (8)
Create a symlink. 创建一个符号链接。
Type |
Name |
Description |
---|---|---|
string |
path |
relative symlink path to create |
u64 |
ino |
inode number inode 号 |
string |
path_link |
target of the symlink 符号链接的目标 |
BTRFS_SEND_C_RENAME (9)
Rename file path. 重命名文件路径。
Type |
Name |
Description |
---|---|---|
string |
path |
relative source file path |
string |
path_to |
relative target file path |
BTRFS_SEND_C_LINK (10)
Create a file hardlink.
创建一个文件硬链接。
Type |
Name |
Description |
---|---|---|
string |
path |
relative source file path |
string |
path_link |
relative target file path to link to |
BTRFS_SEND_C_UNLINK (11)
Unlink file. 取消链接文件。
Type |
Name |
Description |
---|---|---|
string |
path |
relative file path 相对文件路径 |
BTRFS_SEND_C_RMDIR (12)
Remove directory. 删除目录。
Type |
Name |
Description |
---|---|---|
string |
path |
relative directory path 相对目录路径 |
BTRFS_SEND_C_SET_XATTR (13)
Set a value of extended attribute.
设置扩展属性的值。
Type |
Name |
Description |
---|---|---|
string |
path |
relative file path 相对文件路径 |
string |
xattr_name |
name of the extended attribute |
data |
xattr_data |
value of the extended attribute |
BTRFS_SEND_C_REMOVE_XATTR (14)
Remove an extended attribute.
删除一个扩展属性。
Type |
Name |
Description |
---|---|---|
string |
path |
relative file path 相对文件路径 |
string |
xattr_name |
name of the extended attribute |
BTRFS_SEND_C_WRITE (15)
Write file data to a given file offset.
将文件数据写入给定文件偏移量。
Type |
Name |
Description |
---|---|---|
string |
path |
relative file path 相对文件路径 |
u64 |
file_offset |
where to write data 要写入数据的位置 |
data |
data |
raw file data (variable length) |
BTRFS_SEND_C_CLONE (16)
BTRFS_SEND_C_CLONE(16)
Clone extents from another file.
从另一个文件克隆范围。
Type |
Name |
Description |
---|---|---|
string |
path |
relative file path 相对文件路径 |
u64 |
file_offset |
offset in the source file to clone from |
u64 |
clone_len |
length of cloned data 克隆数据的长度 |
uuid |
clone_uuid |
|
u64 |
clone_ctransid |
|
string |
clone_path |
clone target relative file path |
u64 |
clone_offset |
clone offset in the target file |
BTRFS_SEND_C_TRUNCATE (17)
Truncate file to a given length.
截断文件到指定长度。
Type |
Name |
Description |
---|---|---|
string |
path |
relative file path 相对文件路径 |
u64 |
size |
truncate to given size 截断到给定大小 |
BTRFS_SEND_C_CHMOD (18)
Chmod a file or directory.
更改文件或目录的权限。
Type |
Name |
Description |
---|---|---|
string |
path |
relative file path 相对文件路径 |
u64 |
mode |
new mode 新模式 |
BTRFS_SEND_C_CHOWN (19)
Change file owner (uid) and group (gid), specified by numeric id. The uid/gid
must exist on the target filesystem, no mapping is done.
更改文件所有者(uid)和组(gid),由数字 ID 指定。 uid/gid 必须存在于目标文件系统上,不进行映射。
Type |
Name |
Description |
---|---|---|
string |
path |
relative file path 相对文件路径 |
u64 |
uid |
numeric used id 数字使用的 ID |
u64 |
gid |
numeric group id 数字组 ID |
BTRFS_SEND_C_UTIMES (20)
Change file atime and mtime, nanosecond precision. While the ctime is also sent
it’s not possible to change it using utimensat. The creation time is sent
since protocol version 2 but cannot be changed on the target filesystem.
更改文件的访问时间和修改时间,纳秒精度。虽然 ctime 也被发送,但无法使用 utimensat 更改它。自协议版本 2 起发送创建时间,但无法在目标文件系统上更改。
Type |
Name |
Description |
---|---|---|
string |
path |
relative file path 相对文件路径 |
timespec |
atime |
file atime 文件访问时间 |
timespec |
mtime |
file mtime 文件修改时间 |
timespec |
ctime |
file ctime 文件创建时间 |
timespec |
otime |
(since v2) file otime (creation time) |
BTRFS_SEND_C_END (21)
Special command to denote end of one logical stream inside the whole stream
sequence. May or may not be processed by receiver.
用于表示整个流序列中一个逻辑流的结束的特殊命令。接收方可能会处理,也可能不会处理。
BTRFS_SEND_C_UPDATE_EXTENT (22)
When send is generated without data (BTRFS_SEND_FLAG_NO_FILE_DATA), this command
informs about changed extent but does not send the actual data.
当没有数据生成发送时(BTRFS_SEND_FLAG_NO_FILE_DATA),此命令通知有关已更改的范围,但不发送实际数据。
Type |
Name |
Description |
---|---|---|
string |
path |
relative file path 相对文件路径 |
u64 |
file_offset |
file offset where data were updated |
u64 |
size |
length of the data 数据的长度 |
Stream version 2 流版本 2
BTRFS_SEND_C_FALLOCATE (23)
Change file extents to preallocated, punch hole or zero fill.
更改文件范围以预分配、打孔或填充零。
Type |
Name |
Description |
---|---|---|
string |
path |
relative file path 相对文件路径 |
u32 |
fallocate_mode |
which fallocate operation to do |
u64 |
file_offset |
file offset where to apply the operation |
u64 |
size |
length of the range 范围的长度 |
BTRFS_SEND_C_FILEATTR (24)
File attributes, representing various flags (SETFLAGS ioctl, XFLAGS, BTRFS
specific inode flags). The value is set from BTRFS inode bits and the stream
format inherits that. Note that some flags like IMMUTABLE or APPEND may affect
ability to change other flags and that for some flags there’s ready interface
to set them.
文件属性,表示各种标志(SETFLAGS ioctl,XFLAGS,BTRFS 特定的 inode 标志)。该值从 BTRFS inode 位设置,流格式继承该值。请注意,像 IMMUTABLE 或 APPEND 这样的一些标志可能会影响更改其他标志的能力,并且对于一些标志,有现成的接口可用于设置它们。
BTRFS_SEND_C_ENCODED_WRITE (25)
File data encoded by the source filesystem and written directly to the target
filesystem, without any other transformation. The data can be compressed or
encrypted and the payload depends on presence of the TLVs.
由源文件系统编码的文件数据直接写入目标文件系统,没有任何其他转换。数据可以被压缩或加密,负载取决于 TLVs 的存在。
Type |
Name |
Description |
---|---|---|
string |
path |
relative file path 相对文件路径 |
u64 |
file_offset |
file offset where to write the data |
u64 |
unencoded_file_len |
|
u64 |
unencoded_len |
|
u64 |
unencoded_offset |
|
u32 |
compression |
(optional) compression type |
u32 |
encryption |
(optional) encryption type |
data |
data |
encoded payload 编码的有效负载 |