feat: full NFSv4.2 server and client in pure Go
Test / test (push) Successful in 2m4s
Release / gates (push) Successful in 2m5s
Release / build (amd64, freebsd) (push) Successful in 1m27s
Release / build (amd64, linux) (push) Successful in 1m22s
Release / build (amd64, netbsd) (push) Successful in 1m19s
Release / build (amd64, openbsd) (push) Successful in 1m20s
Release / build (arm64, darwin) (push) Successful in 1m21s
Release / build (arm64, freebsd) (push) Successful in 1m26s
Release / build (arm64, linux) (push) Successful in 1m25s
Release / build (arm64, netbsd) (push) Successful in 1m31s
Release / build (arm64, openbsd) (push) Successful in 1m27s
Release / build (loong64, linux) (push) Successful in 1m37s
Release / build (riscv64, linux) (push) Successful in 1m21s
Release / release (push) Successful in 40s
Test / test (push) Successful in 2m4s
Release / gates (push) Successful in 2m5s
Release / build (amd64, freebsd) (push) Successful in 1m27s
Release / build (amd64, linux) (push) Successful in 1m22s
Release / build (amd64, netbsd) (push) Successful in 1m19s
Release / build (amd64, openbsd) (push) Successful in 1m20s
Release / build (arm64, darwin) (push) Successful in 1m21s
Release / build (arm64, freebsd) (push) Successful in 1m26s
Release / build (arm64, linux) (push) Successful in 1m25s
Release / build (arm64, netbsd) (push) Successful in 1m31s
Release / build (arm64, openbsd) (push) Successful in 1m27s
Release / build (loong64, linux) (push) Successful in 1m37s
Release / build (riscv64, linux) (push) Successful in 1m21s
Release / release (push) Successful in 40s
Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -0,0 +1,256 @@
|
||||
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Package nfs4 carries the NFSv4.2 wire vocabulary: the program and
|
||||
// operation numbers, the error codes, the attribute table, and the
|
||||
// encoding of the COMPOUND procedure and its operations.
|
||||
//
|
||||
// The constants follow RFC 8881 and RFC 7862. Only operations implemented
|
||||
// here are named; the dispatcher answers everything else with
|
||||
// NFS4ERR_NOT_SUPP.
|
||||
package nfs4
|
||||
|
||||
// The NFS program of RFC 8881. Version 4 is the only RPC program version
|
||||
// the NFSv4 family uses; the minor version travels inside COMPOUND.
|
||||
const (
|
||||
Program = 100003
|
||||
Version = 4
|
||||
MinorVersion = 2
|
||||
|
||||
ProcNull = 0
|
||||
ProcCompound = 1
|
||||
)
|
||||
|
||||
// Operation numbers, RFC 8881 section 15. Operations 1 and 2 are unassigned.
|
||||
const (
|
||||
OpAccess = 3
|
||||
OpClose = 4
|
||||
OpCommit = 5
|
||||
OpCreate = 6
|
||||
OpDelegPurge = 7
|
||||
OpDelegReturn = 8
|
||||
OpGetattr = 9
|
||||
OpGetfh = 10
|
||||
OpLink = 11
|
||||
OpLock = 12
|
||||
OpLockt = 13
|
||||
OpLocku = 14
|
||||
OpLookup = 15
|
||||
OpLookupp = 16
|
||||
OpNverify = 17
|
||||
OpOpen = 18
|
||||
OpOpenattr = 19
|
||||
OpOpenConfirm = 20
|
||||
OpOpenDowngrade = 21
|
||||
OpPutfh = 22
|
||||
OpPutPubfh = 23
|
||||
OpPutRootfh = 24
|
||||
OpRead = 25
|
||||
OpReaddir = 26
|
||||
OpReadlink = 27
|
||||
OpRemove = 28
|
||||
OpRename = 29
|
||||
OpRenew = 30
|
||||
OpRestorefh = 31
|
||||
OpSavefh = 32
|
||||
OpSecinfo = 33
|
||||
OpSetattr = 34
|
||||
OpSetClientID = 35
|
||||
OpSetClientIDConfirm = 36
|
||||
OpVerify = 37
|
||||
OpWrite = 38
|
||||
OpReleaseLockOwner = 39
|
||||
OpBackchannelCtl = 40
|
||||
OpBindConnToSession = 41
|
||||
OpExchangeID = 42
|
||||
OpCreateSession = 43
|
||||
OpDestroySession = 44
|
||||
OpFreeStateid = 45
|
||||
OpGetDirDelegation = 46
|
||||
OpGetDeviceInfo = 47
|
||||
OpGetDeviceList = 48
|
||||
OpLayoutCommit = 49
|
||||
OpLayoutGet = 50
|
||||
OpLayoutReturn = 51
|
||||
OpSecinfoNoName = 52
|
||||
OpSequence = 53
|
||||
OpSetSsv = 54
|
||||
OpTestStateid = 55
|
||||
OpWantDelegation = 56
|
||||
OpDestroyClientID = 57
|
||||
OpReclaimComplete = 58
|
||||
OpAllocate = 59
|
||||
OpCopy = 60
|
||||
OpCopyNotify = 61
|
||||
OpDeallocate = 62
|
||||
OpIoAdvise = 63
|
||||
OpLayoutError = 64
|
||||
OpLayoutStats = 65
|
||||
OpOffloadCancel = 66
|
||||
OpOffloadStatus = 67
|
||||
OpReadPlus = 68
|
||||
OpSeek = 69
|
||||
OpWriteSame = 70
|
||||
OpClone = 71
|
||||
OpGetxattr = 72
|
||||
OpSetxattr = 73
|
||||
OpListxattr = 74
|
||||
OpRemovexattr = 75
|
||||
OpIllegal = 10044
|
||||
)
|
||||
|
||||
// NFS4ERR statuses. Every number here was verified against the error
|
||||
// table of RFC 8881 section 15.1; several plausible looking values are
|
||||
// wrong by a few dozen, which real clients answer with a mismatch.
|
||||
const (
|
||||
ErrOK = 0
|
||||
ErrPerm = 1
|
||||
ErrNoEnt = 2
|
||||
ErrIO = 5
|
||||
ErrNXIO = 6
|
||||
ErrAccess = 13
|
||||
ErrExist = 17
|
||||
ErrXDev = 18
|
||||
ErrNotDir = 20
|
||||
ErrIsDir = 21
|
||||
ErrInval = 22
|
||||
ErrFBig = 27
|
||||
ErrNoSpc = 28
|
||||
ErrROFS = 30
|
||||
ErrNameTooLong = 63
|
||||
ErrNotEmpty = 66
|
||||
ErrDQuot = 69
|
||||
ErrStale = 70
|
||||
ErrBadHandle = 10001
|
||||
ErrNotSupp = 10004
|
||||
ErrTooSmall = 10005
|
||||
ErrServerFault = 10006
|
||||
ErrBadType = 10007
|
||||
ErrDelay = 10008
|
||||
ErrSame = 10009
|
||||
ErrDenied = 10010
|
||||
ErrExpired = 10011
|
||||
ErrLocked = 10012
|
||||
ErrGrace = 10013
|
||||
ErrNoGrace = 10033
|
||||
ErrLocksHeld = 10037
|
||||
ErrFHExpired = 10014
|
||||
ErrShareDenied = 10015
|
||||
ErrWrongSec = 10016
|
||||
ErrClidInUse = 10017
|
||||
ErrResource = 10018
|
||||
ErrMoved = 10019
|
||||
ErrNoFileHandle = 10020
|
||||
ErrMinorVersMismatch = 10021
|
||||
ErrStaleClientID = 10022
|
||||
ErrOldStateid = 10024
|
||||
ErrBadStateid = 10025
|
||||
ErrBadSeqid = 10026
|
||||
ErrNotSame = 10027
|
||||
ErrAttrNotSupp = 10032
|
||||
ErrDeadLock = 10045
|
||||
ErrFileOpen = 10046
|
||||
ErrOpIllegal = 10044
|
||||
ErrBadName = 10041
|
||||
ErrBadSession = 10052
|
||||
ErrBadSlot = 10053
|
||||
ErrSequencePos = 10064
|
||||
ErrCompleteAlready = 10054
|
||||
ErrConnNotBound = 10055
|
||||
ErrNotOnlyOp = 10081
|
||||
ErrOpNotInSession = 10071
|
||||
ErrSeqMisordered = 10063
|
||||
ErrRetryUncachedRep = 10068
|
||||
ErrClientIDBusy = 10074
|
||||
ErrDeadSession = 10078
|
||||
ErrBadIOMode = 10049
|
||||
ErrBadLayout = 10050
|
||||
ErrNoMatchingLayout = 10060
|
||||
ErrUnknownLayoutType = 10062
|
||||
ErrPnfsNoLayout = 10080
|
||||
ErrNoXattr = 10095
|
||||
ErrXattr2Big = 10096
|
||||
ErrWrongType = 10083
|
||||
ErrBadOwner = 10093
|
||||
)
|
||||
|
||||
// Layout return kinds of the layoutreturn4 returntype switch, RFC 8881
|
||||
// section 18.44.
|
||||
const (
|
||||
ReturnFile = 1
|
||||
ReturnFsid = 2
|
||||
ReturnAll = 3
|
||||
)
|
||||
|
||||
// File types of the fattr4 type attribute.
|
||||
const (
|
||||
NF4Reg = 1
|
||||
NF4Dir = 2
|
||||
NF4Blk = 3
|
||||
NF4Chr = 4
|
||||
NF4Lnk = 5
|
||||
NF4Sock = 6
|
||||
NF4Fifo = 7
|
||||
)
|
||||
|
||||
// Access mask bits, RFC 8881 section 15.2.2.
|
||||
const (
|
||||
AccessRead = 1 << 0
|
||||
AccessLookup = 1 << 1
|
||||
AccessModify = 1 << 2
|
||||
AccessExtend = 1 << 3
|
||||
AccessDelete = 1 << 4
|
||||
AccessExec = 1 << 5
|
||||
)
|
||||
|
||||
// Write stability levels, RFC 8881 section 15.8. The server always answers
|
||||
// FILE_SYNC, so the client needs no replay bookkeeping.
|
||||
const (
|
||||
StableUnstable = 0
|
||||
StableDataSync = 1
|
||||
StableFileSync = 2
|
||||
)
|
||||
|
||||
// CREATE modes of the createhow4 union.
|
||||
const (
|
||||
CreateUnchecked = 0
|
||||
CreateGuarded = 1
|
||||
CreateExclusive = 2
|
||||
CreateExclusive1 = 3 // EXCLUSIVE4_1 of RFC 8881
|
||||
)
|
||||
|
||||
// File handle expiry classes. This server serves handles that survive as
|
||||
// long as the server process does.
|
||||
const (
|
||||
FH4Persistent = 0
|
||||
FH4VolatileAny = 1
|
||||
FH4VolatileMigrate = 2
|
||||
FH4VolatileNoMigrate = 3
|
||||
)
|
||||
|
||||
// A Stateid is the 16 byte state identifier of RFC 8881 section 8.2: a
|
||||
// 32 bit sequence number followed by a 12 byte other field. The all zero
|
||||
// stateid is the anonymous stateid.
|
||||
type Stateid [16]byte
|
||||
|
||||
// AllZero is the anonymous stateid: no lock state applies to the request.
|
||||
var AllZero Stateid
|
||||
|
||||
// Append appends the stateid to b in wire order.
|
||||
func (s Stateid) Append(b []byte) []byte {
|
||||
return append(b, s[:]...)
|
||||
}
|
||||
|
||||
// Security flavours a SECINFO answer names, the AUTH values of RFC 5531.
|
||||
const (
|
||||
SecFlavorNone = 0
|
||||
SecFlavorSys = 1
|
||||
SecFlavorGSS = 6
|
||||
)
|
||||
|
||||
// The secinfo_style4 styles of RFC 8881 section 18.44: the current file
|
||||
// handle, or its parent directory.
|
||||
const (
|
||||
StyleCurrentFH = 0 // SECINFO_STYLE4_CURRENT_FH
|
||||
StyleParent = 1 // SECINFO_STYLE4_PARENT
|
||||
)
|
||||
Reference in New Issue
Block a user