Module Name: src Committed By: martin Date: Fri Sep 20 11:31:32 UTC 2024
Modified Files: src/sys/arch/i386/stand [netbsd-10]: Makefile.booters src/sys/arch/i386/stand/efiboot [netbsd-10]: Makefile.efiboot src/sys/arch/i386/stand/pxeboot [netbsd-10]: Makefile src/sys/lib/libsa [netbsd-10]: nfs.c nfsv2.h rpcv2.h Added Files: src/sys/lib/libsa [netbsd-10]: nfsv3.h Removed Files: src/sys/arch/i386/stand/libsa [netbsd-10]: nfs.c Log Message: Pull up following revision(s) (requested by rin in ticket #894): sys/arch/i386/stand/Makefile.booters: revision 1.98 sys/lib/libsa/nfsv3.h: revision 1.1 sys/lib/libsa/rpcv2.h: revision 1.4 sys/arch/i386/stand/efiboot/Makefile.efiboot: revision 1.23 sys/lib/libsa/nfsv2.h: revision 1.5 sys/lib/libsa/nfs.c: revision 1.51 sys/lib/libsa/nfs.c: revision 1.52 sys/arch/i386/stand/libsa/nfs.c: file removal sys/lib/libsa/nfs.c: revision 1.53 sys/arch/i386/stand/libsa/nfs.c: revision 1.20 sys/arch/i386/stand/libsa/nfs.c: revision 1.21 sys/arch/i386/stand/pxeboot/Makefile: revision 1.29 Add NFSv3 support. Try NFSv3 and fall back to NFSv2. Merge with generic libsa NFS code to minimize differences and to learn NFSv3. libsa: nfs: Fix NFS_NOSYMLINK option for previous Used only by mvme68k. Align again with libsa (NFS_NOSYMLINK fix). libsa/nfs.c: Add `LIBSA_NFS_IMPLICIT_MOUNT` compile-time option by which nfs_mount() is automatically called from nfs_open(), as done for nfs.c in i386/stand. This is only functional difference b/w two copies of nfs.c. Now, we can safely retire the latter. XXX It would be really nice to drop this option also. However, unfortunately, it is too much for me at the very moment... i386: stand: Retire its own nfs.c, and switch to libsa/nfs.c. NFC To generate a diff of this commit: cvs rdiff -u -r1.94.20.1 -r1.94.20.2 src/sys/arch/i386/stand/Makefile.booters cvs rdiff -u -r1.19.4.1 -r1.19.4.2 \ src/sys/arch/i386/stand/efiboot/Makefile.efiboot cvs rdiff -u -r1.19 -r0 src/sys/arch/i386/stand/libsa/nfs.c cvs rdiff -u -r1.28 -r1.28.26.1 src/sys/arch/i386/stand/pxeboot/Makefile cvs rdiff -u -r1.50 -r1.50.24.1 src/sys/lib/libsa/nfs.c cvs rdiff -u -r1.4 -r1.4.194.1 src/sys/lib/libsa/nfsv2.h cvs rdiff -u -r0 -r1.1.4.2 src/sys/lib/libsa/nfsv3.h cvs rdiff -u -r1.3 -r1.3.194.1 src/sys/lib/libsa/rpcv2.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/i386/stand/Makefile.booters diff -u src/sys/arch/i386/stand/Makefile.booters:1.94.20.1 src/sys/arch/i386/stand/Makefile.booters:1.94.20.2 --- src/sys/arch/i386/stand/Makefile.booters:1.94.20.1 Thu Dec 14 17:56:08 2023 +++ src/sys/arch/i386/stand/Makefile.booters Fri Sep 20 11:31:31 2024 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.booters,v 1.94.20.1 2023/12/14 17:56:08 martin Exp $ +# $NetBSD: Makefile.booters,v 1.94.20.2 2024/09/20 11:31:31 martin Exp $ NOLIBCSANITIZER= NOSANITIZER= @@ -64,6 +64,7 @@ LIBZ= ${ZLIB} ### find out what to use for libsa SA_AS= library SAMISCMAKEFLAGS+="SA_USE_LOADFILE=yes" +SAMISCCPPFLAGS+=-DLIBSA_NFS_IMPLICIT_MOUNT .include "${S}/lib/libsa/Makefile.inc" LIBSA= ${SALIB} Index: src/sys/arch/i386/stand/efiboot/Makefile.efiboot diff -u src/sys/arch/i386/stand/efiboot/Makefile.efiboot:1.19.4.1 src/sys/arch/i386/stand/efiboot/Makefile.efiboot:1.19.4.2 --- src/sys/arch/i386/stand/efiboot/Makefile.efiboot:1.19.4.1 Mon Sep 11 13:25:42 2023 +++ src/sys/arch/i386/stand/efiboot/Makefile.efiboot Fri Sep 20 11:31:32 2024 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.efiboot,v 1.19.4.1 2023/09/11 13:25:42 martin Exp $ +# $NetBSD: Makefile.efiboot,v 1.19.4.2 2024/09/20 11:31:32 martin Exp $ S= ${.CURDIR}/../../../../.. @@ -21,9 +21,7 @@ LIBI386SRCS= biosdisk.c bootinfo.c booti LIBI386SRCS+= comio_direct.c LIBI386SRCS+= diskbuf.c exec.c menuutils.c parseutils.c pread.c LIBI386SRCS+= exec_multiboot1.c exec_multiboot2.c -# use our own nfs implementation -LIBSASRCS+= nfs.c -SRCS= ${SOURCES} ${EXTRA_SOURCES} ${LIBI386SRCS} ${LIBSASRCS} +SRCS= ${SOURCES} ${EXTRA_SOURCES} ${LIBI386SRCS} .include <bsd.init.mk> @@ -86,6 +84,7 @@ GNUEFIARCH?= ${MACHINE_CPU} CPPFLAGS+= -I${EFIDIR}/inc -I${EFIDIR}/inc/${GNUEFIARCH} CPPFLAGS+= -I${EFIDIR}/inc/protocol +SAMISCCPPFLAGS+= -DLIBSA_NFS_IMPLICIT_MOUNT SAMISCCPPFLAGS+= -DLIBSA_PRINTF_LONGLONG_SUPPORT SAMISCCPPFLAGS+= -DLIBSA_PRINTF_WIDTH_SUPPORT SAMISCCPPFLAGS+= -D"cdb2devb(bno)=(bno)" Index: src/sys/arch/i386/stand/pxeboot/Makefile diff -u src/sys/arch/i386/stand/pxeboot/Makefile:1.28 src/sys/arch/i386/stand/pxeboot/Makefile:1.28.26.1 --- src/sys/arch/i386/stand/pxeboot/Makefile:1.28 Fri Sep 27 08:57:10 2019 +++ src/sys/arch/i386/stand/pxeboot/Makefile Fri Sep 20 11:31:32 2024 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.28 2019/09/27 08:57:10 gson Exp $ +# $NetBSD: Makefile,v 1.28.26.1 2024/09/20 11:31:32 martin Exp $ S= ${.CURDIR}/../../../.. @@ -15,9 +15,6 @@ RELOC= 0x0 SRCS= main.c dev_net.c devopen.c conf.c SRCS+=exec.c exec_multiboot1.c exec_multiboot2.c pxe.c pxe_call.S -# use our own nfs implementation -.PATH: ${.CURDIR}/../libsa -SRCS+= nfs.c .include <bsd.init.mk> Index: src/sys/lib/libsa/nfs.c diff -u src/sys/lib/libsa/nfs.c:1.50 src/sys/lib/libsa/nfs.c:1.50.24.1 --- src/sys/lib/libsa/nfs.c:1.50 Sun Jan 26 10:13:10 2020 +++ src/sys/lib/libsa/nfs.c Fri Sep 20 11:31:32 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: nfs.c,v 1.50 2020/01/26 10:13:10 skrll Exp $ */ +/* $NetBSD: nfs.c,v 1.50.24.1 2024/09/20 11:31:32 martin Exp $ */ /*- * Copyright (c) 1993 John Brezak @@ -53,46 +53,18 @@ #include "rpcv2.h" #include "nfsv2.h" +#include "nfsv3.h" #include "stand.h" #include "net.h" #include "nfs.h" #include "rpc.h" -/* Define our own NFS attributes */ -struct nfsv2_fattrs { - n_long fa_type; - n_long fa_mode; - n_long fa_nlink; - n_long fa_uid; - n_long fa_gid; - n_long fa_size; - n_long fa_blocksize; - n_long fa_rdev; - n_long fa_blocks; - n_long fa_fsid; - n_long fa_fileid; - struct nfsv2_time fa_atime; - struct nfsv2_time fa_mtime; - struct nfsv2_time fa_ctime; -}; - - -struct nfs_read_args { - u_char fh[NFS_FHSIZE]; - n_long off; - n_long len; - n_long xxx; /* XXX what's this for? */ -}; +/* Storage for any filehandle (including length for V3) */ +#define NFS_FHSTORE (NFS_FHSIZE < NFS_V3FHSIZE ? NFS_V3FHSIZE + 4: NFS_FHSIZE) /* Data part of nfs rpc reply (also the largest thing we receive) */ #define NFSREAD_SIZE 1024 -struct nfs_read_repl { - n_long errno; - struct nfsv2_fattrs fa; - n_long count; - u_char data[NFSREAD_SIZE]; -}; #ifndef NFS_NOSYMLINK struct nfs_readlnk_repl { @@ -102,16 +74,68 @@ struct nfs_readlnk_repl { }; #endif +static inline uint64_t +getnquad(n_long x[2]) { + return (uint64_t)ntohl(x[0]) << 32 | ntohl(x[1]); +} + +static inline void +setnquad(n_long x[2], uint64_t v) +{ + x[0] = htonl((n_long)(v >> 32)); + x[1] = htonl((n_long)(v & 0xffffffff)); +} + struct nfs_iodesc { struct iodesc *iodesc; off_t off; - u_char fh[NFS_FHSIZE]; - struct nfsv2_fattrs fa; /* all in network order */ + int version; + u_char fh[NFS_FHSTORE]; + union { + /* all in network order */ + struct nfsv2_fattr v2; + struct nfsv3_fattr v3; + } u_fa; }; +static inline size_t +fhstore(int version, u_char *fh) +{ + size_t len; + + switch (version) { + case NFS_VER2: + len = NFS_FHSIZE; + break; + case NFS_VER3: + len = fh[0] << 24 | fh[1] << 16 | fh[2] << 8 | fh[3]; + if (len > NFS_V3FHSIZE) + len = NFS_V3FHSIZE; + len = 4 + roundup(len, 4); + break; + default: + len = 0; + break; + } + + return len; +} + +static inline size_t +fhcopy(int version, u_char *src, u_char *dst) +{ + size_t len = fhstore(version, src); + memcpy(dst, src, len); + return len; +} + +#define setfh(d, s) fhcopy((d)->version, (s), (d)->fh) +#define getfh(d, s) fhcopy((d)->version, (d)->fh, (s)) + + struct nfs_iodesc nfs_root_node; -int nfs_getrootfh(struct iodesc *, char *, u_char *); +int nfs_getrootfh(struct iodesc *, char *, u_char *, int *); int nfs_lookupfh(struct nfs_iodesc *, const char *, int, struct nfs_iodesc *); int nfs_readlink(struct nfs_iodesc *, char *); @@ -122,7 +146,7 @@ ssize_t nfs_readdata(struct nfs_iodesc * * On error, return non-zero and set errno. */ int -nfs_getrootfh(struct iodesc *d, char *path, u_char *fhp) +nfs_getrootfh(struct iodesc *d, char *path, u_char *fhp, int *versionp) { int len; struct args { @@ -131,7 +155,7 @@ nfs_getrootfh(struct iodesc *d, char *pa } *args; struct repl { n_long errno; - u_char fh[NFS_FHSIZE]; + u_char fh[NFS_FHSTORE]; } *repl; struct { n_long h[RPC_HEADER_WORDS]; @@ -159,8 +183,14 @@ nfs_getrootfh(struct iodesc *d, char *pa (void)memcpy(args->path, path, len); len = 4 + roundup(len, 4); - cc = rpc_call(d, RPCPROG_MNT, RPCMNT_VER1, RPCMNT_MOUNT, + *versionp = NFS_VER3; + cc = rpc_call(d, RPCPROG_MNT, RPCMNT_VER3, RPCMNT_MOUNT, args, len, repl, sizeof(*repl)); + if (cc == -1 || cc < 4 || repl->errno) { + *versionp = NFS_VER2; + cc = rpc_call(d, RPCPROG_MNT, RPCMNT_VER1, RPCMNT_MOUNT, + args, len, repl, sizeof(*repl)); + } if (cc == -1) { /* errno was set by rpc_call */ return -1; @@ -173,7 +203,7 @@ nfs_getrootfh(struct iodesc *d, char *pa errno = ntohl(repl->errno); return -1; } - (void)memcpy(fhp, repl->fh, sizeof(repl->fh)); + fhcopy(*versionp, repl->fh, fhp); return 0; } @@ -185,58 +215,126 @@ int nfs_lookupfh(struct nfs_iodesc *d, const char *name, int len, struct nfs_iodesc *newfd) { - int rlen; - struct args { + struct argsv2 { u_char fh[NFS_FHSIZE]; n_long len; char name[FNAME_SIZE]; - } *args; - struct repl { + } *argsv2; + struct argsv3 { + u_char fh[NFS_FHSTORE]; + n_long len; + char name[FNAME_SIZE]; + } *argsv3; + struct replv2 { n_long errno; u_char fh[NFS_FHSIZE]; - struct nfsv2_fattrs fa; - } *repl; + struct nfsv2_fattr fa; + } *replv2; + struct replv3 { + n_long errno; + u_char fh[NFS_FHSTORE]; + n_long fattrflag; + struct nfsv3_fattr fa; + n_long dattrflag; + struct nfsv3_fattr da; + } *replv3; struct { n_long h[RPC_HEADER_WORDS]; - struct args d; + union { + struct argsv2 v2; + struct argsv3 v3; + } u_d; } sdata; struct { n_long h[RPC_HEADER_WORDS]; - struct repl d; + union { + struct replv2 v2; + struct replv3 v3; + } u_d; } rdata; ssize_t cc; + size_t alen; #ifdef NFS_DEBUG if (debug) printf("%s: called\n", __func__); #endif - args = &sdata.d; - repl = &rdata.d; + argsv2 = &sdata.u_d.v2; + argsv3 = &sdata.u_d.v3; + replv2 = &rdata.u_d.v2; + replv3 = &rdata.u_d.v3; + + switch (d->version) { + case NFS_VER2: + (void)memset(argsv2, 0, sizeof(*argsv2)); + getfh(d, argsv2->fh); + if ((size_t)len > sizeof(argsv2->name)) + len = sizeof(argsv2->name); + (void)memcpy(argsv2->name, name, len); + argsv2->len = htonl(len); + + /* padded name, name length */ + len = roundup(len, 4) + 4; + /* filehandle size */ + alen = fhstore(d->version, argsv2->fh); - (void)memset(args, 0, sizeof(*args)); - (void)memcpy(args->fh, d->fh, sizeof(args->fh)); - if ((size_t)len > sizeof(args->name)) - len = sizeof(args->name); - (void)memcpy(args->name, name, len); - args->len = htonl(len); - len = 4 + roundup(len, 4); - len += NFS_FHSIZE; + cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_LOOKUP, + argsv2, alen+len, replv2, sizeof(*replv2)); + break; + case NFS_VER3: + (void)memset(argsv3, 0, sizeof(*argsv3)); + getfh(d, argsv3->fh); + if ((size_t)len > sizeof(argsv3->name)) + len = sizeof(argsv3->name); + (void)memcpy(argsv3->name, name, len); + argsv3->len = htonl(len); + + /* padded name, name length */ + len = roundup(len, 4) + 4; + /* filehandle size */ + alen = fhstore(d->version, argsv3->fh); - rlen = sizeof(*repl); + /* adjust for variable sized file handle */ + memmove(argsv3->fh + alen, &argsv3->len, len); + + cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER3, NFSV3PROC_LOOKUP, + argsv3, alen+len, replv3, sizeof(*replv3)); + break; + default: + return ENOSYS; + } - cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_LOOKUP, - args, len, repl, rlen); if (cc == -1) return errno; /* XXX - from rpc_call */ if (cc < 4) return EIO; - if (repl->errno) { - /* saerrno.h now matches NFS error numbers. */ - return ntohl(repl->errno); + + switch (d->version) { + case NFS_VER2: + if (replv2->errno) { + /* saerrno.h now matches NFS error numbers. */ + return ntohl(replv2->errno); + } + + setfh(newfd, replv2->fh); + (void)memcpy(&newfd->u_fa.v2, &replv2->fa, + sizeof(newfd->u_fa.v2)); + break; + case NFS_VER3: + if (replv3->errno) { + /* saerrno.h now matches NFS error numbers. */ + return ntohl(replv3->errno); + } + + setfh(newfd, replv3->fh); + + if (replv3->fattrflag) { + (void)memcpy(&newfd->u_fa.v3, &replv3->fa, + sizeof(newfd->u_fa.v3)); + } + break; } - (void)memcpy(&newfd->fh, repl->fh, sizeof(newfd->fh)); - (void)memcpy(&newfd->fa, &repl->fa, sizeof(newfd->fa)); return 0; } @@ -249,7 +347,7 @@ nfs_readlink(struct nfs_iodesc *d, char { struct { n_long h[RPC_HEADER_WORDS]; - u_char fh[NFS_FHSIZE]; + u_char fh[NFS_FHSTORE]; } sdata; struct { n_long h[RPC_HEADER_WORDS]; @@ -262,10 +360,10 @@ nfs_readlink(struct nfs_iodesc *d, char printf("%s: called\n", __func__); #endif - (void)memcpy(sdata.fh, d->fh, NFS_FHSIZE); - cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_READLINK, - sdata.fh, NFS_FHSIZE, - &rdata.d, sizeof(rdata.d)); + getfh(d, sdata.fh); + cc = rpc_call(d->iodesc, NFS_PROG, d->version, NFSPROC_READLINK, + sdata.fh, fhstore(d->version, sdata.fh), + &rdata.d, sizeof(rdata.d)); if (cc == -1) return errno; @@ -292,34 +390,99 @@ nfs_readlink(struct nfs_iodesc *d, char ssize_t nfs_readdata(struct nfs_iodesc *d, off_t off, void *addr, size_t len) { - struct nfs_read_args *args; - struct nfs_read_repl *repl; + struct argsv2 { + u_char fh[NFS_FHSIZE]; + n_long off; + n_long len; + n_long xxx; /* XXX what's this for? */ + } *argsv2; + struct argsv3 { + u_char fh[NFS_FHSTORE]; + n_long off[2]; + n_long len; + } *argsv3; + struct replv2 { + n_long errno; + struct nfsv2_fattr fa; + n_long count; + u_char data[NFSREAD_SIZE]; + } *replv2; + struct replv3 { + n_long errno; + n_long attrflag; + struct nfsv3_fattr fa; + n_long count; + n_long eof; + n_long length; + u_char data[NFSREAD_SIZE]; + } *replv3; + struct replv3_noattr { + n_long errno; + n_long attrflag; + n_long count; + n_long eof; + n_long length; + u_char data[NFSREAD_SIZE]; + } *replv3no; struct { n_long h[RPC_HEADER_WORDS]; - struct nfs_read_args d; + union { + struct argsv2 v2; + struct argsv3 v3; + } u_d; } sdata; struct { n_long h[RPC_HEADER_WORDS]; - struct nfs_read_repl d; + union { + struct replv2 v2; + struct replv3 v3; + } u_d; } rdata; ssize_t cc; long x; - size_t hlen, rlen; + size_t hlen, rlen, alen; + u_char *data; - args = &sdata.d; - repl = &rdata.d; + argsv2 = &sdata.u_d.v2; + argsv3 = &sdata.u_d.v3; + replv2 = &rdata.u_d.v2; + replv3 = &rdata.u_d.v3; - (void)memcpy(args->fh, d->fh, NFS_FHSIZE); - args->off = htonl((n_long)off); if (len > NFSREAD_SIZE) len = NFSREAD_SIZE; - args->len = htonl((n_long)len); - args->xxx = htonl((n_long)0); - hlen = sizeof(*repl) - NFSREAD_SIZE; - - cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_READ, - args, sizeof(*args), - repl, sizeof(*repl)); + + switch (d->version) { + case NFS_VER2: + getfh(d, argsv2->fh); + argsv2->off = htonl((n_long)off); + argsv2->len = htonl((n_long)len); + argsv2->xxx = htonl((n_long)0); + hlen = sizeof(*replv2) - NFSREAD_SIZE; + cc = rpc_call(d->iodesc, NFS_PROG, d->version, NFSPROC_READ, + argsv2, sizeof(*argsv2), + replv2, sizeof(*replv2)); + break; + case NFS_VER3: + getfh(d, argsv3->fh); + setnquad(argsv3->off, (uint64_t)off); + argsv3->len = htonl((n_long)len); + hlen = sizeof(*replv3) - NFSREAD_SIZE; + + /* adjust for variable sized file handle */ + alen = sizeof(*argsv3) - offsetof(struct argsv3, off); + memmove(argsv3->fh + fhstore(d->version, argsv3->fh), + &argsv3->off, alen); + alen += fhstore(d->version, argsv3->fh); + + cc = rpc_call(d->iodesc, NFS_PROG, d->version, NFSPROC_READ, + argsv3, alen, + replv3, sizeof(*replv3)); + break; + default: + errno = ENOSYS; + return -1; + } + if (cc == -1) { /* errno was already set by rpc_call */ return -1; @@ -328,18 +491,44 @@ nfs_readdata(struct nfs_iodesc *d, off_t errno = EBADRPC; return -1; } - if (repl->errno) { - errno = ntohl(repl->errno); + + switch (d->version) { + case NFS_VER2: + if (replv2->errno) { + errno = ntohl(replv2->errno); + return -1; + } + x = ntohl(replv2->count); + data = replv2->data; + break; + case NFS_VER3: + if (replv3->errno) { + errno = ntohl(replv3->errno); + return -1; + } + + /* adjust for optional attributes */ + if (replv3->attrflag) { + x = ntohl(replv3->length); + data = replv3->data; + } else { + replv3no = (struct replv3_noattr *)replv3; + x = ntohl(replv3no->length); + data = replv3no->data; + } + break; + default: + errno = ENOSYS; return -1; } + rlen = cc - hlen; - x = ntohl(repl->count); if (rlen < (size_t)x) { printf("%s: short packet, %zu < %ld\n", __func__, rlen, x); errno = EBADRPC; return -1; } - (void)memcpy(addr, repl->data, x); + (void)memcpy(addr, data, x); return x; } @@ -351,7 +540,8 @@ int nfs_mount(int sock, struct in_addr ip, char *path) { struct iodesc *desc; - struct nfsv2_fattrs *fa; + struct nfsv2_fattr *fa2; + struct nfsv3_fattr *fa3; if (!(desc = socktodesc(sock))) { errno = EINVAL; @@ -361,14 +551,27 @@ nfs_mount(int sock, struct in_addr ip, c /* Bind to a reserved port. */ desc->myport = htons(--rpc_port); desc->destip = ip; - if (nfs_getrootfh(desc, path, nfs_root_node.fh)) + if (nfs_getrootfh(desc, path, nfs_root_node.fh, &nfs_root_node.version)) return -1; nfs_root_node.iodesc = desc; /* Fake up attributes for the root dir. */ - fa = &nfs_root_node.fa; - fa->fa_type = htonl(NFDIR); - fa->fa_mode = htonl(0755); - fa->fa_nlink = htonl(2); + switch (nfs_root_node.version) { + case NFS_VER2: + fa2 = &nfs_root_node.u_fa.v2; + fa2->fa_type = htonl(NFDIR); + fa2->fa_mode = htonl(0755); + fa2->fa_nlink = htonl(2); + break; + case NFS_VER3: + fa3 = &nfs_root_node.u_fa.v3; + fa3->fa_type = htonl(NFDIR); + fa3->fa_mode = htonl(0755); + fa3->fa_nlink = htonl(2); + break; + default: + errno = ENOSYS; + return -1; + } #ifdef NFS_DEBUG if (debug) @@ -393,6 +596,7 @@ nfs_open(const char *path, struct open_f char namebuf[NFS_MAXPATHLEN + 1]; char linkbuf[NFS_MAXPATHLEN + 1]; int nlinks = 0; + n_long fa_type; #endif int error = 0; @@ -400,6 +604,12 @@ nfs_open(const char *path, struct open_f if (debug) printf("%s: %s\n", __func__, path); #endif + +#ifdef LIBSA_NFS_IMPLICIT_MOUNT + if (nfs_mount(*((int *)(f->f_devdata)), rootip, rootpath)) + return errno; +#endif + if (nfs_root_node.iodesc == NULL) { printf("%s: must mount first.\n", __func__); return ENXIO; @@ -422,7 +632,18 @@ nfs_open(const char *path, struct open_f /* * Check that current node is a directory. */ - if (currfd->fa.fa_type != htonl(NFDIR)) { + switch (currfd->version) { + case NFS_VER2: + fa_type = currfd->u_fa.v2.fa_type; + break; + case NFS_VER3: + fa_type = currfd->u_fa.v3.fa_type; + break; + default: + fa_type = htonl(NFNON); + break; + } + if (fa_type != htonl(NFDIR)) { error = ENOTDIR; goto out; } @@ -431,6 +652,7 @@ nfs_open(const char *path, struct open_f newfd = alloc(sizeof(*newfd)); newfd->iodesc = currfd->iodesc; newfd->off = 0; + newfd->version = currfd->version; /* * Get next component of path name. @@ -456,7 +678,18 @@ nfs_open(const char *path, struct open_f /* * Check for symbolic link */ - if (newfd->fa.fa_type == htonl(NFLNK)) { + switch (newfd->version) { + case NFS_VER2: + fa_type = newfd->u_fa.v2.fa_type; + break; + case NFS_VER3: + fa_type = newfd->u_fa.v3.fa_type; + break; + default: + fa_type = htonl(NFNON); + break; + } + if (fa_type == htonl(NFLNK)) { int link_len, len; error = nfs_readlink(newfd, linkbuf); @@ -506,6 +739,7 @@ out: currfd = alloc(sizeof(*currfd)); currfd->iodesc = nfs_root_node.iodesc; currfd->off = 0; + currfd->version = nfs_root_node.version; cp = path; /* @@ -613,7 +847,18 @@ __compactcall off_t nfs_seek(struct open_file *f, off_t offset, int where) { struct nfs_iodesc *d = (struct nfs_iodesc *)f->f_fsdata; - n_long size = ntohl(d->fa.fa_size); + off_t size; + + switch (d->version) { + case NFS_VER2: + size = ntohl(d->u_fa.v2.fa_size); + break; + case NFS_VER3: + size = getnquad(d->u_fa.v3.fa_size); + break; + default: + return -1; + } switch (where) { case SEEK_SET: @@ -642,15 +887,29 @@ nfs_stat(struct open_file *f, struct sta struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata; n_long ftype, mode; - ftype = ntohl(fp->fa.fa_type); - mode = ntohl(fp->fa.fa_mode); - mode |= nfs_stat_types[ftype & 7]; + switch (fp->version) { + case NFS_VER2: + ftype = ntohl(fp->u_fa.v2.fa_type); + mode = ntohl(fp->u_fa.v2.fa_mode); + sb->st_nlink = ntohl(fp->u_fa.v2.fa_nlink); + sb->st_uid = ntohl(fp->u_fa.v2.fa_uid); + sb->st_gid = ntohl(fp->u_fa.v2.fa_gid); + sb->st_size = ntohl(fp->u_fa.v2.fa_size); + break; + case NFS_VER3: + ftype = ntohl(fp->u_fa.v3.fa_type); + mode = ntohl(fp->u_fa.v3.fa_mode); + sb->st_nlink = ntohl(fp->u_fa.v3.fa_nlink); + sb->st_uid = ntohl(fp->u_fa.v3.fa_uid); + sb->st_gid = ntohl(fp->u_fa.v3.fa_gid); + sb->st_size = getnquad(fp->u_fa.v3.fa_size); + break; + default: + return -1; + } + mode |= nfs_stat_types[ftype & 7]; sb->st_mode = mode; - sb->st_nlink = ntohl(fp->fa.fa_nlink); - sb->st_uid = ntohl(fp->fa.fa_uid); - sb->st_gid = ntohl(fp->fa.fa_gid); - sb->st_size = ntohl(fp->fa.fa_size); return 0; } Index: src/sys/lib/libsa/nfsv2.h diff -u src/sys/lib/libsa/nfsv2.h:1.4 src/sys/lib/libsa/nfsv2.h:1.4.194.1 --- src/sys/lib/libsa/nfsv2.h:1.4 Sun Dec 11 12:24:46 2005 +++ src/sys/lib/libsa/nfsv2.h Fri Sep 20 11:31:31 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: nfsv2.h,v 1.4 2005/12/11 12:24:46 christos Exp $ */ +/* $NetBSD: nfsv2.h,v 1.4.194.1 2024/09/20 11:31:31 martin Exp $ */ /* * Copyright (c) 1989, 1993 @@ -144,19 +144,3 @@ struct nfsv2_fattr { struct nfsv2_time fa_ctime; }; -struct nfsv2_sattr { - n_long sa_mode; - n_long sa_uid; - n_long sa_gid; - n_long sa_size; - struct nfsv2_time sa_atime; - struct nfsv2_time sa_mtime; -}; - -struct nfsv2_statfs { - n_long sf_tsize; - n_long sf_bsize; - n_long sf_blocks; - n_long sf_bfree; - n_long sf_bavail; -}; Index: src/sys/lib/libsa/rpcv2.h diff -u src/sys/lib/libsa/rpcv2.h:1.3 src/sys/lib/libsa/rpcv2.h:1.3.194.1 --- src/sys/lib/libsa/rpcv2.h:1.3 Sun Dec 11 12:24:46 2005 +++ src/sys/lib/libsa/rpcv2.h Fri Sep 20 11:31:31 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: rpcv2.h,v 1.3 2005/12/11 12:24:46 christos Exp $ */ +/* $NetBSD: rpcv2.h,v 1.3.194.1 2024/09/20 11:31:31 martin Exp $ */ /* * Copyright (c) 1989, 1993 @@ -75,6 +75,7 @@ /* RPC Prog definitions */ #define RPCPROG_MNT 100005 #define RPCMNT_VER1 1 +#define RPCMNT_VER3 3 #define RPCMNT_MOUNT 1 #define RPCMNT_DUMP 2 #define RPCMNT_UMOUNT 3 Added files: Index: src/sys/lib/libsa/nfsv3.h diff -u /dev/null src/sys/lib/libsa/nfsv3.h:1.1.4.2 --- /dev/null Fri Sep 20 11:31:32 2024 +++ src/sys/lib/libsa/nfsv3.h Fri Sep 20 11:31:31 2024 @@ -0,0 +1,73 @@ +/* $NetBSD: nfsv3.h,v 1.1.4.2 2024/09/20 11:31:31 martin Exp $ */ + +/* + * Copyright (c) 2023 Michael van Elst + * + * This code is derived from software contributed to Berkeley by + * Rick Macklem at The University of Guelph. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * nfs definitions as per the version 3 specs + */ + +#define NFS_VER3 3 +#define NFS_V3FHSIZE 64 + +/* Sizes in bytes of various nfs rpc components */ +#define NFSX_V3FH 64 +#define NFSX_V3FATTR 84 + +/* Different V3 procedure numbers that we need */ +#define NFSV3PROC_LOOKUP 3 + +/* Structs for common parts of the rpc's */ +struct nfsv3_time { + n_long nfs_sec; + n_long nfs_nsec; +}; + +struct nfsv3_spec { + n_long specdata1; + n_long specdata2; +}; + +/* + * File attributes and setable attributes. + */ +struct nfsv3_fattr { + n_long fa_type; + n_long fa_mode; + n_long fa_nlink; + n_long fa_uid; + n_long fa_gid; + n_long fa_size[2]; /* nfsuint64 */ + n_long fa_used[2]; /* nfsuint64 */ + struct nfsv3_spec fa_rdev; + n_long fa_fsid[2]; /* nfsuint64 */ + n_long fa_fileid[2]; /* nfsuint64 */ + struct nfsv3_time fa_atime; + struct nfsv3_time fa_mtime; + struct nfsv3_time fa_ctime; +};