NFSD: Add infrastructure for generating NFSv2 XDR encoders and decoders

NFSD's NFSv2 XDR codecs are hand-maintained; they are being converted
to xdrgen-generated code one RPC procedure at a time. The first step
is to generate and commit the xdrgen C code based on nfs2.x. The
generated code can be refreshed any time nfs2.x is modified by
running "(cd fs/nfsd && make xdrgen)".

Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260916162859.2051-4-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
This commit is contained in:
Chuck Lever 2026-09-16 12:28:32 -04:00
parent 9c8a74ada9
commit f49b703d85
5 changed files with 1402 additions and 2 deletions

View File

@ -10,6 +10,8 @@
* or other IP ownership notice.
*/
pragma header nfs2;
const NFS_MAXDATA = 8192;
const NFS_MAXPATHLEN = 1024;
const NFS_MAXNAMLEN = 255;

View File

@ -14,7 +14,7 @@ nfsd-y += nfssvc.o nfsctl.o nfsfh.o vfs.o \
export.o auth.o lockd.o nfscache.o \
stats.o filecache.o nfs3proc.o nfs3xdr.o \
netlink.o
nfsd-$(CONFIG_NFSD_V2) += nfsproc.o nfsxdr.o
nfsd-$(CONFIG_NFSD_V2) += nfsproc.o nfsxdr.o nfs2xdr_gen.o
nfsd-$(CONFIG_NFSD_V2_ACL) += nfs2acl.o
nfsd-$(CONFIG_NFSD_V3_ACL) += nfs3acl.o
nfsd-$(CONFIG_NFSD_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4idmap.o \
@ -37,13 +37,24 @@ nfsd-$(CONFIG_DEBUG_FS) += debugfs.o
#
.PHONY: xdrgen
xdrgen: ../../include/linux/sunrpc/xdrgen/nfs4_1.h nfs4xdr_gen.h nfs4xdr_gen.c
XDRGEN_DEFINITIONS = ../../include/linux/sunrpc/xdrgen/nfs2.h \
../../include/linux/sunrpc/xdrgen/nfs4_1.h
XDRGEN_DECLARATIONS = nfs2xdr_gen.h nfs4xdr_gen.h
XDRGEN_SOURCE = nfs2xdr_gen.c nfs4xdr_gen.c
xdrgen: $(XDRGEN_DEFINITIONS) $(XDRGEN_DECLARATIONS) $(XDRGEN_SOURCE)
../../include/linux/sunrpc/xdrgen/nfs2.h: ../../Documentation/sunrpc/xdr/nfs2.x
../../tools/net/sunrpc/xdrgen/xdrgen definitions $< > $@
../../include/linux/sunrpc/xdrgen/nfs4_1.h: ../../Documentation/sunrpc/xdr/nfs4_1.x
../../tools/net/sunrpc/xdrgen/xdrgen definitions $< > $@
nfs2xdr_gen.h: ../../Documentation/sunrpc/xdr/nfs2.x
../../tools/net/sunrpc/xdrgen/xdrgen declarations $< > $@
nfs4xdr_gen.h: ../../Documentation/sunrpc/xdr/nfs4_1.x
../../tools/net/sunrpc/xdrgen/xdrgen declarations $< > $@
nfs2xdr_gen.c: ../../Documentation/sunrpc/xdr/nfs2.x
../../tools/net/sunrpc/xdrgen/xdrgen source $< > $@
nfs4xdr_gen.c: ../../Documentation/sunrpc/xdr/nfs4_1.x
../../tools/net/sunrpc/xdrgen/xdrgen source $< > $@

1054
fs/nfsd/nfs2xdr_gen.c Normal file

File diff suppressed because it is too large Load Diff

35
fs/nfsd/nfs2xdr_gen.h Normal file
View File

@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Generated by xdrgen. Manual edits will be lost. */
/* XDR specification file: ../../Documentation/sunrpc/xdr/nfs2.x */
/* XDR specification modification time: Tue Sep 8 11:23:43 2026 */
#ifndef _LINUX_XDRGEN_NFS2_DECL_H
#define _LINUX_XDRGEN_NFS2_DECL_H
#include <linux/types.h>
#include <linux/sunrpc/xdr.h>
#include <linux/sunrpc/xdrgen/_defs.h>
#include <linux/sunrpc/xdrgen/_builtins.h>
#include <linux/sunrpc/xdrgen/nfs2.h>
bool nfs_svc_decode_fhandle(struct svc_rqst *rqstp, struct xdr_stream *xdr);
bool nfs_svc_decode_sattrargs(struct svc_rqst *rqstp, struct xdr_stream *xdr);
bool nfs_svc_decode_diropargs(struct svc_rqst *rqstp, struct xdr_stream *xdr);
bool nfs_svc_decode_readargs(struct svc_rqst *rqstp, struct xdr_stream *xdr);
bool nfs_svc_decode_writeargs(struct svc_rqst *rqstp, struct xdr_stream *xdr);
bool nfs_svc_decode_createargs(struct svc_rqst *rqstp, struct xdr_stream *xdr);
bool nfs_svc_decode_renameargs(struct svc_rqst *rqstp, struct xdr_stream *xdr);
bool nfs_svc_decode_linkargs(struct svc_rqst *rqstp, struct xdr_stream *xdr);
bool nfs_svc_decode_symlinkargs(struct svc_rqst *rqstp, struct xdr_stream *xdr);
bool nfs_svc_decode_readdirargs(struct svc_rqst *rqstp, struct xdr_stream *xdr);
bool nfs_svc_encode_attrstat(struct svc_rqst *rqstp, struct xdr_stream *xdr);
bool nfs_svc_encode_diropres(struct svc_rqst *rqstp, struct xdr_stream *xdr);
bool nfs_svc_encode_readlinkres(struct svc_rqst *rqstp, struct xdr_stream *xdr);
bool nfs_svc_encode_readres(struct svc_rqst *rqstp, struct xdr_stream *xdr);
bool nfs_svc_encode_nfsstat(struct svc_rqst *rqstp, struct xdr_stream *xdr);
bool nfs_svc_encode_readdirres(struct svc_rqst *rqstp, struct xdr_stream *xdr);
bool nfs_svc_encode_statfsres(struct svc_rqst *rqstp, struct xdr_stream *xdr);
#endif /* _LINUX_XDRGEN_NFS2_DECL_H */

View File

@ -0,0 +1,298 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Generated by xdrgen. Manual edits will be lost. */
/* XDR specification file: ../../Documentation/sunrpc/xdr/nfs2.x */
/* XDR specification modification time: Tue Sep 8 11:23:43 2026 */
#ifndef _LINUX_XDRGEN_NFS2_DEF_H
#define _LINUX_XDRGEN_NFS2_DEF_H
#include <linux/types.h>
#include <linux/sunrpc/xdrgen/_defs.h>
enum { NFS_MAXDATA = 8192 };
enum { NFS_MAXPATHLEN = 1024 };
enum { NFS_MAXNAMLEN = 255 };
enum { NFS_COOKIESIZE = 4 };
enum { NFS_FHSIZE = 32 };
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,
};
typedef enum nfsstat nfsstat;
enum ftype {
NFNON = 0,
NFREG = 1,
NFDIR = 2,
NFBLK = 3,
NFCHR = 4,
NFLNK = 5,
};
typedef enum ftype ftype;
typedef u8 fhandle[NFS_FHSIZE];
typedef u8 nfscookie[NFS_COOKIESIZE];
struct timeval {
u32 seconds;
u32 useconds;
};
struct fattr {
ftype type;
u32 mode;
u32 nlink;
u32 uid;
u32 gid;
u32 size;
u32 blocksize;
u32 rdev;
u32 blocks;
u32 fsid;
u32 fileid;
struct timeval atime;
struct timeval mtime;
struct timeval ctime;
};
struct sattr {
u32 mode;
u32 uid;
u32 gid;
u32 size;
struct timeval atime;
struct timeval mtime;
};
typedef string filename;
typedef string path;
struct attrstat {
nfsstat status;
union {
struct fattr attributes;
} u;
};
struct diropargs {
fhandle dir;
filename name;
};
struct diropok {
fhandle file;
struct fattr attributes;
};
struct diropres {
nfsstat status;
union {
struct diropok diropok;
} u;
};
struct sattrargs {
fhandle file;
struct sattr attributes;
};
struct readlinkres {
nfsstat status;
union {
path data;
} u;
};
struct readargs {
fhandle file;
u32 offset;
u32 count;
u32 totalcount;
};
struct readresok {
struct fattr attributes;
opaque data;
};
struct readres {
nfsstat status;
union {
struct readresok readresok;
} u;
};
struct writeargs {
fhandle file;
u32 beginoffset;
u32 offset;
u32 totalcount;
opaque data;
};
struct createargs {
struct diropargs where;
struct sattr attributes;
};
struct renameargs {
struct diropargs from;
struct diropargs to;
};
struct linkargs {
fhandle from;
struct diropargs to;
};
struct symlinkargs {
struct diropargs from;
path to;
struct sattr attributes;
};
struct readdirargs {
fhandle dir;
nfscookie cookie;
u32 count;
};
struct entry {
u32 fileid;
filename name;
nfscookie cookie;
};
struct readdirok {
struct entry *entries;
bool eof;
};
struct readdirres {
nfsstat status;
union {
struct readdirok readdirok;
} u;
};
struct info {
u32 tsize;
u32 bsize;
u32 blocks;
u32 bfree;
u32 bavail;
};
struct statfsres {
nfsstat status;
union {
struct info info;
} u;
};
enum {
NFSPROC_NULL = 0,
NFSPROC_GETATTR = 1,
NFSPROC_SETATTR = 2,
NFSPROC_ROOT = 3,
NFSPROC_LOOKUP = 4,
NFSPROC_READLINK = 5,
NFSPROC_READ = 6,
NFSPROC_WRITECACHE = 7,
NFSPROC_WRITE = 8,
NFSPROC_CREATE = 9,
NFSPROC_REMOVE = 10,
NFSPROC_RENAME = 11,
NFSPROC_LINK = 12,
NFSPROC_SYMLINK = 13,
NFSPROC_MKDIR = 14,
NFSPROC_RMDIR = 15,
NFSPROC_READDIR = 16,
NFSPROC_STATFS = 17,
};
#ifndef NFS_PROGRAM
#define NFS_PROGRAM (100003)
#endif
#define NFS2_nfsstat_sz (XDR_int)
#define NFS2_ftype_sz (XDR_int)
#define NFS2_fhandle_sz (XDR_QUADLEN(NFS_FHSIZE))
#define NFS2_nfscookie_sz (XDR_QUADLEN(NFS_COOKIESIZE))
#define NFS2_timeval_sz \
(XDR_unsigned_int + XDR_unsigned_int)
#define NFS2_fattr_sz \
(NFS2_ftype_sz + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + NFS2_timeval_sz + NFS2_timeval_sz + NFS2_timeval_sz)
#define NFS2_sattr_sz \
(XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + NFS2_timeval_sz + NFS2_timeval_sz)
#define NFS2_filename_sz (XDR_unsigned_int + XDR_QUADLEN(NFS_MAXNAMLEN))
#define NFS2_path_sz (XDR_unsigned_int + XDR_QUADLEN(NFS_MAXPATHLEN))
#define NFS2_attrstat_sz \
(NFS2_nfsstat_sz + NFS2_fattr_sz)
#define NFS2_diropargs_sz \
(NFS2_fhandle_sz + NFS2_filename_sz)
#define NFS2_diropok_sz \
(NFS2_fhandle_sz + NFS2_fattr_sz)
#define NFS2_diropres_sz \
(NFS2_nfsstat_sz + NFS2_diropok_sz)
#define NFS2_sattrargs_sz \
(NFS2_fhandle_sz + NFS2_sattr_sz)
#define NFS2_readlinkres_sz \
(NFS2_nfsstat_sz + NFS2_path_sz)
#define NFS2_readargs_sz \
(NFS2_fhandle_sz + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int)
#define NFS2_readresok_sz \
(NFS2_fattr_sz + XDR_unsigned_int + XDR_QUADLEN(NFS_MAXDATA))
#define NFS2_readres_sz \
(NFS2_nfsstat_sz + NFS2_readresok_sz)
#define NFS2_writeargs_sz \
(NFS2_fhandle_sz + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_QUADLEN(NFS_MAXDATA))
#define NFS2_createargs_sz \
(NFS2_diropargs_sz + NFS2_sattr_sz)
#define NFS2_renameargs_sz \
(NFS2_diropargs_sz + NFS2_diropargs_sz)
#define NFS2_linkargs_sz \
(NFS2_fhandle_sz + NFS2_diropargs_sz)
#define NFS2_symlinkargs_sz \
(NFS2_diropargs_sz + NFS2_path_sz + NFS2_sattr_sz)
#define NFS2_readdirargs_sz \
(NFS2_fhandle_sz + NFS2_nfscookie_sz + XDR_unsigned_int)
#define NFS2_entry_sz \
(XDR_bool + XDR_unsigned_int + NFS2_filename_sz + NFS2_nfscookie_sz)
#define NFS2_readdirok_sz \
(XDR_bool + XDR_bool)
#define NFS2_readdirres_sz \
(NFS2_nfsstat_sz + NFS2_readdirok_sz)
#define NFS2_info_sz \
(XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int)
#define NFS2_statfsres_sz \
(NFS2_nfsstat_sz + NFS2_info_sz)
#define NFS2_MAX_ARGS_SZ \
(NFS2_writeargs_sz)
#endif /* _LINUX_XDRGEN_NFS2_DEF_H */