FUSE协议解析

原创
2018/11/30 14:00
阅读数 622

由于以前有项目是用到FUSE,将S3等对象存储映射为文件存储的,但我不是负责那一块,所以一直只是知道FUSE是个什么东西,而没有用过。刚好趁着没工作的这段时间,学习Golang,顺便把FUSE也了解下,实现了一个简易版的libfuse: https://github.com/mingforpc/fuse-go和一个可以将HDFS Mount到本地文件夹的程序: https://github.com/mingforpc/hadoop-fs

由于刚学并整理,如有遗漏或者错误!请拼命指出,谢谢!

什么是FUSE

FUSE的全称是Filesystem in Userspace,即用户空间文件系统,是系统内核提供的一个功能,使得可以在用户态下实现一个自定义的文件系统。比如CEPH和GlusterFS等都有使用到FUSE。

libfuse则是提供给用户态下的开发包。

FUSE是怎么交互的

FUSE是通过读写/dev/fuse让用户态的文件系统进程和内核通信的。

大概流程

程序需要先打开/dev/fuse,然后通过mount()/dev/fuse的fd,进程的用户id和组id传入,进行文件系统的挂载。

PS: libfuse通过自己写的fusermount程序(编译安装libfuse后会在/bin/下),可以让我们实现的文件系统程序在非root权限下挂载,这部分我还不是很了解,我自己实现的go版libfuse也只是依赖于这个fusermount。

FUSE的指令号、对应的函数、请求格式与响应

程序从/dev/fuse中读取请求,不需要担心像TCP有半包粘包等问题,一次读取一条请求。buffer不够大,会报异常。

请求和响应,都是以二进制字节表示的,下文中的结构体只是为了方便看。

请求头

每个命令的前 40 bytes为请求头,转为Golang的结构体如下:

// Each query starts with a FuseInHeader
type FuseInHeader struct {
	Len     uint32
	Opcode  uint32
	Unique  uint64
	Nodeid  uint64
	Uid     uint32
	Gid     uint32
	Pid     uint32
	Padding uint32
}
  • Len: 是整个请求的字节数长度,包括请求头后的具体内容
  • Opcode: 请求的类型
  • Unique: 该请求唯一标识,响应中要对应着该Unique
  • Nodeid: 该请求针对的文件nodeid,目标文件或者文件夹的nodeid
  • Uid: 对该文件/文件夹操作的进程的用户ID
  • Gid: 对该文件/文件夹操作的进程的用户组ID
  • Pid: 对该文件/文件夹操作的进程的进程ID

响应头

程序写入/dev/fuse的每个响应的前 16 bytes为响应头,转为Golang的结构体如下:

type FuseOutHeader struct {
	Len    uint32
	Error  int32
	Unique uint64
}
  • Len: 是整个响应的字节数长度,包括响应头后的具体内容
  • Error: 一个负数的错误码,成功返回0,其他对应着系统(error.h)的错误代码,但是为负数,每个操作的错误返回可以查看linux man中相应的函数
  • Unique: 对应者请求的唯一标识

请求类型和具体结构

数字对应着请求中的Opcode

FUSE_LOOKUP = 1

lookup()函数,Look up a directory entry by name and get its attributes.

如解析所说,获取代请求头Nodeid文件夹下该名字的文件的属性,包含着 inode id等。

请求头后的实体
type FuseLookupIn struct {
	Name string // 字符串结尾的`\0`会计算到长度中,解析时需注意
}
  • Name: 文件名
响应头的实体
type FuseEntryOut struct {
	NodeId         uint64 /* Inode ID */
	Generation     uint64 /* Inode generation: nodeid:gen must be unique for the fs's lifetime */
	EntryValid     uint64 /* Cache timeout for the name */
	AttrValid      uint64 /* Cache timeout for the attributes */
	EntryValidNsec uint32
	AttrValidNsec  uint32

	Attr FuseAttr
}

type FuseAttr struct {
	Ino       uint64
	Size      uint64
	Blocks    uint64
	Atime     uint64
	Mtime     uint64
	Ctime     uint64
	AtimeNsec uint32
	MtimeNsec uint32
	CtimeNsec uint32
	Mode      uint32
	Nlink     uint32
	Uid       uint32
	Gid       uint32
	Rdev      uint32
	Blksize   uint32
	Padding   uint32
}
  • NodeId: 文件的Inode ID
  • Generation: 同一个文件, nodeid和gen的组合,必须在整个文件系统的生命周期中唯一
  • EntryValid: 对于文件的Name的缓存时间,单位是秒
  • EntryValidNsec: 同上,但是该属性表示毫秒部分
  • AttrValid: 对于文件的属性的缓存时间,单位是秒
  • AttrValidNsec: 同上,但是该属性表示毫秒部分
  • Attr: 该文件的属性,可以对应属性的意义可以参考文件属性stat
FUSE_FORGET = 2

forget()函数,Forget about an inode

不需要返回任何响应的操作。

请求头后的实体
// forget (should not send any reply)
type FuseForgetIn struct {
	Nlookup uint64
}
FUSE_GETATTR = 3

getattr()函数,Get file attributes.

请求头后的实体
type FuseGetattrIn struct {
	GetattrFlags uint32
	Dummy        uint32
	Fh           uint64
}
响应头的实体
type FuseAttrOut struct {
	AttrValid     uint64 /* Cache timeout for the attributes */
	AttrValidNsec uint32
	Dummp         uint32

	Attr FuseAttr
}

type FuseAttr struct {
	Ino       uint64
	Size      uint64
	Blocks    uint64
	Atime     uint64
	Mtime     uint64
	Ctime     uint64
	AtimeNsec uint32
	MtimeNsec uint32
	CtimeNsec uint32
	Mode      uint32
	Nlink     uint32
	Uid       uint32
	Gid       uint32
	Rdev      uint32
	Blksize   uint32
	Padding   uint32
}
  • AttrValid: 属性的有效时间,单位秒
  • AttrValidNsec: 同上,但是该属性表示毫秒部分
  • Attr: 该文件的属性,可以对应属性的意义可以参考文件属性stat
FUSE_SETATTR = 4

setattr()函数,Set file attributes

请求头后的实体
type FuseSetattrIn struct {
	Valid     uint32
	Padding   uint32
	Fh        uint64
	Size      uint64
	LockOwner uint64
	Atime     uint64
	Mtime     uint64
	Ctime     uint64
	AtimeNsec uint32
	MtimeNsec uint32
	CtimeNsec uint32
	Mode      uint32
	Unused4   uint32
	Uid       uint32
	Gid       uint32
	Unused5   uint32
}
  • Valid: 用来标识需要给文件设置哪些属性的:
    • FUSE_SET_ATTR_MODE = (1 << 0)
    • FUSE_SET_ATTR_UID = (1 << 1)
    • FUSE_SET_ATTR_GID = (1 << 2)
    • FUSE_SET_ATTR_SIZE = (1 << 3)
    • FUSE_SET_ATTR_ATIME = (1 << 4)
    • FUSE_SET_ATTR_MTIME = (1 << 5)
    • FUSE_SET_ATTR_ATIME_NOW = (1 << 7)
    • FUSE_SET_ATTR_MTIME_NOW = (1 << 8)
    • FUSE_SET_ATTR_CTIME = (1 << 10)
  • Size: 文件的大小
  • Atime 和 AtimeNsec: 文件的 access time
  • Mtime 和 MtimeNsec: 文件的 modification time
  • Ctime 和 CtimeNsec: 文件的 status time
  • Mode: 文件的模式(文件类型和权限)
  • Uid: 文件所属的用户
  • Gid: 文件所属的用户组
响应头的实体
type FuseAttrOut struct {
	AttrValid     uint64 /* Cache timeout for the attributes */
	AttrValidNsec uint32
	Dummp         uint32

	Attr FuseAttr
}

type FuseAttr struct {
	Ino       uint64
	Size      uint64
	Blocks    uint64
	Atime     uint64
	Mtime     uint64
	Ctime     uint64
	AtimeNsec uint32
	MtimeNsec uint32
	CtimeNsec uint32
	Mode      uint32
	Nlink     uint32
	Uid       uint32
	Gid       uint32
	Rdev      uint32
	Blksize   uint32
	Padding   uint32
}
FUSE_READLINK = 5

readlink()函数,Read symbolic link

请求头后的实体

FUSE_READLINK 请求头后没有实体。

响应头的实体
type FuseReadlinkOut struct {
	Path string
}
FUSE_SYMLINK = 6

symlink()函数,Create a symbolic link

请求头后的实体
type FuseSymlinkIn struct {
	Name string

	LinkName string
}

Name 和 LinkName 之间会以 '\0'分隔。

  • Name: 软连接文件的文件名
  • LinkName: 软连接所连接的文件名
响应头的实体
type FuseEntryOut struct {
	NodeId         uint64 /* Inode ID */
	Generation     uint64 /* Inode generation: nodeid:gen must be unique for the fs's lifetime */
	EntryValid     uint64 /* Cache timeout for the name */
	AttrValid      uint64 /* Cache timeout for the attributes */
	EntryValidNsec uint32
	AttrValidNsec  uint32

	Attr FuseAttr
}

type FuseAttr struct {
	Ino       uint64
	Size      uint64
	Blocks    uint64
	Atime     uint64
	Mtime     uint64
	Ctime     uint64
	AtimeNsec uint32
	MtimeNsec uint32
	CtimeNsec uint32
	Mode      uint32
	Nlink     uint32
	Uid       uint32
	Gid       uint32
	Rdev      uint32
	Blksize   uint32
	Padding   uint32
}

属性见lookup中的。

FUSE_MKNOD = 8

mknod()函数,Create file node

请求头后的实体
type FuseMknodIn struct {
	Mode    uint32
	Rdev    uint32
	Umask   uint32
	Padding uint32

	Name string
}
响应头的实体
type FuseEntryOut struct {
	NodeId         uint64 /* Inode ID */
	Generation     uint64 /* Inode generation: nodeid:gen must be unique for the fs's lifetime */
	EntryValid     uint64 /* Cache timeout for the name */
	AttrValid      uint64 /* Cache timeout for the attributes */
	EntryValidNsec uint32
	AttrValidNsec  uint32

	Attr FuseAttr
}

type FuseAttr struct {
	Ino       uint64
	Size      uint64
	Blocks    uint64
	Atime     uint64
	Mtime     uint64
	Ctime     uint64
	AtimeNsec uint32
	MtimeNsec uint32
	CtimeNsec uint32
	Mode      uint32
	Nlink     uint32
	Uid       uint32
	Gid       uint32
	Rdev      uint32
	Blksize   uint32
	Padding   uint32
}

属性见lookup中的。

FUSE_MKDIR = 9

mkdir()函数,Create a directory

请求头后的实体
type FuseMkdirIn struct {
	Mode  uint32
	Umask uint32

	Name string
}
  • Mode: 目录的模式(包含文件类型和权限)
  • Name: 要创建的目录的名称
响应头的实体
type FuseEntryOut struct {
	NodeId         uint64 /* Inode ID */
	Generation     uint64 /* Inode generation: nodeid:gen must be unique for the fs's lifetime */
	EntryValid     uint64 /* Cache timeout for the name */
	AttrValid      uint64 /* Cache timeout for the attributes */
	EntryValidNsec uint32
	AttrValidNsec  uint32

	Attr FuseAttr
}

type FuseAttr struct {
	Ino       uint64
	Size      uint64
	Blocks    uint64
	Atime     uint64
	Mtime     uint64
	Ctime     uint64
	AtimeNsec uint32
	MtimeNsec uint32
	CtimeNsec uint32
	Mode      uint32
	Nlink     uint32
	Uid       uint32
	Gid       uint32
	Rdev      uint32
	Blksize   uint32
	Padding   uint32
}

属性见lookup中的。

FUSE_UNLINK = 10

unlink()函数, Remove a directory

请求头后的实体
type FuseUnlinkIn struct {
	Name string
}
  • Name: 要删除的目录名字
响应头的实体

无需响应实体,只需返回响应头

FUSE_RMDIR = 11

rmdir()函数,Remove a directory

请求头后的实体

参考unlink()

响应头的实体

参考unlink()

FUSE_RENAME = 12

rename()函数,Rename a file

请求头后的实体
type FuseRenameIn struct {
	NewDir uint64

	OldName string

	NewName string
}
  • NewDir: 新目录的 inode id(旧目录的inode id在请求头中)
  • OldName: 旧文件名
  • NewName: 新文件名
响应头的实体

无需响应实体,只需返回响应头

FUSE_LINK = 13

link()函数, Create a hard link

请求头后的实体
type FuseLinkIn struct {
	OldNodeid uint64
	NewName string
}
响应头的实体
type FuseReadlinkOut struct {
	Path string
}
FUSE_OPEN = 14

open()函数,Open a file

请求头后的实体
type FuseOpenIn struct {
	Flags  uint32
	Unused uint32
}
响应头的实体
type FuseOpenOut struct {
	Fh        uint64
	OpenFlags uint32
	Padding   uint32
}
FUSE_READ = 15

read()函数,Read data

请求头后的实体
type FuseReadIn struct {
	Fh        uint64
	Offset    uint64
	Size      uint32
	ReadFlags uint32
	LockOwner uint64
	Flags     uint32
	Padding   uint32
}
  • Offset: 读取开始位置,相对于文件开头的偏移量
  • Size: 内核缓存区的大小(读取的数据大小不能超过这个限制)
响应头的实体
type FuseReadOut struct {
	Content []byte
}

在响应头后紧跟着读取的二进制数据

FUSE_WRITE = 16

write()函数,Write data

请求头后的实体
type FuseWriteIn struct {
	Fh         uint64
	Offset     uint64
	Size       uint32
	WriteFlags uint32
	LockOwner  uint64
	Flags      uint32
	Padding    uint32

	Buf []byte
}
  • Offset: 开始写入数据位置的偏移量
  • Size: 写入数据的字节数
  • Buf: 写入的数据
响应头的实体
type FuseWriteOut struct {
	Size    uint32
	Padding uint32
}
  • Size: 成功写入数据的字节数
FUSE_STATFS = 17

statfs()函数,Get file system statistics

请求头后的实体

statfs只有请求头

响应头的实体
type FuseStatfs struct {
	Blocks  uint64
	Bfree   uint64
	Bavail  uint64
	Files   uint64
	Ffree   uint64
	Bsize   uint32
	NameLen uint32
	Frsize  uint32
	Padding uint32
	Spare   [6]uint32
}
FUSE_RELEASE = 18

release()函数,Release an open file

请求头后的实体
type FuseReleaseIn struct {
	Fh           uint64
	Flags        uint32
	ReleaseFlags uint32
	LockOwner    uint64
}
响应头的实体

release只需响应头返回成功与否

FUSE_FSYNC = 20

fsync()函数,Synchronize file contents

请求头后的实体
type FuseFsyncIn struct {
	Fh         uint64
	FsyncFlags uint32
	Padding    uint32
}
响应头的实体

fsync只需响应头返回成功与否

FUSE_SETXATTR = 21

setxattr()函数,Set an extended attribute

请求头后的实体
type FuseSetxattrIn struct {
	Size  uint32
	Flags uint32

	Name  string
	Value string
}
  • Size: 是Value的字节数
  • Name: 文件扩展属性的属性名
  • Value: 文件扩展属性的值
响应头的实体

setxattr只需响应头返回成功与否

FUSE_GETXATTR = 22

getxattr()函数,Get an extended attribute

请求头后的实体
type FuseGetxattrIn struct {
	Size    uint32
	Padding uint32

	Name string
}
  • Size: Name的长度
  • Name: 要获取的文件扩展属性的名字
响应头的实体
type FuseGetxattrOut struct {
	Size    uint32
	Padding uint32

	Value string
}
  • Size: 表示返回的Value大小
  • Value: 文件扩展属性Name对应的值
FUSE_LISTXATTR = 23

listxattr()函数, List extended attribute names

请求头后的实体
type FuseListxattrIn struct {
	Size    uint32
	Padding uint32
}
  • Size: 表示内核接收的缓存大小
响应头的实体
type FuseListxattrOut struct {
	Size    uint32
	Padding uint32

	Value string
}
  • Size: 表示返回的Value大小
  • Value: 包含文件额外属性名的字符串,格式类似"user.name\0system.name"

FuseListxattrIn中的Size为0, 不需要往FuseListxattrOut写入Value。

特殊

  • 当Value为空时,响应实体为FuseListxattrOut
  • 当Value有值时,响应实体不需要FuseListxattrOut,而是在响应头FuseOutHeader后紧跟着Value的值
FUSE_REMOVEXATTR = 24

removexattr()函数,Remove an extended attribute

请求头后的实体
type FuseRemovexattrIn struct {
	Name string
}
  • Name: 要删除的文件额外属性名
响应头的实体

removexattr只需响应头返回成功与否

FUSE_FLUSH = 25

flush()函数,Flush method

请求头后的实体
type FuseFlushIn struct {
	Fh        uint64
	Unused    uint32
	Padding   uint32
	LockOwner uint64
}
响应头的实体

flush只需响应头返回成功与否

FUSE_INIT = 26

init()函数, Initialize filesystem

Fuse文件系统的初始化函数,当Mount以后,从/dev/fuse读到的第一个请求就是init,只有初始化后,才会接收到其他请求。

请求头后的实体
type FuseInitIn struct {
	Major        uint32
	Minor        uint32
	MaxReadahead uint32
	Flags        uint32
}
  • Major: Fuse的主版本号
  • Minor: Fuse的副版本号
  • Flags: 内核Fuse能提供的功能
    • FUSE_ASYNC_READ = (1 << 0)
    • FUSE_POSIX_LOCKS = (1 << 1)
    • FUSE_FILE_OPS = (1 << 2)
    • FUSE_ATOMIC_O_TRUNC = (1 << 3)
    • FUSE_EXPORT_SUPPORT = (1 << 4)
    • FUSE_BIG_WRITES = (1 << 5)
    • FUSE_DONT_MASK = (1 << 6)
    • FUSE_SPLICE_WRITE = (1 << 7)
    • FUSE_SPLICE_MOVE = (1 << 8)
    • FUSE_SPLICE_READ = (1 << 9)
    • FUSE_FLOCK_LOCKS = (1 << 10)
    • FUSE_HAS_IOCTL_DIR = (1 << 11)
    • FUSE_AUTO_INVAL_DATA = (1 << 12)
    • FUSE_DO_READDIRPLUS = (1 << 13)
    • FUSE_READDIRPLUS_AUTO = (1 << 14)
    • FUSE_ASYNC_DIO = (1 << 15)
    • FUSE_WRITEBACK_CACHE = (1 << 16)
    • FUSE_NO_OPEN_SUPPORT = (1 << 17)
    • FUSE_PARALLEL_DIROPS = (1 << 18)
    • FUSE_HANDLE_KILLPRIV = (1 << 19)
    • FUSE_POSIX_ACL = (1 << 20)
响应头的实体
type FuseInitOut struct {
	Major               uint32
	Minor               uint32
	MaxReadahead        uint32
	Flags               uint32
	MaxBackground       uint16
	CongestionThreshold uint16
	MaxWrite            uint32
	TimeGran            uint32
	Unused              [9]uint32
}
  • Major: 主版本号
  • Minor: 副版本号
  • Flags: 程序希望Fuse提供的功能
FUSE_OPENDIR = 27

opendir()函数,Open a directory

请求头后的实体
type FuseOpenIn struct {
	Flags  uint32
	Unused uint32
}
响应头的实体
type FuseOpenOut struct {
	Fh        uint64
	OpenFlags uint32
	Padding   uint32
}
FUSE_READDIR = 28

readdir()函数,Read directory

请求头后的实体
type FuseReadIn struct {
	Fh        uint64
	Offset    uint64
	Size      uint32
	ReadFlags uint32
	LockOwner uint64
	Flags     uint32
	Padding   uint32
}
  • Offset: 开始的偏移量
  • Size: 内核所能接收的字节数大小
响应头的实体
type FuseReadOut struct {
	Content []byte
}

type FuseDirent struct {
	Ino     uint64
	Off     uint64
	NameLen uint32
	DirType uint32
	Name    string
}

读取目录比较特殊,读取目录是返回有目录中哪些文件的,FuseReadOut中是多个FuseDirent的二进制格式。

并且FuseReadOut的大小不能超过,FuseReadIn中Size的大小。

同时,每个FuseDirent的二进制字节数,必须要凑齐为8的倍数,比如某个FuseDirent的字节数是30,必须在其后加上"\0\0"以凑齐32。

FUSE_RELEASEDIR = 29

releasedir()函数,Release an open directory

请求头后的实体
type FuseReleaseIn struct {
	Fh           uint64
	Flags        uint32
	ReleaseFlags uint32
	LockOwner    uint64
}
响应头的实体

releasedir只需响应头返回成功与否

FUSE_FSYNCDIR = 30

fsyncdir()函数,Synchronize directory contents

请求头后的实体
type FuseFsyncIn struct {
	Fh         uint64
	FsyncFlags uint32
	Padding    uint32
}
响应头的实体

fsyncdir只需响应头返回成功与否

FUSE_GETLK = 31

getlk()函数,Test for a POSIX file lock

请求头后的实体
type FuseLkIn struct {
	Fh      uint64
	Owner   uint64
	Lk      FuseFileLock
	LkFlags uint32
	Padding uint32
}

type FuseFileLock struct {
	Start uint64
	End   uint64
	Type  uint32
	Pid   uint32 /* tgid */
}
响应头的实体
type FuseFileLock struct {
	Start uint64
	End   uint64
	Type  uint32
	Pid   uint32 /* tgid */
}
FUSE_SETLK = 32

setlk()函数,Acquire, modify or release a POSIX file lock

请求头后的实体
type FuseLkIn struct {
	Fh      uint64
	Owner   uint64
	Lk      FuseFileLock
	LkFlags uint32
	Padding uint32
}

type FuseFileLock struct {
	Start uint64
	End   uint64
	Type  uint32
	Pid   uint32 /* tgid */
}
响应头的实体
type FuseFileLock struct {
	Start uint64
	End   uint64
	Type  uint32
	Pid   uint32 /* tgid */
}
FUSE_SETLKW = 33

setlk()相同

FUSE_ACCESS = 34

access()函数,Check file access permissions

请求头后的实体
type FuseAccessIn struct {
	Mask    uint32
	Padding uint32
}
响应头的实体

access只需响应头返回成功与否

FUSE_CREATE = 35

create()函数,Create and open a file

请求头后的实体
type FuseCreateIn struct {
	Flags   uint32
	Mode    uint32
	Umask   uint32
	Padding uint32

	Name string
}
  • Mode: 文件类型以及权限模式
  • Name: 文件名
响应头的实体
type FuseCreateOut struct {
	Entry FuseEntryOut
	Open  FuseOpenOut
}

type FuseEntryOut struct {
	NodeId         uint64 /* Inode ID */
	Generation     uint64 /* Inode generation: nodeid:gen must be unique for the fs's lifetime */
	EntryValid     uint64 /* Cache timeout for the name */
	AttrValid      uint64 /* Cache timeout for the attributes */
	EntryValidNsec uint32
	AttrValidNsec  uint32

	Attr FuseAttr
}

type FuseAttr struct {
	Ino       uint64
	Size      uint64
	Blocks    uint64
	Atime     uint64
	Mtime     uint64
	Ctime     uint64
	AtimeNsec uint32
	MtimeNsec uint32
	CtimeNsec uint32
	Mode      uint32
	Nlink     uint32
	Uid       uint32
	Gid       uint32
	Rdev      uint32
	Blksize   uint32
	Padding   uint32
}

type FuseOpenOut struct {
	Fh        uint64
	OpenFlags uint32
	Padding   uint32
}

create的响应实体FuseCreateOut需要有FuseEntryOutFuseOpenOut的结构

FUSE_INTERRUPT = 36

程序中断接收到的请求

请求头后的实体
struct FuseInterruptIn {
	uint64_t	unique;
};
FUSE_BMAP = 37

bmap()函数,Map block index within file to block index within device

请求头后的实体
type FuseBmapIn struct {
	Block     uint64
	BlockSize uint32
	Padding   uint32
}
响应头的实体
type FuseBmapOut struct {
	Block uint64
}
FUSE_DESTROY = 38

destory()函数,Clean up filesystem.

没有请求实体,不需要返回响应。

FUSE_IOCTL = 39

ioctl()函数

请求头后的实体
type FuseIoctlIn struct {
	Fh      uint64
	Flags   uint32
	Cmd     uint32
	Arg     uint64
	InSize  uint32
	OutSize uint32

	InBuf []byte
}
响应头的实体
type FuseIoctlOut struct {
	Result  int32
	Flags   uint32
	InIovs  uint32
	OutIovs uint32
}
FUSE_POLL = 40

poll()函数,Poll for IO readiness

请求头后的实体
type FusePollIn struct {
	Fh     uint64
	Kh     uint64
	Flags  uint32
	Events uint32
}
响应头的实体
type FusePollOut struct {
	Revents uint32
	Padding uint32
}
FUSE_BATCH_FORGET = 42

forget_multi()函数,Forget about multiple inodes

不需要响应

请求头后的实体
type FuseBatchForgetIn struct {
	Count uint32
	Dummy uint32

	NodeList []FuseForgetOne
}

type FuseForgetOne struct {
	Nodeid  uint64
	Nlookup uint64
}
FUSE_FALLOCATE = 43

fallocate()函数,Allocate requested space.

请求头后的实体
type FuseFallocateIn struct {
	Fh      uint64
	Offset  uint64
	Length  uint64
	Mode    uint32
	Padding uint32
}
响应头的实体

fallocate只需响应头返回成功与否

FUSE_READDIRPLUS = 44

readdirplus()函数,Read directory with attributes

请求头后的实体
type FuseReadIn struct {
	Fh        uint64
	Offset    uint64
	Size      uint32
	ReadFlags uint32
	LockOwner uint64
	Flags     uint32
	Padding   uint32
}
响应头的实体
type FuseReadOut struct {
	Content []byte
}
FUSE_RENAME2 = 45

参考rename但请求略有不同

请求头后的实体
type FuseRename2In struct {
	NewDir  uint64
	Flags   uint32
	Padding uint32

	OldName string
	NewName string
}
响应头的实体

rename只需响应头返回成功与否

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部