forked from RepoMirrors/btrfs
refactor send definitions
This commit is contained in:
parent
3db12b2294
commit
cdc1bf5c04
|
@ -1,6 +1,7 @@
|
|||
package btrfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
@ -52,6 +53,54 @@ func asRootRef(p []byte) rootRef {
|
|||
return ref
|
||||
}
|
||||
|
||||
var treeKeyNames = map[treeKeyType]string{
|
||||
inodeItemKey: "inodeItem",
|
||||
inodeRefKey: "inodeRef",
|
||||
inodeExtrefKey: "inodeExtref",
|
||||
xattrItemKey: "xattrItemKey",
|
||||
orphanItemKey: "orphanItem",
|
||||
dirLogItemKey: "dirLogItem",
|
||||
dirLogIndexKey: "dirLogIndex",
|
||||
dirItemKey: "dirItem",
|
||||
dirIndexKey: "dirIndex",
|
||||
extentDataKey: "extentData",
|
||||
extentCsumKey: "extentCsum",
|
||||
rootItemKey: "rootItem",
|
||||
rootBackrefKey: "rootBackref",
|
||||
rootRefKey: "rootRef",
|
||||
extentItemKey: "extentItem",
|
||||
metadataItemKey: "metadataItem",
|
||||
treeBlockRefKey: "treeBlockRef",
|
||||
extentDataRefKey: "extentDataRef",
|
||||
extentRefV0Key: "extentRefV0",
|
||||
sharedBlockRefKey: "sharedBlockRef",
|
||||
sharedDataRefKey: "sharedDataRef",
|
||||
blockGroupItemKey: "blockGroupItem",
|
||||
freeSpaceInfoKey: "freeSpaceInfo",
|
||||
freeSpaceExtentKey: "freeSpaceExtent",
|
||||
freeSpaceBitmapKey: "freeSpaceBitmap",
|
||||
devExtentKey: "devExtent",
|
||||
devItemKey: "devItem",
|
||||
chunkItemKey: "chunkItem",
|
||||
qgroupStatusKey: "qgroupStatus",
|
||||
qgroupInfoKey: "qgroupInfo",
|
||||
qgroupLimitKey: "qgroupLimit",
|
||||
qgroupRelationKey: "qgroupRelation",
|
||||
temporaryItemKey: "temporaryItem",
|
||||
persistentItemKey: "persistentItem",
|
||||
devReplaceKey: "devReplace",
|
||||
uuidKeySubvol: "uuidKeySubvol",
|
||||
uuidKeyReceivedSubvol: "uuidKeyReceivedSubvol",
|
||||
stringItemKey: "stringItem",
|
||||
}
|
||||
|
||||
func (t treeKeyType) String() string {
|
||||
if name, ok := treeKeyNames[t]; ok {
|
||||
return name
|
||||
}
|
||||
return fmt.Sprintf("%#x", int(t))
|
||||
}
|
||||
|
||||
// btrfs_disk_key_raw is a raw bytes for btrfs_disk_key structure
|
||||
type btrfs_disk_key_raw [17]byte
|
||||
|
||||
|
|
10
receive.go
10
receive.go
|
@ -66,7 +66,7 @@ type streamReader struct {
|
|||
buf *bytes.Buffer
|
||||
}
|
||||
type sendCommandArgs struct {
|
||||
Type tlvType
|
||||
Type sendCmdAttr
|
||||
Data []byte
|
||||
}
|
||||
type sendCommand struct {
|
||||
|
@ -110,12 +110,12 @@ func (sr *streamReader) ReadCommand() (*sendCommand, error) {
|
|||
return nil, err
|
||||
}
|
||||
data = data[th.Size():]
|
||||
if th.Type > _BTRFS_SEND_A_MAX { // || th.Len > _BTRFS_SEND_BUF_SIZE {
|
||||
if sendCmdAttr(th.Type) > sendAttrMax { // || th.Len > _BTRFS_SEND_BUF_SIZE {
|
||||
return nil, fmt.Errorf("invalid tlv in cmd: %+v", th)
|
||||
}
|
||||
b := make([]byte, th.Len)
|
||||
copy(b, data)
|
||||
cmd.Args = append(cmd.Args, sendCommandArgs{Type: th.Type, Data: b})
|
||||
cmd.Args = append(cmd.Args, sendCommandArgs{Type: sendCmdAttr(th.Type), Data: b})
|
||||
}
|
||||
return &cmd, nil
|
||||
}
|
||||
|
@ -125,11 +125,11 @@ func newStreamReader(r io.Reader) (*streamReader, error) {
|
|||
_, err := io.ReadFull(r, buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if bytes.Compare(buf[:sendStreamMagicSize], []byte(_BTRFS_SEND_STREAM_MAGIC)) != 0 {
|
||||
} else if bytes.Compare(buf[:sendStreamMagicSize], []byte(sendStreamMagic)) != 0 {
|
||||
return nil, errors.New("unexpected stream header")
|
||||
}
|
||||
version := binary.LittleEndian.Uint32(buf[sendStreamMagicSize:])
|
||||
if version > _BTRFS_SEND_STREAM_VERSION {
|
||||
if version > sendStreamVersion {
|
||||
return nil, fmt.Errorf("stream version %d not supported", version)
|
||||
}
|
||||
return &streamReader{r: r}, nil
|
||||
|
|
243
send_h.go
243
send_h.go
|
@ -3,17 +3,20 @@ package btrfs
|
|||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var sendEndianess = binary.LittleEndian
|
||||
|
||||
const (
|
||||
sendStreamMagic = "btrfs-stream\x00"
|
||||
sendStreamMagicSize = len(sendStreamMagic)
|
||||
sendStreamVersion = 1
|
||||
)
|
||||
|
||||
const (
|
||||
_BTRFS_SEND_STREAM_MAGIC = "btrfs-stream"
|
||||
sendStreamMagicSize = len(_BTRFS_SEND_STREAM_MAGIC)
|
||||
_BTRFS_SEND_STREAM_VERSION = 1
|
||||
)
|
||||
|
||||
const (
|
||||
_BTRFS_SEND_BUF_SIZE = 64 * 1024
|
||||
_BTRFS_SEND_READ_SIZE = 48 * 1024
|
||||
sendBufSize = 64 * 1024
|
||||
sendReadSize = 48 * 1024
|
||||
)
|
||||
|
||||
type tlvType uint16
|
||||
|
@ -30,115 +33,211 @@ const (
|
|||
)
|
||||
|
||||
type streamHeader struct {
|
||||
Magic [len(_BTRFS_SEND_STREAM_MAGIC)]byte
|
||||
Magic [sendStreamMagicSize]byte
|
||||
Version uint32
|
||||
}
|
||||
|
||||
const cmdHeaderSize = 10
|
||||
|
||||
type cmdHeader struct {
|
||||
Len uint32 // len excluding the header
|
||||
Cmd uint16
|
||||
Cmd sendCmd
|
||||
Crc uint32 // crc including the header with zero crc field
|
||||
}
|
||||
|
||||
func (h *cmdHeader) Size() int { return 10 }
|
||||
func (h *cmdHeader) Size() int { return cmdHeaderSize }
|
||||
func (h *cmdHeader) Unmarshal(p []byte) error {
|
||||
if len(p) < h.Size() {
|
||||
if len(p) < cmdHeaderSize {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
h.Len = binary.LittleEndian.Uint32(p[0:])
|
||||
h.Cmd = binary.LittleEndian.Uint16(p[4:])
|
||||
h.Crc = binary.LittleEndian.Uint32(p[6:])
|
||||
h.Len = sendEndianess.Uint32(p[0:])
|
||||
h.Cmd = sendCmd(sendEndianess.Uint16(p[4:]))
|
||||
h.Crc = sendEndianess.Uint32(p[6:])
|
||||
return nil
|
||||
}
|
||||
|
||||
const tlvHeaderSize = 4
|
||||
|
||||
type tlvHeader struct {
|
||||
Type tlvType
|
||||
Type uint16
|
||||
Len uint16 // len excluding the header
|
||||
}
|
||||
|
||||
func (h *tlvHeader) Size() int { return 4 }
|
||||
func (h *tlvHeader) Size() int { return tlvHeaderSize }
|
||||
func (h *tlvHeader) Unmarshal(p []byte) error {
|
||||
if len(p) < h.Size() {
|
||||
if len(p) < tlvHeaderSize {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
h.Type = tlvType(binary.LittleEndian.Uint16(p[0:]))
|
||||
h.Len = binary.LittleEndian.Uint16(p[2:])
|
||||
h.Type = sendEndianess.Uint16(p[0:])
|
||||
h.Len = sendEndianess.Uint16(p[2:])
|
||||
return nil
|
||||
}
|
||||
|
||||
type sendCmd uint16
|
||||
|
||||
func (c sendCmd) String() string {
|
||||
var name string
|
||||
if int(c) < len(sendCmdTypeNames) {
|
||||
name = sendCmdTypeNames[int(c)]
|
||||
}
|
||||
if name != "" {
|
||||
return name
|
||||
}
|
||||
return strconv.FormatInt(int64(c), 16)
|
||||
}
|
||||
|
||||
var sendCmdTypeNames = []string{
|
||||
"<zero>",
|
||||
|
||||
"subvol",
|
||||
"snapshot",
|
||||
|
||||
"mkfile",
|
||||
"mkdir",
|
||||
"mknod",
|
||||
"mkfifo",
|
||||
"mksock",
|
||||
"symlink",
|
||||
|
||||
"rename",
|
||||
"link",
|
||||
"unlink",
|
||||
"rmdir",
|
||||
|
||||
"set_xattr",
|
||||
"remove_xattr",
|
||||
|
||||
"write",
|
||||
"clone",
|
||||
|
||||
"truncate",
|
||||
"chmod",
|
||||
"chown",
|
||||
"utimes",
|
||||
|
||||
"end",
|
||||
"update_extent",
|
||||
"<max>",
|
||||
}
|
||||
|
||||
const (
|
||||
_BTRFS_SEND_C_UNSPEC = sendCmd(iota)
|
||||
sendCmdUnspec = sendCmd(iota)
|
||||
|
||||
_BTRFS_SEND_C_SUBVOL
|
||||
_BTRFS_SEND_C_SNAPSHOT
|
||||
sendCmdSubvol
|
||||
sendCmdSnapshot
|
||||
|
||||
_BTRFS_SEND_C_MKFILE
|
||||
_BTRFS_SEND_C_MKDIR
|
||||
_BTRFS_SEND_C_MKNOD
|
||||
_BTRFS_SEND_C_MKFIFO
|
||||
_BTRFS_SEND_C_MKSOCK
|
||||
_BTRFS_SEND_C_SYMLINK
|
||||
sendCmdMkfile
|
||||
sendCmdMkdir
|
||||
sendCmdMknod
|
||||
sendCmdMkfifo
|
||||
sendCmdMksock
|
||||
sendCmdSymlink
|
||||
|
||||
_BTRFS_SEND_C_RENAME
|
||||
_BTRFS_SEND_C_LINK
|
||||
_BTRFS_SEND_C_UNLINK
|
||||
_BTRFS_SEND_C_RMDIR
|
||||
sendCmdRename
|
||||
sendCmdLink
|
||||
sendCmdUnlink
|
||||
sendCmdRmdir
|
||||
|
||||
_BTRFS_SEND_C_SET_XATTR
|
||||
_BTRFS_SEND_C_REMOVE_XATTR
|
||||
sendCmdSetXattr
|
||||
sendCmdRemoveXattr
|
||||
|
||||
_BTRFS_SEND_C_WRITE
|
||||
_BTRFS_SEND_C_CLONE
|
||||
sendCmdWrite
|
||||
sendCmdClone
|
||||
|
||||
_BTRFS_SEND_C_TRUNCATE
|
||||
_BTRFS_SEND_C_CHMOD
|
||||
_BTRFS_SEND_C_CHOWN
|
||||
_BTRFS_SEND_C_UTIMES
|
||||
sendCmdTruncate
|
||||
sendCmdChmod
|
||||
sendCmdChown
|
||||
sendCmdUtimes
|
||||
|
||||
_BTRFS_SEND_C_END
|
||||
_BTRFS_SEND_C_UPDATE_EXTENT
|
||||
__BTRFS_SEND_C_MAX
|
||||
sendCmdEnd
|
||||
sendCmdUpdateExtent
|
||||
_sendCmdMax
|
||||
)
|
||||
|
||||
const _BTRFS_SEND_C_MAX = __BTRFS_SEND_C_MAX - 1
|
||||
const sendCmdMax = _sendCmdMax - 1
|
||||
|
||||
type sendCmdAttr uint16
|
||||
|
||||
func (c sendCmdAttr) String() string {
|
||||
var name string
|
||||
if int(c) < len(sendAttrNames) {
|
||||
name = sendAttrNames[int(c)]
|
||||
}
|
||||
if name != "" {
|
||||
return name
|
||||
}
|
||||
return strconv.FormatInt(int64(c), 16)
|
||||
}
|
||||
|
||||
const (
|
||||
_BTRFS_SEND_A_UNSPEC = iota
|
||||
sendAttrUnspec = sendCmdAttr(iota)
|
||||
|
||||
_BTRFS_SEND_A_UUID
|
||||
_BTRFS_SEND_A_CTRANSID
|
||||
sendAttrUuid
|
||||
sendAttrCtransid
|
||||
|
||||
_BTRFS_SEND_A_INO
|
||||
_BTRFS_SEND_A_SIZE
|
||||
_BTRFS_SEND_A_MODE
|
||||
_BTRFS_SEND_A_UID
|
||||
_BTRFS_SEND_A_GID
|
||||
_BTRFS_SEND_A_RDEV
|
||||
_BTRFS_SEND_A_CTIME
|
||||
_BTRFS_SEND_A_MTIME
|
||||
_BTRFS_SEND_A_ATIME
|
||||
_BTRFS_SEND_A_OTIME
|
||||
sendAttrIno
|
||||
sendAttrSize
|
||||
sendAttrMode
|
||||
sendAttrUid
|
||||
sendAttrGid
|
||||
sendAttrRdev
|
||||
sendAttrCtime
|
||||
sendAttrMtime
|
||||
sendAttrAtime
|
||||
sendAttrOtime
|
||||
|
||||
_BTRFS_SEND_A_XATTR_NAME
|
||||
_BTRFS_SEND_A_XATTR_DATA
|
||||
sendAttrXattrName
|
||||
sendAttrXattrData
|
||||
|
||||
_BTRFS_SEND_A_PATH
|
||||
_BTRFS_SEND_A_PATH_TO
|
||||
_BTRFS_SEND_A_PATH_LINK
|
||||
sendAttrPath
|
||||
sendAttrPathTo
|
||||
sendAttrPathLink
|
||||
|
||||
_BTRFS_SEND_A_FILE_OFFSET
|
||||
_BTRFS_SEND_A_DATA
|
||||
sendAttrFileOffset
|
||||
sendAttrData
|
||||
|
||||
_BTRFS_SEND_A_CLONE_UUID
|
||||
_BTRFS_SEND_A_CLONE_CTRANSID
|
||||
_BTRFS_SEND_A_CLONE_PATH
|
||||
_BTRFS_SEND_A_CLONE_OFFSET
|
||||
_BTRFS_SEND_A_CLONE_LEN
|
||||
sendAttrCloneUuid
|
||||
sendAttrCloneCtransid
|
||||
sendAttrClonePath
|
||||
sendAttrCloneOffset
|
||||
sendAttrCloneLen
|
||||
|
||||
__BTRFS_SEND_A_MAX
|
||||
_sendAttrMax
|
||||
)
|
||||
const _BTRFS_SEND_A_MAX = __BTRFS_SEND_A_MAX - 1
|
||||
const sendAttrMax = _sendAttrMax - 1
|
||||
|
||||
var sendAttrNames = []string{
|
||||
"<zero>",
|
||||
|
||||
"uuid",
|
||||
"ctransid",
|
||||
|
||||
"ino",
|
||||
"size",
|
||||
"mode",
|
||||
"uid",
|
||||
"gid",
|
||||
"rdev",
|
||||
"ctime",
|
||||
"mtime",
|
||||
"atime",
|
||||
"otime",
|
||||
|
||||
"xattrname",
|
||||
"xattrdata",
|
||||
|
||||
"path",
|
||||
"pathto",
|
||||
"pathlink",
|
||||
|
||||
"fileoffset",
|
||||
"data",
|
||||
|
||||
"cloneuuid",
|
||||
"clonectransid",
|
||||
"clonepath",
|
||||
"cloneoffset",
|
||||
"clonelen",
|
||||
|
||||
"<max>",
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ func SnapshotSubVolume(subvol, dst string, ro bool) error {
|
|||
//}
|
||||
copy(args.name[:], newName)
|
||||
if err := iocSnapCreateV2(fdst, &args); err != nil {
|
||||
return fmt.Errorf("ioc failed: %v", err)
|
||||
return fmt.Errorf("snapshot create failed: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue