smoothfs

package module
v0.2.13 Latest Latest
Warning

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

Go to latest
Published: Jun 12, 2026 License: GPL-2.0 Imports: 15 Imported by: 0

README

smoothfs

smoothfs is the storage engine behind SmoothNAS tiering. It gives SmoothNAS one place to keep fast and slow data together while moving files between tiers automatically.

What people use it for:

  • keep hot data on SSD/NVMe and cold data on slower media
  • preserve familiar NFS/SMB/iSCSI behavior while storage placement is optimized
  • reduce cost without changing NAS workflows
  • provide safer movement with explicit state transitions and recovery paths

For SmoothNAS operators this means:

  • better performance where it matters
  • simpler storage growth on mixed hardware
  • predictable operations because active-LUN movement and recovery flows are explicit

Why it is useful

  • One namespace, multiple media classes: one mount path and one view for users.
  • Policy driven: heat + policy determines movement while preserving POSIX correctness.
  • Production-aware controls: quiesce/reconcile, movement logs, and explicit active-LUN workflow prevent surprise behavior.
  • Integrated package path: kernel module, userspace daemon, and support scripts are delivered in Debian artifacts for SmoothNAS deployments.

For SmoothNAS

SmoothNAS should consume this repository as an external component instead of duplicating its implementation.

  • kernel filesystem + movement engine: src/smoothfs
  • userspace control-plane: controlplane
  • API contracts: client.go, events.go, uapi.go, pools.go
  • operator docs and phased delivery notes: docs

Documentation

English:

Dutch:

Verification

go test ./...

Runtime behavior and kernel packaging tests are in src/smoothfs/test and are intended for prepared Linux hosts with matching kernel/filesystem/Samba/iSCSI prerequisites.

Repo layout

  • src/smoothfs: kernel module, DKMS, Samba VFS integration, and test harnesses
  • controlplane: planner/worker/recovery service logic
  • docs: operator and design documentation
  • tierd directory in SmoothNAS consumes these contracts

Documentation

Overview

Package smoothfs provides the low-coupling userspace contract for the smoothfs kernel module. It intentionally carries the generic-netlink client, event decoder, and managed-pool helpers that consumers can import as a versioned dependency.

Index

Constants

View Source
const (
	GenlFamilyName    = "smoothfs"
	GenlFamilyVersion = 1
	GenlMcastGroup    = "events"
	OIDLen            = 16
)
View Source
const (
	CmdUnspec         uint8 = 0
	CmdRegisterPool   uint8 = 1
	CmdPolicyPush     uint8 = 2
	CmdMovePlan       uint8 = 3
	CmdTierDown       uint8 = 4
	CmdReconcile      uint8 = 5
	CmdQuiesce        uint8 = 6
	CmdInspect        uint8 = 7
	CmdReprobe        uint8 = 8
	EventMountReady   uint8 = 9
	EventHeatSample   uint8 = 10
	EventMoveState    uint8 = 11
	EventTierFault    uint8 = 12
	CmdMoveCutover    uint8 = 13
	CmdRevokeMappings uint8 = 14
	EventSpill        uint8 = 15
)

Generic netlink commands. Keep in sync with src/smoothfs/uapi_smoothfs.h.

View Source
const (
	AttrUnspec             uint16 = 0
	AttrPoolUUID           uint16 = 1
	AttrPoolName           uint16 = 2
	AttrFSID               uint16 = 3
	AttrTierRank           uint16 = 4
	AttrTierCaps           uint16 = 5
	AttrTierPath           uint16 = 6
	AttrTierID             uint16 = 7
	AttrObjectID           uint16 = 8
	AttrGeneration         uint16 = 9
	AttrMovementState      uint16 = 10
	AttrCurrentTier        uint16 = 11
	AttrIntendedTier       uint16 = 12
	AttrTransactionSeq     uint16 = 13
	AttrPinState           uint16 = 14
	AttrHeatSampleBlob     uint16 = 15
	AttrCheckpointSeq      uint16 = 16
	AttrReconcileReason    uint16 = 17
	AttrTiers              uint16 = 18
	AttrRelPath            uint16 = 19
	AttrForce              uint16 = 20
	AttrSizeBytes          uint16 = 21
	AttrAnySpillSinceMount uint16 = 22
	AttrWriteSeq           uint16 = 23
	AttrRangeStaged        uint16 = 24
)

Generic netlink attributes. Keep in sync with src/smoothfs/uapi_smoothfs.h.

View Source
const DefaultMountBase = "/mnt/smoothfs"
View Source
const HeatSampleRecordSize = 56
View Source
const SystemdUnitDir = "/etc/systemd/system"

Variables

View Source
var ErrNotLoaded = errors.New("smoothfs kernel module not loaded")

ErrNotLoaded is returned by Open if the smoothfs kernel module is not loaded (the genetlink family doesn't exist).

Functions

func DestroyManagedPool

func DestroyManagedPool(p ManagedPool) error

func MountpointForPool

func MountpointForPool(base, name string) string

func RenderMountUnit

func RenderMountUnit(p ManagedPool) (string, error)

func UnitFilenameFor

func UnitFilenameFor(mountpoint string) string

func ValidatePoolName

func ValidatePoolName(name string) error

func ValidateTiers

func ValidateTiers(tiers []string) error

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a thin generic-netlink wrapper for the "smoothfs" family.

func Open

func Open() (*Client, error)

func (*Client) Close

func (c *Client) Close() error

func (*Client) Inspect

func (c *Client) Inspect(poolUUID uuid.UUID, oid [OIDLen]byte) (*InspectResult, error)

func (*Client) MoveCutover

func (c *Client) MoveCutover(poolUUID uuid.UUID, oid [OIDLen]byte, seq uint64) error

func (*Client) MoveCutoverVerifyWriteSeq

func (c *Client) MoveCutoverVerifyWriteSeq(poolUUID uuid.UUID, oid [OIDLen]byte, seq, writeSeq uint64) error

func (*Client) MovePlan

func (c *Client) MovePlan(poolUUID uuid.UUID, oid [OIDLen]byte, destTier uint8, seq uint64) error

func (*Client) MovePlanForce

func (c *Client) MovePlanForce(poolUUID uuid.UUID, oid [OIDLen]byte, destTier uint8, seq uint64, force bool) error

func (*Client) Quiesce

func (c *Client) Quiesce(poolUUID uuid.UUID) error

func (*Client) Receive

func (c *Client) Receive() ([]genetlink.Message, error)

func (*Client) Reconcile

func (c *Client) Reconcile(poolUUID uuid.UUID, reason string) error

func (*Client) RevokeMappings

func (c *Client) RevokeMappings(poolUUID uuid.UUID, oid [OIDLen]byte) error

type CreateManagedPoolRequest

type CreateManagedPoolRequest struct {
	Name      string
	UUID      uuid.UUID
	Tiers     []string
	MountBase string
}

type Event

type Event struct {
	PoolUUID           uuid.UUID
	Type               uint8
	PoolName           string
	AnySpillSinceMount bool
	HeatSamples        []HeatSampleRecord
	Tiers              []MountedTier
	Move               *MoveStateEvent
	Tier               *TierFaultEvent
	Spill              *SpillEvent
}

Event is the tagged union of multicast messages from the kernel.

func DecodeEvent

func DecodeEvent(msg genetlink.Message) (*Event, error)

type HeatSampleRecord

type HeatSampleRecord struct {
	OID            [OIDLen]byte
	OpenCountDelta uint32

	ReadBytesDelta  uint64
	WriteBytesDelta uint64
	LastAccessNS    uint64
	SampleWindowNS  uint64
	// contains filtered or unexported fields
}

HeatSampleRecord matches the 56-byte on-wire layout in uapi_smoothfs.h.

type InspectResult

type InspectResult struct {
	OID             [OIDLen]byte
	CurrentTier     uint8
	IntendedTier    uint8
	MovementState   MovementState
	PinState        PinState
	Generation      uint32
	WriteSeq        uint64
	HasWriteSeq     bool
	RangeStaged     bool
	TransactionSeq  uint64
	RelPath         string
	CurrentTierPath string
}

type ManagedPool

type ManagedPool struct {
	Name       string    `json:"name"`
	UUID       uuid.UUID `json:"uuid"`
	Tiers      []string  `json:"tiers"`
	Mountpoint string    `json:"mountpoint"`
	UnitPath   string    `json:"unit_path"`
}

func CreateManagedPool

func CreateManagedPool(req CreateManagedPoolRequest) (*ManagedPool, error)

type MountedTier

type MountedTier struct {
	Rank uint8
	Path string
	Caps uint32
}

type MoveStateEvent

type MoveStateEvent struct {
	OID            [OIDLen]byte
	NewState       MovementState
	TransactionSeq uint64
}

type MovementState

type MovementState string

MovementState mirrors the on-disk movement_state CHECK column + kernel-internal enum.

const (
	StatePlaced              MovementState = "placed"
	StatePlanAccepted        MovementState = "plan_accepted"
	StateDestinationReserved MovementState = "destination_reserved"
	StateCopyInProgress      MovementState = "copy_in_progress"
	StateCopyComplete        MovementState = "copy_complete"
	StateCopyVerified        MovementState = "copy_verified"
	StateCutoverInProgress   MovementState = "cutover_in_progress"
	StateSwitched            MovementState = "switched"
	StateCleanupInProgress   MovementState = "cleanup_in_progress"
	StateCleanupComplete     MovementState = "cleanup_complete"
	StateFailed              MovementState = "failed"
	StateStale               MovementState = "stale"
)

type PinState

type PinState string

PinState mirrors the on-disk pin_state CHECK column.

const (
	PinNone     PinState = "none"
	PinHot      PinState = "pin_hot"
	PinCold     PinState = "pin_cold"
	PinHardlink PinState = "pin_hardlink"
	PinLease    PinState = "pin_lease"
	PinLUN      PinState = "pin_lun"
)

type SpillEvent

type SpillEvent struct {
	OID        [OIDLen]byte
	SourceTier uint8
	DestTier   uint8
	SizeBytes  uint64
}

type TierFaultEvent

type TierFaultEvent struct {
	TierRank uint8
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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