Linux NFS development
 help / color / mirror / Atom feed
From: Chuck Lever <cel@kernel.org>
To: NeilBrown <neil@brown.name>, Jeff Layton <jlayton@kernel.org>,
	Olga Kornievskaia <okorniev@redhat.com>,
	Dai Ngo <dai.ngo@oracle.com>, Tom Talpey <tom@talpey.com>
Cc: <linux-nfs@vger.kernel.org>
Subject: [PATCH v1 01/27] Documentation: Add the RPC language description of NFSv2
Date: Wed, 16 Sep 2026 12:28:30 -0400	[thread overview]
Message-ID: <20260916162859.2051-2-cel@kernel.org> (raw)
In-Reply-To: <20260916162859.2051-1-cel@kernel.org>

In order to generate source code to encode and decode NFSv2 protocol
elements, include a copy of the RPC language description of NFSv2
for xdrgen to process. The language description is an amalgam of
RFC 1094 and the Open Group's XNFS specification:

 https://pubs.opengroup.org/onlinepubs/9629799/chap7.htm

The goals of replacing hand-written XDR functions with ones that
are tool-generated are to improve memory safety and make XDR
encoding and decoding less brittle to maintain. Parts of the
NFSv4 protocol are still being extended actively. Tool-generated
XDR code reduces the time it takes to get a working implementation
of new protocol elements.

The xdrgen utility derives both the type definitions and the
encode/decode functions directly from protocol specifications,
using names and symbols familiar to anyone who knows those specs.
Unlike hand-written code that can inadvertently diverge from the
specification, xdrgen guarantees that the generated code matches
the specification exactly.

We would eventually like xdrgen to generate Rust code as well,
making the conversion of the kernel's NFS stacks to use Rust just
a little easier for us.

Signed-off-by: Chuck Lever <cel@kernel.org>
---
 Documentation/sunrpc/xdr/nfs2.x | 237 ++++++++++++++++++++++++++++++++
 1 file changed, 237 insertions(+)
 create mode 100644 Documentation/sunrpc/xdr/nfs2.x

diff --git a/Documentation/sunrpc/xdr/nfs2.x b/Documentation/sunrpc/xdr/nfs2.x
new file mode 100644
index 000000000000..8a05975ad65a
--- /dev/null
+++ b/Documentation/sunrpc/xdr/nfs2.x
@@ -0,0 +1,237 @@
+/*
+ * This document was extracted by hand from RFC 1094. Several errors
+ * and omissions were corrected. Additional sources for this protocol
+ * specification include:
+ *
+ *   https://pubs.opengroup.org/onlinepubs/9629799/chap7.htm
+ *
+ * Note that RFC 1094's official date of publication (March 1989) is
+ * before the IETF required its RFCs to carry an explicit copyright
+ * or other IP ownership notice.
+ */
+
+const NFS_MAXDATA = 8192;
+const NFS_MAXPATHLEN = 1024;
+const NFS_MAXNAMLEN = 255;
+const NFS_COOKIESIZE = 4;
+const NFS_FHSIZE = 32;
+
+/*
+ * RFC 1094 calls the following enum "stat". That name conflicts with
+ * the Linux kernel's "struct stat" because in C, struct, union, and
+ * enum tags all share a single tag namespace. Details are specified
+ * in the C11 standard, Section 6.2.3.
+ */
+enum nfsstat {
+	NFS_OK			= 0,
+	NFSERR_PERM		= 1,
+	NFSERR_NOENT		= 2,
+	NFSERR_IO		= 5,
+	NFSERR_NXIO		= 6,
+	NFSERR_ACCES		= 13,
+	NFSERR_EXIST		= 17,
+	NFSERR_NODEV		= 19,
+	NFSERR_NOTDIR		= 20,
+	NFSERR_ISDIR		= 21,
+	NFSERR_FBIG		= 27,
+	NFSERR_NOSPC		= 28,
+	NFSERR_ROFS		= 30,
+	NFSERR_NAMETOOLONG	= 63,
+	NFSERR_NOTEMPTY		= 66,
+	NFSERR_DQUOT		= 69,
+	NFSERR_STALE		= 70,
+	NFSERR_WFLUSH		= 99
+};
+
+enum ftype {
+	NFNON		= 0,
+	NFREG		= 1,
+	NFDIR		= 2,
+	NFBLK		= 3,
+	NFCHR		= 4,
+	NFLNK		= 5
+};
+
+typedef opaque		fhandle[NFS_FHSIZE];
+typedef opaque		nfscookie[NFS_COOKIESIZE];
+
+struct timeval {
+	unsigned int	seconds;
+	unsigned int	useconds;
+};
+
+struct fattr {
+	ftype		type;
+	unsigned int	mode;
+	unsigned int	nlink;
+	unsigned int	uid;
+	unsigned int	gid;
+	unsigned int	size;
+	unsigned int	blocksize;
+	unsigned int	rdev;
+	unsigned int	blocks;
+	unsigned int	fsid;
+	unsigned int	fileid;
+	timeval		atime;
+	timeval		mtime;
+	timeval		ctime;
+};
+
+struct sattr {
+	unsigned int	mode;
+	unsigned int	uid;
+	unsigned int	gid;
+	unsigned int	size;
+	timeval		atime;
+	timeval		mtime;
+};
+
+typedef string		filename<NFS_MAXNAMLEN>;
+typedef string		path<NFS_MAXPATHLEN>;
+
+union attrstat switch (nfsstat status) {
+	case NFS_OK:
+		fattr		attributes;
+	default:
+		void;
+};
+
+struct diropargs {
+	fhandle		dir;
+	filename	name;
+};
+
+struct diropok {
+	fhandle		file;
+	fattr		attributes;
+};
+
+union diropres switch (nfsstat status) {
+	case NFS_OK:
+		diropok		diropok;
+	default:
+		void;
+};
+
+struct sattrargs {
+	fhandle		file;
+	sattr		attributes;
+};
+
+union readlinkres switch (nfsstat status) {
+	case NFS_OK:
+		path		data;
+	default:
+		void;
+};
+
+struct readargs {
+	fhandle		file;
+	unsigned int	offset;
+	unsigned int	count;
+	unsigned int	totalcount;
+};
+
+struct readresok {
+	fattr		attributes;
+	opaque		data<NFS_MAXDATA>;
+};
+
+union readres switch (nfsstat status) {
+	case NFS_OK:
+		readresok	readresok;
+	default:
+		void;
+};
+
+struct writeargs {
+	fhandle		file;
+	unsigned int	beginoffset;
+	unsigned int	offset;
+	unsigned int	totalcount;
+	opaque		data<NFS_MAXDATA>;
+};
+
+struct createargs {
+	diropargs	where;
+	sattr		attributes;
+};
+
+struct renameargs {
+	diropargs	from;
+	diropargs	to;
+};
+
+struct linkargs {
+	fhandle		from;
+	diropargs	to;
+};
+
+struct symlinkargs {
+	diropargs	from;
+	path		to;
+	sattr		attributes;
+};
+
+struct readdirargs {
+	fhandle		dir;
+	nfscookie	cookie;
+	unsigned int	count;
+};
+
+struct entry {
+	unsigned int	fileid;
+	filename	name;
+	nfscookie	cookie;
+	entry		*nextentry;
+};
+
+struct readdirok {
+	entry		*entries;
+	bool		eof;
+};
+
+union readdirres switch (nfsstat status) {
+	case NFS_OK:
+		readdirok	readdirok;
+	default:
+		void;
+};
+
+struct info {
+	unsigned int	tsize;
+	unsigned int	bsize;
+	unsigned int	blocks;
+	unsigned int	bfree;
+	unsigned int	bavail;
+};
+
+union statfsres switch (nfsstat status) {
+	case NFS_OK:
+		info		info;
+	default:
+		void;
+};
+
+program NFS_PROGRAM {
+	version NFS_VERSION {
+		void		NFSPROC_NULL(void) = 0;
+		attrstat	NFSPROC_GETATTR(fhandle) = 1;
+		attrstat	NFSPROC_SETATTR(sattrargs) = 2;
+		void		NFSPROC_ROOT(void) = 3;
+		diropres	NFSPROC_LOOKUP(diropargs) = 4;
+		readlinkres	NFSPROC_READLINK(fhandle) = 5;
+		readres		NFSPROC_READ(readargs) = 6;
+		void		NFSPROC_WRITECACHE(void) = 7;
+		attrstat	NFSPROC_WRITE(writeargs) = 8;
+		diropres	NFSPROC_CREATE(createargs) = 9;
+		nfsstat		NFSPROC_REMOVE(diropargs) = 10;
+		nfsstat		NFSPROC_RENAME(renameargs) = 11;
+		nfsstat		NFSPROC_LINK(linkargs) = 12;
+		nfsstat		NFSPROC_SYMLINK(symlinkargs) = 13;
+		diropres	NFSPROC_MKDIR(createargs) = 14;
+		nfsstat		NFSPROC_RMDIR(diropargs) = 15;
+		readdirres	NFSPROC_READDIR(readdirargs) = 16;
+		statfsres	NFSPROC_STATFS(fhandle) = 17;
+	} = 2;
+} = 100003;
-- 
2.55.0


  reply	other threads:[~2026-09-16 16:29 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-16 16:28 [PATCH v1 00/27] Convert server-side NFSv2 XDR to use xdrgen Chuck Lever
2026-09-16 16:28 ` Chuck Lever [this message]
2026-09-16 16:28 ` [PATCH v1 1/2] NFSD: map fh_verify() status codes for NFS_ACLv2 replies Chuck Lever
2026-09-17 11:57   ` Jeff Layton
2026-09-16 16:28 ` [PATCH v1 02/27] NFSD: Add infrastructure for generating NFSv2 XDR encoders and decoders Chuck Lever
2026-09-16 16:28 ` [PATCH v1 2/2] NFSD: map fh_verify() status codes for NFS_ACLv3 replies Chuck Lever
2026-09-17 11:57   ` Jeff Layton
2026-09-16 16:28 ` [PATCH v1 03/27] NFSD: Use xdrgen-generated NFSv2 protocol definitions Chuck Lever
2026-09-16 16:28 ` [PATCH v1 04/27] NFSD: Remove '#include "xdr.h"' from fs/nfsd/xdr3.h Chuck Lever
2026-09-16 16:28 ` [PATCH v1 05/27] NFSD: Relocate the NFSv2 XDR storage union into nfsproc.c Chuck Lever
2026-09-16 16:28 ` [PATCH v1 06/27] NFSD: Use xdrgen XDR functions for the NFSv2 NULL procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 07/27] NFSD: Use xdrgen XDR functions for NFSv2 GETATTR procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 08/27] NFSD: Use xdrgen XDR functions for NFSv2 SETATTR procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 09/27] NFSD: Use xdrgen XDR functions for the NFSv2 ROOT procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 10/27] NFSD: Use xdrgen XDR functions for the NFSv2 LOOKUP procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 11/27] NFSD: Use xdrgen XDR functions for NFSv2 READLINK procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 12/27] NFSD: Use xdrgen XDR functions for NFSv2 READ procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 13/27] NFSD: Use xdrgen XDR functions for the NFSv2 WRITECACHE procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 14/27] NFSD: Use xdrgen XDR functions for NFSv2 WRITE procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 15/27] NFSD: Refactor nfsd_proc_create() Chuck Lever
2026-09-16 16:28 ` [PATCH v1 16/27] NFSD: Use xdrgen XDR functions for NFSv2 CREATE procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 17/27] NFSD: Use xdrgen XDR functions for the NFSv2 REMOVE procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 18/27] NFSD: Use xdrgen XDR functions for the NFSv2 RENAME procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 19/27] NFSD: Use xdrgen XDR functions for the NFSv2 LINK procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 20/27] NFSD: Use xdrgen XDR functions for NFSv2 SYMLINK procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 21/27] NFSD: Use xdrgen XDR functions for NFSv2 MKDIR procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 22/27] NFSD: Use xdrgen XDR functions for NFSv2 RMDIR procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 23/27] NFSD: Use xdrgen XDR functions for the NFSv2 STATFS procedure Chuck Lever
2026-09-16 16:28 ` [PATCH v1 24/27] NFSD: Use xdrgen XDR functions for NFSv2 READDIR arguments Chuck Lever
2026-09-16 16:28 ` [PATCH v1 25/27] NFSD: Add a streaming directory reader Chuck Lever
2026-09-16 16:28 ` [PATCH v1 26/27] NFSD: Refactor NFSv2 directory cookie encoding Chuck Lever
2026-09-16 16:28 ` [PATCH v1 27/27] NFSD: Use xdrgen XDR functions for NFSv2 READDIR results Chuck Lever
2026-09-17 11:56 ` [PATCH v1 00/27] Convert server-side NFSv2 XDR to use xdrgen Jeff Layton
2026-09-17 14:57   ` Chuck Lever

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260916162859.2051-2-cel@kernel.org \
    --to=cel@kernel.org \
    --cc=dai.ngo@oracle.com \
    --cc=jlayton@kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=neil@brown.name \
    --cc=okorniev@redhat.com \
    --cc=tom@talpey.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox