fs

package module
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 10, 2026 License: BSD-3-Clause Imports: 2 Imported by: 0

README

go-virtio/fs

Pure-Go virtio-fs (FUSE-over-virtio) guest driver targeting the go-virtio/common transport interfaces. Implements the modern-transport (Virtio 1.0+) init sequence, the request virtqueue, and the FUSE-over-virtio wire framing for the standard PCI-bound virtio-fs device (VID 0x1AF4, DID 0x105A — device type 26).

CGO=0, no architecture-specific assembly, 100% statement test coverage.

Scope

Like go-virtio/blk this package owns device bring-up, a request virtqueue, and the on-the-wire request format. For virtio-fs the request format is a FUSE message carried as a descriptor chain (Virtio 1.2 §5.11.6):

readable descriptors : [ struct fuse_in_header  | op-specific in-args  ]
writable descriptors : [ struct fuse_out_header | op-specific out-args ]

The driver exposes a read-write mount closure, each op cited from Linux include/uapi/linux/fuse.h.

Read-side ops:

Method FUSE opcode in-args / out-args
Init() FUSE_INIT (26) fuse_init_infuse_init_out (major 7 nego.)
Lookup(parent, name)Entry FUSE_LOOKUP (1) NUL-terminated name → fuse_entry_out
GetAttr(nodeid)Attr FUSE_GETATTR (3) fuse_getattr_infuse_attr_out
Open(nodeid)fh FUSE_OPEN (14) fuse_open_in (O_RDONLY) → fuse_open_out
Read(nodeid, fh, off, size)[]byte FUSE_READ (15) fuse_read_in → raw bytes
Release(nodeid, fh) FUSE_RELEASE (18) fuse_release_in → (no out-args)
Forget(nodeid, nlookup) FUSE_FORGET (2) fuse_forget_in → (no reply at all)
Destroy() FUSE_DESTROY (38) (no in-args) → (no out-args)

Write-side ops (added in v0.2.0):

Method FUSE opcode in-args / out-args
OpenRW(nodeid, flags)fh FUSE_OPEN (14) fuse_open_in (O_WRONLY/O_RDWR) → fuse_open_out
Write(nodeid, fh, off, data)n FUSE_WRITE (16) fuse_write_in + data region (3-region chain) → fuse_write_out
Create(parent, name, mode, flags)(Entry, fh) FUSE_CREATE (35) fuse_create_in + name → fuse_entry_outfuse_open_out
Mkdir(parent, name, mode)Entry FUSE_MKDIR (9) fuse_mkdir_in + name → fuse_entry_out
Mknod(parent, name, mode, rdev)Entry FUSE_MKNOD (8) fuse_mknod_in + name → fuse_entry_out
Symlink(parent, name, target)Entry FUSE_SYMLINK (6) name + target → fuse_entry_out
Link(oldnodeid, newparent, newname)Entry FUSE_LINK (13) fuse_link_in + name → fuse_entry_out
SetAttr(nodeid, SetAttrIn)Attr FUSE_SETATTR (4) fuse_setattr_in (FATTR_* mask) → fuse_attr_out
Unlink(parent, name) FUSE_UNLINK (10) name → (error-only)
Rmdir(parent, name) FUSE_RMDIR (11) name → (error-only)
Rename(oldparent, old, newparent, new) FUSE_RENAME (12) fuse_rename_in + old + new → (error-only)
Fsync(nodeid, fh, datasync) FUSE_FSYNC (20) fuse_fsync_in → (error-only)
Flush(nodeid, fh) FUSE_FLUSH (25) fuse_flush_in → (error-only)

SetAttr covers truncate (FattrSize), chmod (FattrMode), chown (FattrUID/FattrGID) and utimes (FattrAtime/FattrMtime) via the fuse_setattr_in.valid mask. FUSE_WRITE is the only op whose request is a three-region descriptor chain — readable [fuse_in_header | fuse_write_in], readable [data], writable [fuse_out_header | fuse_write_out]; all other ops keep the two-region read/write split.

The FUSE protocol major is 7; the minor is negotiated down to whatever the device offers in FUSE_INIT. The FUSE_INIT request also proposes the two write-relevant protocol flags FUSE_BIG_WRITES (1<<5, permit multi-page write data regions) and FUSE_ATOMIC_O_TRUNC (1<<3, atomic O_TRUNC on open/create); the negotiated intersection is recorded in VirtioFS.FuseFlags. FUSE_WRITEBACK_CACHE is deliberately not negotiated (it shifts page-cache writeback to the kernel, which this raw request driver does not implement).

Queues

Queue 0 is the hiprio queue (FUSE_FORGET / FUSE_INTERRUPT fast-path); queues 1..num_request_queues are the request queues (Virtio 1.2 §5.11.2). This driver submits every request on the first request queue (index 1) and does not use the hiprio queue.

Device config

virtio_fs_config (Linux virtio_fs.h) is char tag[36] followed by __le32 num_request_queues; both are read at OpenVirtioFS into VirtioFS.Tag (trailing NULs trimmed) and VirtioFS.NumRequestQueues.

Quick start

import virtiofs "github.com/go-virtio/fs"

// transport is any value that implements go-virtio/common.Transport.
fs, err := virtiofs.OpenVirtioFS(transport)
if err != nil { return err }
if err := fs.Init(); err != nil { return err } // FUSE_INIT handshake

// Read /hello.txt from the shared dir (root nodeid is always 1).
e, err := fs.Lookup(1, "hello.txt")
if err != nil { return err }
fh, err := fs.Open(e.NodeID)
if err != nil { return err }
data, err := fs.Read(e.NodeID, fh, 0, uint32(e.Attr.Size))
if err != nil { return err }
_ = fs.Release(e.NodeID, fh)
fmt.Printf("%s\n", data)

// Create + write a new file, then truncate + fsync + close it.
ne, wfh, err := fs.Create(1, "out.txt", 0o100644, virtiofs.OpenReadWrite)
if err != nil { return err }
n, err := fs.Write(ne.NodeID, wfh, 0, []byte("written via virtio-fs"))
if err != nil { return err }
_, err = fs.SetAttr(ne.NodeID, virtiofs.SetAttrIn{Valid: virtiofs.FattrSize, Size: uint64(n)})
if err != nil { return err }
if err := fs.Fsync(ne.NodeID, wfh, false); err != nil { return err }
_ = fs.Flush(ne.NodeID, wfh)
_ = fs.Release(ne.NodeID, wfh)

Device-ID centralization

Per the org convention, virtio device IDs live in go-virtio/common. This driver consumes them from common v0.1.5, which centralizes DeviceTypeFS (26), PCIDeviceIDModernFS (0x105A) and PCIDeviceIDIsFS alongside the other DeviceType* / PCIDeviceIDModern* constants.

Tests

GOWORK=off go test -cover ./...   # 100.0% of statements

White-box tests drive a fake common.Transport (fakeFSDevice) that serves canned FUSE replies, plus an injection harness (injectTransport) that fails each transport touch-point to exercise every error branch.

References

  • Virtio 1.2 §5.11 "File System Device".
  • Linux include/uapi/linux/virtio_fs.hstruct virtio_fs_config.
  • Linux include/uapi/linux/virtio_ids.hVIRTIO_ID_FS = 26.
  • Linux include/uapi/linux/fuse.h — every FUSE struct + opcode.

Documentation

Overview

Package fs is a pure-Go virtio-fs (FUSE-over-virtio) guest driver. It drives a modern (Virtio 1.0+) PCI virtio-fs device through the transport interfaces defined in github.com/go-virtio/common; the same code drives a UEFI-backed device, a bare-metal device, or a virtio-mmio device depending on which common.Transport implementation the caller supplies.

Scope — this package owns device bring-up, the request virtqueue, the FUSE-over-virtio descriptor-chain framing (readable [fuse_in_header | in-args], writable [fuse_out_header | out-args]; Virtio 1.2 §5.11), and a read-write mount closure: Init, Lookup, GetAttr, Open/OpenRW, Read, Write, Create, Mkdir, Mknod, Symlink, Link, SetAttr, Unlink, Rmdir, Rename, Fsync, Flush, Release, Forget, Destroy. FUSE_WRITE carries its data in an extra readable descriptor (a three-region chain); every other op keeps the two-region read/write split.

  • Modern transport (VIRTIO_F_VERSION_1 mandatory). Legacy devices are rejected by the common init sequence.
  • Queue 0 is the hiprio queue; queues 1..num_request_queues are the request queues (Virtio 1.2 §5.11.2). This driver issues all FUSE requests on the first request queue (index 1) and does not use the hiprio queue (no FUSE_INTERRUPT / FUSE_FORGET fast-path needed here; FUSE_FORGET is submitted on the request queue).
  • No virtio feature bit beyond VIRTIO_F_VERSION_1 is negotiated. (VIRTIO_FS_F_NOTIFICATION exists but is not required for the request path.)

The FUSE protocol itself is versioned independently of virtio: this driver speaks FUSE major 7 and negotiates the minor down to whatever the device offers (FUSE_INIT, Linux fuse.h).

References:

  • Virtio 1.2 §5.11 "File System Device" — device-type 26 binding, virtio_fs_config (tag[36] + le32 num_request_queues), queue layout (hiprio + request queues).
  • Linux include/uapi/linux/virtio_fs.h — struct virtio_fs_config.
  • Linux include/uapi/linux/virtio_ids.h — VIRTIO_ID_FS = 26.
  • Linux include/uapi/linux/fuse.h — every FUSE wire struct + opcode cited at its use site below (FUSE_KERNEL_VERSION = 7).
  • Virtio 1.1 §3.1.1 "Device Initialization" — the status-bit choreography (shared with blk/net/console via common).

Index

Constants

View Source
const (
	FuseOpLookup  uint32 = 1
	FuseOpForget  uint32 = 2
	FuseOpGetattr uint32 = 3
	FuseOpSetattr uint32 = 4
	FuseOpSymlink uint32 = 6
	FuseOpMknod   uint32 = 8
	FuseOpMkdir   uint32 = 9
	FuseOpUnlink  uint32 = 10
	FuseOpRmdir   uint32 = 11
	FuseOpRename  uint32 = 12
	FuseOpLink    uint32 = 13
	FuseOpOpen    uint32 = 14
	FuseOpRead    uint32 = 15
	FuseOpWrite   uint32 = 16
	FuseOpRelease uint32 = 18
	FuseOpFsync   uint32 = 20
	FuseOpFlush   uint32 = 25
	FuseOpInit    uint32 = 26
	FuseOpCreate  uint32 = 35
	FuseOpDestroy uint32 = 38
)

FUSE opcodes (Linux fuse.h: enum fuse_opcode). The read-only mount subset plus the read-write closure.

View Source
const (
	FattrMode     uint32 = 1 << 0  // FATTR_MODE      (chmod)
	FattrUID      uint32 = 1 << 1  // FATTR_UID       (chown user)
	FattrGID      uint32 = 1 << 2  // FATTR_GID       (chown group)
	FattrSize     uint32 = 1 << 3  // FATTR_SIZE      (truncate)
	FattrAtime    uint32 = 1 << 4  // FATTR_ATIME     (utimes access)
	FattrMtime    uint32 = 1 << 5  // FATTR_MTIME     (utimes modify)
	FattrFh       uint32 = 1 << 6  // FATTR_FH        (fh field valid)
	FattrAtimeNow uint32 = 1 << 7  // FATTR_ATIME_NOW
	FattrMtimeNow uint32 = 1 << 8  // FATTR_MTIME_NOW
	FattrCtime    uint32 = 1 << 10 // FATTR_CTIME
)

FUSE_SETATTR valid-mask bits (Linux fuse.h: FATTR_*). The `valid` field of fuse_setattr_in selects which attributes the request changes.

View Source
const (
	OpenReadOnly  uint32 = 0 // O_RDONLY
	OpenWriteOnly uint32 = 1 // O_WRONLY
	OpenReadWrite uint32 = 2 // O_RDWR
)

Open-flag values for Open/OpenRW/Create (the POSIX open(2) access modes, Linux asm-generic/fcntl.h: O_RDONLY/O_WRONLY/O_RDWR). FUSE passes them through verbatim in fuse_open_in.flags / fuse_create_in.flags.

View Source
const (
	FuseBigWrites     uint32 = 1 << 5  // FUSE_BIG_WRITES
	FuseAtomicOTrunc  uint32 = 1 << 3  // FUSE_ATOMIC_O_TRUNC
	FuseWritebackCach uint32 = 1 << 16 // FUSE_WRITEBACK_CACHE (not negotiated)
)

FUSE_INIT flag bits (Linux fuse.h: FUSE_*), the protocol-level feature handshake carried in fuse_init_in.flags / fuse_init_out.flags (independent of the virtio feature bits). The read-write closure proposes the two that affect write semantics:

  • FUSE_BIG_WRITES (1<<5): the kernel/guest may send writes larger than one page. virtiofsd assumes it at FUSE 7.x; we set it so the Write op is permitted to carry multi-page data regions.
  • FUSE_ATOMIC_O_TRUNC (1<<3): O_TRUNC is handled atomically by the OPEN/CREATE op itself (no separate SETATTR-size-0). Required for a correct OpenRW(...O_TRUNC)/Create truncating open.

FUSE_WRITEBACK_CACHE (1<<16) is deliberately NOT negotiated: it shifts page-cache writeback responsibility to the kernel and is a host/guest page-cache optimization this raw request driver does not implement.

View Source
const AcceptedFeatures uint64 = common.FeatureVersion1

AcceptedFeatures is the feature mask the driver negotiates ON — only the non-negotiable VIRTIO_F_VERSION_1.

FuseInitFlags is the fuse_init_in.flags mask the driver proposes (the device intersects it with its own). Only write-relevant bits are set.

View Source
const FuseKernelMinorVersion uint32 = 31

FuseKernelMinorVersion is the FUSE minor version the driver proposes in FUSE_INIT; the negotiated minor is min(proposed, device-offered) (Linux fuse.h: FUSE_KERNEL_MINOR_VERSION). We propose a conservative 31 (the baseline virtiofsd requires) and accept whatever the device reports back.

View Source
const FuseKernelVersion uint32 = 7

FuseKernelVersion is the FUSE major protocol version this driver speaks (Linux fuse.h: FUSE_KERNEL_VERSION = 7).

View Source
const HiprioQueueIdx uint16 = 0

HiprioQueueIdx is the index of the hiprio queue (queue 0) — used for FUSE_FORGET / FUSE_INTERRUPT priority requests (Virtio 1.2 §5.11.2). This read-only driver does not submit on it.

View Source
const RequestQueueIdx uint16 = 1

RequestQueueIdx is the index of the first request queue. Queue 0 is hiprio; request queues start at index 1 (Virtio 1.2 §5.11.2).

View Source
const RequestQueueSize uint16 = 16

RequestQueueSize is the desired ring size (clamped + rounded during setup). A FUSE request consumes 2–4 descriptors; the driver issues them one at a time.

View Source
const TxPollIterations = 200000

TxPollIterations is the default busy-poll budget for one request.

Variables

View Source
var (
	ErrNotModernDevice   = fsError("go-virtio/fs: device doesn't offer VIRTIO_F_VERSION_1 (legacy-only)")
	ErrFeaturesNotOK     = fsError("go-virtio/fs: FEATURES_OK status bit didn't stick after DriverFeature write")
	ErrInitWrongDeviceID = fsError("go-virtio/fs: PCI device ID is not 0x105A (modern virtio-fs device)")
	ErrQueueNotAvailable = fsError("go-virtio/fs: device reports QueueSize=0 for the request queue")
	ErrRequestTimeout    = fsError("go-virtio/fs: request poll timeout (device did not complete the request)")
	ErrFuseError         = fsError("go-virtio/fs: device returned a non-zero fuse_out_header.error")
	ErrFuseVersion       = fsError("go-virtio/fs: device FUSE major version is not 7")
	ErrShortReply        = fsError("go-virtio/fs: device wrote fewer reply bytes than the op requires")
	ErrNoEntry           = fsError("go-virtio/fs: FUSE_LOOKUP returned nodeid 0 (no such entry)")
	ErrZeroSize          = fsError("go-virtio/fs: Read/Write size must be positive")
	ErrShortWrite        = fsError("go-virtio/fs: device accepted fewer bytes than requested (short write)")
)

Sentinel errors for the virtio-fs path.

Functions

func AcceptFeatures

func AcceptFeatures(deviceFeatures uint64) (uint64, error)

AcceptFeatures returns the negotiated mask (requires VERSION_1).

Types

type Attr

type Attr struct {
	Ino   uint64 // inode number
	Size  uint64 // file size in bytes
	Mode  uint32 // st_mode (type + permission bits)
	Nlink uint32 // link count
}

Attr is the decoded subset of FUSE fuse_attr (Linux fuse.h) the read-only mount surface exposes. Only the fields a caller needs to stat + read a file are decoded.

func ParseAttr

func ParseAttr(b []byte) Attr

ParseAttr decodes the subset of a 92-byte FUSE fuse_attr (Linux fuse.h) the read-only surface exposes. `b` MUST be at least fuseAttrSize bytes (callers slice exactly that).

type Entry

type Entry struct {
	NodeID uint64 // nodeid to use in subsequent ops (0 = negative lookup)
	Attr   Attr
}

Entry is the decoded result of a FUSE_LOOKUP (fuse_entry_out): the node id assigned to the looked-up name plus its attributes.

type SetAttrIn added in v0.2.0

type SetAttrIn struct {
	Valid uint32 // FATTR_* mask selecting which fields below are live
	Fh    uint64 // open handle (only if FattrFh set in Valid)
	Size  uint64 // new size (truncate; FattrSize)
	Mode  uint32 // new st_mode (chmod; FattrMode)
	UID   uint32 // new owner uid (FattrUID)
	GID   uint32 // new owner gid (FattrGID)
	Atime uint64 // access time, seconds (FattrAtime)
	Mtime uint64 // modify time, seconds (FattrMtime)
}

SetAttrIn carries the fuse_setattr_in fields the caller wants to change for SetAttr. Only fields flagged in Valid (FATTR_* bits) are applied by the device; the others are ignored.

type VirtioFS

type VirtioFS struct {
	// Cfg is the modern-transport handle.
	Cfg *common.ModernConfig

	// Tag is the virtio_fs_config mount tag (Virtio 1.2 §5.11.5), the
	// name the guest mounts ("-o tag"). Trailing NULs are trimmed.
	Tag string

	// NumRequestQueues is the device-advertised request-queue count
	// (virtio_fs_config.num_request_queues).
	NumRequestQueues uint32

	// NegotiatedFeatures records the virtio feature handshake result.
	NegotiatedFeatures uint64

	// FuseMajor / FuseMinor record the negotiated FUSE protocol version
	// (populated by Init).
	FuseMajor uint32
	FuseMinor uint32

	// FuseFlags records the negotiated FUSE_INIT flags (the intersection
	// of FuseInitFlags and the device-offered fuse_init_out.flags),
	// populated by Init.
	FuseFlags uint32
	// contains filtered or unexported fields
}

VirtioFS wraps one initialised virtio-fs device.

func OpenVirtioFS

func OpenVirtioFS(t common.Transport) (*VirtioFS, error)

OpenVirtioFS drives the full bring-up of one virtio-fs device:

  1. Verify the PCI device ID is 0x105A (modern virtio-fs).
  2. InitModernConfig walks PCI caps + populates the BAR locators.
  3. Reset → ACK → DRIVER status progression.
  4. Read DeviceFeature, require VERSION_1, mask, write DriverFeature.
  5. Set FEATURES_OK, verify it stuck.
  6. Read virtio_fs_config (tag + num_request_queues).
  7. Allocate + publish the first request queue (index 1).
  8. DRIVER_OK status.

The caller next calls Init() to perform the FUSE_INIT handshake.

func (*VirtioFS) Create added in v0.2.0

func (f *VirtioFS) Create(parent uint64, name string, mode, flags uint32) (Entry, uint64, error)

Create performs FUSE_CREATE (Linux fuse.h, opcode 35) in directory `parent`: an atomic create+open of `name` with `mode` (st_mode incl. type/perm bits) and access `flags` (OpenWriteOnly/OpenReadWrite, OR-ed with create-time flags such as O_EXCL). The in-args are fuse_create_in{flags, mode, umask, open_flags} followed by the NUL-terminated name; the reply is fuse_entry_out immediately followed by fuse_open_out. Returns the new Entry and the open file handle.

func (*VirtioFS) Destroy

func (f *VirtioFS) Destroy() error

Destroy performs FUSE_DESTROY (Linux fuse.h, opcode 38), tearing down the FUSE session. No in-args; the device writes a fuse_out_header with no out-args.

func (*VirtioFS) Flush added in v0.2.0

func (f *VirtioFS) Flush(nodeid, fh uint64) error

Flush performs FUSE_FLUSH (Linux fuse.h, opcode 25) on (nodeid, fh), issued on each close(2) of a duplicated handle (one per open). The in-args are fuse_flush_in{fh, unused, padding, lock_owner}; error-only reply.

func (*VirtioFS) Forget

func (f *VirtioFS) Forget(nodeid uint64, nlookup uint64) error

Forget performs FUSE_FORGET (Linux fuse.h, opcode 2) on `nodeid`, telling the device to drop `nlookup` references to the node. in-args are fuse_forget_in{nlookup}. FUSE_FORGET has no reply at all (the device does not write a fuse_out_header), so this submits the request and reclaims without awaiting out-args.

func (*VirtioFS) Fsync added in v0.2.0

func (f *VirtioFS) Fsync(nodeid, fh uint64, datasync bool) error

Fsync performs FUSE_FSYNC (Linux fuse.h, opcode 20) on (nodeid, fh), flushing the file's data (and, unless datasync, metadata) to stable storage. `datasync` true sets fsync_flags bit 0 (FUSE_FSYNC_FDATASYNC). The in-args are fuse_fsync_in{fh, fsync_flags, padding}; error-only reply.

func (*VirtioFS) GetAttr

func (f *VirtioFS) GetAttr(nodeid uint64) (Attr, error)

GetAttr performs FUSE_GETATTR (Linux fuse.h, opcode 3) on `nodeid`. in-args are fuse_getattr_in{getattr_flags=0, dummy=0, fh=0} (a path-based getattr, no open handle). The reply is fuse_attr_out{attr_valid, attr_valid_nsec, dummy, attr}.

func (*VirtioFS) Init

func (f *VirtioFS) Init() error

Init performs the FUSE_INIT handshake (Linux fuse.h, opcode 26). It sends fuse_init_in{major=7, minor, max_readahead, flags} on nodeid 0 and parses fuse_init_out{major, minor, ...}, recording the negotiated version. Returns ErrFuseVersion if the device reports a major other than 7 (the only major this driver speaks).

func (f *VirtioFS) Link(oldnodeid, newparent uint64, newname string) (Entry, error)

Link performs FUSE_LINK (Linux fuse.h, opcode 13): create a hard link `newname` in directory `newparent` pointing at the existing node `oldnodeid`. The in-args are fuse_link_in{oldnodeid} followed by the NUL-terminated new name; the reply is fuse_entry_out.

func (*VirtioFS) Lookup

func (f *VirtioFS) Lookup(parent uint64, name string) (Entry, error)

Lookup performs FUSE_LOOKUP (Linux fuse.h, opcode 1): resolve `name` within directory node `parent`. The in-args are the NUL-terminated name; the reply is fuse_entry_out{nodeid, ..., attr}. A nodeid of 0 means a negative lookup (name does not exist) — returned as ErrNoEntry.

func (*VirtioFS) Mkdir added in v0.2.0

func (f *VirtioFS) Mkdir(parent uint64, name string, mode uint32) (Entry, error)

Mkdir performs FUSE_MKDIR (Linux fuse.h, opcode 9) in directory `parent`, creating subdirectory `name` with permission bits `mode`. The in-args are fuse_mkdir_in{mode, umask} followed by the NUL-terminated name; the reply is fuse_entry_out for the new directory.

func (*VirtioFS) Mknod added in v0.2.0

func (f *VirtioFS) Mknod(parent uint64, name string, mode, rdev uint32) (Entry, error)

Mknod performs FUSE_MKNOD (Linux fuse.h, opcode 8) in directory `parent`, creating a non-directory node `name` with st_mode `mode` (type bits select regular file / fifo / socket / device) and device number `rdev` (0 for non-device nodes). The in-args are fuse_mknod_in{mode, rdev, umask, padding} followed by the NUL-terminated name; the reply is fuse_entry_out.

func (*VirtioFS) Open

func (f *VirtioFS) Open(nodeid uint64) (uint64, error)

Open performs FUSE_OPEN (Linux fuse.h, opcode 14) on `nodeid`, read-only. It is unchanged from the read-only closure (flags = O_RDONLY); the returned fh is used in Read/Release.

func (*VirtioFS) OpenRW added in v0.2.0

func (f *VirtioFS) OpenRW(nodeid uint64, flags uint32) (uint64, error)

OpenRW performs FUSE_OPEN (Linux fuse.h, opcode 14) on `nodeid` with an explicit access mode in `flags` (OpenReadOnly / OpenWriteOnly / OpenReadWrite, optionally OR-ed with other open(2) flags such as O_TRUNC). The in-args are fuse_open_in{flags, open_flags}; the reply is fuse_open_out{fh, open_flags, backing_id}; the returned fh is used in Read/Write/Fsync/Flush/Release.

func (*VirtioFS) Read

func (f *VirtioFS) Read(nodeid, fh, off uint64, size uint32) ([]byte, error)

Read performs FUSE_READ (Linux fuse.h, opcode 15) on (nodeid, fh), reading up to `size` bytes at byte offset `off`. The in-args are fuse_read_in{fh, offset, size, read_flags, lock_owner, flags, padding}; the reply is raw file bytes (no out-args struct — the device writes the data directly after fuse_out_header). The returned slice length is min(size, bytes-available) — a short read at EOF.

func (*VirtioFS) Release

func (f *VirtioFS) Release(nodeid, fh uint64) error

Release performs FUSE_RELEASE (Linux fuse.h, opcode 18) on (nodeid, fh), closing the open handle. in-args are fuse_release_in{fh, flags, release_flags, lock_owner}; there are no out-args.

func (*VirtioFS) Rename added in v0.2.0

func (f *VirtioFS) Rename(oldparent uint64, oldname string, newparent uint64, newname string) error

Rename performs FUSE_RENAME (Linux fuse.h, opcode 12): move/rename `oldname` in directory `oldparent` to `newname` in directory `newparent`. The in-args are fuse_rename_in{newdir} followed by the NUL-terminated oldname and the NUL-terminated newname; the reply is error-only.

func (*VirtioFS) RequestQueue

func (f *VirtioFS) RequestQueue() *common.Virtqueue

RequestQueue exposes the request virtqueue handle for diagnostics.

func (*VirtioFS) Rmdir added in v0.2.0

func (f *VirtioFS) Rmdir(parent uint64, name string) error

Rmdir performs FUSE_RMDIR (Linux fuse.h, opcode 11): remove the empty subdirectory `name` from directory `parent`. The in-args are the NUL-terminated name; the reply is error-only.

func (*VirtioFS) SetAttr added in v0.2.0

func (f *VirtioFS) SetAttr(nodeid uint64, in SetAttrIn) (Attr, error)

SetAttr performs FUSE_SETATTR (Linux fuse.h, opcode 4) on `nodeid`, changing the attributes selected by in.Valid (truncate via FattrSize, chmod via FattrMode, chown via FattrUID/FattrGID, utimes via FattrAtime/FattrMtime, etc.). The in-args are fuse_setattr_in; the reply is fuse_attr_out, returned as the updated Attr.

func (f *VirtioFS) Symlink(parent uint64, name, target string) (Entry, error)

Symlink performs FUSE_SYMLINK (Linux fuse.h, opcode 6) in directory `parent`, creating symlink `name` whose target is `target`. FUSE_SYMLINK has no fixed in-args struct: the in-args are the NUL-terminated link name followed by the NUL-terminated target. The reply is fuse_entry_out.

func (f *VirtioFS) Unlink(parent uint64, name string) error

Unlink performs FUSE_UNLINK (Linux fuse.h, opcode 10): remove the non-directory entry `name` from directory `parent`. The in-args are the NUL-terminated name; the reply is error-only (no out-args).

func (*VirtioFS) Write added in v0.2.0

func (f *VirtioFS) Write(nodeid, fh, off uint64, data []byte) (int, error)

Write performs FUSE_WRITE (Linux fuse.h, opcode 16) on (nodeid, fh), writing `data` at byte offset `off`. The request is a THREE-region chain (Virtio 1.2 §5.11.6): readable [fuse_in_header | fuse_write_in], readable [data], writable [fuse_out_header | fuse_write_out]. The reply fuse_write_out{size, padding} reports the bytes the device accepted; Write returns that count and ErrShortWrite if it is less than len(data).

fuse_write_in (Linux fuse.h): fh, offset, size, write_flags, lock_owner, flags, padding.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL