2020-07-27 13:25:21 -07:00
|
|
|
// Copyright 2020 The gVisor Authors.
|
|
|
|
|
//
|
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
|
//
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
//
|
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
|
|
package linux
|
|
|
|
|
|
2020-07-27 14:42:31 -04:00
|
|
|
import (
|
2023-02-06 11:21:37 -08:00
|
|
|
"time"
|
|
|
|
|
|
2020-09-14 10:56:25 -07:00
|
|
|
"gvisor.dev/gvisor/pkg/marshal/primitive"
|
2020-07-27 14:42:31 -04:00
|
|
|
)
|
2020-08-13 22:23:40 +00:00
|
|
|
|
2020-12-11 12:04:46 -08:00
|
|
|
// FUSEOpcode is a FUSE operation code.
|
|
|
|
|
//
|
2020-07-27 13:25:21 -07:00
|
|
|
// +marshal
|
|
|
|
|
type FUSEOpcode uint32
|
|
|
|
|
|
2020-12-11 12:04:46 -08:00
|
|
|
// FUSEOpID is a FUSE operation ID.
|
|
|
|
|
//
|
2020-07-27 13:25:21 -07:00
|
|
|
// +marshal
|
|
|
|
|
type FUSEOpID uint64
|
|
|
|
|
|
2020-08-13 22:23:40 +00:00
|
|
|
// FUSE_ROOT_ID is the id of root inode.
|
|
|
|
|
const FUSE_ROOT_ID = 1
|
|
|
|
|
|
2020-12-11 12:04:46 -08:00
|
|
|
// Opcodes for FUSE operations.
|
|
|
|
|
//
|
|
|
|
|
// Analogous to the opcodes in include/linux/fuse.h.
|
2020-07-27 13:25:21 -07:00
|
|
|
const (
|
|
|
|
|
FUSE_LOOKUP FUSEOpcode = 1
|
|
|
|
|
FUSE_FORGET = 2 /* no reply */
|
|
|
|
|
FUSE_GETATTR = 3
|
|
|
|
|
FUSE_SETATTR = 4
|
|
|
|
|
FUSE_READLINK = 5
|
|
|
|
|
FUSE_SYMLINK = 6
|
|
|
|
|
_
|
|
|
|
|
FUSE_MKNOD = 8
|
|
|
|
|
FUSE_MKDIR = 9
|
|
|
|
|
FUSE_UNLINK = 10
|
|
|
|
|
FUSE_RMDIR = 11
|
|
|
|
|
FUSE_RENAME = 12
|
|
|
|
|
FUSE_LINK = 13
|
|
|
|
|
FUSE_OPEN = 14
|
|
|
|
|
FUSE_READ = 15
|
|
|
|
|
FUSE_WRITE = 16
|
|
|
|
|
FUSE_STATFS = 17
|
|
|
|
|
FUSE_RELEASE = 18
|
|
|
|
|
_
|
|
|
|
|
FUSE_FSYNC = 20
|
|
|
|
|
FUSE_SETXATTR = 21
|
|
|
|
|
FUSE_GETXATTR = 22
|
|
|
|
|
FUSE_LISTXATTR = 23
|
|
|
|
|
FUSE_REMOVEXATTR = 24
|
|
|
|
|
FUSE_FLUSH = 25
|
|
|
|
|
FUSE_INIT = 26
|
|
|
|
|
FUSE_OPENDIR = 27
|
|
|
|
|
FUSE_READDIR = 28
|
|
|
|
|
FUSE_RELEASEDIR = 29
|
|
|
|
|
FUSE_FSYNCDIR = 30
|
|
|
|
|
FUSE_GETLK = 31
|
|
|
|
|
FUSE_SETLK = 32
|
|
|
|
|
FUSE_SETLKW = 33
|
|
|
|
|
FUSE_ACCESS = 34
|
|
|
|
|
FUSE_CREATE = 35
|
|
|
|
|
FUSE_INTERRUPT = 36
|
|
|
|
|
FUSE_BMAP = 37
|
|
|
|
|
FUSE_DESTROY = 38
|
|
|
|
|
FUSE_IOCTL = 39
|
|
|
|
|
FUSE_POLL = 40
|
|
|
|
|
FUSE_NOTIFY_REPLY = 41
|
|
|
|
|
FUSE_BATCH_FORGET = 42
|
2023-02-13 12:14:59 -08:00
|
|
|
FUSE_FALLOCATE = 43
|
2020-07-27 13:25:21 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
// FUSE_MIN_READ_BUFFER is the minimum size the read can be for any FUSE filesystem.
|
|
|
|
|
// This is the minimum size Linux supports. See linux.fuse.h.
|
|
|
|
|
FUSE_MIN_READ_BUFFER uint32 = 8192
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// FUSEHeaderIn is the header read by the daemon with each request.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
2024-02-07 16:59:37 -08:00
|
|
|
// +stateify savable
|
2020-07-27 13:25:21 -07:00
|
|
|
type FUSEHeaderIn struct {
|
|
|
|
|
// Len specifies the total length of the data, including this header.
|
|
|
|
|
Len uint32
|
|
|
|
|
|
|
|
|
|
// Opcode specifies the kind of operation of the request.
|
|
|
|
|
Opcode FUSEOpcode
|
|
|
|
|
|
|
|
|
|
// Unique specifies the unique identifier for this request.
|
|
|
|
|
Unique FUSEOpID
|
|
|
|
|
|
|
|
|
|
// NodeID is the ID of the filesystem object being operated on.
|
|
|
|
|
NodeID uint64
|
|
|
|
|
|
|
|
|
|
// UID is the UID of the requesting process.
|
|
|
|
|
UID uint32
|
|
|
|
|
|
|
|
|
|
// GID is the GID of the requesting process.
|
|
|
|
|
GID uint32
|
|
|
|
|
|
|
|
|
|
// PID is the PID of the requesting process.
|
|
|
|
|
PID uint32
|
|
|
|
|
|
|
|
|
|
_ uint32
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-25 11:00:51 -08:00
|
|
|
// SizeOfFUSEHeaderIn is the size of the FUSEHeaderIn struct.
|
|
|
|
|
var SizeOfFUSEHeaderIn = uint32((*FUSEHeaderIn)(nil).SizeBytes())
|
|
|
|
|
|
2020-07-27 13:25:21 -07:00
|
|
|
// FUSEHeaderOut is the header written by the daemon when it processes
|
|
|
|
|
// a request and wants to send a reply (almost all operations require a
|
|
|
|
|
// reply; if they do not, this will be explicitly documented).
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
2024-02-07 16:59:37 -08:00
|
|
|
// +stateify savable
|
2020-07-27 13:25:21 -07:00
|
|
|
type FUSEHeaderOut struct {
|
|
|
|
|
// Len specifies the total length of the data, including this header.
|
|
|
|
|
Len uint32
|
|
|
|
|
|
|
|
|
|
// Error specifies the error that occurred (0 if none).
|
|
|
|
|
Error int32
|
|
|
|
|
|
|
|
|
|
// Unique specifies the unique identifier of the corresponding request.
|
|
|
|
|
Unique FUSEOpID
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-25 11:00:51 -08:00
|
|
|
// SizeOfFUSEHeaderOut is the size of the FUSEHeaderOut struct.
|
|
|
|
|
var SizeOfFUSEHeaderOut = uint32((*FUSEHeaderOut)(nil).SizeBytes())
|
|
|
|
|
|
2020-06-27 02:14:56 +00:00
|
|
|
// FUSE_INIT flags, consistent with the ones in include/uapi/linux/fuse.h.
|
2023-10-25 12:06:44 -07:00
|
|
|
// Our target version is 7.23 but we have few implemented in advance.
|
2020-06-27 02:14:56 +00:00
|
|
|
const (
|
2020-09-02 13:50:31 -07:00
|
|
|
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_MAX_PAGES = 1 << 22 // From FUSE 7.28
|
2020-06-27 02:14:56 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// currently supported FUSE protocol version numbers.
|
|
|
|
|
const (
|
|
|
|
|
FUSE_KERNEL_VERSION = 7
|
|
|
|
|
FUSE_KERNEL_MINOR_VERSION = 31
|
|
|
|
|
)
|
|
|
|
|
|
2020-07-15 18:32:51 +00:00
|
|
|
// Constants relevant to FUSE operations.
|
|
|
|
|
const (
|
2020-09-11 23:28:13 +00:00
|
|
|
FUSE_NAME_MAX = 1024
|
|
|
|
|
FUSE_PAGE_SIZE = 4096
|
|
|
|
|
FUSE_DIRENT_ALIGN = 8
|
2020-07-15 18:32:51 +00:00
|
|
|
)
|
|
|
|
|
|
2020-06-27 02:14:56 +00:00
|
|
|
// FUSEInitIn is the request sent by the kernel to the daemon,
|
|
|
|
|
// to negotiate the version and flags.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEInitIn struct {
|
|
|
|
|
// Major version supported by kernel.
|
|
|
|
|
Major uint32
|
|
|
|
|
|
|
|
|
|
// Minor version supported by the kernel.
|
|
|
|
|
Minor uint32
|
|
|
|
|
|
|
|
|
|
// MaxReadahead is the maximum number of bytes to read-ahead
|
|
|
|
|
// decided by the kernel.
|
|
|
|
|
MaxReadahead uint32
|
|
|
|
|
|
|
|
|
|
// Flags of this init request.
|
|
|
|
|
Flags uint32
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FUSEInitOut is the reply sent by the daemon to the kernel
|
2020-09-02 13:50:31 -07:00
|
|
|
// for FUSEInitIn. We target FUSE 7.23; this struct supports 7.28.
|
2020-06-27 02:14:56 +00:00
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEInitOut struct {
|
|
|
|
|
// Major version supported by daemon.
|
|
|
|
|
Major uint32
|
|
|
|
|
|
|
|
|
|
// Minor version supported by daemon.
|
|
|
|
|
Minor uint32
|
|
|
|
|
|
|
|
|
|
// MaxReadahead is the maximum number of bytes to read-ahead.
|
|
|
|
|
// Decided by the daemon, after receiving the value from kernel.
|
|
|
|
|
MaxReadahead uint32
|
|
|
|
|
|
|
|
|
|
// Flags of this init reply.
|
|
|
|
|
Flags uint32
|
|
|
|
|
|
|
|
|
|
// MaxBackground is the maximum number of pending background requests
|
|
|
|
|
// that the daemon wants.
|
|
|
|
|
MaxBackground uint16
|
|
|
|
|
|
|
|
|
|
// CongestionThreshold is the daemon-decided threshold for
|
|
|
|
|
// the number of the pending background requests.
|
|
|
|
|
CongestionThreshold uint16
|
|
|
|
|
|
|
|
|
|
// MaxWrite is the daemon's maximum size of a write buffer.
|
|
|
|
|
// Kernel adjusts it to the minimum (fuse/init.go:fuseMinMaxWrite).
|
|
|
|
|
// if the value from daemon is too small.
|
|
|
|
|
MaxWrite uint32
|
|
|
|
|
|
|
|
|
|
// TimeGran is the daemon's time granularity for mtime and ctime metadata.
|
|
|
|
|
// The unit is nanosecond.
|
|
|
|
|
// Value should be power of 10.
|
|
|
|
|
// 1 indicates full nanosecond granularity support.
|
|
|
|
|
TimeGran uint32
|
|
|
|
|
|
|
|
|
|
// MaxPages is the daemon's maximum number of pages for one write operation.
|
|
|
|
|
// Kernel adjusts it to the maximum (fuse/init.go:FUSE_MAX_MAX_PAGES).
|
|
|
|
|
// if the value from daemon is too large.
|
|
|
|
|
MaxPages uint16
|
|
|
|
|
|
2020-09-02 13:50:31 -07:00
|
|
|
_ uint16
|
2020-06-27 02:14:56 +00:00
|
|
|
|
|
|
|
|
_ [8]uint32
|
|
|
|
|
}
|
2020-08-10 18:15:32 -07:00
|
|
|
|
2022-01-26 00:48:59 +02:00
|
|
|
// FUSEStatfsOut is the reply sent by the daemon to the kernel
|
|
|
|
|
// for FUSE_STATFS.
|
|
|
|
|
// from https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/fuse.h#L252
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEStatfsOut struct {
|
|
|
|
|
// Blocks is the maximum number of data blocks the filesystem may store, in
|
|
|
|
|
// units of BlockSize.
|
|
|
|
|
Blocks uint64
|
|
|
|
|
|
|
|
|
|
// BlocksFree is the number of free data blocks, in units of BlockSize.
|
|
|
|
|
BlocksFree uint64
|
|
|
|
|
|
|
|
|
|
// BlocksAvailable is the number of data blocks free for use by
|
|
|
|
|
// unprivileged users, in units of BlockSize.
|
|
|
|
|
BlocksAvailable uint64
|
|
|
|
|
|
|
|
|
|
// Files is the number of used file nodes on the filesystem.
|
|
|
|
|
Files uint64
|
|
|
|
|
|
|
|
|
|
// FileFress is the number of free file nodes on the filesystem.
|
|
|
|
|
FilesFree uint64
|
|
|
|
|
|
|
|
|
|
// BlockSize is the optimal transfer block size in bytes.
|
|
|
|
|
BlockSize uint32
|
|
|
|
|
|
|
|
|
|
// NameLength is the maximum file name length.
|
|
|
|
|
NameLength uint32
|
|
|
|
|
|
|
|
|
|
// FragmentSize is equivalent to BlockSize.
|
|
|
|
|
FragmentSize uint32
|
|
|
|
|
|
|
|
|
|
_ uint32
|
|
|
|
|
|
|
|
|
|
Spare [6]uint32
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-09 09:16:09 -07:00
|
|
|
// FUSE_GETATTR_FH is currently the only flag of FUSEGetAttrIn.GetAttrFlags.
|
|
|
|
|
// If it is set, the file handle (FUSEGetAttrIn.Fh) is used to indicate the
|
|
|
|
|
// object instead of the node id attribute in the request header.
|
|
|
|
|
const FUSE_GETATTR_FH = (1 << 0)
|
|
|
|
|
|
2020-08-10 18:15:32 -07:00
|
|
|
// FUSEGetAttrIn is the request sent by the kernel to the daemon,
|
|
|
|
|
// to get the attribute of a inode.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEGetAttrIn struct {
|
|
|
|
|
// GetAttrFlags specifies whether getattr request is sent with a nodeid or
|
|
|
|
|
// with a file handle.
|
|
|
|
|
GetAttrFlags uint32
|
|
|
|
|
|
|
|
|
|
_ uint32
|
|
|
|
|
|
|
|
|
|
// Fh is the file handler when GetAttrFlags has FUSE_GETATTR_FH bit. If
|
|
|
|
|
// used, the operation is analogous to fstat(2).
|
|
|
|
|
Fh uint64
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-25 12:06:44 -07:00
|
|
|
// FUSEAttr is the struct used in the response FUSEGetAttrOut.
|
2020-08-10 18:15:32 -07:00
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEAttr struct {
|
2020-09-09 13:10:56 -07:00
|
|
|
// Ino is the inode number of this file.
|
|
|
|
|
Ino uint64
|
|
|
|
|
|
|
|
|
|
// Size is the size of this file.
|
|
|
|
|
Size uint64
|
|
|
|
|
|
|
|
|
|
// Blocks is the number of the 512B blocks allocated by this file.
|
|
|
|
|
Blocks uint64
|
|
|
|
|
|
|
|
|
|
// Atime is the time of last access.
|
|
|
|
|
Atime uint64
|
|
|
|
|
|
|
|
|
|
// Mtime is the time of last modification.
|
|
|
|
|
Mtime uint64
|
|
|
|
|
|
|
|
|
|
// Ctime is the time of last status change.
|
|
|
|
|
Ctime uint64
|
|
|
|
|
|
|
|
|
|
// AtimeNsec is the nano second part of Atime.
|
2020-08-10 18:15:32 -07:00
|
|
|
AtimeNsec uint32
|
2020-09-09 13:10:56 -07:00
|
|
|
|
|
|
|
|
// MtimeNsec is the nano second part of Mtime.
|
2020-08-10 18:15:32 -07:00
|
|
|
MtimeNsec uint32
|
2020-09-09 13:10:56 -07:00
|
|
|
|
|
|
|
|
// CtimeNsec is the nano second part of Ctime.
|
2020-08-10 18:15:32 -07:00
|
|
|
CtimeNsec uint32
|
2020-09-09 13:10:56 -07:00
|
|
|
|
|
|
|
|
// Mode contains the file type and mode.
|
|
|
|
|
Mode uint32
|
|
|
|
|
|
|
|
|
|
// Nlink is the number of the hard links.
|
|
|
|
|
Nlink uint32
|
|
|
|
|
|
|
|
|
|
// UID is user ID of the owner.
|
|
|
|
|
UID uint32
|
|
|
|
|
|
|
|
|
|
// GID is group ID of the owner.
|
|
|
|
|
GID uint32
|
|
|
|
|
|
|
|
|
|
// Rdev is the device ID if this is a special file.
|
|
|
|
|
Rdev uint32
|
|
|
|
|
|
|
|
|
|
// BlkSize is the block size for filesystem I/O.
|
|
|
|
|
BlkSize uint32
|
|
|
|
|
|
|
|
|
|
_ uint32
|
2020-08-10 18:15:32 -07:00
|
|
|
}
|
|
|
|
|
|
2023-02-06 11:21:37 -08:00
|
|
|
// ATimeNsec returns the last access time as the total time since the unix epoch
|
|
|
|
|
// in nanoseconds.
|
|
|
|
|
func (a FUSEAttr) ATimeNsec() int64 {
|
|
|
|
|
return int64(a.Atime)*time.Second.Nanoseconds() + int64(a.AtimeNsec)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MTimeNsec returns the last modification time as the total time since the unix
|
|
|
|
|
// epoch in nanoseconds.
|
|
|
|
|
func (a FUSEAttr) MTimeNsec() int64 {
|
|
|
|
|
return int64(a.Mtime)*time.Second.Nanoseconds() + int64(a.MtimeNsec)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CTimeNsec returns the last change time as the total time since the unix epoch
|
|
|
|
|
// in nanoseconds.
|
|
|
|
|
func (a FUSEAttr) CTimeNsec() int64 {
|
|
|
|
|
return int64(a.Ctime)*time.Second.Nanoseconds() + int64(a.CtimeNsec)
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-01 17:18:31 -08:00
|
|
|
// FUSEAttrOut is the reply sent by the daemon to the kernel
|
|
|
|
|
// for FUSEGetAttrIn and FUSESetAttrIn.
|
2020-08-10 18:15:32 -07:00
|
|
|
//
|
|
|
|
|
// +marshal
|
2023-02-01 17:18:31 -08:00
|
|
|
type FUSEAttrOut struct {
|
2020-08-10 18:15:32 -07:00
|
|
|
// AttrValid and AttrValidNsec describe the attribute cache duration
|
|
|
|
|
AttrValid uint64
|
|
|
|
|
|
|
|
|
|
// AttrValidNsec is the nanosecond part of the attribute cache duration
|
|
|
|
|
AttrValidNsec uint32
|
|
|
|
|
|
|
|
|
|
_ uint32
|
|
|
|
|
|
|
|
|
|
// Attr contains the metadata returned from the FUSE server
|
|
|
|
|
Attr FUSEAttr
|
|
|
|
|
}
|
2020-08-13 22:23:40 +00:00
|
|
|
|
|
|
|
|
// FUSEEntryOut is the reply sent by the daemon to the kernel
|
|
|
|
|
// for FUSE_MKNOD, FUSE_MKDIR, FUSE_SYMLINK, FUSE_LINK and
|
|
|
|
|
// FUSE_LOOKUP.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEEntryOut struct {
|
|
|
|
|
// NodeID is the ID for current inode.
|
|
|
|
|
NodeID uint64
|
|
|
|
|
|
|
|
|
|
// Generation is the generation number of inode.
|
|
|
|
|
// Used to identify an inode that have different ID at different time.
|
|
|
|
|
Generation uint64
|
|
|
|
|
|
|
|
|
|
// EntryValid indicates timeout for an entry.
|
|
|
|
|
EntryValid uint64
|
|
|
|
|
|
|
|
|
|
// AttrValid indicates timeout for an entry's attributes.
|
|
|
|
|
AttrValid uint64
|
|
|
|
|
|
|
|
|
|
// EntryValidNsec indicates timeout for an entry in nanosecond.
|
|
|
|
|
EntryValidNSec uint32
|
|
|
|
|
|
|
|
|
|
// AttrValidNsec indicates timeout for an entry's attributes in nanosecond.
|
|
|
|
|
AttrValidNSec uint32
|
|
|
|
|
|
|
|
|
|
// Attr contains the attributes of an entry.
|
|
|
|
|
Attr FUSEAttr
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-05 10:40:53 -07:00
|
|
|
// CString represents a null terminated string which can be marshalled.
|
2021-11-16 13:28:18 -08:00
|
|
|
//
|
|
|
|
|
// +marshal dynamic
|
2021-11-05 10:40:53 -07:00
|
|
|
type CString string
|
|
|
|
|
|
|
|
|
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
|
|
|
|
func (s *CString) MarshalBytes(buf []byte) []byte {
|
|
|
|
|
copy(buf, *s)
|
|
|
|
|
buf[len(*s)] = 0 // null char
|
|
|
|
|
return buf[s.SizeBytes():]
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
|
|
|
|
func (s *CString) UnmarshalBytes(buf []byte) []byte {
|
|
|
|
|
panic("Unimplemented, CString is never unmarshalled")
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-05 10:40:53 -07:00
|
|
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
|
|
|
|
func (s *CString) SizeBytes() int {
|
|
|
|
|
// 1 extra byte for null-terminated string.
|
|
|
|
|
return len(*s) + 1
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-13 22:23:40 +00:00
|
|
|
// FUSELookupIn is the request sent by the kernel to the daemon
|
|
|
|
|
// to look up a file name.
|
|
|
|
|
//
|
2021-11-16 13:28:18 -08:00
|
|
|
// +marshal dynamic
|
2020-08-13 22:23:40 +00:00
|
|
|
type FUSELookupIn struct {
|
|
|
|
|
// Name is a file name to be looked up.
|
2021-11-05 10:40:53 -07:00
|
|
|
Name CString
|
2020-08-13 22:23:40 +00:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
|
|
|
|
func (r *FUSELookupIn) UnmarshalBytes(buf []byte) []byte {
|
|
|
|
|
panic("Unimplemented, FUSELookupIn is never unmarshalled")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
2021-11-05 10:40:53 -07:00
|
|
|
func (r *FUSELookupIn) MarshalBytes(buf []byte) []byte {
|
|
|
|
|
return r.Name.MarshalBytes(buf)
|
2020-08-13 22:23:40 +00:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
2020-08-13 22:23:40 +00:00
|
|
|
func (r *FUSELookupIn) SizeBytes() int {
|
2021-11-05 10:40:53 -07:00
|
|
|
return r.Name.SizeBytes()
|
2020-08-13 22:23:40 +00:00
|
|
|
}
|
2020-08-18 01:46:39 +00:00
|
|
|
|
|
|
|
|
// MAX_NON_LFS indicates the maximum offset without large file support.
|
|
|
|
|
const MAX_NON_LFS = ((1 << 31) - 1)
|
|
|
|
|
|
|
|
|
|
// flags returned by OPEN request.
|
|
|
|
|
const (
|
|
|
|
|
// FOPEN_DIRECT_IO indicates bypassing page cache for this opened file.
|
|
|
|
|
FOPEN_DIRECT_IO = 1 << 0
|
2023-01-25 11:00:51 -08:00
|
|
|
// FOPEN_KEEP_CACHE avoids invalidating the data cache on open.
|
2020-08-18 01:46:39 +00:00
|
|
|
FOPEN_KEEP_CACHE = 1 << 1
|
|
|
|
|
// FOPEN_NONSEEKABLE indicates the file cannot be seeked.
|
|
|
|
|
FOPEN_NONSEEKABLE = 1 << 2
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// FUSEOpenIn is the request sent by the kernel to the daemon,
|
|
|
|
|
// to negotiate flags and get file handle.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEOpenIn struct {
|
|
|
|
|
// Flags of this open request.
|
|
|
|
|
Flags uint32
|
|
|
|
|
|
|
|
|
|
_ uint32
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FUSEOpenOut is the reply sent by the daemon to the kernel
|
|
|
|
|
// for FUSEOpenIn.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEOpenOut struct {
|
2023-01-25 11:00:51 -08:00
|
|
|
// Fh is the file handler for opened files.
|
2020-08-18 01:46:39 +00:00
|
|
|
Fh uint64
|
|
|
|
|
|
2023-01-25 11:00:51 -08:00
|
|
|
// OpenFlag for the opened files.
|
2020-08-18 01:46:39 +00:00
|
|
|
OpenFlag uint32
|
2020-09-11 23:28:13 +00:00
|
|
|
|
|
|
|
|
_ uint32
|
2020-07-15 18:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
2022-01-26 00:48:59 +02:00
|
|
|
// FUSECreateOut is the reply sent by the daemon to the kernel
|
|
|
|
|
// for FUSECreateMeta.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSECreateOut struct {
|
|
|
|
|
FUSEEntryOut
|
|
|
|
|
FUSEOpenOut
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-15 18:32:51 +00:00
|
|
|
// FUSE_READ flags, consistent with the ones in include/uapi/linux/fuse.h.
|
|
|
|
|
const (
|
|
|
|
|
FUSE_READ_LOCKOWNER = 1 << 1
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// FUSEReadIn is the request sent by the kernel to the daemon
|
|
|
|
|
// for FUSE_READ.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEReadIn struct {
|
|
|
|
|
// Fh is the file handle in userspace.
|
|
|
|
|
Fh uint64
|
|
|
|
|
|
|
|
|
|
// Offset is the read offset.
|
|
|
|
|
Offset uint64
|
|
|
|
|
|
|
|
|
|
// Size is the number of bytes to read.
|
|
|
|
|
Size uint32
|
|
|
|
|
|
|
|
|
|
// ReadFlags for this FUSE_READ request.
|
|
|
|
|
// Currently only contains FUSE_READ_LOCKOWNER.
|
|
|
|
|
ReadFlags uint32
|
|
|
|
|
|
|
|
|
|
// LockOwner is the id of the lock owner if there is one.
|
|
|
|
|
LockOwner uint64
|
|
|
|
|
|
|
|
|
|
// Flags for the underlying file.
|
|
|
|
|
Flags uint32
|
2020-08-18 01:46:39 +00:00
|
|
|
|
|
|
|
|
_ uint32
|
|
|
|
|
}
|
2020-08-18 20:59:28 +00:00
|
|
|
|
2020-09-01 01:49:57 +00:00
|
|
|
// FUSEWriteIn is the first part of the payload of the
|
|
|
|
|
// request sent by the kernel to the daemon
|
|
|
|
|
// for FUSE_WRITE (struct for FUSE version >= 7.9).
|
|
|
|
|
//
|
|
|
|
|
// The second part of the payload is the
|
|
|
|
|
// binary bytes of the data to be written.
|
2022-01-26 00:48:59 +02:00
|
|
|
// See FUSEWritePayloadIn that combines header & payload.
|
2020-09-01 01:49:57 +00:00
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEWriteIn struct {
|
|
|
|
|
// Fh is the file handle in userspace.
|
|
|
|
|
Fh uint64
|
|
|
|
|
|
|
|
|
|
// Offset is the write offset.
|
|
|
|
|
Offset uint64
|
|
|
|
|
|
|
|
|
|
// Size is the number of bytes to write.
|
|
|
|
|
Size uint32
|
|
|
|
|
|
|
|
|
|
// ReadFlags for this FUSE_WRITE request.
|
|
|
|
|
WriteFlags uint32
|
|
|
|
|
|
|
|
|
|
// LockOwner is the id of the lock owner if there is one.
|
|
|
|
|
LockOwner uint64
|
|
|
|
|
|
|
|
|
|
// Flags for the underlying file.
|
|
|
|
|
Flags uint32
|
|
|
|
|
|
|
|
|
|
_ uint32
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-25 11:00:51 -08:00
|
|
|
// SizeOfFUSEWriteIn is the size of the FUSEWriteIn struct.
|
|
|
|
|
var SizeOfFUSEWriteIn = uint32((*FUSEWriteIn)(nil).SizeBytes())
|
|
|
|
|
|
2022-01-26 00:48:59 +02:00
|
|
|
// FUSEWritePayloadIn combines header - FUSEWriteIn and payload
|
|
|
|
|
// in a single marshallable struct when sending request by the
|
|
|
|
|
// kernel to the daemon
|
|
|
|
|
//
|
|
|
|
|
// +marshal dynamic
|
|
|
|
|
type FUSEWritePayloadIn struct {
|
2022-02-03 13:24:54 -08:00
|
|
|
Header FUSEWriteIn
|
2022-01-26 00:48:59 +02:00
|
|
|
Payload primitive.ByteSlice
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
|
|
|
|
func (r *FUSEWritePayloadIn) SizeBytes() int {
|
|
|
|
|
if r == nil {
|
|
|
|
|
return (*FUSEWriteIn)(nil).SizeBytes()
|
|
|
|
|
}
|
|
|
|
|
return r.Header.SizeBytes() + r.Payload.SizeBytes()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
|
|
|
|
func (r *FUSEWritePayloadIn) MarshalBytes(dst []byte) []byte {
|
2022-02-03 13:24:54 -08:00
|
|
|
dst = r.Header.MarshalUnsafe(dst)
|
|
|
|
|
dst = r.Payload.MarshalUnsafe(dst)
|
|
|
|
|
return dst
|
2022-01-26 00:48:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
|
|
|
|
func (r *FUSEWritePayloadIn) UnmarshalBytes(src []byte) []byte {
|
2022-02-03 13:24:54 -08:00
|
|
|
panic("Unimplemented, FUSEWritePayloadIn is never unmarshalled")
|
2022-01-26 00:48:59 +02:00
|
|
|
}
|
|
|
|
|
|
2020-09-01 01:49:57 +00:00
|
|
|
// FUSEWriteOut is the payload of the reply sent by the daemon to the kernel
|
|
|
|
|
// for a FUSE_WRITE request.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEWriteOut struct {
|
|
|
|
|
// Size is the number of bytes written.
|
|
|
|
|
Size uint32
|
|
|
|
|
|
|
|
|
|
_ uint32
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-18 20:59:28 +00:00
|
|
|
// FUSEReleaseIn is the request sent by the kernel to the daemon
|
|
|
|
|
// when there is no more reference to a file.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEReleaseIn struct {
|
|
|
|
|
// Fh is the file handler for the file to be released.
|
|
|
|
|
Fh uint64
|
|
|
|
|
|
|
|
|
|
// Flags of the file.
|
|
|
|
|
Flags uint32
|
|
|
|
|
|
|
|
|
|
// ReleaseFlags of this release request.
|
|
|
|
|
ReleaseFlags uint32
|
|
|
|
|
|
|
|
|
|
// LockOwner is the id of the lock owner if there is one.
|
|
|
|
|
LockOwner uint64
|
|
|
|
|
}
|
2020-08-18 21:51:06 +00:00
|
|
|
|
2020-09-03 14:06:59 -07:00
|
|
|
// FUSECreateMeta contains all the static fields of FUSECreateIn,
|
|
|
|
|
// which is used for FUSE_CREATE.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSECreateMeta struct {
|
|
|
|
|
// Flags of the creating file.
|
|
|
|
|
Flags uint32
|
|
|
|
|
|
|
|
|
|
// Mode is the mode of the creating file.
|
|
|
|
|
Mode uint32
|
|
|
|
|
|
|
|
|
|
// Umask is the current file mode creation mask.
|
|
|
|
|
Umask uint32
|
|
|
|
|
_ uint32
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-26 00:48:59 +02:00
|
|
|
// FUSERenameIn sent by the kernel for FUSE_RENAME
|
|
|
|
|
//
|
|
|
|
|
// +marshal dynamic
|
|
|
|
|
type FUSERenameIn struct {
|
2022-02-03 13:24:54 -08:00
|
|
|
Newdir primitive.Uint64
|
2022-01-26 00:48:59 +02:00
|
|
|
Oldname CString
|
|
|
|
|
Newname CString
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
|
|
|
|
func (r *FUSERenameIn) MarshalBytes(dst []byte) []byte {
|
|
|
|
|
dst = r.Newdir.MarshalBytes(dst)
|
|
|
|
|
dst = r.Oldname.MarshalBytes(dst)
|
|
|
|
|
return r.Newname.MarshalBytes(dst)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
|
|
|
|
func (r *FUSERenameIn) UnmarshalBytes(buf []byte) []byte {
|
|
|
|
|
panic("Unimplemented, FUSERmDirIn is never unmarshalled")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
|
|
|
|
func (r *FUSERenameIn) SizeBytes() int {
|
|
|
|
|
return r.Newdir.SizeBytes() + r.Oldname.SizeBytes() + r.Newname.SizeBytes()
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-03 14:06:59 -07:00
|
|
|
// FUSECreateIn contains all the arguments sent by the kernel to the daemon, to
|
|
|
|
|
// atomically create and open a new regular file.
|
|
|
|
|
//
|
2021-11-16 13:28:18 -08:00
|
|
|
// +marshal dynamic
|
2020-09-03 14:06:59 -07:00
|
|
|
type FUSECreateIn struct {
|
2023-01-25 11:00:51 -08:00
|
|
|
// CreateMeta contains mode, rdev and umash fields for FUSE_MKNODS.
|
2020-09-03 14:06:59 -07:00
|
|
|
CreateMeta FUSECreateMeta
|
|
|
|
|
|
|
|
|
|
// Name is the name of the node to create.
|
2021-11-05 10:40:53 -07:00
|
|
|
Name CString
|
2020-09-03 14:06:59 -07:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
2021-11-05 10:40:53 -07:00
|
|
|
func (r *FUSECreateIn) MarshalBytes(buf []byte) []byte {
|
|
|
|
|
buf = r.CreateMeta.MarshalBytes(buf)
|
|
|
|
|
return r.Name.MarshalBytes(buf)
|
2020-09-03 14:06:59 -07:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
|
|
|
|
func (r *FUSECreateIn) UnmarshalBytes(buf []byte) []byte {
|
|
|
|
|
panic("Unimplemented, FUSECreateIn is never unmarshalled")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
2020-09-03 14:06:59 -07:00
|
|
|
func (r *FUSECreateIn) SizeBytes() int {
|
2021-11-05 10:40:53 -07:00
|
|
|
return r.CreateMeta.SizeBytes() + r.Name.SizeBytes()
|
2020-09-03 14:06:59 -07:00
|
|
|
}
|
|
|
|
|
|
2020-08-18 21:51:06 +00:00
|
|
|
// FUSEMknodMeta contains all the static fields of FUSEMknodIn,
|
|
|
|
|
// which is used for FUSE_MKNOD.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEMknodMeta struct {
|
|
|
|
|
// Mode of the inode to create.
|
|
|
|
|
Mode uint32
|
|
|
|
|
|
|
|
|
|
// Rdev encodes device major and minor information.
|
|
|
|
|
Rdev uint32
|
|
|
|
|
|
|
|
|
|
// Umask is the current file mode creation mask.
|
|
|
|
|
Umask uint32
|
|
|
|
|
|
|
|
|
|
_ uint32
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FUSEMknodIn contains all the arguments sent by the kernel
|
|
|
|
|
// to the daemon, to create a new file node.
|
|
|
|
|
//
|
2021-11-16 13:28:18 -08:00
|
|
|
// +marshal dynamic
|
2020-08-18 21:51:06 +00:00
|
|
|
type FUSEMknodIn struct {
|
2023-01-25 11:00:51 -08:00
|
|
|
// MknodMeta contains mode, rdev and umash fields for FUSE_MKNODS.
|
2020-08-18 21:51:06 +00:00
|
|
|
MknodMeta FUSEMknodMeta
|
|
|
|
|
// Name is the name of the node to create.
|
2021-11-05 10:40:53 -07:00
|
|
|
Name CString
|
2020-08-18 21:51:06 +00:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
2021-11-05 10:40:53 -07:00
|
|
|
func (r *FUSEMknodIn) MarshalBytes(buf []byte) []byte {
|
|
|
|
|
buf = r.MknodMeta.MarshalBytes(buf)
|
|
|
|
|
return r.Name.MarshalBytes(buf)
|
2020-08-19 20:11:59 -04:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
|
|
|
|
func (r *FUSEMknodIn) UnmarshalBytes(buf []byte) []byte {
|
|
|
|
|
panic("Unimplemented, FUSEMknodIn is never unmarshalled")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
2020-08-18 21:51:06 +00:00
|
|
|
func (r *FUSEMknodIn) SizeBytes() int {
|
2021-11-05 10:40:53 -07:00
|
|
|
return r.MknodMeta.SizeBytes() + r.Name.SizeBytes()
|
2020-08-18 21:51:06 +00:00
|
|
|
}
|
2020-08-18 23:09:34 +00:00
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// FUSESymlinkIn is the request sent by the kernel to the daemon,
|
2020-08-18 23:09:34 +00:00
|
|
|
// to create a symbolic link.
|
|
|
|
|
//
|
2021-11-16 13:28:18 -08:00
|
|
|
// +marshal dynamic
|
|
|
|
|
type FUSESymlinkIn struct {
|
2020-08-18 23:09:34 +00:00
|
|
|
// Name of symlink to create.
|
2021-11-05 10:40:53 -07:00
|
|
|
Name CString
|
2020-08-18 23:09:34 +00:00
|
|
|
|
|
|
|
|
// Target of the symlink.
|
2021-11-05 10:40:53 -07:00
|
|
|
Target CString
|
2020-08-18 23:09:34 +00:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
|
|
|
|
func (r *FUSESymlinkIn) MarshalBytes(buf []byte) []byte {
|
2021-11-05 10:40:53 -07:00
|
|
|
buf = r.Name.MarshalBytes(buf)
|
|
|
|
|
return r.Target.MarshalBytes(buf)
|
2020-08-19 20:11:59 -04:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
|
|
|
|
func (r *FUSESymlinkIn) UnmarshalBytes(buf []byte) []byte {
|
|
|
|
|
panic("Unimplemented, FUSEMknodIn is never unmarshalled")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
|
|
|
|
func (r *FUSESymlinkIn) SizeBytes() int {
|
2021-11-05 10:40:53 -07:00
|
|
|
return r.Name.SizeBytes() + r.Target.SizeBytes()
|
2020-08-18 23:09:34 +00:00
|
|
|
}
|
2020-08-18 23:50:22 +00:00
|
|
|
|
2023-02-03 14:57:23 -08:00
|
|
|
// FUSELinkIn is the request sent by the kernel to create a hard link.
|
|
|
|
|
//
|
|
|
|
|
// +marshal dynamic
|
|
|
|
|
type FUSELinkIn struct {
|
|
|
|
|
// OldNodeID is the ID of the inode that is being linked to.
|
|
|
|
|
OldNodeID primitive.Uint64
|
|
|
|
|
// Name of the new hard link to create.
|
|
|
|
|
Name CString
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
|
|
|
|
func (r *FUSELinkIn) MarshalBytes(buf []byte) []byte {
|
|
|
|
|
buf = r.OldNodeID.MarshalBytes(buf)
|
|
|
|
|
return r.Name.MarshalBytes(buf)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
|
|
|
|
func (r *FUSELinkIn) UnmarshalBytes(buf []byte) []byte {
|
|
|
|
|
panic("Unimplemented, FUSELinkIn is never unmarshalled")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
|
|
|
|
func (r *FUSELinkIn) SizeBytes() int {
|
|
|
|
|
return r.OldNodeID.SizeBytes() + r.Name.SizeBytes()
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-18 23:50:22 +00:00
|
|
|
// FUSEEmptyIn is used by operations without request body.
|
2021-11-16 13:28:18 -08:00
|
|
|
//
|
|
|
|
|
// +marshal dynamic
|
|
|
|
|
type FUSEEmptyIn struct{}
|
2020-08-18 23:50:22 +00:00
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
2021-11-05 10:40:53 -07:00
|
|
|
func (r *FUSEEmptyIn) MarshalBytes(buf []byte) []byte {
|
|
|
|
|
return buf
|
|
|
|
|
}
|
2020-08-19 20:11:59 -04:00
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
|
|
|
|
func (r *FUSEEmptyIn) UnmarshalBytes(buf []byte) []byte {
|
|
|
|
|
panic("Unimplemented, FUSEEmptyIn is never unmarshalled")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
2020-08-18 23:50:22 +00:00
|
|
|
func (r *FUSEEmptyIn) SizeBytes() int {
|
|
|
|
|
return 0
|
|
|
|
|
}
|
2020-08-18 22:45:47 +00:00
|
|
|
|
|
|
|
|
// FUSEMkdirMeta contains all the static fields of FUSEMkdirIn,
|
|
|
|
|
// which is used for FUSE_MKDIR.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEMkdirMeta struct {
|
|
|
|
|
// Mode of the directory of create.
|
|
|
|
|
Mode uint32
|
|
|
|
|
// Umask is the user file creation mask.
|
|
|
|
|
Umask uint32
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FUSEMkdirIn contains all the arguments sent by the kernel
|
|
|
|
|
// to the daemon, to create a new directory.
|
|
|
|
|
//
|
2021-11-16 13:28:18 -08:00
|
|
|
// +marshal dynamic
|
2020-08-18 22:45:47 +00:00
|
|
|
type FUSEMkdirIn struct {
|
|
|
|
|
// MkdirMeta contains Mode and Umask of the directory to create.
|
|
|
|
|
MkdirMeta FUSEMkdirMeta
|
|
|
|
|
// Name of the directory to create.
|
2021-11-05 10:40:53 -07:00
|
|
|
Name CString
|
2020-08-18 22:45:47 +00:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
2021-11-05 10:40:53 -07:00
|
|
|
func (r *FUSEMkdirIn) MarshalBytes(buf []byte) []byte {
|
|
|
|
|
buf = r.MkdirMeta.MarshalBytes(buf)
|
|
|
|
|
return r.Name.MarshalBytes(buf)
|
2020-08-19 20:11:59 -04:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
|
|
|
|
func (r *FUSEMkdirIn) UnmarshalBytes(buf []byte) []byte {
|
|
|
|
|
panic("Unimplemented, FUSEMkdirIn is never unmarshalled")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
2020-08-18 22:45:47 +00:00
|
|
|
func (r *FUSEMkdirIn) SizeBytes() int {
|
2021-11-05 10:40:53 -07:00
|
|
|
return r.MkdirMeta.SizeBytes() + r.Name.SizeBytes()
|
2020-08-18 22:45:47 +00:00
|
|
|
}
|
2020-08-11 12:13:01 -04:00
|
|
|
|
|
|
|
|
// FUSERmDirIn is the request sent by the kernel to the daemon
|
|
|
|
|
// when trying to remove a directory.
|
|
|
|
|
//
|
2021-11-16 13:28:18 -08:00
|
|
|
// +marshal dynamic
|
2020-08-11 12:13:01 -04:00
|
|
|
type FUSERmDirIn struct {
|
2020-09-09 16:44:35 -07:00
|
|
|
// Name is a directory name to be removed.
|
2021-11-05 10:40:53 -07:00
|
|
|
Name CString
|
2020-08-11 12:13:01 -04:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
2021-11-05 10:40:53 -07:00
|
|
|
func (r *FUSERmDirIn) MarshalBytes(buf []byte) []byte {
|
|
|
|
|
return r.Name.MarshalBytes(buf)
|
2020-08-19 20:11:59 -04:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
|
|
|
|
func (r *FUSERmDirIn) UnmarshalBytes(buf []byte) []byte {
|
|
|
|
|
panic("Unimplemented, FUSERmDirIn is never unmarshalled")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
2020-08-11 12:13:01 -04:00
|
|
|
func (r *FUSERmDirIn) SizeBytes() int {
|
2021-11-05 10:40:53 -07:00
|
|
|
return r.Name.SizeBytes()
|
2020-08-11 12:13:01 -04:00
|
|
|
}
|
|
|
|
|
|
2020-07-27 14:42:31 -04:00
|
|
|
// FUSEDirents is a list of Dirents received from the FUSE daemon server.
|
|
|
|
|
// It is used for FUSE_READDIR.
|
|
|
|
|
//
|
2021-11-16 13:28:18 -08:00
|
|
|
// +marshal dynamic
|
2020-07-27 14:42:31 -04:00
|
|
|
type FUSEDirents struct {
|
|
|
|
|
Dirents []*FUSEDirent
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FUSEDirent is a Dirent received from the FUSE daemon server.
|
|
|
|
|
// It is used for FUSE_READDIR.
|
|
|
|
|
//
|
2021-11-16 13:28:18 -08:00
|
|
|
// +marshal dynamic
|
2020-07-27 14:42:31 -04:00
|
|
|
type FUSEDirent struct {
|
|
|
|
|
// Meta contains all the static fields of FUSEDirent.
|
|
|
|
|
Meta FUSEDirentMeta
|
|
|
|
|
// Name is the filename of the dirent.
|
|
|
|
|
Name string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FUSEDirentMeta contains all the static fields of FUSEDirent.
|
|
|
|
|
// It is used for FUSE_READDIR.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEDirentMeta struct {
|
|
|
|
|
// Inode of the dirent.
|
|
|
|
|
Ino uint64
|
|
|
|
|
// Offset of the dirent.
|
|
|
|
|
Off uint64
|
|
|
|
|
// NameLen is the length of the dirent name.
|
|
|
|
|
NameLen uint32
|
|
|
|
|
// Type of the dirent.
|
|
|
|
|
Type uint32
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
2020-07-27 14:42:31 -04:00
|
|
|
func (r *FUSEDirents) SizeBytes() int {
|
|
|
|
|
var sizeBytes int
|
|
|
|
|
for _, dirent := range r.Dirents {
|
|
|
|
|
sizeBytes += dirent.SizeBytes()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sizeBytes
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
|
|
|
|
func (r *FUSEDirents) MarshalBytes(buf []byte) []byte {
|
|
|
|
|
panic("Unimplemented, FUSEDirents is never marshalled")
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-19 20:11:59 -04:00
|
|
|
// UnmarshalBytes deserializes FUSEDirents from the src buffer.
|
2021-11-05 10:40:53 -07:00
|
|
|
func (r *FUSEDirents) UnmarshalBytes(src []byte) []byte {
|
2020-08-19 20:11:59 -04:00
|
|
|
for {
|
|
|
|
|
if len(src) <= (*FUSEDirentMeta)(nil).SizeBytes() {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Its unclear how many dirents there are in src. Each dirent is dynamically
|
|
|
|
|
// sized and so we can't make assumptions about how many dirents we can allocate.
|
|
|
|
|
if r.Dirents == nil {
|
|
|
|
|
r.Dirents = make([]*FUSEDirent, 0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We have to allocate a struct for each dirent - there must be a better way
|
|
|
|
|
// to do this. Linux allocates 1 page to store all the dirents and then
|
|
|
|
|
// simply reads them from the page.
|
|
|
|
|
var dirent FUSEDirent
|
2021-11-05 10:40:53 -07:00
|
|
|
src = dirent.UnmarshalBytes(src)
|
2020-08-19 20:11:59 -04:00
|
|
|
r.Dirents = append(r.Dirents, &dirent)
|
|
|
|
|
}
|
2021-11-05 10:40:53 -07:00
|
|
|
return src
|
2020-08-19 20:11:59 -04:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
2020-07-27 14:42:31 -04:00
|
|
|
func (r *FUSEDirent) SizeBytes() int {
|
|
|
|
|
dataSize := r.Meta.SizeBytes() + len(r.Name)
|
|
|
|
|
|
|
|
|
|
// Each Dirent must be padded such that its size is a multiple
|
|
|
|
|
// of FUSE_DIRENT_ALIGN. Similar to the fuse dirent alignment
|
|
|
|
|
// in linux/fuse.h.
|
|
|
|
|
return (dataSize + (FUSE_DIRENT_ALIGN - 1)) & ^(FUSE_DIRENT_ALIGN - 1)
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
|
|
|
|
func (r *FUSEDirent) MarshalBytes(buf []byte) []byte {
|
|
|
|
|
panic("Unimplemented, FUSEDirent is never marshalled")
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-12 17:31:23 -08:00
|
|
|
// shiftNextDirent advances buf to the start of the next dirent, per
|
|
|
|
|
// FUSE ABI. buf should begin at the start of a dirent.
|
|
|
|
|
func (r *FUSEDirent) shiftNextDirent(buf []byte) []byte {
|
|
|
|
|
nextOff := r.SizeBytes()
|
|
|
|
|
if nextOff > len(buf) { // Handle overflow.
|
|
|
|
|
return buf[len(buf):]
|
|
|
|
|
}
|
|
|
|
|
return buf[nextOff:]
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
2021-11-05 10:40:53 -07:00
|
|
|
func (r *FUSEDirent) UnmarshalBytes(src []byte) []byte {
|
2021-11-12 17:31:23 -08:00
|
|
|
srcP := r.Meta.UnmarshalBytes(src)
|
2020-08-19 20:11:59 -04:00
|
|
|
|
2023-09-19 10:46:32 -07:00
|
|
|
if r.Meta.NameLen > FUSE_NAME_MAX || r.Meta.NameLen > uint32(len(srcP)) {
|
2020-08-19 20:11:59 -04:00
|
|
|
// The name is too long and therefore invalid. We don't
|
|
|
|
|
// need to unmarshal the name since it'll be thrown away.
|
2021-11-12 17:31:23 -08:00
|
|
|
return r.shiftNextDirent(src)
|
2020-08-19 20:11:59 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buf := make([]byte, r.Meta.NameLen)
|
|
|
|
|
name := primitive.ByteSlice(buf)
|
2021-11-12 17:31:23 -08:00
|
|
|
name.UnmarshalBytes(srcP[:r.Meta.NameLen])
|
2020-08-19 20:11:59 -04:00
|
|
|
r.Name = string(name)
|
2021-11-12 17:31:23 -08:00
|
|
|
return r.shiftNextDirent(src)
|
2020-08-19 20:11:59 -04:00
|
|
|
}
|
2020-09-09 10:44:09 -07:00
|
|
|
|
|
|
|
|
// FATTR_* consts are the attribute flags defined in include/uapi/linux/fuse.h.
|
|
|
|
|
// These should be or-ed together for setattr to know what has been changed.
|
|
|
|
|
const (
|
|
|
|
|
FATTR_MODE = (1 << 0)
|
|
|
|
|
FATTR_UID = (1 << 1)
|
|
|
|
|
FATTR_GID = (1 << 2)
|
|
|
|
|
FATTR_SIZE = (1 << 3)
|
|
|
|
|
FATTR_ATIME = (1 << 4)
|
|
|
|
|
FATTR_MTIME = (1 << 5)
|
|
|
|
|
FATTR_FH = (1 << 6)
|
|
|
|
|
FATTR_ATIME_NOW = (1 << 7)
|
|
|
|
|
FATTR_MTIME_NOW = (1 << 8)
|
|
|
|
|
FATTR_LOCKOWNER = (1 << 9)
|
|
|
|
|
FATTR_CTIME = (1 << 10)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// FUSESetAttrIn is the request sent by the kernel to the daemon,
|
|
|
|
|
// to set the attribute(s) of a file.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSESetAttrIn struct {
|
|
|
|
|
// Valid indicates which attributes are modified by this request.
|
|
|
|
|
Valid uint32
|
|
|
|
|
|
|
|
|
|
_ uint32
|
|
|
|
|
|
|
|
|
|
// Fh is used to identify the file if FATTR_FH is set in Valid.
|
|
|
|
|
Fh uint64
|
|
|
|
|
|
|
|
|
|
// Size is the size that the request wants to change to.
|
|
|
|
|
Size uint64
|
|
|
|
|
|
|
|
|
|
// LockOwner is the owner of the lock that the request wants to change to.
|
|
|
|
|
LockOwner uint64
|
|
|
|
|
|
|
|
|
|
// Atime is the access time that the request wants to change to.
|
|
|
|
|
Atime uint64
|
|
|
|
|
|
|
|
|
|
// Mtime is the modification time that the request wants to change to.
|
|
|
|
|
Mtime uint64
|
|
|
|
|
|
|
|
|
|
// Ctime is the status change time that the request wants to change to.
|
|
|
|
|
Ctime uint64
|
|
|
|
|
|
|
|
|
|
// AtimeNsec is the nano second part of Atime.
|
|
|
|
|
AtimeNsec uint32
|
|
|
|
|
|
|
|
|
|
// MtimeNsec is the nano second part of Mtime.
|
|
|
|
|
MtimeNsec uint32
|
|
|
|
|
|
|
|
|
|
// CtimeNsec is the nano second part of Ctime.
|
|
|
|
|
CtimeNsec uint32
|
|
|
|
|
|
|
|
|
|
// Mode is the file mode that the request wants to change to.
|
|
|
|
|
Mode uint32
|
|
|
|
|
|
|
|
|
|
_ uint32
|
|
|
|
|
|
|
|
|
|
// UID is the user ID of the owner that the request wants to change to.
|
|
|
|
|
UID uint32
|
|
|
|
|
|
|
|
|
|
// GID is the group ID of the owner that the request wants to change to.
|
|
|
|
|
GID uint32
|
|
|
|
|
|
|
|
|
|
_ uint32
|
|
|
|
|
}
|
2020-09-09 17:13:18 -07:00
|
|
|
|
|
|
|
|
// FUSEUnlinkIn is the request sent by the kernel to the daemon
|
|
|
|
|
// when trying to unlink a node.
|
|
|
|
|
//
|
2021-11-16 13:28:18 -08:00
|
|
|
// +marshal dynamic
|
2020-09-09 17:13:18 -07:00
|
|
|
type FUSEUnlinkIn struct {
|
|
|
|
|
// Name of the node to unlink.
|
2021-11-05 10:40:53 -07:00
|
|
|
Name CString
|
2020-09-09 17:13:18 -07:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
2021-11-05 10:40:53 -07:00
|
|
|
func (r *FUSEUnlinkIn) MarshalBytes(buf []byte) []byte {
|
|
|
|
|
return r.Name.MarshalBytes(buf)
|
2020-09-09 17:13:18 -07:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 13:28:18 -08:00
|
|
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
|
|
|
|
func (r *FUSEUnlinkIn) UnmarshalBytes(buf []byte) []byte {
|
|
|
|
|
panic("Unimplemented, FUSEUnlinkIn is never unmarshalled")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
2020-09-09 17:13:18 -07:00
|
|
|
func (r *FUSEUnlinkIn) SizeBytes() int {
|
2021-11-05 10:40:53 -07:00
|
|
|
return r.Name.SizeBytes()
|
2020-09-09 17:13:18 -07:00
|
|
|
}
|
2022-01-26 00:48:59 +02:00
|
|
|
|
|
|
|
|
// FUSEFsyncIn is the request sent by the kernel to the daemon
|
|
|
|
|
// when trying to fsync a file.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEFsyncIn struct {
|
|
|
|
|
Fh uint64
|
|
|
|
|
|
|
|
|
|
FsyncFlags uint32
|
|
|
|
|
|
|
|
|
|
// padding
|
|
|
|
|
_ uint32
|
|
|
|
|
}
|
2023-02-01 17:18:31 -08:00
|
|
|
|
|
|
|
|
// FUSEAccessIn is the request sent by the kernel to the daemon when checking
|
|
|
|
|
// permissions on a file.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEAccessIn struct {
|
|
|
|
|
Mask uint32
|
|
|
|
|
// padding
|
|
|
|
|
_ uint32
|
|
|
|
|
}
|
2023-02-13 12:14:59 -08:00
|
|
|
|
|
|
|
|
// FUSEFallocateIn is the request sent by the kernel to the daemon to perform
|
|
|
|
|
// a fallocate operation.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEFallocateIn struct {
|
|
|
|
|
Fh uint64
|
|
|
|
|
Offset uint64
|
|
|
|
|
Length uint64
|
|
|
|
|
Mode uint32
|
|
|
|
|
// padding
|
|
|
|
|
_ uint32
|
|
|
|
|
}
|
2023-10-05 17:25:37 -07:00
|
|
|
|
|
|
|
|
// FUSEFlushIn is the request sent by the kernel to the daemon after a file is
|
|
|
|
|
// closed.
|
|
|
|
|
//
|
|
|
|
|
// +marshal
|
|
|
|
|
type FUSEFlushIn struct {
|
|
|
|
|
Fh uint64
|
|
|
|
|
_ uint32 // unused
|
|
|
|
|
_ uint32 // padding
|
|
|
|
|
LockOwner uint64
|
|
|
|
|
}
|