// Copyright (c) 2026 Petr BalvĂ­n (https://petrbalvin.org) // SPDX-License-Identifier: MIT // The codecs of the remaining NFSv4.1 operations: the parent lookups, the // attribute comparisons, the lock owner release and the session binding // family. package nfs4 import ( "sourcedock.dev/petrbalvin/nfs/internal/xdr" ) // Connection direction and binding values of the CREATE_SESSION and // BIND_CONN_TO_SESSION channel directory, RFC 8881 section 2.10.1. const ( Cdfc4Fore = 1 Cdfc4Back = 2 Cdfc4ForeOrBoth = 3 Cdfc4BackOrBoth = 7 Cdfs4Fore = 1 Cdfs4Back = 2 Cdfs4Both = 3 Cdfs4Arrow = 4 ) // AppendLookupp appends the LOOKUPP argop, which carries no arguments. func AppendLookupp(b []byte) []byte { return xdr.AppendUint32(b, OpLookupp) } // AppendPutPubfh appends the PUTPUBFH argop, which carries no arguments. func AppendPutPubfh(b []byte) []byte { return xdr.AppendUint32(b, OpPutPubfh) } // AppendVerifyArgs appends the VERIFY argop: the attributes the file must // carry for the compound to proceed. NVERIFY shares the shape and demands // the opposite. func AppendVerifyArgs(b []byte, request Bitmap, a Attrs) []byte { b = xdr.AppendUint32(b, OpVerify) return AppendFattr(b, request, a) } // AppendNverifyArgs appends the NVERIFY argop: the attributes the file // must not carry. func AppendNverifyArgs(b []byte, request Bitmap, a Attrs) []byte { b = xdr.AppendUint32(b, OpNverify) return AppendFattr(b, request, a) } // AppendReleaseLockOwnerArgs appends the RELEASE_LOCKOWNER argop: the // client whose lock owner dies and the owner itself. func AppendReleaseLockOwnerArgs(b []byte, clientid uint64, owner []byte) []byte { b = xdr.AppendUint32(b, OpReleaseLockOwner) b = xdr.AppendUint64(b, clientid) return xdr.AppendVarOpaque(b, owner) } // AppendDelegReturnArgs appends the DELEGRETURN argop: the stateid of the // delegation the client gives back. func AppendDelegReturnArgs(b []byte, st Stateid) []byte { b = xdr.AppendUint32(b, OpDelegReturn) return st.Append(b) } // AppendBackchannelCtlArgs appends the BACKCHANNEL_CTL argop: the program // number of the back channel the client runs. func AppendBackchannelCtlArgs(b []byte, program uint32) []byte { b = xdr.AppendUint32(b, OpBackchannelCtl) return xdr.AppendUint32(b, program) } // AppendBindConnToSessionArgs appends the BIND_CONN_TO_SESSION argop of // RFC 7863: the session, the direction the connection should serve and // the RDMA mode flag. func AppendBindConnToSessionArgs(b []byte, id SessionID, dir uint32, rdma bool) []byte { b = xdr.AppendUint32(b, OpBindConnToSession) b = append(b, id[:]...) b = xdr.AppendUint32(b, dir) return xdr.AppendBool(b, rdma) } // AppendBindConnToSessionRes appends the result: the session and the // direction the server granted. func AppendBindConnToSessionRes(b []byte, id SessionID, dir uint32) []byte { b = append(b, id[:]...) return xdr.AppendUint32(b, dir) } // AppendFreeStateidArgs appends the FREE_STATEID argop: the lock stateid // the client retires. func AppendFreeStateidArgs(b []byte, st Stateid) []byte { b = xdr.AppendUint32(b, OpFreeStateid) return st.Append(b) } // AppendTestStateidArgs appends the TEST_STATEID argop: the stateids the // client asks about. func AppendTestStateidArgs(b []byte, sts []Stateid) []byte { b = xdr.AppendUint32(b, OpTestStateid) b = xdr.AppendUint32(b, uint32(len(sts))) for _, st := range sts { b = st.Append(b) } return b } // AppendTestStateidRes appends the result: one status per stateid, in the // order the arguments named them. func AppendTestStateidRes(b []byte, statuses []uint32) []byte { b = xdr.AppendUint32(b, uint32(len(statuses))) for _, s := range statuses { b = xdr.AppendUint32(b, s) } return b }