Skip to main content

nfs_rs/nfs4/
mod.rs

1//! Wire-level definitions shared by NFSv4 minor versions.
2
3pub(crate) mod acl;
4pub(crate) mod attrs;
5pub(crate) mod compound;
6pub(crate) mod fastxdr;
7pub(crate) mod stateid;
8
9pub use fastxdr::nfsstat4 as Nfs4ErrorCode;
10impl std::error::Error for Nfs4ErrorCode {}
11
12impl std::fmt::Display for Nfs4ErrorCode {
13    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14        match self {
15            Nfs4ErrorCode::NFS4_OK => write!(f, "call completed successfully"),
16            Nfs4ErrorCode::NFS4ERR_PERM => write!(f, "permission denied"),
17            Nfs4ErrorCode::NFS4ERR_NOENT => write!(f, "no such file or directory"),
18            Nfs4ErrorCode::NFS4ERR_IO => write!(f, "i/o error"),
19            Nfs4ErrorCode::NFS4ERR_NXIO => write!(f, "no such device or address"),
20            Nfs4ErrorCode::NFS4ERR_ACCESS => write!(f, "access denied"),
21            Nfs4ErrorCode::NFS4ERR_EXIST => write!(f, "file exists"),
22            Nfs4ErrorCode::NFS4ERR_XDEV => write!(f, "cross-device link"),
23            Nfs4ErrorCode::NFS4ERR_NOTDIR => write!(f, "not a directory"),
24            Nfs4ErrorCode::NFS4ERR_ISDIR => write!(f, "is a directory"),
25            Nfs4ErrorCode::NFS4ERR_INVAL => write!(f, "invalid argument"),
26            Nfs4ErrorCode::NFS4ERR_FBIG => write!(f, "file too large"),
27            Nfs4ErrorCode::NFS4ERR_NOSPC => write!(f, "no space left on device"),
28            Nfs4ErrorCode::NFS4ERR_ROFS => write!(f, "read-only file system"),
29            Nfs4ErrorCode::NFS4ERR_MLINK => write!(f, "too many hard links"),
30            Nfs4ErrorCode::NFS4ERR_NAMETOOLONG => write!(f, "name too long"),
31            Nfs4ErrorCode::NFS4ERR_NOTEMPTY => write!(f, "directory not empty"),
32            Nfs4ErrorCode::NFS4ERR_DQUOT => write!(f, "quota exceeded"),
33            Nfs4ErrorCode::NFS4ERR_STALE => write!(f, "stale file handle"),
34            Nfs4ErrorCode::NFS4ERR_BADHANDLE => write!(f, "illegal file handle"),
35            Nfs4ErrorCode::NFS4ERR_BAD_COOKIE => write!(f, "stale cookie"),
36            Nfs4ErrorCode::NFS4ERR_NOTSUPP => write!(f, "operation not supported"),
37            Nfs4ErrorCode::NFS4ERR_TOOSMALL => write!(f, "buffer too small"),
38            Nfs4ErrorCode::NFS4ERR_SERVERFAULT => write!(f, "server fault"),
39            Nfs4ErrorCode::NFS4ERR_BADTYPE => write!(f, "bad type"),
40            Nfs4ErrorCode::NFS4ERR_DELAY => write!(f, "server busy, retry later"),
41            Nfs4ErrorCode::NFS4ERR_SAME => write!(f, "no change"),
42            Nfs4ErrorCode::NFS4ERR_DENIED => write!(f, "lock denied"),
43            Nfs4ErrorCode::NFS4ERR_EXPIRED => write!(f, "lock/stateid expired"),
44            Nfs4ErrorCode::NFS4ERR_LOCKED => write!(f, "file locked"),
45            Nfs4ErrorCode::NFS4ERR_GRACE => write!(f, "server in grace period"),
46            Nfs4ErrorCode::NFS4ERR_FHEXPIRED => write!(f, "file handle expired"),
47            Nfs4ErrorCode::NFS4ERR_SHARE_DENIED => write!(f, "share denied"),
48            Nfs4ErrorCode::NFS4ERR_WRONGSEC => write!(f, "wrong security flavor"),
49            Nfs4ErrorCode::NFS4ERR_CLID_INUSE => write!(f, "client ID in use"),
50            Nfs4ErrorCode::NFS4ERR_MOVED => write!(f, "filesystem moved"),
51            Nfs4ErrorCode::NFS4ERR_NOFILEHANDLE => write!(f, "no current filehandle"),
52            Nfs4ErrorCode::NFS4ERR_MINOR_VERS_MISMATCH => write!(f, "minor version mismatch"),
53            Nfs4ErrorCode::NFS4ERR_STALE_CLIENTID => write!(f, "stale client ID"),
54            Nfs4ErrorCode::NFS4ERR_STALE_STATEID => write!(f, "stale state ID"),
55            Nfs4ErrorCode::NFS4ERR_OLD_STATEID => write!(f, "old state ID"),
56            Nfs4ErrorCode::NFS4ERR_BAD_STATEID => write!(f, "bad state ID"),
57            Nfs4ErrorCode::NFS4ERR_BAD_SEQID => write!(f, "bad sequence ID"),
58            Nfs4ErrorCode::NFS4ERR_NOT_SAME => write!(f, "verify/nverify mismatch"),
59            Nfs4ErrorCode::NFS4ERR_LOCK_RANGE => write!(f, "lock range not supported"),
60            Nfs4ErrorCode::NFS4ERR_SYMLINK => write!(f, "symlink encountered"),
61            Nfs4ErrorCode::NFS4ERR_RESTOREFH => write!(f, "no saved filehandle"),
62            Nfs4ErrorCode::NFS4ERR_LEASE_MOVED => write!(f, "lease moved"),
63            Nfs4ErrorCode::NFS4ERR_ATTRNOTSUPP => write!(f, "attribute not supported"),
64            Nfs4ErrorCode::NFS4ERR_NO_GRACE => write!(f, "not in grace period"),
65            Nfs4ErrorCode::NFS4ERR_RECLAIM_BAD => write!(f, "reclaim error"),
66            Nfs4ErrorCode::NFS4ERR_RECLAIM_CONFLICT => write!(f, "reclaim conflict"),
67            Nfs4ErrorCode::NFS4ERR_BADXDR => write!(f, "bad XDR"),
68            Nfs4ErrorCode::NFS4ERR_LOCKS_HELD => write!(f, "locks still held"),
69            Nfs4ErrorCode::NFS4ERR_OPENMODE => write!(f, "open mode conflict"),
70            Nfs4ErrorCode::NFS4ERR_BADOWNER => write!(f, "bad owner"),
71            Nfs4ErrorCode::NFS4ERR_BADCHAR => write!(f, "bad character in name"),
72            Nfs4ErrorCode::NFS4ERR_BADNAME => write!(f, "bad name"),
73            Nfs4ErrorCode::NFS4ERR_BAD_RANGE => write!(f, "bad lock range"),
74            Nfs4ErrorCode::NFS4ERR_LOCK_NOTSUPP => write!(f, "lock not supported"),
75            Nfs4ErrorCode::NFS4ERR_OP_ILLEGAL => write!(f, "illegal operation"),
76            Nfs4ErrorCode::NFS4ERR_DEADLOCK => write!(f, "deadlock"),
77            Nfs4ErrorCode::NFS4ERR_FILE_OPEN => write!(f, "file is open"),
78            Nfs4ErrorCode::NFS4ERR_ADMIN_REVOKED => write!(f, "admin revoked"),
79            Nfs4ErrorCode::NFS4ERR_CB_PATH_DOWN => write!(f, "callback path down"),
80            // NFSv4.1-specific errors
81            Nfs4ErrorCode::NFS4ERR_BADIOMODE => write!(f, "bad I/O mode"),
82            Nfs4ErrorCode::NFS4ERR_BADLAYOUT => write!(f, "bad layout"),
83            Nfs4ErrorCode::NFS4ERR_BAD_SESSION_DIGEST => write!(f, "bad session digest"),
84            Nfs4ErrorCode::NFS4ERR_BADSESSION => write!(f, "bad session"),
85            Nfs4ErrorCode::NFS4ERR_BADSLOT => write!(f, "bad slot"),
86            Nfs4ErrorCode::NFS4ERR_COMPLETE_ALREADY => write!(f, "reclaim complete already"),
87            Nfs4ErrorCode::NFS4ERR_CONN_NOT_BOUND_TO_SESSION => {
88                write!(f, "connection not bound to session")
89            }
90            Nfs4ErrorCode::NFS4ERR_DELEG_ALREADY_WANTED => write!(f, "delegation already wanted"),
91            Nfs4ErrorCode::NFS4ERR_BACK_CHAN_BUSY => write!(f, "backchannel busy"),
92            Nfs4ErrorCode::NFS4ERR_LAYOUTTRYLATER => write!(f, "layout try later"),
93            Nfs4ErrorCode::NFS4ERR_LAYOUTUNAVAILABLE => write!(f, "layout unavailable"),
94            Nfs4ErrorCode::NFS4ERR_NOMATCHING_LAYOUT => write!(f, "no matching layout"),
95            Nfs4ErrorCode::NFS4ERR_RECALLCONFLICT => write!(f, "recall conflict"),
96            Nfs4ErrorCode::NFS4ERR_UNKNOWN_LAYOUTTYPE => write!(f, "unknown layout type"),
97            Nfs4ErrorCode::NFS4ERR_SEQ_MISORDERED => write!(f, "sequence misordered"),
98            Nfs4ErrorCode::NFS4ERR_SEQUENCE_POS => write!(f, "sequence position error"),
99            Nfs4ErrorCode::NFS4ERR_REQ_TOO_BIG => write!(f, "request too big"),
100            Nfs4ErrorCode::NFS4ERR_REP_TOO_BIG => write!(f, "reply too big"),
101            Nfs4ErrorCode::NFS4ERR_REP_TOO_BIG_TO_CACHE => write!(f, "reply too big to cache"),
102            Nfs4ErrorCode::NFS4ERR_RETRY_UNCACHED_REP => write!(f, "retry uncached reply"),
103            Nfs4ErrorCode::NFS4ERR_UNSAFE_COMPOUND => write!(f, "unsafe compound"),
104            Nfs4ErrorCode::NFS4ERR_TOO_MANY_OPS => write!(f, "too many operations"),
105            Nfs4ErrorCode::NFS4ERR_OP_NOT_IN_SESSION => write!(f, "operation not in session"),
106            Nfs4ErrorCode::NFS4ERR_HASH_ALG_UNSUPP => write!(f, "hash algorithm unsupported"),
107            Nfs4ErrorCode::NFS4ERR_CLIENTID_BUSY => write!(f, "client ID busy"),
108            Nfs4ErrorCode::NFS4ERR_PNFS_IO_HOLE => write!(f, "pNFS I/O hole"),
109            Nfs4ErrorCode::NFS4ERR_SEQ_FALSE_RETRY => write!(f, "sequence false retry"),
110            Nfs4ErrorCode::NFS4ERR_BAD_HIGH_SLOT => write!(f, "bad high slot"),
111            Nfs4ErrorCode::NFS4ERR_DEADSESSION => write!(f, "dead session"),
112            Nfs4ErrorCode::NFS4ERR_ENCR_ALG_UNSUPP => write!(f, "encryption algorithm unsupported"),
113            Nfs4ErrorCode::NFS4ERR_PNFS_NO_LAYOUT => write!(f, "pNFS no layout"),
114            Nfs4ErrorCode::NFS4ERR_NOT_ONLY_OP => write!(f, "not the only operation"),
115            Nfs4ErrorCode::NFS4ERR_WRONG_CRED => write!(f, "wrong credentials"),
116            Nfs4ErrorCode::NFS4ERR_WRONG_TYPE => write!(f, "wrong type"),
117            Nfs4ErrorCode::NFS4ERR_DIRDELEG_UNAVAIL => {
118                write!(f, "directory delegation unavailable")
119            }
120            Nfs4ErrorCode::NFS4ERR_REJECT_DELEG => write!(f, "delegation rejected"),
121            Nfs4ErrorCode::NFS4ERR_RETURNCONFLICT => write!(f, "return conflict"),
122            Nfs4ErrorCode::NFS4ERR_DELEG_REVOKED => write!(f, "delegation revoked"),
123        }
124    }
125}
126
127/// RFC 7530 common attribute numbers.
128pub(crate) mod attrnum {
129    pub(crate) const ACL: u32 = 12;
130    pub(crate) const ACLSUPPORT: u32 = 13;
131    pub(crate) const DACL: u32 = 58;
132    pub(crate) const SACL: u32 = 59;
133    pub(crate) const FILEHANDLE: u32 = 19;
134    pub(crate) const FILEID: u32 = 20;
135    pub(crate) const MODE: u32 = 33;
136}
137
138#[cfg(test)]
139mod tests {
140    use super::{Nfs4ErrorCode, attrnum};
141
142    #[test]
143    fn rfc7530_common_attribute_numbers_are_stable() {
144        assert_eq!(attrnum::ACL, 12);
145        assert_eq!(attrnum::ACLSUPPORT, 13);
146        assert_eq!(attrnum::FILEHANDLE, 19);
147        assert_eq!(attrnum::FILEID, 20);
148        assert_eq!(attrnum::MODE, 33);
149    }
150
151    #[test]
152    fn rfc7530_status_discriminants_match_the_wire_registry() {
153        assert_eq!(Nfs4ErrorCode::NFS4_OK as u32, 0);
154        assert_eq!(Nfs4ErrorCode::NFS4ERR_BAD_STATEID as u32, 10025);
155        assert_eq!(Nfs4ErrorCode::NFS4ERR_BAD_SEQID as u32, 10026);
156    }
157
158    #[test]
159    fn nfsv41_status_extensions_remain_explicit() {
160        assert_eq!(Nfs4ErrorCode::NFS4ERR_BADIOMODE as u32, 10049);
161        assert_eq!(Nfs4ErrorCode::NFS4ERR_BADSESSION as u32, 10052);
162        assert_eq!(Nfs4ErrorCode::NFS4ERR_SEQ_MISORDERED as u32, 10063);
163    }
164
165    #[test]
166    fn shared_attribute_documentation_does_not_claim_a_v41_numbering_shift() {
167        let source = include_str!("attrs.rs").to_ascii_lowercase();
168        assert!(!source.contains("new in nfsv4.1"));
169        assert!(!source.contains("shifted +1 from v4.0"));
170        assert!(!source.contains("nfsv4.1 numbering"));
171    }
172}