diff options
author | peter <peter@FreeBSD.org> | 2001-09-18 23:32:09 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2001-09-18 23:32:09 +0000 |
commit | 85182a8d785d189f1e845c7d66810e3977ac161b (patch) | |
tree | 626c88f61c1e52e9cd18eaec61b54aaaee5d3bfc /sys/nfsclient | |
parent | abe9cf18de01077e00cd2ee3d47363af647e65e4 (diff) | |
download | FreeBSD-src-85182a8d785d189f1e845c7d66810e3977ac161b.zip FreeBSD-src-85182a8d785d189f1e845c7d66810e3977ac161b.tar.gz |
Cleanup and split of nfs client and server code.
This builds on the top of several repo-copies.
Diffstat (limited to 'sys/nfsclient')
-rw-r--r-- | sys/nfsclient/bootp_subr.c | 471 | ||||
-rw-r--r-- | sys/nfsclient/krpc.h | 10 | ||||
-rw-r--r-- | sys/nfsclient/krpc_subr.c | 29 | ||||
-rw-r--r-- | sys/nfsclient/nfs.h | 567 | ||||
-rw-r--r-- | sys/nfsclient/nfs_bio.c | 294 | ||||
-rw-r--r-- | sys/nfsclient/nfs_lock.c | 37 | ||||
-rw-r--r-- | sys/nfsclient/nfs_lock.h | 26 | ||||
-rw-r--r-- | sys/nfsclient/nfs_nfsiod.c | 1097 | ||||
-rw-r--r-- | sys/nfsclient/nfs_node.c | 93 | ||||
-rw-r--r-- | sys/nfsclient/nfs_socket.c | 1157 | ||||
-rw-r--r-- | sys/nfsclient/nfs_subs.c | 1809 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vfsops.c | 266 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vnops.c | 971 | ||||
-rw-r--r-- | sys/nfsclient/nfsargs.h | 641 | ||||
-rw-r--r-- | sys/nfsclient/nfsdiskless.h | 11 | ||||
-rw-r--r-- | sys/nfsclient/nfsm_subs.h | 571 | ||||
-rw-r--r-- | sys/nfsclient/nfsmount.h | 18 | ||||
-rw-r--r-- | sys/nfsclient/nfsnode.h | 44 | ||||
-rw-r--r-- | sys/nfsclient/nfsstats.h | 664 | ||||
-rw-r--r-- | sys/nfsclient/nlminfo.h | 3 |
20 files changed, 1497 insertions, 7282 deletions
diff --git a/sys/nfsclient/bootp_subr.c b/sys/nfsclient/bootp_subr.c index 063f77f..8d3ad2a 100644 --- a/sys/nfsclient/bootp_subr.c +++ b/sys/nfsclient/bootp_subr.c @@ -1,5 +1,3 @@ -/* $FreeBSD$ */ - /* * Copyright (c) 1995 Gordon Ross, Adam Glass * Copyright (c) 1992 Regents of the University of California. @@ -42,6 +40,9 @@ * $NetBSD: krpc_subr.c,v 1.10 1995/08/08 20:43:43 gwr Exp $ */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + #include "opt_bootp.h" #include <sys/param.h> @@ -64,9 +65,9 @@ #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> -#include <nfs/nfs.h> -#include <nfs/nfsdiskless.h> -#include <nfs/krpc.h> +#include <nfsclient/nfs.h> +#include <nfsclient/nfsdiskless.h> +#include <nfsclient/krpc.h> #include <nfs/xdr_subs.h> @@ -207,38 +208,31 @@ struct bootpc_globalcontext { #define DHCP_REQUEST 3 #define DHCP_ACK 5 -extern int nfs_diskless_valid; -extern struct nfsv3_diskless nfsv3_diskless; - /* mountd RPC */ -static int md_mount(struct sockaddr_in *mdsin, char *path, - u_char *fhp, int *fhsizep, - struct nfs_args *args,struct thread *td); -static int md_lookup_swap(struct sockaddr_in *mdsin,char *path, - u_char *fhp, int *fhsizep, - struct nfs_args *args, - struct thread *td); -static int setfs(struct sockaddr_in *addr, char *path, char *p); -static int getdec(char **ptr); -static char *substr(char *a,char *b); -static void mountopts(struct nfs_args *args, char *p); -static int xdr_opaque_decode(struct mbuf **ptr, u_char *buf, int len); -static int xdr_int_decode(struct mbuf **ptr, int *iptr); -static void print_in_addr(struct in_addr addr); -static void print_sin_addr(struct sockaddr_in *addr); -static void clear_sinaddr(struct sockaddr_in *sin); -static -struct bootpc_ifcontext *allocifctx(struct bootpc_globalcontext *gctx); -static void bootpc_compose_query(struct bootpc_ifcontext *ifctx, - struct bootpc_globalcontext *gctx, - struct thread *td); +static int md_mount(struct sockaddr_in *mdsin, char *path, u_char *fhp, + int *fhsizep, struct nfs_args *args, struct thread *td); +static int md_lookup_swap(struct sockaddr_in *mdsin, char *path, + u_char *fhp, int *fhsizep, struct nfs_args *args, + struct thread *td); +static int setfs(struct sockaddr_in *addr, char *path, char *p); +static int getdec(char **ptr); +static char *substr(char *a, char *b); +static void mountopts(struct nfs_args *args, char *p); +static int xdr_opaque_decode(struct mbuf **ptr, u_char *buf, int len); +static int xdr_int_decode(struct mbuf **ptr, int *iptr); +static void print_in_addr(struct in_addr addr); +static void print_sin_addr(struct sockaddr_in *addr); +static void clear_sinaddr(struct sockaddr_in *sin); +static struct bootpc_ifcontext *allocifctx(struct bootpc_globalcontext *gctx); +static void bootpc_compose_query(struct bootpc_ifcontext *ifctx, + struct bootpc_globalcontext *gctx, struct thread *td); static unsigned char *bootpc_tag(struct bootpc_tagcontext *tctx, - struct bootp_packet *bp, int len, int tag); + struct bootp_packet *bp, int len, int tag); static void bootpc_tag_helper(struct bootpc_tagcontext *tctx, - unsigned char *start, int len, int tag); + unsigned char *start, int len, int tag); #ifdef BOOTP_DEBUG -void bootpboot_p_sa(struct sockaddr *sa,struct sockaddr *ma); +void bootpboot_p_sa(struct sockaddr *sa, struct sockaddr *ma); void bootpboot_p_ma(struct sockaddr *ma); void bootpboot_p_rtentry(struct rtentry *rt); void bootpboot_p_tree(struct radix_node *rn); @@ -247,23 +241,21 @@ void bootpboot_p_if(struct ifnet *ifp, struct ifaddr *ifa); void bootpboot_p_iflist(void); #endif -static int bootpc_call(struct bootpc_globalcontext *gctx, - struct thread *td); +static int bootpc_call(struct bootpc_globalcontext *gctx, + struct thread *td); -static int bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx, - struct bootpc_globalcontext *gctx, - struct thread *td); +static int bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx, + struct bootpc_globalcontext *gctx, struct thread *td); -static int bootpc_adjust_interface(struct bootpc_ifcontext *ifctx, - struct bootpc_globalcontext *gctx, - struct thread *td); +static int bootpc_adjust_interface(struct bootpc_ifcontext *ifctx, + struct bootpc_globalcontext *gctx, struct thread *td); -static void bootpc_decode_reply(struct nfsv3_diskless *nd, - struct bootpc_ifcontext *ifctx, - struct bootpc_globalcontext *gctx); +static void bootpc_decode_reply(struct nfsv3_diskless *nd, + struct bootpc_ifcontext *ifctx, + struct bootpc_globalcontext *gctx); -static int bootpc_received(struct bootpc_globalcontext *gctx, - struct bootpc_ifcontext *ifctx); +static int bootpc_received(struct bootpc_globalcontext *gctx, + struct bootpc_ifcontext *ifctx); static __inline int bootpc_ifctx_isresolved(struct bootpc_ifcontext *ifctx); static __inline int bootpc_ifctx_isunresolved(struct bootpc_ifcontext *ifctx); @@ -275,7 +267,7 @@ void bootpc_init(void); * In order to have multiple active interfaces with address 0.0.0.0 * and be able to send data to a selected interface, we perform * some tricks: - * + * * - The 'broadcast' address is different for each interface. * * - We temporarily add routing pointing 255.255.255.255 to the @@ -285,9 +277,9 @@ void bootpc_init(void); #ifdef BOOTP_DEBUG void -bootpboot_p_sa(struct sockaddr *sa, - struct sockaddr *ma) +bootpboot_p_sa(struct sockaddr *sa, struct sockaddr *ma) { + if (sa == NULL) { printf("(sockaddr *) <null>"); return; @@ -296,7 +288,7 @@ bootpboot_p_sa(struct sockaddr *sa, case AF_INET: { struct sockaddr_in *sin; - + sin = (struct sockaddr_in *) sa; printf("inet "); print_sin_addr(sin); @@ -311,7 +303,7 @@ bootpboot_p_sa(struct sockaddr *sa, { struct sockaddr_dl *sli; int i; - + sli = (struct sockaddr_dl *) sa; printf("link %.*s ", sli->sdl_nlen, sli->sdl_data); for (i = 0; i < sli->sdl_alen; i++) { @@ -326,10 +318,10 @@ bootpboot_p_sa(struct sockaddr *sa, } } - void bootpboot_p_ma(struct sockaddr *ma) { + if (ma == NULL) { printf("<null>"); return; @@ -337,10 +329,10 @@ bootpboot_p_ma(struct sockaddr *ma) printf("%x", *(int *)ma); } - void bootpboot_p_rtentry(struct rtentry *rt) { + bootpboot_p_sa(rt_key(rt), rt_mask(rt)); printf(" "); bootpboot_p_ma(rt->rt_genmask); @@ -352,10 +344,10 @@ bootpboot_p_rtentry(struct rtentry *rt) printf(" %s%d\n", rt->rt_ifp->if_name, rt->rt_ifp->if_unit); } - void bootpboot_p_tree(struct radix_node *rn) { + while (rn != NULL) { if (rn->rn_bit < 0) { if ((rn->rn_flags & RNF_ROOT) != 0) { @@ -371,18 +363,18 @@ bootpboot_p_tree(struct radix_node *rn) } } - void bootpboot_p_rtlist(void) { + printf("Routing table:\n"); bootpboot_p_tree(rt_tables[AF_INET]->rnh_treetop); } - void bootpboot_p_if(struct ifnet *ifp, struct ifaddr *ifa) { + printf("%s%d flags %x, addr ", ifp->if_name, ifp->if_unit, @@ -395,13 +387,12 @@ bootpboot_p_if(struct ifnet *ifp, struct ifaddr *ifa) printf("\n"); } - void bootpboot_p_iflist(void) { struct ifnet *ifp; struct ifaddr *ifa; - + printf("Interface list:\n"); for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; @@ -415,10 +406,10 @@ bootpboot_p_iflist(void) } #endif /* defined(BOOTP_DEBUG) */ - static void clear_sinaddr(struct sockaddr_in *sin) { + bzero(sin, sizeof(*sin)); sin->sin_len = sizeof(*sin); sin->sin_family = AF_INET; @@ -426,7 +417,6 @@ clear_sinaddr(struct sockaddr_in *sin) sin->sin_port = 0; } - static struct bootpc_ifcontext * allocifctx(struct bootpc_globalcontext *gctx) { @@ -435,7 +425,7 @@ allocifctx(struct bootpc_globalcontext *gctx) M_TEMP, M_WAITOK); if (ifctx == NULL) panic("Failed to allocate bootp interface context structure"); - + bzero(ifctx, sizeof(*ifctx)); ifctx->xid = gctx->xid; #ifdef BOOTP_NO_DHCP @@ -447,49 +437,48 @@ allocifctx(struct bootpc_globalcontext *gctx) return ifctx; } - static __inline int bootpc_ifctx_isresolved(struct bootpc_ifcontext *ifctx) { + if (ifctx->state == IF_BOOTP_RESOLVED || ifctx->state == IF_DHCP_RESOLVED) return 1; return 0; } - static __inline int bootpc_ifctx_isunresolved(struct bootpc_ifcontext *ifctx) { + if (ifctx->state == IF_BOOTP_UNRESOLVED || ifctx->state == IF_DHCP_UNRESOLVED) return 1; return 0; } - static __inline int bootpc_ifctx_isfailed(struct bootpc_ifcontext *ifctx) { + if (ifctx->state == IF_BOOTP_FAILED || ifctx->state == IF_DHCP_FAILED) return 1; return 0; } - static int bootpc_received(struct bootpc_globalcontext *gctx, - struct bootpc_ifcontext *ifctx) + struct bootpc_ifcontext *ifctx) { unsigned char dhcpreplytype; char *p; + /* * Need timeout for fallback to less * desirable alternative. */ - /* This call used for the side effect (badopt flag) */ (void) bootpc_tag(&gctx->tmptag, &gctx->reply, gctx->replylen, @@ -498,14 +487,14 @@ bootpc_received(struct bootpc_globalcontext *gctx, /* If packet is invalid, ignore it */ if (gctx->tmptag.badopt != 0) return 0; - + p = bootpc_tag(&gctx->tmptag, &gctx->reply, gctx->replylen, TAG_DHCP_MSGTYPE); if (p != NULL) dhcpreplytype = *p; else dhcpreplytype = DHCP_NOMSG; - + switch (ifctx->dhcpquerytype) { case DHCP_DISCOVER: if (dhcpreplytype != DHCP_OFFER /* Normal DHCP offer */ @@ -520,10 +509,9 @@ bootpc_received(struct bootpc_globalcontext *gctx, return 0; case DHCP_NOMSG: } - - + /* Ignore packet unless it gives us a root tag we didn't have */ - + if ((ifctx->state == IF_BOOTP_RESOLVED || (ifctx->dhcpquerytype == DHCP_DISCOVER && (ifctx->state == IF_DHCP_OFFERED || @@ -535,12 +523,10 @@ bootpc_received(struct bootpc_globalcontext *gctx, gctx->replylen, TAG_ROOT) == NULL)) return 0; - - bcopy(&gctx->reply, - &ifctx->reply, - gctx->replylen); + + bcopy(&gctx->reply, &ifctx->reply, gctx->replylen); ifctx->replylen = gctx->replylen; - + /* XXX: Only reset if 'perfect' response */ if (ifctx->state == IF_BOOTP_UNRESOLVED) ifctx->state = IF_BOOTP_RESOLVED; @@ -553,8 +539,8 @@ bootpc_received(struct bootpc_globalcontext *gctx, } else if (ifctx->state == IF_DHCP_OFFERED && ifctx->dhcpquerytype == DHCP_REQUEST) ifctx->state = IF_DHCP_RESOLVED; - - + + if (ifctx->dhcpquerytype == DHCP_DISCOVER && ifctx->state != IF_BOOTP_RESOLVED) { p = bootpc_tag(&gctx->tmptag, &ifctx->reply, @@ -566,7 +552,7 @@ bootpc_received(struct bootpc_globalcontext *gctx, ifctx->gotdhcpserver = 0; return 1; } - + ifctx->gotrootpath = (bootpc_tag(&gctx->tmptag, &ifctx->reply, ifctx->replylen, TAG_ROOT) != NULL); @@ -580,8 +566,7 @@ bootpc_received(struct bootpc_globalcontext *gctx, } static int -bootpc_call(struct bootpc_globalcontext *gctx, - struct thread *td) +bootpc_call(struct bootpc_globalcontext *gctx, struct thread *td) { struct socket *so; struct sockaddr_in *sin, dst; @@ -597,14 +582,14 @@ bootpc_call(struct bootpc_globalcontext *gctx, int gotrootpath; int retry; const char *s; - + /* * Create socket and set its recieve timeout. */ error = socreate(AF_INET, &so, SOCK_DGRAM, 0, td); if (error != 0) goto out; - + tv.tv_sec = 1; tv.tv_usec = 0; bzero(&sopt, sizeof(sopt)); @@ -612,11 +597,11 @@ bootpc_call(struct bootpc_globalcontext *gctx, sopt.sopt_name = SO_RCVTIMEO; sopt.sopt_val = &tv; sopt.sopt_valsize = sizeof tv; - + error = sosetopt(so, &sopt); if (error != 0) goto out; - + /* * Enable broadcast. */ @@ -641,7 +626,7 @@ bootpc_call(struct bootpc_globalcontext *gctx, error = sosetopt(so, &sopt); if (error != 0) goto out; - + /* * Bind the local endpoint to a bootp client port. */ @@ -653,7 +638,7 @@ bootpc_call(struct bootpc_globalcontext *gctx, printf("bind failed\n"); goto out; } - + /* * Setup socket address for the server. */ @@ -661,7 +646,7 @@ bootpc_call(struct bootpc_globalcontext *gctx, clear_sinaddr(sin); sin->sin_addr.s_addr = INADDR_BROADCAST; sin->sin_port = htons(IPPORT_BOOTPS); - + /* * Send it, repeatedly, until a reply is received, * but delay each re-send by an increasing amount. @@ -670,7 +655,7 @@ bootpc_call(struct bootpc_globalcontext *gctx, timo = 0; rtimo = 0; for (;;) { - + outstanding = 0; gotrootpath = 0; @@ -683,7 +668,7 @@ bootpc_call(struct bootpc_globalcontext *gctx, TAG_ROOT) != NULL) gotrootpath = 1; } - + for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) { @@ -708,9 +693,9 @@ bootpc_call(struct bootpc_globalcontext *gctx, ifctx->sentmsg = 0; bootpc_compose_query(ifctx, gctx, td); } - + /* Send BOOTP request (or re-send). */ - + if (ifctx->sentmsg == 0) { switch(ifctx->dhcpquerytype) { case DHCP_DISCOVER: @@ -736,7 +721,7 @@ bootpc_call(struct bootpc_globalcontext *gctx, aio.iov_base = (caddr_t) &ifctx->call; aio.iov_len = sizeof(ifctx->call); - + auio.uio_iov = &aio; auio.uio_iovcnt = 1; auio.uio_segflg = UIO_SYSSPACE; @@ -744,9 +729,9 @@ bootpc_call(struct bootpc_globalcontext *gctx, auio.uio_offset = 0; auio.uio_resid = sizeof(ifctx->call); auio.uio_td = td; - + /* Set netmask to 0.0.0.0 */ - + sin = (struct sockaddr_in *) &ifctx->ireq.ifr_addr; clear_sinaddr(sin); error = ifioctl(ifctx->so, SIOCSIFNETMASK, @@ -755,7 +740,7 @@ bootpc_call(struct bootpc_globalcontext *gctx, panic("bootpc_call:" "set if netmask, error=%d", error); - + error = sosend(so, (struct sockaddr *) &dst, &auio, NULL, NULL, 0, td); if (error != 0) { @@ -765,9 +750,9 @@ bootpc_call(struct bootpc_globalcontext *gctx, /* XXX: Is this needed ? */ tsleep(&error, PZERO + 8, "bootpw", 10); - + /* Set netmask to 255.0.0.0 */ - + sin = (struct sockaddr_in *) &ifctx->ireq.ifr_addr; clear_sinaddr(sin); sin->sin_addr.s_addr = htonl(0xff000000u); @@ -777,15 +762,15 @@ bootpc_call(struct bootpc_globalcontext *gctx, panic("bootpc_call:" "set if netmask, error=%d", error); - + } - + if (outstanding == 0 && (rtimo == 0 || time_second >= rtimo)) { error = 0; goto gotreply; } - + /* Determine new timeout. */ if (timo < MAX_RESEND_DELAY) timo++; @@ -794,7 +779,7 @@ bootpc_call(struct bootpc_globalcontext *gctx, print_sin_addr(&dst); printf("\n"); } - + /* * Wait for up to timo seconds for a reply. * The socket receive timeout was set to 1 second. @@ -803,7 +788,7 @@ bootpc_call(struct bootpc_globalcontext *gctx, while (time_second < atimo) { aio.iov_base = (caddr_t) &gctx->reply; aio.iov_len = sizeof(gctx->reply); - + auio.uio_iov = &aio; auio.uio_iovcnt = 1; auio.uio_segflg = UIO_SYSSPACE; @@ -811,7 +796,7 @@ bootpc_call(struct bootpc_globalcontext *gctx, auio.uio_offset = 0; auio.uio_resid = sizeof(gctx->reply); auio.uio_td = td; - + rcvflg = 0; error = soreceive(so, NULL, &auio, NULL, NULL, &rcvflg); @@ -822,7 +807,7 @@ bootpc_call(struct bootpc_globalcontext *gctx, if (bootpc_ifctx_isresolved(ifctx) != 0 || bootpc_ifctx_isfailed(ifctx) != 0) continue; - + ifctx->call.secs = htons(gctx->secs); } if (error == EWOULDBLOCK) @@ -830,27 +815,27 @@ bootpc_call(struct bootpc_globalcontext *gctx, if (error != 0) goto out; len = sizeof(gctx->reply) - auio.uio_resid; - + /* Do we have the required number of bytes ? */ if (len < BOOTP_MIN_LEN) continue; gctx->replylen = len; - + /* Is it a reply? */ if (gctx->reply.op != BOOTP_REPLY) continue; - + /* Is this an answer to our query */ for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) { if (gctx->reply.xid != ifctx->call.xid) continue; - + /* Same HW address size ? */ if (gctx->reply.hlen != ifctx->call.hlen) continue; - + /* Correct HW address ? */ if (bcmp(gctx->reply.chaddr, ifctx->call.chaddr, @@ -927,18 +912,18 @@ bootpc_call(struct bootpc_globalcontext *gctx, ifctx->state = IF_DHCP_UNRESOLVED; } } - + if (retry != 0) continue; - + if (gotrootpath != 0) { gctx->gotrootpath = gotrootpath; if (rtimo != 0 && time_second >= rtimo) break; } } /* forever send/receive */ - - /* + + /* * XXX: These are errors of varying seriousness being silently * ignored */ @@ -968,22 +953,19 @@ bootpc_call(struct bootpc_globalcontext *gctx, #endif error = ETIMEDOUT; goto out; - + gotreply: out: soclose(so); return error; } - static int bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx, - struct bootpc_globalcontext *gctx, - struct thread *td) + struct bootpc_globalcontext *gctx, struct thread *td) { struct sockaddr_in *sin; int error; - struct ifreq *ireq; struct socket *so; struct ifaddr *ifa; @@ -992,7 +974,7 @@ bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx, error = socreate(AF_INET, &ifctx->so, SOCK_DGRAM, 0, td); if (error != 0) panic("nfs_boot: socreate, error=%d", error); - + ireq = &ifctx->ireq; so = ifctx->so; @@ -1009,23 +991,23 @@ bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx, error = ifioctl(so, SIOCSIFFLAGS, (caddr_t)ireq, td); if (error != 0) panic("bootpc_fakeup_interface: SIFFLAGS, error=%d", error); - + /* * Do enough of ifconfig(8) so that the chosen interface * can talk to the servers. (just set the address) */ - + /* addr is 0.0.0.0 */ - + sin = (struct sockaddr_in *) &ireq->ifr_addr; clear_sinaddr(sin); error = ifioctl(so, SIOCSIFADDR, (caddr_t) ireq, td); if (error != 0 && (error != EEXIST || ifctx == gctx->interfaces)) panic("bootpc_fakeup_interface: " "set if addr, error=%d", error); - + /* netmask is 255.0.0.0 */ - + sin = (struct sockaddr_in *) &ireq->ifr_addr; clear_sinaddr(sin); sin->sin_addr.s_addr = htonl(0xff000000u); @@ -1033,51 +1015,49 @@ bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx, if (error != 0) panic("bootpc_fakeup_interface: set if netmask, error=%d", error); - + /* Broadcast is 255.255.255.255 */ - + sin = (struct sockaddr_in *)&ireq->ifr_addr; clear_sinaddr(sin); clear_sinaddr(&ifctx->broadcast); sin->sin_addr.s_addr = htonl(INADDR_BROADCAST); ifctx->broadcast.sin_addr.s_addr = sin->sin_addr.s_addr; - + error = ifioctl(so, SIOCSIFBRDADDR, (caddr_t)ireq, td); if (error != 0) panic("bootpc_fakeup_interface: " "set if broadcast addr, error=%d", error); - + /* Get HW address */ - + sdl = NULL; for (ifa = TAILQ_FIRST(&ifctx->ifp->if_addrhead); ifa != NULL; - ifa = TAILQ_NEXT(ifa,ifa_link)) + ifa = TAILQ_NEXT(ifa, ifa_link)) if (ifa->ifa_addr->sa_family == AF_LINK && (sdl = ((struct sockaddr_dl *) ifa->ifa_addr)) != NULL && sdl->sdl_type == IFT_ETHER) break; - + if (sdl == NULL) panic("bootpc: Unable to find HW address for %s", ifctx->ireq.ifr_name); ifctx->sdl = sdl; - + return error; } static int bootpc_adjust_interface(struct bootpc_ifcontext *ifctx, - struct bootpc_globalcontext *gctx, - struct thread *td) + struct bootpc_globalcontext *gctx, struct thread *td) { int error; struct sockaddr_in defdst; struct sockaddr_in defmask; struct sockaddr_in *sin; - struct ifreq *ireq; struct socket *so; struct sockaddr_in *myaddr; @@ -1093,7 +1073,7 @@ bootpc_adjust_interface(struct bootpc_ifcontext *ifctx, if (bootpc_ifctx_isresolved(ifctx) == 0) { /* Shutdown interfaces where BOOTP failed */ - + printf("Shutdown interface %s\n", ifctx->ireq.ifr_name); error = ifioctl(so, SIOCGIFFLAGS, (caddr_t)ireq, td); if (error != 0) @@ -1104,7 +1084,7 @@ bootpc_adjust_interface(struct bootpc_ifcontext *ifctx, if (error != 0) panic("bootpc_adjust_interface: " "SIOCSIFFLAGS, error=%d", error); - + sin = (struct sockaddr_in *) &ireq->ifr_addr; clear_sinaddr(sin); error = ifioctl(so, SIOCDIFADDR, (caddr_t) ireq, td); @@ -1112,7 +1092,7 @@ bootpc_adjust_interface(struct bootpc_ifcontext *ifctx, ifctx == gctx->interfaces)) panic("bootpc_adjust_interface: " "SIOCDIFADDR, error=%d", error); - + return 0; } @@ -1126,9 +1106,9 @@ bootpc_adjust_interface(struct bootpc_ifcontext *ifctx, if (error != 0) panic("bootpc_adjust_interface: " "set if netmask, error=%d", error); - + /* Broadcast is with host part of IP address all 1's */ - + sin = (struct sockaddr_in *) &ireq->ifr_addr; clear_sinaddr(sin); sin->sin_addr.s_addr = myaddr->sin_addr.s_addr | @@ -1137,13 +1117,13 @@ bootpc_adjust_interface(struct bootpc_ifcontext *ifctx, if (error != 0) panic("bootpc_adjust_interface: " "set if broadcast addr, error=%d", error); - + bcopy(myaddr, &ireq->ifr_addr, sizeof(*myaddr)); error = ifioctl(so, SIOCSIFADDR, (caddr_t) ireq, td); if (error != 0 && (error != EEXIST || ifctx == gctx->interfaces)) panic("bootpc_adjust_interface: " "set if addr, error=%d", error); - + /* Add new default route */ if (ifctx->gotgw != 0 || gctx->gotgw == 0) { @@ -1160,17 +1140,16 @@ bootpc_adjust_interface(struct bootpc_ifcontext *ifctx, return error; } } - + return 0; } - static int setfs(struct sockaddr_in *addr, char *path, char *p) { unsigned int ip; int val; - + ip = 0; if (((val = getdec(&p)) < 0) || (val > 255)) return 0; @@ -1196,16 +1175,15 @@ setfs(struct sockaddr_in *addr, char *path, char *p) if (*p != ':') return 0; p++; - + addr->sin_addr.s_addr = htonl(ip); addr->sin_len = sizeof(struct sockaddr_in); addr->sin_family = AF_INET; - + strncpy(path, p, MNAMELEN - 1); return 1; } - static int getdec(char **ptr) { @@ -1224,13 +1202,12 @@ getdec(char **ptr) return ret; } - static char * substr(char *a, char *b) { char *loc1; char *loc2; - + while (*a != '\0') { loc1 = a; loc2 = b; @@ -1246,12 +1223,11 @@ substr(char *a, char *b) return 0; } - static void mountopts(struct nfs_args *args, char *p) { char *tmp; - + args->version = NFS_ARGSVERSION; args->rsize = 8192; args->wsize = 8192; @@ -1273,16 +1249,15 @@ mountopts(struct nfs_args *args, char *p) args->sotype = SOCK_STREAM; } - static int xdr_opaque_decode(struct mbuf **mptr, u_char *buf, int len) { struct mbuf *m; int alignedlen; - + m = *mptr; alignedlen = ( len + 3 ) & ~3; - + if (m->m_len < alignedlen) { m = m_pullup(m, alignedlen); if (m == NULL) { @@ -1296,40 +1271,37 @@ xdr_opaque_decode(struct mbuf **mptr, u_char *buf, int len) return 0; } - static int xdr_int_decode(struct mbuf **mptr, int *iptr) { u_int32_t i; + if (xdr_opaque_decode(mptr, (u_char *) &i, sizeof(u_int32_t)) != 0) return EBADRPC; *iptr = fxdr_unsigned(u_int32_t, i); return 0; } - static void print_sin_addr(struct sockaddr_in *sin) { + print_in_addr(sin->sin_addr); } - static void print_in_addr(struct in_addr addr) { unsigned int ip; - + ip = ntohl(addr.s_addr); printf("%d.%d.%d.%d", ip >> 24, (ip >> 16) & 255, (ip >> 8) & 255, ip & 255); } static void -bootpc_compose_query(ifctx, gctx, td) - struct bootpc_ifcontext *ifctx; - struct bootpc_globalcontext *gctx; - struct thread *td; +bootpc_compose_query(struct bootpc_ifcontext *ifctx, + struct bootpc_globalcontext *gctx, struct thread *td) { unsigned char *vendp; uint32_t leasetime; @@ -1337,7 +1309,7 @@ bootpc_compose_query(ifctx, gctx, td) ifctx->gotrootpath = 0; bzero((caddr_t) &ifctx->call, sizeof(ifctx->call)); - + /* bootpc part */ ifctx->call.op = BOOTP_REQUEST; /* BOOTREQUEST */ ifctx->call.htype = 1; /* 10mb ethernet */ @@ -1347,7 +1319,7 @@ bootpc_compose_query(ifctx, gctx, td) ifctx->xid++; ifctx->call.xid = txdr_unsigned(ifctx->xid); bcopy(LLADDR(ifctx->sdl), &ifctx->call.chaddr, ifctx->sdl->sdl_alen); - + vendp = ifctx->call.vend; *vendp++ = 99; /* RFC1048 cookie */ *vendp++ = 130; @@ -1390,25 +1362,22 @@ bootpc_compose_query(ifctx, gctx, td) ; } *vendp = TAG_END; - + ifctx->call.secs = 0; ifctx->call.flags = htons(0x8000); /* We need an broadcast answer */ } - static int bootpc_hascookie(struct bootp_packet *bp) { + return (bp->vend[0] == 99 && bp->vend[1] == 130 && bp->vend[2] == 83 && bp->vend[3] == 99); } - static void bootpc_tag_helper(struct bootpc_tagcontext *tctx, - unsigned char *start, - int len, - int tag) + unsigned char *start, int len, int tag) { unsigned char *j; unsigned char *ej; @@ -1416,10 +1385,10 @@ bootpc_tag_helper(struct bootpc_tagcontext *tctx, if (tctx->badtag != 0 || tctx->badopt != 0) return; - + j = start; ej = j + len; - + while (j < ej) { code = *j++; if (code == TAG_PAD) @@ -1444,17 +1413,14 @@ bootpc_tag_helper(struct bootpc_tagcontext *tctx, } if (code == TAG_OVERLOAD) tctx->overload = *j; - + j += len; } } - static unsigned char * bootpc_tag(struct bootpc_tagcontext *tctx, - struct bootp_packet *bp, - int len, - int tag) + struct bootp_packet *bp, int len, int tag) { unsigned char *j; unsigned char *ej; @@ -1467,13 +1433,13 @@ bootpc_tag(struct bootpc_tagcontext *tctx, if (bootpc_hascookie(bp) == 0) return NULL; - + j = &bp->vend[4]; ej = (unsigned char *) bp + len; bootpc_tag_helper(tctx, &bp->vend[4], (unsigned char *) bp + len - &bp->vend[4], tag); - + if ((tctx->overload & OVERLOAD_FILE) != 0) bootpc_tag_helper(tctx, (unsigned char *) bp->file, @@ -1484,19 +1450,16 @@ bootpc_tag(struct bootpc_tagcontext *tctx, (unsigned char *) bp->sname, sizeof(bp->sname), tag); - + if (tctx->badopt != 0 || tctx->badtag != 0 || tctx->foundopt == 0) return NULL; tctx->buf[tctx->taglen] = '\0'; return tctx->buf; } - static void -bootpc_decode_reply(nd, ifctx, gctx) - struct nfsv3_diskless *nd; - struct bootpc_ifcontext *ifctx; - struct bootpc_globalcontext *gctx; +bootpc_decode_reply(struct nfsv3_diskless *nd, struct bootpc_ifcontext *ifctx, + struct bootpc_globalcontext *gctx) { char *p; unsigned int ip; @@ -1507,19 +1470,19 @@ bootpc_decode_reply(nd, ifctx, gctx) clear_sinaddr(&ifctx->myaddr); clear_sinaddr(&ifctx->netmask); clear_sinaddr(&ifctx->gw); - + ifctx->myaddr.sin_addr = ifctx->reply.yiaddr; - + ip = ntohl(ifctx->myaddr.sin_addr.s_addr); snprintf(gctx->lookup_path, sizeof(gctx->lookup_path), "swap.%d.%d.%d.%d", ip >> 24, (ip >> 16) & 255, (ip >> 8) & 255, ip & 255); - + printf("%s at ", ifctx->ireq.ifr_name); print_sin_addr(&ifctx->myaddr); printf(" server "); print_in_addr(ifctx->reply.siaddr); - + ifctx->gw.sin_addr = ifctx->reply.giaddr; if (ifctx->reply.giaddr.s_addr != htonl(INADDR_ANY)) { printf(" via gateway "); @@ -1529,14 +1492,14 @@ bootpc_decode_reply(nd, ifctx, gctx) /* This call used for the side effect (overload flag) */ (void) bootpc_tag(&gctx->tmptag, &ifctx->reply, ifctx->replylen, TAG_END); - + if ((gctx->tmptag.overload & OVERLOAD_SNAME) == 0) if (ifctx->reply.sname[0] != '\0') printf(" server name %s", ifctx->reply.sname); if ((gctx->tmptag.overload & OVERLOAD_FILE) == 0) if (ifctx->reply.file[0] != '\0') printf(" boot file %s", ifctx->reply.file); - + printf("\n"); p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, @@ -1551,7 +1514,7 @@ bootpc_decode_reply(nd, ifctx, gctx) print_sin_addr(&ifctx->netmask); printf(" "); } - + p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, TAG_ROUTERS); if (p != NULL) { @@ -1567,7 +1530,7 @@ bootpc_decode_reply(nd, ifctx, gctx) gctx->gotgw = 1; } } - + p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, TAG_ROOT); if (p != NULL) { @@ -1575,11 +1538,11 @@ bootpc_decode_reply(nd, ifctx, gctx) printf("rootfs %s (ignored) ", p); } else if (setfs(&nd->root_saddr, nd->root_hostnam, p)) { - printf("rootfs %s ",p); + printf("rootfs %s ", p); gctx->gotrootpath = 1; ifctx->gotrootpath = 1; gctx->setrootfs = ifctx; - + p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, TAG_ROOTOPTS); @@ -1588,7 +1551,7 @@ bootpc_decode_reply(nd, ifctx, gctx) printf("rootopts %s ", p); } } else - panic("Failed to set rootfs to %s",p); + panic("Failed to set rootfs to %s", p); } p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, @@ -1610,7 +1573,7 @@ bootpc_decode_reply(nd, ifctx, gctx) mountopts(&nd->swap_args, p); printf("swapopts %s ", p); } - + p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen, TAG_SWAPSIZE); @@ -1641,13 +1604,13 @@ bootpc_decode_reply(nd, ifctx, gctx) } else { strcpy(nd->my_hostnam, p); strcpy(hostname, p); - printf("hostname %s ",hostname); + printf("hostname %s ", hostname); gctx->sethostname = ifctx; } } printf("\n"); - + if (ifctx->gotnetmask == 0) { if (IN_CLASSA(ntohl(ifctx->myaddr.sin_addr.s_addr))) ifctx->netmask.sin_addr.s_addr = htonl(IN_CLASSA_NET); @@ -1674,7 +1637,7 @@ bootpc_init(void) nd = &nfsv3_diskless; td = curthread; - + /* * If already filled in, don't touch it here */ @@ -1686,15 +1649,15 @@ bootpc_init(void) */ while (time_second == 0) tsleep(&time_second, PZERO + 8, "arpkludge", 10); - + gctx = malloc(sizeof(*gctx), M_TEMP, M_WAITOK); if (gctx == NULL) panic("Failed to allocate bootp global context structure"); - + bzero(gctx, sizeof(*gctx)); gctx->xid = ~0xFFFF; gctx->starttime = time_second; - + ifctx = allocifctx(gctx); /* @@ -1729,7 +1692,7 @@ bootpc_init(void) ifctx = allocifctx(gctx); } free(ifctx, M_TEMP); - + if (gctx->interfaces == NULL) { #ifdef BOOTP_WIRED_TO panic("bootpc_init: Could not find interface specified " @@ -1739,20 +1702,20 @@ bootpc_init(void) panic("bootpc_init: no suitable interface"); #endif } - + gctx->gotrootpath = 0; gctx->gotswappath = 0; gctx->gotgw = 0; - + for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) bootpc_fakeup_interface(ifctx, gctx, td); - + for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) bootpc_compose_query(ifctx, gctx, td); - + ifctx = gctx->interfaces; error = bootpc_call(gctx, td); - + if (error != 0) { #ifdef BOOTP_NFSROOT panic("BOOTP call failed"); @@ -1760,25 +1723,25 @@ bootpc_init(void) printf("BOOTP call failed\n"); #endif } - + mountopts(&nd->root_args, NULL); - + mountopts(&nd->swap_args, NULL); for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) if (bootpc_ifctx_isresolved(ifctx) != 0) bootpc_decode_reply(nd, ifctx, gctx); - + if (gctx->gotswappath == 0) nd->swap_nblks = 0; #ifdef BOOTP_NFSROOT if (gctx->gotrootpath == 0) panic("bootpc: No root path offered"); #endif - + for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) { bootpc_adjust_interface(ifctx, gctx, td); - + soclose(ifctx->so); } @@ -1794,17 +1757,17 @@ bootpc_init(void) } if (ifctx == NULL) goto out; - + if (gctx->gotrootpath != 0) { - + error = md_mount(&nd->root_saddr, nd->root_hostnam, nd->root_fh, &nd->root_fhsize, &nd->root_args, td); if (error != 0) panic("nfs_boot: mountd root, error=%d", error); - + if (gctx->gotswappath != 0) { - + error = md_mount(&nd->swap_saddr, nd->swap_hostnam, nd->swap_fh, &nd->swap_fhsize, @@ -1812,7 +1775,7 @@ bootpc_init(void) if (error != 0) panic("nfs_boot: mountd swap, error=%d", error); - + error = md_lookup_swap(&nd->swap_saddr, gctx->lookup_path, nd->swap_fh, &nd->swap_fhsize, @@ -1823,7 +1786,7 @@ bootpc_init(void) } nfs_diskless_valid = 3; } - + strcpy(nd->myif.ifra_name, ifctx->ireq.ifr_name); bcopy(&ifctx->myaddr, &nd->myif.ifra_addr, sizeof(ifctx->myaddr)); bcopy(&ifctx->myaddr, &nd->myif.ifra_broadaddr, sizeof(ifctx->myaddr)); @@ -1831,7 +1794,7 @@ bootpc_init(void) ifctx->myaddr.sin_addr.s_addr | ~ ifctx->netmask.sin_addr.s_addr; bcopy(&ifctx->netmask, &nd->myif.ifra_mask, sizeof(ifctx->netmask)); - + out: for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = nctx) { nctx = ifctx->next; @@ -1840,26 +1803,21 @@ out: free(gctx, M_TEMP); } - /* * RPC: mountd/mount * Given a server pathname, get an NFS file handle. * Also, sets sin->sin_port to the NFS service port. */ static int -md_mount(struct sockaddr_in *mdsin, /* mountd server address */ - char *path, - u_char *fhp, - int *fhsizep, - struct nfs_args *args, - struct thread *td) +md_mount(struct sockaddr_in *mdsin, char *path, u_char *fhp, int *fhsizep, + struct nfs_args *args, struct thread *td) { struct mbuf *m; int error; int authunixok; int authcount; int authver; - + #ifdef BOOTP_NFSV3 /* First try NFS v3 */ /* Get port number for MOUNTD. */ @@ -1867,7 +1825,7 @@ md_mount(struct sockaddr_in *mdsin, /* mountd server address */ &mdsin->sin_port, td); if (error == 0) { m = xdr_string_encode(path, strlen(path)); - + /* Do RPC to mountd. */ error = krpc_call(mdsin, RPCPROG_MNT, RPCMNT_VER3, RPCMNT_MOUNT, &m, NULL, td); @@ -1877,28 +1835,28 @@ md_mount(struct sockaddr_in *mdsin, /* mountd server address */ } else { #endif /* Fallback to NFS v2 */ - + /* Get port number for MOUNTD. */ error = krpc_portmap(mdsin, RPCPROG_MNT, RPCMNT_VER1, &mdsin->sin_port, td); if (error != 0) return error; - + m = xdr_string_encode(path, strlen(path)); - + /* Do RPC to mountd. */ error = krpc_call(mdsin, RPCPROG_MNT, RPCMNT_VER1, RPCMNT_MOUNT, &m, NULL, td); if (error != 0) return error; /* message already freed */ - + #ifdef BOOTP_NFSV3 } #endif if (xdr_int_decode(&m, &error) != 0 || error != 0) goto bad; - + if ((args->flags & NFSMNT_NFSV3) != 0) { if (xdr_int_decode(&m, fhsizep) != 0 || *fhsizep > NFSX_V3FHMAX || @@ -1926,31 +1884,26 @@ md_mount(struct sockaddr_in *mdsin, /* mountd server address */ if (authunixok == 0) goto bad; } - + /* Set port number for NFS use. */ error = krpc_portmap(mdsin, NFS_PROG, (args->flags & NFSMNT_NFSV3) ? NFS_VER3 : NFS_VER2, &mdsin->sin_port, td); - + goto out; - + bad: error = EBADRPC; - + out: m_freem(m); return error; } - static int -md_lookup_swap(struct sockaddr_in *mdsin, /* mountd server address */ - char *path, - u_char *fhp, - int *fhsizep, - struct nfs_args *args, - struct thread *td) +md_lookup_swap(struct sockaddr_in *mdsin, char *path, u_char *fhp, int *fhsizep, + struct nfs_args *args, struct thread *td) { struct mbuf *m; int error; @@ -1961,11 +1914,11 @@ md_lookup_swap(struct sockaddr_in *mdsin, /* mountd server address */ u_int32_t v2[17]; u_int32_t v3[21]; } fattribs; - - m = m_get(M_TRYWAIT,MT_DATA); + + m = m_get(M_TRYWAIT, MT_DATA); if (m == NULL) return ENOBUFS; - + if ((args->flags & NFSMNT_NFSV3) != 0) { *mtod(m, u_int32_t *) = txdr_unsigned(*fhsizep); bcopy(fhp, mtod(m, u_char *) + sizeof(u_int32_t), *fhsizep); @@ -1974,7 +1927,7 @@ md_lookup_swap(struct sockaddr_in *mdsin, /* mountd server address */ bcopy(fhp, mtod(m, u_char *), NFSX_V2FH); m->m_len = NFSX_V2FH; } - + m->m_next = xdr_string_encode(path, strlen(path)); if (m->m_next == NULL) { error = ENOBUFS; @@ -1997,7 +1950,7 @@ md_lookup_swap(struct sockaddr_in *mdsin, /* mountd server address */ error = ENOENT; goto out; } - + if ((args->flags & NFSMNT_NFSV3) != 0) { if (xdr_int_decode(&m, fhsizep) != 0 || *fhsizep > NFSX_V3FHMAX || @@ -2005,10 +1958,10 @@ md_lookup_swap(struct sockaddr_in *mdsin, /* mountd server address */ goto bad; } else *fhsizep = NFSX_V2FH; - + if (xdr_opaque_decode(&m, fhp, *fhsizep) != 0) goto bad; - + if ((args->flags & NFSMNT_NFSV3) != 0) { if (xdr_int_decode(&m, &attribs_present) != 0) goto bad; @@ -2024,18 +1977,18 @@ md_lookup_swap(struct sockaddr_in *mdsin, /* mountd server address */ goto bad; size = fxdr_unsigned(u_int32_t, fattribs.v2[5]); } - + if (nfsv3_diskless.swap_nblks == 0 && size != -1) { nfsv3_diskless.swap_nblks = size / 1024; printf("md_lookup_swap: Swap size is %d KB\n", nfsv3_diskless.swap_nblks); } - + goto out; - + bad: error = EBADRPC; - + out: m_freem(m); return error; diff --git a/sys/nfsclient/krpc.h b/sys/nfsclient/krpc.h index b6136e3..44b84e0 100644 --- a/sys/nfsclient/krpc.h +++ b/sys/nfsclient/krpc.h @@ -8,14 +8,14 @@ struct thread; struct sockaddr; struct sockaddr_in; -int krpc_call __P((struct sockaddr_in *_sin, +int krpc_call(struct sockaddr_in *_sin, u_int prog, u_int vers, u_int func, - struct mbuf **data, struct sockaddr **from, struct thread *td)); + struct mbuf **data, struct sockaddr **from, struct thread *td); -int krpc_portmap __P((struct sockaddr_in *_sin, - u_int prog, u_int vers, u_int16_t *portp,struct thread *td)); +int krpc_portmap(struct sockaddr_in *_sin, + u_int prog, u_int vers, u_int16_t *portp, struct thread *td); -struct mbuf *xdr_string_encode __P((char *str, int len)); +struct mbuf *xdr_string_encode(char *str, int len); /* * RPC definitions for the portmapper diff --git a/sys/nfsclient/krpc_subr.c b/sys/nfsclient/krpc_subr.c index 709af4a..06b9c81 100644 --- a/sys/nfsclient/krpc_subr.c +++ b/sys/nfsclient/krpc_subr.c @@ -1,5 +1,4 @@ /* $NetBSD: krpc_subr.c,v 1.12.4.1 1996/06/07 00:52:26 cgd Exp $ */ -/* $FreeBSD$ */ /* * Copyright (c) 1995 Gordon Ross, Adam Glass @@ -43,6 +42,9 @@ * @(#) Header: rpc.c,v 1.12 93/09/28 08:31:56 leres Exp (LBL) */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + #include <sys/param.h> #include <sys/systm.h> #include <sys/malloc.h> @@ -55,7 +57,7 @@ #include <netinet/in.h> #include <nfs/rpcv2.h> -#include <nfs/krpc.h> +#include <nfsclient/krpc.h> #include <nfs/xdr_subs.h> /* @@ -124,11 +126,8 @@ struct rpc_reply { * Returns non-zero error on failure. */ int -krpc_portmap(sin, prog, vers, portp, td) - struct sockaddr_in *sin; /* server address */ - u_int prog, vers; /* host order */ - u_int16_t *portp; /* network order */ - struct thread *td; +krpc_portmap(struct sockaddr_in *sin, u_int prog, u_int vers, u_int16_t *portp, + struct thread *td) { struct sdata { u_int32_t prog; /* call program */ @@ -164,7 +163,7 @@ krpc_portmap(sin, prog, vers, portp, td) sin->sin_port = htons(PMAPPORT); error = krpc_call(sin, PMAPPROG, PMAPVERS, PMAPPROC_GETPORT, &m, NULL, td); - if (error) + if (error) return error; if (m->m_len < sizeof(*rdata)) { @@ -185,12 +184,8 @@ krpc_portmap(sin, prog, vers, portp, td) * the address from whence the response came is saved there. */ int -krpc_call(sa, prog, vers, func, data, from_p, td) - struct sockaddr_in *sa; - u_int prog, vers, func; - struct mbuf **data; /* input/output */ - struct sockaddr **from_p; /* output */ - struct thread *td; +krpc_call(struct sockaddr_in *sa, u_int prog, u_int vers, u_int func, + struct mbuf **data, struct sockaddr **from_p, struct thread *td) { struct socket *so; struct sockaddr_in *sin, ssin; @@ -354,7 +349,7 @@ krpc_call(sa, prog, vers, func, data, from_p, td) m_freem(m); m = NULL; } - bzero(&auio,sizeof(auio)); + bzero(&auio, sizeof(auio)); auio.uio_resid = len = 1<<16; rcvflg = 0; error = soreceive(so, &from, &auio, &m, NULL, &rcvflg); @@ -456,9 +451,7 @@ struct xdr_string { }; struct mbuf * -xdr_string_encode(str, len) - char *str; - int len; +xdr_string_encode(char *str, int len) { struct mbuf *m; struct xdr_string *xs; diff --git a/sys/nfsclient/nfs.h b/sys/nfsclient/nfs.h index da808f4..5811883 100644 --- a/sys/nfsclient/nfs.h +++ b/sys/nfsclient/nfs.h @@ -37,18 +37,19 @@ * $FreeBSD$ */ -#ifndef _NFS_NFS_H_ -#define _NFS_NFS_H_ +#ifndef _NFSCLIENT_NFS_H_ +#define _NFSCLIENT_NFS_H_ #ifdef _KERNEL #include "opt_nfs.h" #endif +#include <nfsclient/nfsargs.h> + /* * Tunable constants for nfs */ -#define NFS_MAXIOVEC 34 #define NFS_TICKINTVL 5 /* Desired time for a tick (msec) */ #define NFS_HZ (hz / nfs_ticks) /* Ticks/sec */ #define NFS_TIMEO (1 * NFS_HZ) /* Default timeout = 1 second */ @@ -56,7 +57,6 @@ #define NFS_MAXTIMEO (60 * NFS_HZ) /* Max timeout to backoff to */ #define NFS_MINIDEMTIMEO (5 * NFS_HZ) /* Min timeout for non-idempotent ops*/ #define NFS_MAXREXMIT 100 /* Stop counting after this many */ -#define NFS_MAXWINDOW 1024 /* Max number of outstanding requests */ #define NFS_RETRANS 10 /* Num of retrans for soft mounts */ #define NFS_MAXGRPS 16 /* Max. size of groups list */ #ifndef NFS_MINATTRTIMO @@ -76,227 +76,48 @@ #define NFS_READDIRSIZE 8192 /* Def. readdir size */ #define NFS_DEFRAHEAD 1 /* Def. read ahead # blocks */ #define NFS_MAXRAHEAD 4 /* Max. read ahead # blocks */ -#define NFS_MAXUIDHASH 64 /* Max. # of hashed uid entries/mp */ #define NFS_MAXASYNCDAEMON 20 /* Max. number async_daemons runnable */ -#define NFS_MAXGATHERDELAY 100 /* Max. write gather delay (msec) */ -#ifndef NFS_GATHERDELAY -#define NFS_GATHERDELAY 10 /* Default write gather delay (msec) */ -#endif #define NFS_DIRBLKSIZ 4096 /* Must be a multiple of DIRBLKSIZ */ #ifdef _KERNEL #define DIRBLKSIZ 512 /* XXX we used to use ufs's DIRBLKSIZ */ #endif +#define NFS_MAXDEADTHRESH 9 /* How long till we say 'server not responding' */ /* * Oddballs */ -#define NMOD(a) ((a) % nfs_asyncdaemons) #define NFS_CMPFH(n, f, s) \ ((n)->n_fhsize == (s) && !bcmp((caddr_t)(n)->n_fhp, (caddr_t)(f), (s))) #define NFS_ISV3(v) (VFSTONFS((v)->v_mount)->nm_flag & NFSMNT_NFSV3) -#define NFS_SRVMAXDATA(n) \ - (((n)->nd_flag & ND_NFSV3) ? (((n)->nd_nam2) ? \ - NFS_MAXDGRAMDATA : NFS_MAXDATA) : NFS_V2MAXDATA) - -/* - * XXX - * The B_INVAFTERWRITE flag should be set to whatever is required by the - * buffer cache code to say "Invalidate the block after it is written back". - */ -#define B_INVAFTERWRITE B_NOCACHE - -/* - * The IO_METASYNC flag should be implemented for local file systems. - * (Until then, it is nothin at all.) - */ -#ifndef IO_METASYNC -#define IO_METASYNC 0 -#endif - -/* - * Arguments to mount NFS - */ -#define NFS_ARGSVERSION 3 /* change when nfs_args changes */ -struct nfs_args { - int version; /* args structure version number */ - struct sockaddr *addr; /* file server address */ - int addrlen; /* length of address */ - int sotype; /* Socket type */ - int proto; /* and Protocol */ - u_char *fh; /* File handle to be mounted */ - int fhsize; /* Size, in bytes, of fh */ - int flags; /* flags */ - int wsize; /* write size in bytes */ - int rsize; /* read size in bytes */ - int readdirsize; /* readdir size in bytes */ - int timeo; /* initial timeout in .1 secs */ - int retrans; /* times to retry send */ - int maxgrouplist; /* Max. size of group list */ - int readahead; /* # of blocks to readahead */ - int leaseterm; /* Term (sec) of lease */ - int deadthresh; /* Retrans threshold */ - char *hostname; /* server's name */ - int acregmin; /* cache attrs for reg files min time */ - int acregmax; /* cache attrs for reg files max time */ - int acdirmin; /* cache attrs for dirs min time */ - int acdirmax; /* cache attrs for dirs max time */ -}; - -/* - * NFS mount option flags - */ -#define NFSMNT_SOFT 0x00000001 /* soft mount (hard is default) */ -#define NFSMNT_WSIZE 0x00000002 /* set write size */ -#define NFSMNT_RSIZE 0x00000004 /* set read size */ -#define NFSMNT_TIMEO 0x00000008 /* set initial timeout */ -#define NFSMNT_RETRANS 0x00000010 /* set number of request retries */ -#define NFSMNT_MAXGRPS 0x00000020 /* set maximum grouplist size */ -#define NFSMNT_INT 0x00000040 /* allow interrupts on hard mount */ -#define NFSMNT_NOCONN 0x00000080 /* Don't Connect the socket */ -#define NFSMNT_NQNFS 0x00000100 /* Use Nqnfs protocol */ -#define NFSMNT_NFSV3 0x00000200 /* Use NFS Version 3 protocol */ -#define NFSMNT_KERB 0x00000400 /* Use Kerberos authentication */ -#define NFSMNT_DUMBTIMR 0x00000800 /* Don't estimate rtt dynamically */ -#define NFSMNT_LEASETERM 0x00001000 /* set lease term (nqnfs) */ -#define NFSMNT_READAHEAD 0x00002000 /* set read ahead */ -#define NFSMNT_DEADTHRESH 0x00004000 /* set dead server retry thresh */ -#define NFSMNT_RESVPORT 0x00008000 /* Allocate a reserved port */ -#define NFSMNT_RDIRPLUS 0x00010000 /* Use Readdirplus for V3 */ -#define NFSMNT_READDIRSIZE 0x00020000 /* Set readdir size */ -#define NFSMNT_ACREGMIN 0x00040000 -#define NFSMNT_ACREGMAX 0x00080000 -#define NFSMNT_ACDIRMIN 0x00100000 -#define NFSMNT_ACDIRMAX 0x00200000 #define NFSSTA_HASWRITEVERF 0x00040000 /* Has write verifier for V3 */ -#define NFSSTA_GOTPATHCONF 0x00080000 /* Got the V3 pathconf info */ #define NFSSTA_GOTFSINFO 0x00100000 /* Got the V3 fsinfo */ -#define NFSSTA_MNTD 0x00200000 /* Mnt server for mnt point */ -#define NFSSTA_DISMINPROG 0x00400000 /* Dismount in progress */ -#define NFSSTA_DISMNT 0x00800000 /* Dismounted */ #define NFSSTA_SNDLOCK 0x01000000 /* Send socket lock */ #define NFSSTA_WANTSND 0x02000000 /* Want above */ #define NFSSTA_RCVLOCK 0x04000000 /* Rcv socket lock */ #define NFSSTA_WANTRCV 0x08000000 /* Want above */ -#define NFSSTA_WAITAUTH 0x10000000 /* Wait for authentication */ -#define NFSSTA_HASAUTH 0x20000000 /* Has authenticator */ -#define NFSSTA_WANTAUTH 0x40000000 /* Wants an authenticator */ -#define NFSSTA_AUTHERR 0x80000000 /* Authentication error */ - -/* - * Structures for the nfssvc(2) syscall. Not that anyone but nfsd and mount_nfs - * should ever try and use it. - */ -struct nfsd_args { - int sock; /* Socket to serve */ - caddr_t name; /* Client addr for connection based sockets */ - int namelen; /* Length of name */ -}; - -struct nfsd_srvargs { - struct nfsd *nsd_nfsd; /* Pointer to in kernel nfsd struct */ - uid_t nsd_uid; /* Effective uid mapped to cred */ - u_int32_t nsd_haddr; /* Ip address of client */ - struct xucred nsd_cr; /* Cred. uid maps to */ - u_int nsd_authlen; /* Length of auth string (ret) */ - u_char *nsd_authstr; /* Auth string (ret) */ - u_int nsd_verflen; /* and the verfier */ - u_char *nsd_verfstr; - struct timeval nsd_timestamp; /* timestamp from verifier */ - u_int32_t nsd_ttl; /* credential ttl (sec) */ - NFSKERBKEY_T nsd_key; /* Session key */ -}; - -struct nfsd_cargs { - char *ncd_dirp; /* Mount dir path */ - uid_t ncd_authuid; /* Effective uid */ - int ncd_authtype; /* Type of authenticator */ - u_int ncd_authlen; /* Length of authenticator string */ - u_char *ncd_authstr; /* Authenticator string */ - u_int ncd_verflen; /* and the verifier */ - u_char *ncd_verfstr; - NFSKERBKEY_T ncd_key; /* Session key */ -}; /* * XXX to allow amd to include nfs.h without nfsproto.h */ #ifdef NFS_NPROCS -/* - * Stats structure - */ -struct nfsstats { - int attrcache_hits; - int attrcache_misses; - int lookupcache_hits; - int lookupcache_misses; - int direofcache_hits; - int direofcache_misses; - int biocache_reads; - int read_bios; - int read_physios; - int biocache_writes; - int write_bios; - int write_physios; - int biocache_readlinks; - int readlink_bios; - int biocache_readdirs; - int readdir_bios; - int rpccnt[NFS_NPROCS]; - int rpcretries; - int srvrpccnt[NFS_NPROCS]; - int srvrpc_errs; - int srv_errs; - int rpcrequests; - int rpctimeouts; - int rpcunexpected; - int rpcinvalid; - int srvcache_inproghits; - int srvcache_idemdonehits; - int srvcache_nonidemdonehits; - int srvcache_misses; - int srvnqnfs_leases; - int srvnqnfs_maxleases; - int srvnqnfs_getleases; - int srvvop_writes; - int accesscache_hits; - int accesscache_misses; -}; +#include <nfsclient/nfsstats.h> #endif - /* - * Flags for nfssvc() system call. + * Flags for nfsclnt() system call. */ -#define NFSSVC_BIOD 0x002 -#define NFSSVC_NFSD 0x004 -#define NFSSVC_ADDSOCK 0x008 -#define NFSSVC_AUTHIN 0x010 -#define NFSSVC_GOTAUTH 0x040 -#define NFSSVC_AUTHINFAIL 0x080 -#define NFSSVC_MNTD 0x100 -#define NFSSVC_LOCKDANS 0x200 +#define NFSCLNT_LOCKDANS 0x200 /* - * fs.nfs sysctl(3) identifiers + * vfs.nfs sysctl(3) identifiers */ #define NFS_NFSSTATS 1 /* struct: struct nfsstats */ -#define NFS_NFSPRIVPORT 2 /* int: prohibit nfs to resvports */ - -#define FS_NFS_NAMES { \ - { 0, 0 }, \ - { "nfsstats", CTLTYPE_STRUCT }, \ - { "nfsprivport", CTLTYPE_INT }, \ -} #ifdef _KERNEL #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_NFSREQ); MALLOC_DECLARE(M_NFSDIROFF); -MALLOC_DECLARE(M_NFSRVDESC); -MALLOC_DECLARE(M_NFSUID); -MALLOC_DECLARE(M_NQLEASE); -MALLOC_DECLARE(M_NFSD); MALLOC_DECLARE(M_NFSBIGFH); MALLOC_DECLARE(M_NFSHASH); #endif @@ -306,8 +127,23 @@ extern vm_zone_t nfsmount_zone; #endif extern struct callout_handle nfs_timer_handle; +extern struct nfsstats nfsstats; -struct uio; struct buf; struct vattr; struct nameidata; /* XXX */ +extern int nfs_numasync; +extern int nfs_pbuf_freecnt; +extern int nfs_ticks; + +/* Data constants in XDR form */ +extern u_int32_t nfs_true, nfs_false, nfs_xdrneg1; +extern u_int32_t rpc_reply, rpc_msgdenied, rpc_mismatch, rpc_vers; +extern u_int32_t rpc_auth_unix, rpc_msgaccepted, rpc_call, rpc_autherr; + +extern int nfsv3_procid[NFS_NPROCS]; + +struct uio; +struct buf; +struct vattr; +struct nameidata; /* * The set of signals the interrupt an I/O in progress for NFSMNT_INT mounts. @@ -366,176 +202,13 @@ extern TAILQ_HEAD(nfs_reqq, nfsreq) nfs_reqq; #define R_MUSTRESEND 0x40 /* Must resend request */ #define R_GETONEREP 0x80 /* Probe for one reply only */ -/* - * A list of nfssvc_sock structures is maintained with all the sockets - * that require service by the nfsd. - * The nfsuid structs hang off of the nfssvc_sock structs in both lru - * and uid hash lists. - */ -#ifndef NFS_UIDHASHSIZ -#define NFS_UIDHASHSIZ 29 /* Tune the size of nfssvc_sock with this */ -#endif -#define NUIDHASH(sock, uid) \ - (&(sock)->ns_uidhashtbl[(uid) % NFS_UIDHASHSIZ]) -#ifndef NFS_WDELAYHASHSIZ -#define NFS_WDELAYHASHSIZ 16 /* and with this */ -#endif -#define NWDELAYHASH(sock, f) \ - (&(sock)->ns_wdelayhashtbl[(*((u_int32_t *)(f))) % NFS_WDELAYHASHSIZ]) -#ifndef NFS_MUIDHASHSIZ -#define NFS_MUIDHASHSIZ 63 /* Tune the size of nfsmount with this */ -#endif -#define NMUIDHASH(nmp, uid) \ - (&(nmp)->nm_uidhashtbl[(uid) % NFS_MUIDHASHSIZ]) +extern struct nfsnodehashhead *nfsnodehashtbl; +extern u_long nfsnodehash; + #define NFSNOHASH(fhsum) \ (&nfsnodehashtbl[(fhsum) & nfsnodehash]) /* - * Network address hash list element - */ -union nethostaddr { - u_int32_t had_inetaddr; - struct sockaddr *had_nam; -}; - -struct nfsuid { - TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */ - LIST_ENTRY(nfsuid) nu_hash; /* Hash list */ - int nu_flag; /* Flags */ - union nethostaddr nu_haddr; /* Host addr. for dgram sockets */ - struct ucred nu_cr; /* Cred uid mapped to */ - int nu_expire; /* Expiry time (sec) */ - struct timeval nu_timestamp; /* Kerb. timestamp */ - u_int32_t nu_nickname; /* Nickname on server */ - NFSKERBKEY_T nu_key; /* and session key */ -}; - -#define nu_inetaddr nu_haddr.had_inetaddr -#define nu_nam nu_haddr.had_nam -/* Bits for nu_flag */ -#define NU_INETADDR 0x1 -#define NU_NAM 0x2 -#define NU_NETFAM(u) (((u)->nu_flag & NU_INETADDR) ? AF_INET : AF_ISO) - -struct nfsrv_rec { - STAILQ_ENTRY(nfsrv_rec) nr_link; - struct sockaddr *nr_address; - struct mbuf *nr_packet; -}; - -struct nfssvc_sock { - TAILQ_ENTRY(nfssvc_sock) ns_chain; /* List of all nfssvc_sock's */ - TAILQ_HEAD(, nfsuid) ns_uidlruhead; - struct file *ns_fp; - struct socket *ns_so; - struct sockaddr *ns_nam; - struct mbuf *ns_raw; - struct mbuf *ns_rawend; - STAILQ_HEAD(, nfsrv_rec) ns_rec; - struct mbuf *ns_frag; - int ns_flag; - int ns_solock; - int ns_cc; - int ns_reclen; - int ns_numuids; - u_int32_t ns_sref; - LIST_HEAD(, nfsrv_descript) ns_tq; /* Write gather lists */ - LIST_HEAD(, nfsuid) ns_uidhashtbl[NFS_UIDHASHSIZ]; - LIST_HEAD(nfsrvw_delayhash, nfsrv_descript) ns_wdelayhashtbl[NFS_WDELAYHASHSIZ]; -}; - -/* Bits for "ns_flag" */ -#define SLP_VALID 0x01 -#define SLP_DOREC 0x02 -#define SLP_NEEDQ 0x04 -#define SLP_DISCONN 0x08 -#define SLP_GETSTREAM 0x10 -#define SLP_LASTFRAG 0x20 -#define SLP_ALLFLAGS 0xff - -extern TAILQ_HEAD(nfssvc_sockhead, nfssvc_sock) nfssvc_sockhead; -extern int nfssvc_sockhead_flag; -#define SLP_INIT 0x01 -#define SLP_WANTINIT 0x02 - -/* - * One of these structures is allocated for each nfsd. - */ -struct nfsd { - TAILQ_ENTRY(nfsd) nfsd_chain; /* List of all nfsd's */ - int nfsd_flag; /* NFSD_ flags */ - struct nfssvc_sock *nfsd_slp; /* Current socket */ - int nfsd_authlen; /* Authenticator len */ - u_char nfsd_authstr[RPCAUTH_MAXSIZ]; /* Authenticator data */ - int nfsd_verflen; /* and the Verifier */ - u_char nfsd_verfstr[RPCVERF_MAXSIZ]; - struct thread *nfsd_td; /* daemon thread ptr */ - struct nfsrv_descript *nfsd_nd; /* Associated nfsrv_descript */ -}; - -/* Bits for "nfsd_flag" */ -#define NFSD_WAITING 0x01 -#define NFSD_REQINPROG 0x02 -#define NFSD_NEEDAUTH 0x04 -#define NFSD_AUTHFAIL 0x08 - -/* - * This structure is used by the server for describing each request. - * Some fields are used only when write request gathering is performed. - */ -struct nfsrv_descript { - u_quad_t nd_time; /* Write deadline (usec) */ - off_t nd_off; /* Start byte offset */ - off_t nd_eoff; /* and end byte offset */ - LIST_ENTRY(nfsrv_descript) nd_hash; /* Hash list */ - LIST_ENTRY(nfsrv_descript) nd_tq; /* and timer list */ - LIST_HEAD(,nfsrv_descript) nd_coalesce; /* coalesced writes */ - struct mbuf *nd_mrep; /* Request mbuf list */ - struct mbuf *nd_md; /* Current dissect mbuf */ - struct mbuf *nd_mreq; /* Reply mbuf list */ - struct sockaddr *nd_nam; /* and socket addr */ - struct sockaddr *nd_nam2; /* return socket addr */ - caddr_t nd_dpos; /* Current dissect pos */ - u_int32_t nd_procnum; /* RPC # */ - int nd_stable; /* storage type */ - int nd_flag; /* nd_flag */ - int nd_len; /* Length of this write */ - int nd_repstat; /* Reply status */ - u_int32_t nd_retxid; /* Reply xid */ - u_int32_t nd_duration; /* Lease duration */ - struct timeval nd_starttime; /* Time RPC initiated */ - fhandle_t nd_fh; /* File handle */ - struct ucred nd_cr; /* Credentials */ -}; - -/* Bits for "nd_flag" */ -#define ND_READ LEASE_READ -#define ND_WRITE LEASE_WRITE -#define ND_CHECK 0x04 -#define ND_LEASE (ND_READ | ND_WRITE | ND_CHECK) -#define ND_NFSV3 0x08 -#define ND_NQNFS 0x10 -#define ND_KERBNICK 0x20 -#define ND_KERBFULL 0x40 -#define ND_KERBAUTH (ND_KERBNICK | ND_KERBFULL) - -extern TAILQ_HEAD(nfsd_head, nfsd) nfsd_head; -extern int nfsd_head_flag; -#define NFSD_CHECKSLP 0x01 - -/* - * These macros compare nfsrv_descript structures. - */ -#define NFSW_CONTIG(o, n) \ - ((o)->nd_eoff >= (n)->nd_off && \ - !bcmp((caddr_t)&(o)->nd_fh, (caddr_t)&(n)->nd_fh, NFSX_V3FH)) - -#define NFSW_SAMECRED(o, n) \ - (((o)->nd_flag & ND_KERBAUTH) == ((n)->nd_flag & ND_KERBAUTH) && \ - !bcmp((caddr_t)&(o)->nd_cr, (caddr_t)&(n)->nd_cr, \ - sizeof (struct ucred))) - -/* * Defines for WebNFS */ @@ -577,151 +250,45 @@ extern int nfs_debug; #endif -u_quad_t nfs_curusec __P((void)); -int nfs_init __P((struct vfsconf *vfsp)); -int nfs_uninit __P((struct vfsconf *vfsp)); -int nfs_reply __P((struct nfsreq *)); -int nfs_getreq __P((struct nfsrv_descript *,struct nfsd *,int)); -int nfs_send __P((struct socket *, struct sockaddr *, struct mbuf *, - struct nfsreq *)); -int nfs_rephead __P((int, struct nfsrv_descript *, struct nfssvc_sock *, - int, int, u_quad_t *, struct mbuf **, struct mbuf **, - caddr_t *)); -int nfs_sndlock __P((struct nfsreq *)); -void nfs_sndunlock __P((struct nfsreq *)); -int nfs_slplock __P((struct nfssvc_sock *, int)); -void nfs_slpunlock __P((struct nfssvc_sock *)); -int nfs_disct __P((struct mbuf **, caddr_t *, int, int, caddr_t *)); -int nfs_vinvalbuf __P((struct vnode *, int, struct ucred *, struct thread *, - int)); -int nfs_readrpc __P((struct vnode *, struct uio *, struct ucred *)); -int nfs_writerpc __P((struct vnode *, struct uio *, struct ucred *, int *, - int *)); -int nfs_commit __P((struct vnode *vp, u_quad_t offset, int cnt, - struct ucred *cred, struct thread *td)); -int nfs_readdirrpc __P((struct vnode *, struct uio *, struct ucred *)); -int nfs_asyncio __P((struct buf *, struct ucred *, struct thread *)); -int nfs_doio __P((struct buf *, struct ucred *, struct thread *)); -int nfs_readlinkrpc __P((struct vnode *, struct uio *, struct ucred *)); -int nfs_sigintr __P((struct nfsmount *, struct nfsreq *, struct proc *)); -int nfs_readdirplusrpc __P((struct vnode *, struct uio *, struct ucred *)); -int nfsm_disct __P((struct mbuf **, caddr_t *, int, int, caddr_t *)); -void nfsm_srvfattr __P((struct nfsrv_descript *, struct vattr *, - struct nfs_fattr *)); -void nfsm_srvwcc __P((struct nfsrv_descript *, int, struct vattr *, int, - struct vattr *, struct mbuf **, char **)); -void nfsm_srvpostopattr __P((struct nfsrv_descript *, int, struct vattr *, - struct mbuf **, char **)); -int netaddr_match __P((int, union nethostaddr *, struct sockaddr *)); -int nfs_request __P((struct vnode *, struct mbuf *, int, struct thread *, - struct ucred *, struct mbuf **, struct mbuf **, - caddr_t *)); -int nfs_loadattrcache __P((struct vnode **, struct mbuf **, caddr_t *, - struct vattr *, int)); -int nfs_namei __P((struct nameidata *, fhandle_t *, int, - struct nfssvc_sock *, struct sockaddr *, struct mbuf **, - caddr_t *, struct vnode **, struct thread *, int, int)); -void nfsm_adj __P((struct mbuf *, int, int)); -int nfsm_mbuftouio __P((struct mbuf **, struct uio *, int, caddr_t *)); -void nfsrv_initcache __P((void)); -int nfs_getauth __P((struct nfsmount *, struct nfsreq *, struct ucred *, - char **, int *, char *, int *, NFSKERBKEY_T)); -int nfs_getnickauth __P((struct nfsmount *, struct ucred *, char **, - int *, char *, int)); -int nfs_savenickauth __P((struct nfsmount *, struct ucred *, int, - NFSKERBKEY_T, struct mbuf **, char **, - struct mbuf *)); -int nfs_adv __P((struct mbuf **, caddr_t *, int, int)); -void nfs_nhinit __P((void)); -void nfs_timer __P((void*)); -int nfsrv_dorec __P((struct nfssvc_sock *, struct nfsd *, - struct nfsrv_descript **)); -int nfsrv_getcache __P((struct nfsrv_descript *, struct nfssvc_sock *, - struct mbuf **)); -void nfsrv_updatecache __P((struct nfsrv_descript *, int, struct mbuf *)); -void nfsrv_cleancache __P((void)); -int nfs_connect __P((struct nfsmount *, struct nfsreq *)); -void nfs_disconnect __P((struct nfsmount *)); -void nfs_safedisconnect __P((struct nfsmount *)); -int nfs_getattrcache __P((struct vnode *, struct vattr *)); -int nfsm_strtmbuf __P((struct mbuf **, char **, const char *, long)); -int nfs_bioread __P((struct vnode *, struct uio *, int, struct ucred *)); -int nfsm_uiotombuf __P((struct uio *, struct mbuf **, int, caddr_t *)); -void nfsrv_init __P((int)); -void nfs_clearcommit __P((struct mount *)); -int nfsrv_errmap __P((struct nfsrv_descript *, int)); -void nfsrvw_sort __P((gid_t *, int)); -void nfsrv_setcred __P((struct ucred *, struct ucred *)); -int nfs_writebp __P((struct buf *, int, struct thread *)); -int nfsrv_object_create __P((struct vnode *)); -void nfsrv_wakenfsd __P((struct nfssvc_sock *slp)); -int nfsrv_writegather __P((struct nfsrv_descript **, struct nfssvc_sock *, - struct thread *, struct mbuf **)); -int nfs_fsinfo __P((struct nfsmount *, struct vnode *, struct ucred *, - struct thread *td)); - -int nfsrv3_access __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_commit __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_create __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_fhtovp __P((fhandle_t *, int, struct vnode **, struct ucred *, - struct nfssvc_sock *, struct sockaddr *, int *, - int, int)); -int nfsrv_setpublicfs __P((struct mount *, struct netexport *, - struct export_args *)); -int nfs_ispublicfh __P((fhandle_t *)); -int nfsrv_fsinfo __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_getattr __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_link __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_lookup __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_mkdir __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_mknod __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_noop __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_null __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_pathconf __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, struct thread *td, - struct mbuf **mrq)); -int nfsrv_read __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_readdir __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_readdirplus __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, struct thread *td, - struct mbuf **mrq)); -int nfsrv_readlink __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, struct thread *td, - struct mbuf **mrq)); -int nfsrv_remove __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_rename __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_rmdir __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_setattr __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_statfs __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_symlink __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -void nfsrv_rcv __P((struct socket *so, void *arg, int waitflag)); -void nfsrv_slpderef __P((struct nfssvc_sock *slp)); +int nfs_init(struct vfsconf *vfsp); +int nfs_uninit(struct vfsconf *vfsp); +int nfs_mountroot(struct mount *mp); +int nfs_send(struct socket *, struct sockaddr *, struct mbuf *, + struct nfsreq *); +int nfs_sndlock(struct nfsreq *); +void nfs_sndunlock(struct nfsreq *); +int nfs_vinvalbuf(struct vnode *, int, struct ucred *, struct thread *, + int); +int nfs_readrpc(struct vnode *, struct uio *, struct ucred *); +int nfs_writerpc(struct vnode *, struct uio *, struct ucred *, int *, + int *); +int nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, + struct ucred *cred, struct thread *td); +int nfs_readdirrpc(struct vnode *, struct uio *, struct ucred *); +int nfs_asyncio(struct buf *, struct ucred *, struct thread *); +int nfs_doio(struct buf *, struct ucred *, struct thread *); +int nfs_readlinkrpc(struct vnode *, struct uio *, struct ucred *); +int nfs_sigintr(struct nfsmount *, struct nfsreq *, struct proc *); +int nfs_readdirplusrpc(struct vnode *, struct uio *, struct ucred *); +int nfs_request(struct vnode *, struct mbuf *, int, struct thread *, + struct ucred *, struct mbuf **, struct mbuf **, caddr_t *); +int nfs_loadattrcache(struct vnode **, struct mbuf **, caddr_t *, + struct vattr *, int); +int nfsm_mbuftouio(struct mbuf **, struct uio *, int, caddr_t *); +void nfs_nhinit(void); +void nfs_timer(void*); +int nfs_connect(struct nfsmount *, struct nfsreq *); +void nfs_disconnect(struct nfsmount *); +void nfs_safedisconnect(struct nfsmount *); +int nfs_getattrcache(struct vnode *, struct vattr *); +int nfsm_strtmbuf(struct mbuf **, char **, const char *, long); +int nfs_bioread(struct vnode *, struct uio *, int, struct ucred *); +int nfsm_uiotombuf(struct uio *, struct mbuf **, int, caddr_t *); +void nfs_clearcommit(struct mount *); +int nfs_writebp(struct buf *, int, struct thread *); +int nfs_fsinfo(struct nfsmount *, struct vnode *, struct ucred *, + struct thread *); + #endif /* _KERNEL */ #endif diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index fa7274d..769ac35 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -34,9 +34,10 @@ * SUCH DAMAGE. * * @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95 - * $FreeBSD$ */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$); #include <sys/param.h> #include <sys/systm.h> @@ -59,10 +60,9 @@ #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> -#include <nfs/nfs.h> -#include <nfs/nfsmount.h> -#include <nfs/nqnfs.h> -#include <nfs/nfsnode.h> +#include <nfsclient/nfs.h> +#include <nfsclient/nfsmount.h> +#include <nfsclient/nfsnode.h> /* * Just call nfs_writebp() with the force argument set to 1. @@ -72,6 +72,7 @@ static int nfs_bwrite(struct buf *bp) { + return (nfs_writebp(bp, 1, curthread)); } @@ -80,26 +81,14 @@ struct buf_ops buf_ops_nfs = { nfs_bwrite }; - -static struct buf *nfs_getcacheblk __P((struct vnode *vp, daddr_t bn, int size, - struct thread *td)); - -extern int nfs_numasync; -extern int nfs_pbuf_freecnt; -extern struct nfsstats nfsstats; +static struct buf *nfs_getcacheblk(struct vnode *vp, daddr_t bn, int size, + struct thread *td); /* * Vnode op for VM getpages. */ int -nfs_getpages(ap) - struct vop_getpages_args /* { - struct vnode *a_vp; - vm_page_t *a_m; - int a_count; - int a_reqpage; - vm_ooffset_t a_offset; - } */ *ap; +nfs_getpages(struct vop_getpages_args *ap) { int i, error, nextoff, size, toff, count, npages; struct uio uio; @@ -218,7 +207,7 @@ nfs_getpages(ap) /* handled by vm_fault now */ /* vm_page_zero_invalid(m, TRUE); */ } - + if (i != ap->a_reqpage) { /* * Whether or not to leave the page activated is up in @@ -250,15 +239,7 @@ nfs_getpages(ap) * Vnode op for VM putpages. */ int -nfs_putpages(ap) - struct vop_putpages_args /* { - struct vnode *a_vp; - vm_page_t *a_m; - int a_count; - int a_sync; - int *a_rtvals; - vm_ooffset_t a_offset; - } */ *ap; +nfs_putpages(struct vop_putpages_args *ap) { struct uio uio; struct iovec iov; @@ -287,16 +268,13 @@ nfs_putpages(ap) npages = btoc(count); offset = IDX_TO_OFF(pages[0]->pindex); - GIANT_REQUIRED; - if ((nmp->nm_flag & NFSMNT_NFSV3) != 0 && (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) { (void)nfs_fsinfo(nmp, vp, cred, td); } - for (i = 0; i < npages; i++) { + for (i = 0; i < npages; i++) rtvals[i] = VM_PAGER_AGAIN; - } /* * When putting pages, do not extend file past EOF. @@ -356,14 +334,10 @@ nfs_putpages(ap) * Vnode op for read using bio */ int -nfs_bioread(vp, uio, ioflag, cred) - register struct vnode *vp; - register struct uio *uio; - int ioflag; - struct ucred *cred; +nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) { - register struct nfsnode *np = VTONFS(vp); - register int biosize, i; + struct nfsnode *np = VTONFS(vp); + int biosize, i; struct buf *bp = 0, *rabp; struct vattr vattr; struct thread *td; @@ -395,7 +369,6 @@ nfs_bioread(vp, uio, ioflag, cred) * For nfs, cache consistency can only be maintained approximately. * Although RFC1094 does not specify the criteria, the following is * believed to be compatible with the reference port. - * For nqnfs, full cache consistency is maintained within the loop. * For nfs: * If the file's modify time on the server has changed since the * last read rpc or you have written to the file, @@ -408,77 +381,34 @@ nfs_bioread(vp, uio, ioflag, cred) * attributes this could be forced by setting n_attrstamp to 0 before * the VOP_GETATTR() call. */ - if ((nmp->nm_flag & NFSMNT_NQNFS) == 0) { - if (np->n_flag & NMODIFIED) { - if (vp->v_type != VREG) { - if (vp->v_type != VDIR) - panic("nfs: bioread, not dir"); - nfs_invaldir(vp); - error = nfs_vinvalbuf(vp, V_SAVE, cred, td, 1); - if (error) - return (error); - } - np->n_attrstamp = 0; - error = VOP_GETATTR(vp, &vattr, cred, td); - if (error) - return (error); - np->n_mtime = vattr.va_mtime.tv_sec; - } else { - error = VOP_GETATTR(vp, &vattr, cred, td); + if (np->n_flag & NMODIFIED) { + if (vp->v_type != VREG) { + if (vp->v_type != VDIR) + panic("nfs: bioread, not dir"); + nfs_invaldir(vp); + error = nfs_vinvalbuf(vp, V_SAVE, cred, td, 1); if (error) return (error); - if (np->n_mtime != vattr.va_mtime.tv_sec) { - if (vp->v_type == VDIR) - nfs_invaldir(vp); - error = nfs_vinvalbuf(vp, V_SAVE, cred, td, 1); - if (error) - return (error); - np->n_mtime = vattr.va_mtime.tv_sec; - } } - } - do { - - /* - * Get a valid lease. If cached data is stale, flush it. - */ - if (nmp->nm_flag & NFSMNT_NQNFS) { - if (NQNFS_CKINVALID(vp, np, ND_READ)) { - do { - error = nqnfs_getlease(vp, ND_READ, cred, td); - } while (error == NQNFS_EXPIRED); - if (error) + np->n_attrstamp = 0; + error = VOP_GETATTR(vp, &vattr, cred, td); + if (error) + return (error); + np->n_mtime = vattr.va_mtime.tv_sec; + } else { + error = VOP_GETATTR(vp, &vattr, cred, td); + if (error) return (error); - if (np->n_lrev != np->n_brev || - (np->n_flag & NQNFSNONCACHE) || - ((np->n_flag & NMODIFIED) && vp->v_type == VDIR)) { + if (np->n_mtime != vattr.va_mtime.tv_sec) { if (vp->v_type == VDIR) - nfs_invaldir(vp); + nfs_invaldir(vp); error = nfs_vinvalbuf(vp, V_SAVE, cred, td, 1); if (error) - return (error); - np->n_brev = np->n_lrev; - } - } else if (vp->v_type == VDIR && (np->n_flag & NMODIFIED)) { - nfs_invaldir(vp); - error = nfs_vinvalbuf(vp, V_SAVE, cred, td, 1); - if (error) - return (error); + return (error); + np->n_mtime = vattr.va_mtime.tv_sec; } - } - if (np->n_flag & NQNFSNONCACHE) { - switch (vp->v_type) { - case VREG: - return (nfs_readrpc(vp, uio, cred)); - case VLNK: - return (nfs_readlinkrpc(vp, uio, cred)); - case VDIR: - break; - default: - printf(" NQNFSNONCACHE: type %x unexpected\n", - vp->v_type); - }; - } + } + do { switch (vp->v_type) { case VREG: nfsstats.biocache_reads++; @@ -517,7 +447,7 @@ nfs_bioread(vp, uio, ioflag, cred) /* * Obtain the buffer cache block. Figure out the buffer size * when we are at EOF. If we are modifying the size of the - * buffer based on an EOF condition we need to hold + * buffer based on an EOF condition we need to hold * nfs_rslock() through obtaining the buffer to prevent * a potential writer-appender from messing with n_size. * Otherwise we may accidently truncate the buffer and @@ -677,7 +607,6 @@ again: (bp->b_flags & B_INVAL) == 0 && (np->n_direofoffset == 0 || (lbn + 1) * NFS_DIRBLKSIZ < np->n_direofoffset) && - !(np->n_flag & NQNFSNONCACHE) && !incore(vp, lbn + 1)) { rabp = nfs_getcacheblk(vp, lbn + 1, NFS_DIRBLKSIZ, td); if (rabp) { @@ -705,7 +634,7 @@ again: * to EOF. *BUT* this information is lost if the buffer goes * away and is reconstituted into a B_CACHE state ( due to * being VMIO ) later. So we keep track of the directory eof - * in np->n_direofoffset and chop it off as an extra step + * in np->n_direofoffset and chop it off as an extra step * right here. */ n = lmin(uio->uio_resid, NFS_DIRBLKSIZ - bp->b_resid - on); @@ -713,7 +642,7 @@ again: n = np->n_direofoffset - uio->uio_offset; break; default: - printf(" nfs_bioread: type %x unexpected\n",vp->v_type); + printf(" nfs_bioread: type %x unexpected\n", vp->v_type); break; }; @@ -727,15 +656,9 @@ again: n = 0; break; case VDIR: - /* - * Invalidate buffer if caching is disabled, forcing a - * re-read from the remote later. - */ - if (np->n_flag & NQNFSNONCACHE) - bp->b_flags |= B_INVAL; break; default: - printf(" nfs_bioread: type %x unexpected\n",vp->v_type); + printf(" nfs_bioread: type %x unexpected\n", vp->v_type); } brelse(bp); } while (error == 0 && uio->uio_resid > 0 && n > 0); @@ -746,13 +669,7 @@ again: * Vnode op for write using bio */ int -nfs_write(ap) - struct vop_write_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap; +nfs_write(struct vop_write_args *ap) { int biosize; struct uio *uio = ap->a_uio; @@ -766,7 +683,7 @@ nfs_write(ap) struct nfsmount *nmp = VFSTONFS(vp->v_mount); daddr_t lbn; int bcount; - int n, on, error = 0, iomode, must_commit; + int n, on, error = 0; int haverslock = 0; struct proc *p = td?td->td_proc:NULL; @@ -868,31 +785,6 @@ restart: biosize = vp->v_mount->mnt_stat.f_iosize; do { - /* - * Check for a valid write lease. - */ - if ((nmp->nm_flag & NFSMNT_NQNFS) && - NQNFS_CKINVALID(vp, np, ND_WRITE)) { - do { - error = nqnfs_getlease(vp, ND_WRITE, cred, td); - } while (error == NQNFS_EXPIRED); - if (error) - break; - if (np->n_lrev != np->n_brev || - (np->n_flag & NQNFSNONCACHE)) { - error = nfs_vinvalbuf(vp, V_SAVE, cred, td, 1); - if (error) - break; - np->n_brev = np->n_lrev; - } - } - if ((np->n_flag & NQNFSNONCACHE) && uio->uio_iovcnt == 1) { - iomode = NFSV3WRITE_FILESYNC; - error = nfs_writerpc(vp, uio, cred, &iomode, &must_commit); - if (must_commit) - nfs_clearcommit(vp->v_mount); - break; - } nfsstats.biocache_writes++; lbn = uio->uio_offset / biosize; on = uio->uio_offset & (biosize-1); @@ -929,7 +821,7 @@ again: } } else { /* - * Obtain the locked cache block first, and then + * Obtain the locked cache block first, and then * adjust the file's size as appropriate. */ bcount = on + n; @@ -960,7 +852,7 @@ again: * op and is typically set, avoiding the read. If a read * is required in special append mode, the server will * probably send us a short-read since we extended the file - * on our end, resulting in b_resid == 0 and, thusly, + * on our end, resulting in b_resid == 0 and, thusly, * B_CACHE getting set. * * We can also avoid issuing the read if the write covers @@ -1001,15 +893,15 @@ again: /* * If dirtyend exceeds file size, chop it down. This should * not normally occur but there is an append race where it - * might occur XXX, so we log it. + * might occur XXX, so we log it. * * If the chopping creates a reverse-indexed or degenerate * situation with dirtyoff/end, we 0 both of them. */ if (bp->b_dirtyend > bcount) { - printf("NFS append race @%lx:%d\n", - (long)bp->b_blkno * DEV_BSIZE, + printf("NFS append race @%lx:%d\n", + (long)bp->b_blkno * DEV_BSIZE, bp->b_dirtyend - bcount); bp->b_dirtyend = bcount; } @@ -1022,9 +914,9 @@ again: * area, just update the b_dirtyoff and b_dirtyend, * otherwise force a write rpc of the old dirty area. * - * While it is possible to merge discontiguous writes due to + * While it is possible to merge discontiguous writes due to * our having a B_CACHE buffer ( and thus valid read data - * for the hole), we don't because it could lead to + * for the hole), we don't because it could lead to * significant cache coherency problems with multiple clients, * especially if locking is implemented later on. * @@ -1041,30 +933,6 @@ again: goto again; } - /* - * Check for valid write lease and get one as required. - * In case getblk() and/or bwrite() delayed us. - */ - if ((nmp->nm_flag & NFSMNT_NQNFS) && - NQNFS_CKINVALID(vp, np, ND_WRITE)) { - do { - error = nqnfs_getlease(vp, ND_WRITE, cred, td); - } while (error == NQNFS_EXPIRED); - if (error) { - brelse(bp); - break; - } - if (np->n_lrev != np->n_brev || - (np->n_flag & NQNFSNONCACHE)) { - brelse(bp); - error = nfs_vinvalbuf(vp, V_SAVE, cred, td, 1); - if (error) - break; - np->n_brev = np->n_lrev; - goto again; - } - } - error = uiomove((char *)bp->b_data + on, n, uio); /* @@ -1082,7 +950,7 @@ again: } /* - * Only update dirtyoff/dirtyend if not a degenerate + * Only update dirtyoff/dirtyend if not a degenerate * condition. */ if (n) { @@ -1097,24 +965,18 @@ again: } /* - * If the lease is non-cachable or IO_SYNC do bwrite(). + * If IO_SYNC do bwrite(). * * IO_INVAL appears to be unused. The idea appears to be * to turn off caching in this case. Very odd. XXX */ - if ((np->n_flag & NQNFSNONCACHE) || (ioflag & IO_SYNC)) { + if ((ioflag & IO_SYNC)) { if (ioflag & IO_INVAL) bp->b_flags |= B_NOCACHE; error = BUF_WRITE(bp); if (error) break; - if (np->n_flag & NQNFSNONCACHE) { - error = nfs_vinvalbuf(vp, V_SAVE, cred, td, 1); - if (error) - break; - } - } else if ((n + on) == biosize && - (nmp->nm_flag & NFSMNT_NQNFS) == 0) { + } else if ((n + on) == biosize) { bp->b_flags |= B_ASYNC; (void)nfs_writebp(bp, 0, 0); } else { @@ -1144,13 +1006,9 @@ again: * its EOF. */ static struct buf * -nfs_getcacheblk(vp, bn, size, td) - struct vnode *vp; - daddr_t bn; - int size; - struct thread *td; +nfs_getcacheblk(struct vnode *vp, daddr_t bn, int size, struct thread *td) { - register struct buf *bp; + struct buf *bp; struct mount *mp; struct nfsmount *nmp; @@ -1182,14 +1040,10 @@ nfs_getcacheblk(vp, bn, size, td) * doing the flush, just wait for completion. */ int -nfs_vinvalbuf(vp, flags, cred, td, intrflg) - struct vnode *vp; - int flags; - struct ucred *cred; - struct thread *td; - int intrflg; +nfs_vinvalbuf(struct vnode *vp, int flags, struct ucred *cred, + struct thread *td, int intrflg) { - register struct nfsnode *np = VTONFS(vp); + struct nfsnode *np = VTONFS(vp); struct nfsmount *nmp = VFSTONFS(vp->v_mount); int error = 0, slpflag, slptimeo; @@ -1213,7 +1067,8 @@ nfs_vinvalbuf(vp, flags, cred, td, intrflg) np->n_flag |= NFLUSHWANT; error = tsleep((caddr_t)&np->n_flag, PRIBIO + 2, "nfsvinval", slptimeo); - if (error && intrflg && nfs_sigintr(nmp, (struct nfsreq *)0, td->td_proc)) + if (error && intrflg && + nfs_sigintr(nmp, (struct nfsreq *)0, td->td_proc)) return (EINTR); } @@ -1223,7 +1078,8 @@ nfs_vinvalbuf(vp, flags, cred, td, intrflg) np->n_flag |= NFLUSHINPROG; error = vinvalbuf(vp, flags, cred, td, slpflag, 0); while (error) { - if (intrflg && nfs_sigintr(nmp, (struct nfsreq *)0, td->td_proc)) { + if (intrflg && + nfs_sigintr(nmp, (struct nfsreq *)0, td->td_proc)) { np->n_flag &= ~NFLUSHINPROG; if (np->n_flag & NFLUSHWANT) { np->n_flag &= ~NFLUSHWANT; @@ -1250,10 +1106,7 @@ nfs_vinvalbuf(vp, flags, cred, td, intrflg) * is eventually dequeued by the async daemon, nfs_doio() *will*. */ int -nfs_asyncio(bp, cred, td) - register struct buf *bp; - struct ucred *cred; - struct thread *td; +nfs_asyncio(struct buf *bp, struct ucred *cred, struct thread *td) { struct nfsmount *nmp; int i; @@ -1272,7 +1125,7 @@ nfs_asyncio(bp, cred, td) nmp = VFSTONFS(bp->b_vp->v_mount); /* - * Commits are usually short and sweet so lets save some cpu and + * Commits are usually short and sweet so lets save some cpu and * leave the async daemons for more important rpc's (such as reads * and writes). */ @@ -1385,10 +1238,7 @@ again: * synchronously or from an nfsiod. */ int -nfs_doio(bp, cr, td) - struct buf *bp; - struct ucred *cr; - struct thread *td; +nfs_doio(struct buf *bp, struct ucred *cr, struct thread *td) { struct uio *uiop; struct vnode *vp; @@ -1397,7 +1247,7 @@ nfs_doio(bp, cr, td) int error = 0, iomode, must_commit = 0; struct uio uio; struct iovec io; - struct proc *p = td?td->td_proc:NULL; + struct proc *p = td ? td->td_proc : NULL; vp = bp->b_vp; np = VTONFS(vp); @@ -1461,7 +1311,7 @@ nfs_doio(bp, cr, td) * hit a file hole. We should zero-fill the remainder. * This can also occur if the server hits the file EOF. * - * Holes used to be able to occur due to pending + * Holes used to be able to occur due to pending * writes, but that is not possible any longer. */ int nread = bp->b_bcount - uiop->uio_resid; @@ -1473,11 +1323,7 @@ nfs_doio(bp, cr, td) } } if (p && (vp->v_flag & VTEXT) && - (((nmp->nm_flag & NFSMNT_NQNFS) && - NQNFS_CKINVALID(vp, np, ND_READ) && - np->n_lrev != np->n_brev) || - (!(nmp->nm_flag & NFSMNT_NQNFS) && - np->n_mtime != np->n_vattr.va_mtime.tv_sec))) { + (np->n_mtime != np->n_vattr.va_mtime.tv_sec)) { uprintf("Process killed due to text file modification\n"); PROC_LOCK(p); psignal(p, SIGKILL); @@ -1508,7 +1354,7 @@ nfs_doio(bp, cr, td) bp->b_flags |= B_INVAL; break; default: - printf("nfs_doio: type %x unexpected\n",vp->v_type); + printf("nfs_doio: type %x unexpected\n", vp->v_type); break; }; if (error) { @@ -1516,7 +1362,7 @@ nfs_doio(bp, cr, td) bp->b_error = error; } } else { - /* + /* * If we only need to commit, try to commit */ if (bp->b_flags & B_NEEDCOMMIT) { @@ -1569,7 +1415,7 @@ nfs_doio(bp, cr, td) * When setting B_NEEDCOMMIT also set B_CLUSTEROK to try * to cluster the buffers needing commit. This will allow * the system to submit a single commit rpc for the whole - * cluster. We can do this even if the buffer is not 100% + * cluster. We can do this even if the buffer is not 100% * dirty (relative to the NFS blocksize), so we optimize the * append-to-file-case. * diff --git a/sys/nfsclient/nfs_lock.c b/sys/nfsclient/nfs_lock.c index b97b3b8..ce047ba 100644 --- a/sys/nfsclient/nfs_lock.c +++ b/sys/nfsclient/nfs_lock.c @@ -26,9 +26,11 @@ * SUCH DAMAGE. * * from BSDI nfs_lock.c,v 2.4 1998/12/14 23:49:56 jch Exp - * $FreeBSD$ */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + #include <sys/param.h> #include <sys/systm.h> #include <sys/fcntl.h> @@ -52,11 +54,11 @@ #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> -#include <nfs/nfs.h> -#include <nfs/nfsmount.h> -#include <nfs/nfsnode.h> -#include <nfs/nfs_lock.h> -#include <nfs/nlminfo.h> +#include <nfsclient/nfs.h> +#include <nfsclient/nfsmount.h> +#include <nfsclient/nfsnode.h> +#include <nfsclient/nfs_lock.h> +#include <nfsclient/nlminfo.h> #define NFSOWNER_1ST_LEVEL_START 1 /* initial entries */ #define NFSOWNER_2ND_LEVEL 256 /* some power of 2 */ @@ -67,7 +69,7 @@ /* * XXX * We have to let the process know if the call succeeded. I'm using an extra - * field in the p_nlminfo field in the proc structure, as it is already for + * field in the p_nlminfo field in the proc structure, as it is already for * lockd stuff. */ @@ -76,14 +78,7 @@ * NFS advisory byte-level locks. */ int -nfs_dolock(ap) - struct vop_advlock_args /* { - struct vnode *a_vp; - caddr_t a_id; - int a_op; - struct flock *a_fl; - int a_flags; - } */ *ap; +nfs_dolock(struct vop_advlock_args *ap) { LOCKD_MSG msg; struct nameidata nd; @@ -198,10 +193,10 @@ nfs_dolock(ap) * retry after 20 seconds if we haven't gotten a responce yet. * This number was picked out of thin air... but is longer * then even a reasonably loaded system should take (at least - * on a local network). XXX Probably should use a back-off + * on a local network). XXX Probably should use a back-off * scheme. */ - if ((error = tsleep((void *)p->p_nlminfo, + if ((error = tsleep((void *)p->p_nlminfo, PCATCH | PUSER, "lockd", 20*hz)) != 0) { if (error == EWOULDBLOCK) { /* @@ -238,14 +233,12 @@ nfs_dolock(ap) * NFS advisory byte-level locks answer from the lock daemon. */ int -nfslockdans(p, ansp) - struct proc *p; - struct lockd_ans *ansp; +nfslockdans(struct proc *p, struct lockd_ans *ansp) { int error; /* Let root, or someone who once was root (lockd generally - * switches to the daemon uid once it is done setting up) make + * switches to the daemon uid once it is done setting up) make * this call. * * XXX This authorization check is probably not right. @@ -261,7 +254,7 @@ nfslockdans(p, ansp) if ((p = pfind(ansp->la_msg_ident.pid)) == NULL) return (ESRCH); - /* verify the pid hasn't been reused (if we can), and it isn't waiting + /* verify the pid hasn't been reused (if we can), and it isn't waiting * for an answer from a more recent request. We return an EPIPE if * the match fails, because we've already used ESRCH above, and this * is sort of like writing on a pipe after the reader has closed it. diff --git a/sys/nfsclient/nfs_lock.h b/sys/nfsclient/nfs_lock.h index 64b6c70..0d081c4 100644 --- a/sys/nfsclient/nfs_lock.h +++ b/sys/nfsclient/nfs_lock.h @@ -31,7 +31,7 @@ /* * lockd uses the nfssvc system call to get the unique kernel services it needs. * It passes in a request structure with a version number at the start. - * This prevents libc from needing to change if the information passed + * This prevents libc from needing to change if the information passed * between lockd and the kernel needs to change. * * If a structure changes, you must bump the version number. @@ -39,26 +39,7 @@ #include <nfs/nfsproto.h> - -#define LOCKD_REQ_VERSION 1 - -struct lockd_req { - int vers; /* keep in sync with kernel please */ - int op; /* F_GETLK | F_SETLK | F_UNLCK */ - int owner; /* owner of lock, -1 to allocate one */ - int owner_rel_ok; /* release owner if no locks left ? */ - int *owner_ret; /* owner alloc/free result target */ - void *fh; /* NFS file handle */ - size_t fh_len; /* NFS file handle length */ - u_quad_t offset; /* offset of where to start lock */ - u_quad_t len; /* length of range to lock */ - int type; /* F_RDLCK | F_WRLCK | F_UNLCK */ - struct ucred cred; /* user credentials to use for lock */ - struct sockaddr saddr; /* XXX how about non AF_INET ?? */ - int pid; /* pid of lock requester */ -}; - -/* +/* * The fifo where the kernel writes requests for locks on remote NFS files, * and where lockd reads these requests. * @@ -107,6 +88,5 @@ struct lockd_ans { #ifdef _KERNEL int nfs_dolock(struct vop_advlock_args *ap); -int nfslockdans(struct proc *p, struct lockd_ans *ansp); -int nfslockdreq(struct proc *p, struct lockd_req *reqp); +int nfslockdans(struct proc *p, struct lockd_ans *ansp); #endif diff --git a/sys/nfsclient/nfs_nfsiod.c b/sys/nfsclient/nfs_nfsiod.c index 657f299..4e0ac10 100644 --- a/sys/nfsclient/nfs_nfsiod.c +++ b/sys/nfsclient/nfs_nfsiod.c @@ -34,9 +34,11 @@ * SUCH DAMAGE. * * @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95 - * $FreeBSD$ */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + #include <sys/param.h> #include <sys/systm.h> #include <sys/sysproto.h> @@ -56,43 +58,26 @@ #include <sys/domain.h> #include <sys/protosw.h> #include <sys/namei.h> +#include <sys/unistd.h> +#include <sys/kthread.h> #include <sys/fcntl.h> #include <sys/lockf.h> +#include <sys/mutex.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <nfs/xdr_subs.h> #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> -#include <nfs/nfs.h> -#include <nfs/nfsm_subs.h> -#include <nfs/nfsrvcache.h> -#include <nfs/nfsmount.h> -#include <nfs/nfsnode.h> -#include <nfs/nqnfs.h> -#include <nfs/nfsrtt.h> -#include <nfs/nfs_lock.h> +#include <nfsclient/nfs.h> +#include <nfsclient/nfsm_subs.h> +#include <nfsclient/nfsmount.h> +#include <nfsclient/nfsnode.h> +#include <nfsclient/nfs_lock.h> static MALLOC_DEFINE(M_NFSSVC, "NFS srvsock", "Nfs server structure"); -/* Global defs. */ -extern int32_t (*nfsrv3_procs[NFS_NPROCS]) __P((struct nfsrv_descript *nd, - struct nfssvc_sock *slp, - struct thread *td, - struct mbuf **mreqp)); -extern int nfs_numasync; -extern time_t nqnfsstarttime; -extern int nqsrv_writeslack; -extern int nfsrtton; -extern struct nfsstats nfsstats; -extern int nfsrvw_procrastinate; -extern int nfsrvw_procrastinate_v3; -static int nuidhash_max = NFS_MAXUIDHASH; - -#ifndef NFS_NOSERVER -static void nfsrv_zapsock __P((struct nfssvc_sock *slp)); -#endif -static int nfssvc_iod __P((struct thread *)); +static void nfssvc_iod(void *); #define TRUE 1 #define FALSE 0 @@ -101,849 +86,52 @@ static int nfs_asyncdaemon[NFS_MAXASYNCDAEMON]; SYSCTL_DECL(_vfs_nfs); -#ifndef NFS_NOSERVER -int nfsd_waiting = 0; -static struct nfsdrt nfsdrt; -static int nfs_numnfsd = 0; -static int notstarted = 1; -static int modify_flag = 0; -static void nfsd_rt __P((int sotype, struct nfsrv_descript *nd, - int cacherep)); -static int nfssvc_addsock __P((struct file *, struct sockaddr *, - struct thread *)); -static int nfssvc_nfsd __P((struct nfsd_srvargs *,caddr_t, - struct thread *)); - -static int nfs_privport = 0; -SYSCTL_INT(_vfs_nfs, NFS_NFSPRIVPORT, nfs_privport, CTLFLAG_RW, &nfs_privport, 0, ""); -SYSCTL_INT(_vfs_nfs, OID_AUTO, gatherdelay, CTLFLAG_RW, &nfsrvw_procrastinate, 0, ""); -SYSCTL_INT(_vfs_nfs, OID_AUTO, gatherdelay_v3, CTLFLAG_RW, &nfsrvw_procrastinate_v3, 0, ""); - -/* - * NFS server system calls - */ - -#endif /* NFS_NOSERVER */ -/* - * Nfs server psuedo system call for the nfsd's - * Based on the flag value it either: - * - adds a socket to the selection list - * - remains in the kernel as an nfsd - * - remains in the kernel as an nfsiod - */ -#ifndef _SYS_SYSPROTO_H_ -struct nfssvc_args { - int flag; - caddr_t argp; -}; -#endif -/* - * MPSAFE - */ -int -nfssvc(td, uap) - struct thread *td; - register struct nfssvc_args *uap; +static void +nfsiod_setup(void *dummy) { -#ifndef NFS_NOSERVER - struct nameidata nd; - struct file *fp; - struct sockaddr *nam; - struct nfsd_args nfsdarg; - struct nfsd_srvargs nfsd_srvargs, *nsd = &nfsd_srvargs; - struct nfsd_cargs ncd; - struct nfsd *nfsd; - struct nfssvc_sock *slp; - struct nfsuid *nuidp; - struct nfsmount *nmp; -#endif /* NFS_NOSERVER */ + int i; int error; + struct proc *p; - mtx_lock(&Giant); - - if ((uap->flag & NFSSVC_LOCKDANS) != 0) { - struct lockd_ans la; - - error = copyin(uap->argp, &la, sizeof(la)); - if (error == 0) - error = nfslockdans(td->td_proc, &la); - goto done2; - } - /* - * Must be super user - */ - error = suser_td(td); - if (error) - goto done2; - while (nfssvc_sockhead_flag & SLP_INIT) { - nfssvc_sockhead_flag |= SLP_WANTINIT; - (void) tsleep((caddr_t)&nfssvc_sockhead, PSOCK, "nfsd init", 0); - } - if (uap->flag & NFSSVC_BIOD) - error = nfssvc_iod(td); -#ifdef NFS_NOSERVER - else - error = ENXIO; -#else /* !NFS_NOSERVER */ - else if (uap->flag & NFSSVC_MNTD) { - error = copyin(uap->argp, (caddr_t)&ncd, sizeof (ncd)); - if (error) - goto done2; - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, - ncd.ncd_dirp, td); - error = namei(&nd); - if (error) - goto done2; - NDFREE(&nd, NDF_ONLY_PNBUF); - if ((nd.ni_vp->v_flag & VROOT) == 0) - error = EINVAL; - nmp = VFSTONFS(nd.ni_vp->v_mount); - vput(nd.ni_vp); + for (i = 0; i < 4; i++) { + error = kthread_create(nfssvc_iod, NULL, &p, RFHIGHPID, + "nfsiod %d", i); if (error) - goto done2; - if ((nmp->nm_state & NFSSTA_MNTD) && - (uap->flag & NFSSVC_GOTAUTH) == 0) { - error = 0; - goto done2; - } - nmp->nm_state |= NFSSTA_MNTD; - error = nqnfs_clientd(nmp, td->td_proc->p_ucred, &ncd, uap->flag, - uap->argp, td); - } else if (uap->flag & NFSSVC_ADDSOCK) { - error = copyin(uap->argp, (caddr_t)&nfsdarg, sizeof(nfsdarg)); - if (error) - goto done2; - error = holdsock(td->td_proc->p_fd, nfsdarg.sock, &fp); - if (error) - goto done2; - /* - * Get the client address for connected sockets. - */ - if (nfsdarg.name == NULL || nfsdarg.namelen == 0) - nam = (struct sockaddr *)0; - else { - error = getsockaddr(&nam, nfsdarg.name, - nfsdarg.namelen); - if (error) { - fdrop(fp, td); - goto done2; - } - } - error = nfssvc_addsock(fp, nam, td); - fdrop(fp, td); - } else { - error = copyin(uap->argp, (caddr_t)nsd, sizeof (*nsd)); - if (error) - goto done2; - if ((uap->flag & NFSSVC_AUTHIN) && - ((nfsd = nsd->nsd_nfsd)) != NULL && - (nfsd->nfsd_slp->ns_flag & SLP_VALID)) { - slp = nfsd->nfsd_slp; - - /* - * First check to see if another nfsd has already - * added this credential. - */ - for (nuidp = NUIDHASH(slp,nsd->nsd_cr.cr_uid)->lh_first; - nuidp != 0; nuidp = nuidp->nu_hash.le_next) { - if (nuidp->nu_cr.cr_uid == nsd->nsd_cr.cr_uid && - (!nfsd->nfsd_nd->nd_nam2 || - netaddr_match(NU_NETFAM(nuidp), - &nuidp->nu_haddr, nfsd->nfsd_nd->nd_nam2))) - break; - } - if (nuidp) { - nfsrv_setcred(&nuidp->nu_cr,&nfsd->nfsd_nd->nd_cr); - nfsd->nfsd_nd->nd_flag |= ND_KERBFULL; - } else { - /* - * Nope, so we will. - */ - if (slp->ns_numuids < nuidhash_max) { - slp->ns_numuids++; - nuidp = (struct nfsuid *) - malloc(sizeof (struct nfsuid), M_NFSUID, - M_WAITOK); - } else - nuidp = (struct nfsuid *)0; - if ((slp->ns_flag & SLP_VALID) == 0) { - if (nuidp) - free((caddr_t)nuidp, M_NFSUID); - } else { - if (nuidp == (struct nfsuid *)0) { - nuidp = slp->ns_uidlruhead.tqh_first; - LIST_REMOVE(nuidp, nu_hash); - TAILQ_REMOVE(&slp->ns_uidlruhead, nuidp, - nu_lru); - if (nuidp->nu_flag & NU_NAM) - FREE(nuidp->nu_nam, M_SONAME); - } - nuidp->nu_flag = 0; - bzero(&nuidp->nu_cr, sizeof(nuidp->nu_cr)); - nuidp->nu_cr.cr_uid = nsd->nsd_cr.cr_uid; - nuidp->nu_cr.cr_ngroups = - nsd->nsd_cr.cr_ngroups; - bcopy(nsd->nsd_cr.cr_groups, - nuidp->nu_cr.cr_groups, - sizeof(nuidp->nu_cr.cr_groups)); - if (nuidp->nu_cr.cr_ngroups > NGROUPS) - nuidp->nu_cr.cr_ngroups = NGROUPS; - nuidp->nu_cr.cr_ref = 1; - nuidp->nu_timestamp = nsd->nsd_timestamp; - nuidp->nu_expire = time_second + nsd->nsd_ttl; - /* - * and save the session key in nu_key. - */ - bcopy(nsd->nsd_key, nuidp->nu_key, - sizeof (nsd->nsd_key)); - if (nfsd->nfsd_nd->nd_nam2) { - struct sockaddr_in *saddr; - - saddr = (struct sockaddr_in *) - nfsd->nfsd_nd->nd_nam2; - switch (saddr->sin_family) { - case AF_INET: - nuidp->nu_flag |= NU_INETADDR; - nuidp->nu_inetaddr = - saddr->sin_addr.s_addr; - break; - case AF_ISO: - default: - nuidp->nu_flag |= NU_NAM; - nuidp->nu_nam = - dup_sockaddr(nfsd->nfsd_nd-> - nd_nam2, 1); - break; - }; - } - TAILQ_INSERT_TAIL(&slp->ns_uidlruhead, nuidp, - nu_lru); - LIST_INSERT_HEAD(NUIDHASH(slp, nsd->nsd_uid), - nuidp, nu_hash); - nfsrv_setcred(&nuidp->nu_cr, - &nfsd->nfsd_nd->nd_cr); - nfsd->nfsd_nd->nd_flag |= ND_KERBFULL; - } - } - } - if ((uap->flag & NFSSVC_AUTHINFAIL) && (nfsd = nsd->nsd_nfsd)) - nfsd->nfsd_flag |= NFSD_AUTHFAIL; - error = nfssvc_nfsd(nsd, uap->argp, td); - } -#endif /* NFS_NOSERVER */ - if (error == EINTR || error == ERESTART) - error = 0; -done2: - mtx_unlock(&Giant); - return (error); -} - -#ifndef NFS_NOSERVER -/* - * Adds a socket to the list for servicing by nfsds. - */ -static int -nfssvc_addsock(fp, mynam, td) - struct file *fp; - struct sockaddr *mynam; - struct thread *td; -{ - register int siz; - register struct nfssvc_sock *slp; - register struct socket *so; - int error, s; - - so = (struct socket *)fp->f_data; -#if 0 - tslp = (struct nfssvc_sock *)0; - /* - * Add it to the list, as required. - */ - if (so->so_proto->pr_protocol == IPPROTO_UDP) { - tslp = nfs_udpsock; - if (tslp->ns_flag & SLP_VALID) { - if (mynam != NULL) - FREE(mynam, M_SONAME); - return (EPERM); - } - } -#endif - if (so->so_type == SOCK_STREAM) - siz = NFS_MAXPACKET + sizeof (u_long); - else - siz = NFS_MAXPACKET; - error = soreserve(so, siz, siz); - if (error) { - if (mynam != NULL) - FREE(mynam, M_SONAME); - return (error); - } - - /* - * Set protocol specific options { for now TCP only } and - * reserve some space. For datagram sockets, this can get called - * repeatedly for the same socket, but that isn't harmful. - */ - if (so->so_type == SOCK_STREAM) { - struct sockopt sopt; - int val; - - bzero(&sopt, sizeof sopt); - sopt.sopt_level = SOL_SOCKET; - sopt.sopt_name = SO_KEEPALIVE; - sopt.sopt_val = &val; - sopt.sopt_valsize = sizeof val; - val = 1; - sosetopt(so, &sopt); - } - if (so->so_proto->pr_domain->dom_family == AF_INET && - so->so_proto->pr_protocol == IPPROTO_TCP) { - struct sockopt sopt; - int val; - - bzero(&sopt, sizeof sopt); - sopt.sopt_level = IPPROTO_TCP; - sopt.sopt_name = TCP_NODELAY; - sopt.sopt_val = &val; - sopt.sopt_valsize = sizeof val; - val = 1; - sosetopt(so, &sopt); - } - so->so_rcv.sb_flags &= ~SB_NOINTR; - so->so_rcv.sb_timeo = 0; - so->so_snd.sb_flags &= ~SB_NOINTR; - so->so_snd.sb_timeo = 0; - - slp = (struct nfssvc_sock *) - malloc(sizeof (struct nfssvc_sock), M_NFSSVC, - M_WAITOK | M_ZERO); - STAILQ_INIT(&slp->ns_rec); - TAILQ_INIT(&slp->ns_uidlruhead); - TAILQ_INSERT_TAIL(&nfssvc_sockhead, slp, ns_chain); - - slp->ns_so = so; - slp->ns_nam = mynam; - fp->f_count++; - slp->ns_fp = fp; - s = splnet(); - so->so_upcallarg = (caddr_t)slp; - so->so_upcall = nfsrv_rcv; - so->so_rcv.sb_flags |= SB_UPCALL; - slp->ns_flag = (SLP_VALID | SLP_NEEDQ); - nfsrv_wakenfsd(slp); - splx(s); - return (0); -} - -/* - * Called by nfssvc() for nfsds. Just loops around servicing rpc requests - * until it is killed by a signal. - */ -static int -nfssvc_nfsd(nsd, argp, td) - struct nfsd_srvargs *nsd; - caddr_t argp; - struct thread *td; -{ - register int siz; - register struct nfssvc_sock *slp; - struct nfsd *nfsd = nsd->nsd_nfsd; - struct nfsrv_descript *nd = NULL; - struct mbuf *m, *mreq; - int error = 0, cacherep, s, sotype, writes_todo; - int procrastinate; - u_quad_t cur_usec; - -#ifndef nolint - cacherep = RC_DOIT; - writes_todo = 0; -#endif - if (nfsd == (struct nfsd *)0) { - nsd->nsd_nfsd = nfsd = (struct nfsd *) - malloc(sizeof (struct nfsd), M_NFSD, M_WAITOK | M_ZERO); - s = splnet(); - nfsd->nfsd_td = td; - TAILQ_INSERT_TAIL(&nfsd_head, nfsd, nfsd_chain); - nfs_numnfsd++; - } else - s = splnet(); - - /* - * Loop getting rpc requests until SIGKILL. - */ - for (;;) { - if ((nfsd->nfsd_flag & NFSD_REQINPROG) == 0) { - while (nfsd->nfsd_slp == (struct nfssvc_sock *)0 && - (nfsd_head_flag & NFSD_CHECKSLP) == 0) { - nfsd->nfsd_flag |= NFSD_WAITING; - nfsd_waiting++; - error = tsleep((caddr_t)nfsd, PSOCK | PCATCH, - "nfsd", 0); - nfsd_waiting--; - if (error) - goto done; - } - if (nfsd->nfsd_slp == (struct nfssvc_sock *)0 && - (nfsd_head_flag & NFSD_CHECKSLP) != 0) { - for (slp = nfssvc_sockhead.tqh_first; slp != 0; - slp = slp->ns_chain.tqe_next) { - if ((slp->ns_flag & (SLP_VALID | SLP_DOREC)) - == (SLP_VALID | SLP_DOREC)) { - slp->ns_flag &= ~SLP_DOREC; - slp->ns_sref++; - nfsd->nfsd_slp = slp; - break; - } - } - if (slp == 0) - nfsd_head_flag &= ~NFSD_CHECKSLP; - } - if ((slp = nfsd->nfsd_slp) == (struct nfssvc_sock *)0) - continue; - if (slp->ns_flag & SLP_VALID) { - if (slp->ns_flag & SLP_DISCONN) - nfsrv_zapsock(slp); - else if (slp->ns_flag & SLP_NEEDQ) { - slp->ns_flag &= ~SLP_NEEDQ; - (void) nfs_slplock(slp, 1); - nfsrv_rcv(slp->ns_so, (caddr_t)slp, - M_TRYWAIT); - nfs_slpunlock(slp); - } - error = nfsrv_dorec(slp, nfsd, &nd); - cur_usec = nfs_curusec(); - if (error && slp->ns_tq.lh_first && - slp->ns_tq.lh_first->nd_time <= cur_usec) { - error = 0; - cacherep = RC_DOIT; - writes_todo = 1; - } else - writes_todo = 0; - nfsd->nfsd_flag |= NFSD_REQINPROG; - } - } else { - error = 0; - slp = nfsd->nfsd_slp; - } - if (error || (slp->ns_flag & SLP_VALID) == 0) { - if (nd) { - free((caddr_t)nd, M_NFSRVDESC); - nd = NULL; - } - nfsd->nfsd_slp = (struct nfssvc_sock *)0; - nfsd->nfsd_flag &= ~NFSD_REQINPROG; - nfsrv_slpderef(slp); - continue; - } - splx(s); - sotype = slp->ns_so->so_type; - if (nd) { - getmicrotime(&nd->nd_starttime); - if (nd->nd_nam2) - nd->nd_nam = nd->nd_nam2; - else - nd->nd_nam = slp->ns_nam; - - /* - * Check to see if authorization is needed. - */ - if (nfsd->nfsd_flag & NFSD_NEEDAUTH) { - nfsd->nfsd_flag &= ~NFSD_NEEDAUTH; - nsd->nsd_haddr = - ((struct sockaddr_in *) - nd->nd_nam)->sin_addr.s_addr; - nsd->nsd_authlen = nfsd->nfsd_authlen; - nsd->nsd_verflen = nfsd->nfsd_verflen; - if (!copyout(nfsd->nfsd_authstr,nsd->nsd_authstr, - nfsd->nfsd_authlen) && - !copyout(nfsd->nfsd_verfstr, nsd->nsd_verfstr, - nfsd->nfsd_verflen) && - !copyout((caddr_t)nsd, argp, sizeof (*nsd))) - return (ENEEDAUTH); - cacherep = RC_DROPIT; - } else - cacherep = nfsrv_getcache(nd, slp, &mreq); - - /* - * Check for just starting up for NQNFS and send - * fake "try again later" replies to the NQNFS clients. - */ - if (notstarted && nqnfsstarttime <= time_second) { - if (modify_flag) { - nqnfsstarttime = time_second + nqsrv_writeslack; - modify_flag = 0; - } else - notstarted = 0; - } - if (notstarted) { - if ((nd->nd_flag & ND_NQNFS) == 0) - cacherep = RC_DROPIT; - else if (nd->nd_procnum != NFSPROC_WRITE) { - nd->nd_procnum = NFSPROC_NOOP; - nd->nd_repstat = NQNFS_TRYLATER; - cacherep = RC_DOIT; - } else - modify_flag = 1; - } else if (nfsd->nfsd_flag & NFSD_AUTHFAIL) { - nfsd->nfsd_flag &= ~NFSD_AUTHFAIL; - nd->nd_procnum = NFSPROC_NOOP; - nd->nd_repstat = (NFSERR_AUTHERR | AUTH_TOOWEAK); - cacherep = RC_DOIT; - } else if (nfs_privport) { - /* Check if source port is privileged */ - u_short port; - struct sockaddr *nam = nd->nd_nam; - struct sockaddr_in *sin; - - sin = (struct sockaddr_in *)nam; - port = ntohs(sin->sin_port); - if (port >= IPPORT_RESERVED && - nd->nd_procnum != NFSPROC_NULL) { - nd->nd_procnum = NFSPROC_NOOP; - nd->nd_repstat = (NFSERR_AUTHERR | AUTH_TOOWEAK); - cacherep = RC_DOIT; - printf("NFS request from unprivileged port (%s:%d)\n", - inet_ntoa(sin->sin_addr), port); - } - } - - } - - /* - * Loop to get all the write rpc relies that have been - * gathered together. - */ - do { - switch (cacherep) { - case RC_DOIT: - if (nd && (nd->nd_flag & ND_NFSV3)) - procrastinate = nfsrvw_procrastinate_v3; - else - procrastinate = nfsrvw_procrastinate; - if (writes_todo || (nd->nd_procnum == NFSPROC_WRITE && - procrastinate > 0 && !notstarted)) - error = nfsrv_writegather(&nd, slp, - nfsd->nfsd_td, &mreq); - else - error = (*(nfsrv3_procs[nd->nd_procnum]))(nd, - slp, nfsd->nfsd_td, &mreq); - if (mreq == NULL) - break; - if (error != 0 && error != NFSERR_RETVOID) { - if (nd->nd_procnum != NQNFSPROC_VACATED) - nfsstats.srv_errs++; - nfsrv_updatecache(nd, FALSE, mreq); - if (nd->nd_nam2) - FREE(nd->nd_nam2, M_SONAME); - break; - } - nfsstats.srvrpccnt[nd->nd_procnum]++; - nfsrv_updatecache(nd, TRUE, mreq); - nd->nd_mrep = (struct mbuf *)0; - case RC_REPLY: - m = mreq; - siz = 0; - while (m) { - siz += m->m_len; - m = m->m_next; - } - if (siz <= 0 || siz > NFS_MAXPACKET) { - printf("mbuf siz=%d\n",siz); - panic("Bad nfs svc reply"); - } - m = mreq; - m->m_pkthdr.len = siz; - m->m_pkthdr.rcvif = (struct ifnet *)0; - /* - * For stream protocols, prepend a Sun RPC - * Record Mark. - */ - if (sotype == SOCK_STREAM) { - M_PREPEND(m, NFSX_UNSIGNED, M_TRYWAIT); - *mtod(m, u_int32_t *) = htonl(0x80000000 | siz); - } - if (slp->ns_so->so_proto->pr_flags & PR_CONNREQUIRED) - (void) nfs_slplock(slp, 1); - if (slp->ns_flag & SLP_VALID) - error = nfs_send(slp->ns_so, nd->nd_nam2, m, NULL); - else { - error = EPIPE; - m_freem(m); - } - if (nfsrtton) - nfsd_rt(sotype, nd, cacherep); - if (nd->nd_nam2) - FREE(nd->nd_nam2, M_SONAME); - if (nd->nd_mrep) - m_freem(nd->nd_mrep); - if (error == EPIPE) - nfsrv_zapsock(slp); - if (slp->ns_so->so_proto->pr_flags & PR_CONNREQUIRED) - nfs_slpunlock(slp); - if (error == EINTR || error == ERESTART) { - free((caddr_t)nd, M_NFSRVDESC); - nfsrv_slpderef(slp); - s = splnet(); - goto done; - } - break; - case RC_DROPIT: - if (nfsrtton) - nfsd_rt(sotype, nd, cacherep); - m_freem(nd->nd_mrep); - if (nd->nd_nam2) - FREE(nd->nd_nam2, M_SONAME); - break; - }; - if (nd) { - FREE((caddr_t)nd, M_NFSRVDESC); - nd = NULL; - } - - /* - * Check to see if there are outstanding writes that - * need to be serviced. - */ - cur_usec = nfs_curusec(); - s = splsoftclock(); - if (slp->ns_tq.lh_first && - slp->ns_tq.lh_first->nd_time <= cur_usec) { - cacherep = RC_DOIT; - writes_todo = 1; - } else - writes_todo = 0; - splx(s); - } while (writes_todo); - s = splnet(); - if (nfsrv_dorec(slp, nfsd, &nd)) { - nfsd->nfsd_flag &= ~NFSD_REQINPROG; - nfsd->nfsd_slp = NULL; - nfsrv_slpderef(slp); - } + panic("nfsiod_setup: kthread_create error %d", error); } -done: - TAILQ_REMOVE(&nfsd_head, nfsd, nfsd_chain); - splx(s); - free((caddr_t)nfsd, M_NFSD); - nsd->nsd_nfsd = (struct nfsd *)0; - if (--nfs_numnfsd == 0) - nfsrv_init(TRUE); /* Reinitialize everything */ - return (error); } +SYSINIT(nfsiod, SI_SUB_KTHREAD_IDLE, SI_ORDER_ANY, nfsiod_setup, NULL); -/* - * Shut down a socket associated with an nfssvc_sock structure. - * Should be called with the send lock set, if required. - * The trick here is to increment the sref at the start, so that the nfsds - * will stop using it and clear ns_flag at the end so that it will not be - * reassigned during cleanup. - */ -static void -nfsrv_zapsock(slp) - register struct nfssvc_sock *slp; -{ - register struct nfsuid *nuidp, *nnuidp; - register struct nfsrv_descript *nwp, *nnwp; - struct socket *so; - struct file *fp; - struct nfsrv_rec *rec; - int s; - - slp->ns_flag &= ~SLP_ALLFLAGS; - fp = slp->ns_fp; - if (fp) { - slp->ns_fp = (struct file *)0; - so = slp->ns_so; - so->so_rcv.sb_flags &= ~SB_UPCALL; - so->so_upcall = NULL; - so->so_upcallarg = NULL; - soshutdown(so, 2); - closef(fp, (struct thread *)0); - if (slp->ns_nam) - FREE(slp->ns_nam, M_SONAME); - m_freem(slp->ns_raw); - while ((rec = STAILQ_FIRST(&slp->ns_rec)) != NULL) { - STAILQ_REMOVE_HEAD(&slp->ns_rec, nr_link); - if (rec->nr_address) - FREE(rec->nr_address, M_SONAME); - m_freem(rec->nr_packet); - free(rec, M_NFSRVDESC); - } - for (nuidp = slp->ns_uidlruhead.tqh_first; nuidp != 0; - nuidp = nnuidp) { - nnuidp = nuidp->nu_lru.tqe_next; - LIST_REMOVE(nuidp, nu_hash); - TAILQ_REMOVE(&slp->ns_uidlruhead, nuidp, nu_lru); - if (nuidp->nu_flag & NU_NAM) - FREE(nuidp->nu_nam, M_SONAME); - free((caddr_t)nuidp, M_NFSUID); - } - s = splsoftclock(); - for (nwp = slp->ns_tq.lh_first; nwp; nwp = nnwp) { - nnwp = nwp->nd_tq.le_next; - LIST_REMOVE(nwp, nd_tq); - free((caddr_t)nwp, M_NFSRVDESC); - } - LIST_INIT(&slp->ns_tq); - splx(s); - } -} - -/* - * Derefence a server socket structure. If it has no more references and - * is no longer valid, you can throw it away. - */ -void -nfsrv_slpderef(slp) - register struct nfssvc_sock *slp; -{ - if (--(slp->ns_sref) == 0 && (slp->ns_flag & SLP_VALID) == 0) { - TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain); - free((caddr_t)slp, M_NFSSVC); - } -} +static int nfs_defect = 0; +SYSCTL_INT(_vfs_nfs, OID_AUTO, defect, CTLFLAG_RW, &nfs_defect, 0, ""); -/* - * Lock a socket against others. - */ int -nfs_slplock(slp, wait) - register struct nfssvc_sock *slp; - int wait; +nfsclnt(struct thread *td, struct nfsclnt_args *uap) { - int *statep = &slp->ns_solock; - - if (!wait && (*statep & NFSSTA_SNDLOCK)) - return(0); /* already locked, fail */ - while (*statep & NFSSTA_SNDLOCK) { - *statep |= NFSSTA_WANTSND; - (void) tsleep((caddr_t)statep, PZERO - 1, "nfsslplck", 0); - } - *statep |= NFSSTA_SNDLOCK; - return (1); -} - -/* - * Unlock the stream socket for others. - */ -void -nfs_slpunlock(slp) - register struct nfssvc_sock *slp; -{ - int *statep = &slp->ns_solock; - - if ((*statep & NFSSTA_SNDLOCK) == 0) - panic("nfs slpunlock"); - *statep &= ~NFSSTA_SNDLOCK; - if (*statep & NFSSTA_WANTSND) { - *statep &= ~NFSSTA_WANTSND; - wakeup((caddr_t)statep); - } -} - -/* - * Initialize the data structures for the server. - * Handshake with any new nfsds starting up to avoid any chance of - * corruption. - */ -void -nfsrv_init(terminating) - int terminating; -{ - register struct nfssvc_sock *slp, *nslp; - - if (nfssvc_sockhead_flag & SLP_INIT) - panic("nfsd init"); - nfssvc_sockhead_flag |= SLP_INIT; - if (terminating) { - for (slp = nfssvc_sockhead.tqh_first; slp != 0; slp = nslp) { - nslp = slp->ns_chain.tqe_next; - if (slp->ns_flag & SLP_VALID) - nfsrv_zapsock(slp); - TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain); - free((caddr_t)slp, M_NFSSVC); - } - nfsrv_cleancache(); /* And clear out server cache */ - } else - nfs_pub.np_valid = 0; + struct lockd_ans la; + int error; - TAILQ_INIT(&nfssvc_sockhead); - nfssvc_sockhead_flag &= ~SLP_INIT; - if (nfssvc_sockhead_flag & SLP_WANTINIT) { - nfssvc_sockhead_flag &= ~SLP_WANTINIT; - wakeup((caddr_t)&nfssvc_sockhead); + if ((uap->flag & NFSCLNT_LOCKDANS) != 0) { + error = copyin(uap->argp, &la, sizeof(la)); + return (error != 0 ? error : nfslockdans(td->td_proc, &la)); } - - TAILQ_INIT(&nfsd_head); - nfsd_head_flag &= ~NFSD_CHECKSLP; - -#if 0 - nfs_udpsock = (struct nfssvc_sock *) - malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK | M_ZERO); - STAILQ_INIT(&nfs_udpsock->ns_rec); - TAILQ_INIT(&nfs_udpsock->ns_uidlruhead); - TAILQ_INSERT_HEAD(&nfssvc_sockhead, nfs_udpsock, ns_chain); - - nfs_cltpsock = (struct nfssvc_sock *) - malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK | M_ZERO); - STAILQ_INIT(&nfs_cltpsock->ns_rec); - TAILQ_INIT(&nfs_cltpsock->ns_uidlruhead); - TAILQ_INSERT_TAIL(&nfssvc_sockhead, nfs_cltpsock, ns_chain); -#endif + return EINVAL; } /* - * Add entries to the server monitor log. - */ -static void -nfsd_rt(sotype, nd, cacherep) - int sotype; - register struct nfsrv_descript *nd; - int cacherep; -{ - register struct drt *rt; - - rt = &nfsdrt.drt[nfsdrt.pos]; - if (cacherep == RC_DOIT) - rt->flag = 0; - else if (cacherep == RC_REPLY) - rt->flag = DRT_CACHEREPLY; - else - rt->flag = DRT_CACHEDROP; - if (sotype == SOCK_STREAM) - rt->flag |= DRT_TCP; - if (nd->nd_flag & ND_NQNFS) - rt->flag |= DRT_NQNFS; - else if (nd->nd_flag & ND_NFSV3) - rt->flag |= DRT_NFSV3; - rt->proc = nd->nd_procnum; - if (nd->nd_nam->sa_family == AF_INET) - rt->ipadr = ((struct sockaddr_in *)nd->nd_nam)->sin_addr.s_addr; - else - rt->ipadr = INADDR_ANY; - rt->resptime = nfs_curusec() - (nd->nd_starttime.tv_sec * 1000000 + nd->nd_starttime.tv_usec); - getmicrotime(&rt->tstamp); - nfsdrt.pos = (nfsdrt.pos + 1) % NFSRTTLOGSIZ; -} -#endif /* NFS_NOSERVER */ - -static int nfs_defect = 0; -SYSCTL_INT(_vfs_nfs, OID_AUTO, defect, CTLFLAG_RW, &nfs_defect, 0, ""); - -/* * Asynchronous I/O daemons for client nfs. * They do read-ahead and write-behind operations on the block I/O cache. * Never returns unless it fails or gets killed. */ -static int -nfssvc_iod(td) - struct thread *td; +static void +nfssvc_iod(void *dummy) { - register struct buf *bp; - register int i, myiod; + struct buf *bp; + int i, myiod; struct nfsmount *nmp; int error = 0; + mtx_lock(&Giant); /* * Assign my position or return error if too many already running */ @@ -955,18 +143,18 @@ nfssvc_iod(td) break; } if (myiod == -1) - return (EBUSY); + return /* XXX (EBUSY) */; nfs_numasync++; /* * Just loop around doin our stuff until SIGKILL */ for (;;) { while (((nmp = nfs_iodmount[myiod]) == NULL - || nmp->nm_bufq.tqh_first == NULL) + || !TAILQ_FIRST(&nmp->nm_bufq)) && error == 0) { if (nmp) nmp->nm_bufqiods--; - nfs_iodwant[myiod] = td->td_proc; + nfs_iodwant[myiod] = curthread->td_proc; nfs_iodmount[myiod] = NULL; error = tsleep((caddr_t)&nfs_iodwant[myiod], PWAIT | PCATCH, "nfsidl", 0); @@ -978,9 +166,9 @@ nfssvc_iod(td) nfs_iodwant[myiod] = NULL; nfs_iodmount[myiod] = NULL; nfs_numasync--; - return (error); + return /* XXX (error) */; } - while ((bp = nmp->nm_bufq.tqh_first) != NULL) { + while ((bp = TAILQ_FIRST(&nmp->nm_bufq)) != NULL) { /* Take one off the front of the list */ TAILQ_REMOVE(&nmp->nm_bufq, bp, b_freelist); nmp->nm_bufqlen--; @@ -1007,208 +195,3 @@ nfssvc_iod(td) } } } - - -/* - * Get an authorization string for the uid by having the mount_nfs sitting - * on this mount point porpous out of the kernel and do it. - */ -int -nfs_getauth(nmp, rep, cred, auth_str, auth_len, verf_str, verf_len, key) - register struct nfsmount *nmp; - struct nfsreq *rep; - struct ucred *cred; - char **auth_str; - int *auth_len; - char *verf_str; - int *verf_len; - NFSKERBKEY_T key; /* return session key */ -{ - int error = 0; - - while ((nmp->nm_state & NFSSTA_WAITAUTH) == 0) { - nmp->nm_state |= NFSSTA_WANTAUTH; - (void) tsleep((caddr_t)&nmp->nm_authtype, PSOCK, - "nfsauth1", 2 * hz); - error = nfs_sigintr(nmp, rep, rep->r_td->td_proc); - if (error) { - nmp->nm_state &= ~NFSSTA_WANTAUTH; - return (error); - } - } - nmp->nm_state &= ~(NFSSTA_WAITAUTH | NFSSTA_WANTAUTH); - nmp->nm_authstr = *auth_str = (char *)malloc(RPCAUTH_MAXSIZ, M_TEMP, M_WAITOK); - nmp->nm_authlen = RPCAUTH_MAXSIZ; - nmp->nm_verfstr = verf_str; - nmp->nm_verflen = *verf_len; - nmp->nm_authuid = cred->cr_uid; - wakeup((caddr_t)&nmp->nm_authstr); - - /* - * And wait for mount_nfs to do its stuff. - */ - while ((nmp->nm_state & NFSSTA_HASAUTH) == 0 && error == 0) { - (void) tsleep((caddr_t)&nmp->nm_authlen, PSOCK, - "nfsauth2", 2 * hz); - error = nfs_sigintr(nmp, rep, rep->r_td->td_proc); - } - if (nmp->nm_state & NFSSTA_AUTHERR) { - nmp->nm_state &= ~NFSSTA_AUTHERR; - error = EAUTH; - } - if (error) - free((caddr_t)*auth_str, M_TEMP); - else { - *auth_len = nmp->nm_authlen; - *verf_len = nmp->nm_verflen; - bcopy((caddr_t)nmp->nm_key, (caddr_t)key, sizeof (key)); - } - nmp->nm_state &= ~NFSSTA_HASAUTH; - nmp->nm_state |= NFSSTA_WAITAUTH; - if (nmp->nm_state & NFSSTA_WANTAUTH) { - nmp->nm_state &= ~NFSSTA_WANTAUTH; - wakeup((caddr_t)&nmp->nm_authtype); - } - return (error); -} - -/* - * Get a nickname authenticator and verifier. - */ -int -nfs_getnickauth(nmp, cred, auth_str, auth_len, verf_str, verf_len) - struct nfsmount *nmp; - struct ucred *cred; - char **auth_str; - int *auth_len; - char *verf_str; - int verf_len; -{ - register struct nfsuid *nuidp; - register u_int32_t *nickp, *verfp; - struct timeval ktvin, ktvout; - -#ifdef DIAGNOSTIC - if (verf_len < (4 * NFSX_UNSIGNED)) - panic("nfs_getnickauth verf too small"); -#endif - for (nuidp = NMUIDHASH(nmp, cred->cr_uid)->lh_first; - nuidp != 0; nuidp = nuidp->nu_hash.le_next) { - if (nuidp->nu_cr.cr_uid == cred->cr_uid) - break; - } - if (!nuidp || nuidp->nu_expire < time_second) - return (EACCES); - - /* - * Move to the end of the lru list (end of lru == most recently used). - */ - TAILQ_REMOVE(&nmp->nm_uidlruhead, nuidp, nu_lru); - TAILQ_INSERT_TAIL(&nmp->nm_uidlruhead, nuidp, nu_lru); - - nickp = (u_int32_t *)malloc(2 * NFSX_UNSIGNED, M_TEMP, M_WAITOK); - *nickp++ = txdr_unsigned(RPCAKN_NICKNAME); - *nickp = txdr_unsigned(nuidp->nu_nickname); - *auth_str = (char *)nickp; - *auth_len = 2 * NFSX_UNSIGNED; - - /* - * Now we must encrypt the verifier and package it up. - */ - verfp = (u_int32_t *)verf_str; - *verfp++ = txdr_unsigned(RPCAKN_NICKNAME); - if (time_second > nuidp->nu_timestamp.tv_sec || - (time_second == nuidp->nu_timestamp.tv_sec && - time_second > nuidp->nu_timestamp.tv_usec)) - getmicrotime(&nuidp->nu_timestamp); - else - nuidp->nu_timestamp.tv_usec++; - ktvin.tv_sec = txdr_unsigned(nuidp->nu_timestamp.tv_sec); - ktvin.tv_usec = txdr_unsigned(nuidp->nu_timestamp.tv_usec); - - /* - * Now encrypt the timestamp verifier in ecb mode using the session - * key. - */ -#ifdef NFSKERB - XXX -#endif - - *verfp++ = ktvout.tv_sec; - *verfp++ = ktvout.tv_usec; - *verfp = 0; - return (0); -} - -/* - * Save the current nickname in a hash list entry on the mount point. - */ -int -nfs_savenickauth(nmp, cred, len, key, mdp, dposp, mrep) - register struct nfsmount *nmp; - struct ucred *cred; - int len; - NFSKERBKEY_T key; - struct mbuf **mdp; - char **dposp; - struct mbuf *mrep; -{ - register struct nfsuid *nuidp; - register u_int32_t *tl; - register int32_t t1; - struct mbuf *md = *mdp; - struct timeval ktvin, ktvout; - u_int32_t nick; - char *dpos = *dposp, *cp2; - int deltasec, error = 0; - - if (len == (3 * NFSX_UNSIGNED)) { - nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); - ktvin.tv_sec = *tl++; - ktvin.tv_usec = *tl++; - nick = fxdr_unsigned(u_int32_t, *tl); - - /* - * Decrypt the timestamp in ecb mode. - */ -#ifdef NFSKERB - XXX -#endif - ktvout.tv_sec = fxdr_unsigned(long, ktvout.tv_sec); - ktvout.tv_usec = fxdr_unsigned(long, ktvout.tv_usec); - deltasec = time_second - ktvout.tv_sec; - if (deltasec < 0) - deltasec = -deltasec; - /* - * If ok, add it to the hash list for the mount point. - */ - if (deltasec <= NFS_KERBCLOCKSKEW) { - if (nmp->nm_numuids < nuidhash_max) { - nmp->nm_numuids++; - nuidp = (struct nfsuid *) - malloc(sizeof (struct nfsuid), M_NFSUID, - M_WAITOK); - } else { - nuidp = nmp->nm_uidlruhead.tqh_first; - LIST_REMOVE(nuidp, nu_hash); - TAILQ_REMOVE(&nmp->nm_uidlruhead, nuidp, - nu_lru); - } - nuidp->nu_flag = 0; - nuidp->nu_cr.cr_uid = cred->cr_uid; - nuidp->nu_expire = time_second + NFS_KERBTTL; - nuidp->nu_timestamp = ktvout; - nuidp->nu_nickname = nick; - bcopy(key, nuidp->nu_key, sizeof (key)); - TAILQ_INSERT_TAIL(&nmp->nm_uidlruhead, nuidp, - nu_lru); - LIST_INSERT_HEAD(NMUIDHASH(nmp, cred->cr_uid), - nuidp, nu_hash); - } - } else - nfsm_adv(nfsm_rndup(len)); -nfsmout: - *mdp = md; - *dposp = dpos; - return (error); -} diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c index 5fe3abc..21769e2 100644 --- a/sys/nfsclient/nfs_node.c +++ b/sys/nfsclient/nfs_node.c @@ -34,9 +34,10 @@ * SUCH DAMAGE. * * @(#)nfs_node.c 8.6 (Berkeley) 5/22/95 - * $FreeBSD$ */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> @@ -54,21 +55,23 @@ #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> -#include <nfs/nfs.h> -#include <nfs/nfsnode.h> -#include <nfs/nfsmount.h> +#include <nfsclient/nfs.h> +#include <nfsclient/nfsnode.h> +#include <nfsclient/nfsmount.h> static vm_zone_t nfsnode_zone; static LIST_HEAD(nfsnodehashhead, nfsnode) *nfsnodehashtbl; static u_long nfsnodehash; +static int nfs_node_hash_lock; #define TRUE 1 #define FALSE 0 +SYSCTL_DECL(_debug_hashstat); + /* * Grab an atomic snapshot of the nfsnode hash chain lengths */ -SYSCTL_DECL(_debug_hashstat); static int sysctl_debug_hashstat_rawnfsnode(SYSCTL_HANDLER_ARGS) { @@ -94,8 +97,8 @@ sysctl_debug_hashstat_rawnfsnode(SYSCTL_HANDLER_ARGS) } return (0); } -SYSCTL_PROC(_debug_hashstat, OID_AUTO, rawnfsnode, CTLTYPE_INT|CTLFLAG_RD, - 0, 0, sysctl_debug_hashstat_rawnfsnode, "S,int", "nfsnode chain lengths"); +SYSCTL_PROC(_debug_hashstat, OID_AUTO, rawnfsnode, CTLTYPE_INT|CTLFLAG_RD, 0, 0, + sysctl_debug_hashstat_rawnfsnode, "S,int", "nfsnode chain lengths"); static int sysctl_debug_hashstat_nfsnode(SYSCTL_HANDLER_ARGS) @@ -148,8 +151,9 @@ SYSCTL_PROC(_debug_hashstat, OID_AUTO, nfsnode, CTLTYPE_INT|CTLFLAG_RD, * and build nfsnode free list. */ void -nfs_nhinit() +nfs_nhinit(void) { + nfsnode_zone = zinit("NFSNODE", sizeof(struct nfsnode), 0, 0, 1); nfsnodehashtbl = hashinit(desiredvnodes, M_NFSHASH, &nfsnodehash); } @@ -160,19 +164,13 @@ nfs_nhinit() * In all cases, a pointer to a * nfsnode structure is returned. */ -static int nfs_node_hash_lock; - int -nfs_nget(mntp, fhp, fhsize, npp) - struct mount *mntp; - register nfsfh_t *fhp; - int fhsize; - struct nfsnode **npp; +nfs_nget(struct mount *mntp, nfsfh_t *fhp, int fhsize, struct nfsnode **npp) { struct thread *td = curthread; /* XXX */ struct nfsnode *np, *np2; struct nfsnodehashhead *nhpp; - register struct vnode *vp; + struct vnode *vp; struct vnode *nvp; int error; int rsflags; @@ -191,7 +189,7 @@ nfs_nget(mntp, fhp, fhsize, npp) retry: nhpp = NFSNOHASH(fnv_32_buf(fhp->fh_bytes, fhsize, FNV1_32_INIT)); loop: - for (np = nhpp->lh_first; np != 0; np = np->n_hash.le_next) { + LIST_FOREACH(np, nhpp, n_hash) { if (mntp != NFSTOV(np)->v_mount || np->n_fhsize != fhsize || bcmp((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize)) continue; @@ -220,7 +218,7 @@ loop: * elsewhere if zalloc should block. */ np = zalloc(nfsnode_zone); - + error = getnewvnode(VT_NFS, mntp, nfsv2_vnodeop_p, &nvp); if (error) { if (nfs_node_hash_lock < 0) @@ -237,7 +235,7 @@ loop: /* * Insert the nfsnode in the hash queue for its new file handle */ - for (np2 = nhpp->lh_first; np2 != 0; np2 = np2->n_hash.le_next) { + LIST_FOREACH(np2, nhpp, n_hash) { if (mntp != NFSTOV(np2)->v_mount || np2->n_fhsize != fhsize || bcmp((caddr_t)fhp, (caddr_t)np2->n_fhp, fhsize)) continue; @@ -272,14 +270,10 @@ loop: } int -nfs_inactive(ap) - struct vop_inactive_args /* { - struct vnode *a_vp; - struct thread *a_td; - } */ *ap; +nfs_inactive(struct vop_inactive_args *ap) { - register struct nfsnode *np; - register struct sillyrename *sp; + struct nfsnode *np; + struct sillyrename *sp; struct thread *td = curthread; /* XXX */ np = VTONFS(ap->a_vp); @@ -314,8 +308,7 @@ nfs_inactive(ap) vrele(sp->s_dvp); FREE((caddr_t)sp, M_NFSREQ); } - np->n_flag &= (NMODIFIED | NFLUSHINPROG | NFLUSHWANT | NQNFSEVICTED | - NQNFSNONCACHE | NQNFSWRITE); + np->n_flag &= (NMODIFIED | NFLUSHINPROG | NFLUSHWANT); VOP_UNLOCK(ap->a_vp, 0, ap->a_td); return (0); } @@ -324,39 +317,28 @@ nfs_inactive(ap) * Reclaim an nfsnode so that it can be used for other purposes. */ int -nfs_reclaim(ap) - struct vop_reclaim_args /* { - struct vnode *a_vp; - } */ *ap; +nfs_reclaim(struct vop_reclaim_args *ap) { - register struct vnode *vp = ap->a_vp; - register struct nfsnode *np = VTONFS(vp); - register struct nfsmount *nmp = VFSTONFS(vp->v_mount); - register struct nfsdmap *dp, *dp2; + struct vnode *vp = ap->a_vp; + struct nfsnode *np = VTONFS(vp); + struct nfsdmap *dp, *dp2; if (prtactive && vp->v_usecount != 0) vprint("nfs_reclaim: pushing active", vp); - if (np->n_hash.le_prev != NULL) + if (np->n_hash.le_prev != NULL) /* XXX beware */ LIST_REMOVE(np, n_hash); /* - * For nqnfs, take it off the timer queue as required. - */ - if ((nmp->nm_flag & NFSMNT_NQNFS) && TAILQ_NEXT(np, n_timer) != 0) { - TAILQ_REMOVE(&nmp->nm_timerhead, np, n_timer); - } - - /* * Free up any directory cookie structures and * large file handle structures that might be associated with * this nfs node. */ if (vp->v_type == VDIR) { - dp = np->n_cookies.lh_first; + dp = LIST_FIRST(&np->n_cookies); while (dp) { dp2 = dp; - dp = dp->ndm_list.le_next; + dp = LIST_NEXT(dp, ndm_list); FREE((caddr_t)dp2, M_NFSDIROFF); } } @@ -377,12 +359,9 @@ nfs_reclaim(ap) * Lock an nfsnode */ int -nfs_lock(ap) - struct vop_lock_args /* { - struct vnode *a_vp; - } */ *ap; +nfs_lock(struct vop_lock_args *ap) { - register struct vnode *vp = ap->a_vp; + struct vnode *vp = ap->a_vp; /* * Ugh, another place where interruptible mounts will get hung. @@ -429,10 +408,7 @@ nfs_lock(ap) * Unlock an nfsnode */ int -nfs_unlock(ap) - struct vop_unlock_args /* { - struct vnode *a_vp; - } */ *ap; +nfs_unlock(struct vop_unlock_args *ap) { #if 0 struct vnode* vp = ap->a_vp; @@ -456,12 +432,9 @@ nfs_unlock(ap) * Check for a locked nfsnode */ int -nfs_islocked(ap) - struct vop_islocked_args /* { - struct vnode *a_vp; - struct thread *a_td; - } */ *ap; +nfs_islocked(struct vop_islocked_args *ap) { + return VTONFS(ap->a_vp)->n_flag & NLOCKED ? 1 : 0; } #endif diff --git a/sys/nfsclient/nfs_socket.c b/sys/nfsclient/nfs_socket.c index 8991672..4bf50e4 100644 --- a/sys/nfsclient/nfs_socket.c +++ b/sys/nfsclient/nfs_socket.c @@ -34,9 +34,11 @@ * SUCH DAMAGE. * * @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95 - * $FreeBSD$ */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + /* * Socket operations for use by nfs */ @@ -63,13 +65,11 @@ #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> -#include <nfs/nfs.h> +#include <nfsclient/nfs.h> #include <nfs/xdr_subs.h> -#include <nfs/nfsm_subs.h> -#include <nfs/nfsmount.h> -#include <nfs/nfsnode.h> -#include <nfs/nfsrtt.h> -#include <nfs/nqnfs.h> +#include <nfsclient/nfsm_subs.h> +#include <nfsclient/nfsmount.h> +#include <nfsclient/nfsnode.h> #define TRUE 1 #define FALSE 0 @@ -93,17 +93,6 @@ ((((n)->nm_srtt[t-1] + 7) >> 3) + (n)->nm_sdrtt[t-1] + 1))) #define NFS_SRTT(r) (r)->r_nmp->nm_srtt[proct[(r)->r_procnum] - 1] #define NFS_SDRTT(r) (r)->r_nmp->nm_sdrtt[proct[(r)->r_procnum] - 1] -/* - * External data, mostly RPC constants in XDR form - */ -extern u_int32_t rpc_reply, rpc_msgdenied, rpc_mismatch, rpc_vers, - rpc_auth_unix, rpc_msgaccepted, rpc_call, rpc_autherr, - rpc_auth_kerb; -extern u_int32_t nfs_prog, nqnfs_prog; -extern time_t nqnfsstarttime; -extern struct nfsstats nfsstats; -extern int nfsv3_procid[NFS_NPROCS]; -extern int nfs_ticks; /* * Defines which timer to use for the procnum. @@ -115,12 +104,11 @@ extern int nfs_ticks; */ static int proct[NFS_NPROCS] = { 0, 1, 0, 2, 1, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, - 0, 0, 0, }; -static int nfs_realign_test; -static int nfs_realign_count; -static int nfs_bufpackets = 4; +static int nfs_realign_test; +static int nfs_realign_count; +static int nfs_bufpackets = 4; SYSCTL_DECL(_vfs_nfs); @@ -145,64 +133,26 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, bufpackets, CTLFLAG_RW, &nfs_bufpackets, 0, ""); #define NFS_CWNDSCALE 256 #define NFS_MAXCWND (NFS_CWNDSCALE * 32) static int nfs_backoff[8] = { 2, 4, 8, 16, 32, 64, 128, 256, }; -int nfsrtton = 0; -struct nfsrtt nfsrtt; struct callout_handle nfs_timer_handle; -static int nfs_msg __P((struct thread *,char *,char *)); -static int nfs_rcvlock __P((struct nfsreq *)); -static void nfs_rcvunlock __P((struct nfsreq *)); -static void nfs_realign __P((struct mbuf **pm, int hsiz)); -static int nfs_receive __P((struct nfsreq *rep, struct sockaddr **aname, - struct mbuf **mp)); -static void nfs_softterm __P((struct nfsreq *rep)); -static int nfs_reconnect __P((struct nfsreq *rep)); -#ifndef NFS_NOSERVER -static int nfsrv_getstream __P((struct nfssvc_sock *,int)); - -int (*nfsrv3_procs[NFS_NPROCS]) __P((struct nfsrv_descript *nd, - struct nfssvc_sock *slp, - struct thread *td, - struct mbuf **mreqp)) = { - nfsrv_null, - nfsrv_getattr, - nfsrv_setattr, - nfsrv_lookup, - nfsrv3_access, - nfsrv_readlink, - nfsrv_read, - nfsrv_write, - nfsrv_create, - nfsrv_mkdir, - nfsrv_symlink, - nfsrv_mknod, - nfsrv_remove, - nfsrv_rmdir, - nfsrv_rename, - nfsrv_link, - nfsrv_readdir, - nfsrv_readdirplus, - nfsrv_statfs, - nfsrv_fsinfo, - nfsrv_pathconf, - nfsrv_commit, - nqnfsrv_getlease, - nqnfsrv_vacated, - nfsrv_noop, - nfsrv_noop -}; -#endif /* NFS_NOSERVER */ +static int nfs_msg(struct thread *, char *, char *); +static int nfs_rcvlock(struct nfsreq *); +static void nfs_rcvunlock(struct nfsreq *); +static void nfs_realign(struct mbuf **pm, int hsiz); +static int nfs_receive(struct nfsreq *rep, struct sockaddr **aname, + struct mbuf **mp); +static int nfs_reply(struct nfsreq *); +static void nfs_softterm(struct nfsreq *rep); +static int nfs_reconnect(struct nfsreq *rep); /* * Initialize sockets and congestion for a new NFS connection. * We do not free the sockaddr if error. */ int -nfs_connect(nmp, rep) - register struct nfsmount *nmp; - struct nfsreq *rep; +nfs_connect(struct nfsmount *nmp, struct nfsreq *rep) { - register struct socket *so; + struct socket *so; int s, error, rcvreserve, sndreserve; int pktscale; struct sockaddr *saddr; @@ -364,7 +314,7 @@ nfs_connect(nmp, rep) so->so_snd.sb_flags |= SB_NOINTR; /* Initialize other non-zero congestion variables */ - nmp->nm_srtt[0] = nmp->nm_srtt[1] = nmp->nm_srtt[2] = + nmp->nm_srtt[0] = nmp->nm_srtt[1] = nmp->nm_srtt[2] = nmp->nm_srtt[3] = (NFS_TIMEO << 3); nmp->nm_sdrtt[0] = nmp->nm_sdrtt[1] = nmp->nm_sdrtt[2] = nmp->nm_sdrtt[3] = 0; @@ -388,11 +338,10 @@ bad: * nb: Must be called with the nfs_sndlock() set on the mount point. */ static int -nfs_reconnect(rep) - register struct nfsreq *rep; +nfs_reconnect(struct nfsreq *rep) { - register struct nfsreq *rp; - register struct nfsmount *nmp = rep->r_nmp; + struct nfsreq *rp; + struct nfsmount *nmp = rep->r_nmp; int error; nfs_disconnect(nmp); @@ -406,7 +355,7 @@ nfs_reconnect(rep) * Loop through outstanding request list and fix up all requests * on old socket. */ - for (rp = nfs_reqq.tqh_first; rp != 0; rp = rp->r_chain.tqe_next) { + TAILQ_FOREACH(rp, &nfs_reqq, r_chain) { if (rp->r_nmp == nmp) rp->r_flags |= R_MUSTRESEND; } @@ -417,10 +366,9 @@ nfs_reconnect(rep) * NFS disconnect. Clean up and unlink. */ void -nfs_disconnect(nmp) - register struct nfsmount *nmp; +nfs_disconnect(struct nfsmount *nmp) { - register struct socket *so; + struct socket *so; if (nmp->nm_so) { so = nmp->nm_so; @@ -431,8 +379,7 @@ nfs_disconnect(nmp) } void -nfs_safedisconnect(nmp) - struct nfsmount *nmp; +nfs_safedisconnect(struct nfsmount *nmp) { struct nfsreq dummyreq; @@ -446,40 +393,31 @@ nfs_safedisconnect(nmp) /* * This is the nfs send routine. For connection based socket types, it * must be called with an nfs_sndlock() on the socket. - * "rep == NULL" indicates that it has been called from a server. - * For the client side: * - return EINTR if the RPC is terminated, 0 otherwise * - set R_MUSTRESEND if the send fails for any reason * - do any cleanup required by recoverable socket errors (?) - * For the server side: - * - return EINTR or ERESTART if interrupted by a signal - * - return EPIPE if a connection is lost for connection based sockets (TCP...) - * - do any cleanup required by recoverable socket errors (?) */ int -nfs_send(so, nam, top, rep) - register struct socket *so; - struct sockaddr *nam; - register struct mbuf *top; - struct nfsreq *rep; +nfs_send(struct socket *so, struct sockaddr *nam, struct mbuf *top, + struct nfsreq *rep) { struct sockaddr *sendnam; int error, soflags, flags; - if (rep) { - if (rep->r_flags & R_SOFTTERM) { - m_freem(top); - return (EINTR); - } - if ((so = rep->r_nmp->nm_so) == NULL) { - rep->r_flags |= R_MUSTRESEND; - m_freem(top); - return (0); - } - rep->r_flags &= ~R_MUSTRESEND; - soflags = rep->r_nmp->nm_soflags; - } else - soflags = so->so_proto->pr_flags; + KASSERT(rep, ("nfs_send: called with rep == NULL")); + + if (rep->r_flags & R_SOFTTERM) { + m_freem(top); + return (EINTR); + } + if ((so = rep->r_nmp->nm_so) == NULL) { + rep->r_flags |= R_MUSTRESEND; + m_freem(top); + return (0); + } + rep->r_flags &= ~R_MUSTRESEND; + soflags = rep->r_nmp->nm_soflags; + if ((soflags & PR_CONNREQUIRED) || (so->so_state & SS_ISCONNECTED)) sendnam = (struct sockaddr *)0; else @@ -491,29 +429,21 @@ nfs_send(so, nam, top, rep) error = so->so_proto->pr_usrreqs->pru_sosend(so, sendnam, 0, top, 0, flags, curthread /*XXX*/); - /* - * ENOBUFS for dgram sockets is transient and non fatal. - * No need to log, and no need to break a soft mount. - */ if (error == ENOBUFS && so->so_type == SOCK_DGRAM) { error = 0; - if (rep) /* do backoff retransmit on client */ - rep->r_flags |= R_MUSTRESEND; + rep->r_flags |= R_MUSTRESEND; } if (error) { - if (rep) { - log(LOG_INFO, "nfs send error %d for server %s\n",error, - rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname); - /* - * Deal with errors for the client side. - */ - if (rep->r_flags & R_SOFTTERM) - error = EINTR; - else - rep->r_flags |= R_MUSTRESEND; - } else - log(LOG_INFO, "nfsd send error %d\n", error); + log(LOG_INFO, "nfs send error %d for server %s\n", error, + rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname); + /* + * Deal with errors for the client side. + */ + if (rep->r_flags & R_SOFTTERM) + error = EINTR; + else + rep->r_flags |= R_MUSTRESEND; /* * Handle any recoverable (soft) socket errors here. (?) @@ -535,15 +465,12 @@ nfs_send(so, nam, top, rep) * we have read any of it, even if the system call has been interrupted. */ static int -nfs_receive(rep, aname, mp) - register struct nfsreq *rep; - struct sockaddr **aname; - struct mbuf **mp; +nfs_receive(struct nfsreq *rep, struct sockaddr **aname, struct mbuf **mp) { - register struct socket *so; + struct socket *so; struct uio auio; struct iovec aio; - register struct mbuf *m; + struct mbuf *m; struct mbuf *control; u_int32_t len; struct sockaddr **getnam; @@ -760,17 +687,16 @@ errout: * with outstanding requests using the xid, until ours is found. */ /* ARGSUSED */ -int -nfs_reply(myrep) - struct nfsreq *myrep; +static int +nfs_reply(struct nfsreq *myrep) { - register struct nfsreq *rep; - register struct nfsmount *nmp = myrep->r_nmp; - register int32_t t1; + struct nfsreq *rep; + struct nfsmount *nmp = myrep->r_nmp; + int32_t t1; struct mbuf *mrep, *md; struct sockaddr *nam; u_int32_t rxid, *tl; - caddr_t dpos, cp2; + caddr_t dpos; int error; /* @@ -822,18 +748,8 @@ nfs_reply(myrep) nfsm_dissect(tl, u_int32_t *, 2*NFSX_UNSIGNED); rxid = *tl++; if (*tl != rpc_reply) { -#ifndef NFS_NOSERVER - if (nmp->nm_flag & NFSMNT_NQNFS) { - if (nqnfs_callback(nmp, mrep, md, dpos)) - nfsstats.rpcinvalid++; - } else { - nfsstats.rpcinvalid++; - m_freem(mrep); - } -#else nfsstats.rpcinvalid++; m_freem(mrep); -#endif nfsmout: if (myrep->r_flags & R_GETONEREP) return (0); @@ -844,31 +760,12 @@ nfsmout: * Loop through the request list to match up the reply * Iff no match, just drop the datagram */ - for (rep = nfs_reqq.tqh_first; rep != 0; - rep = rep->r_chain.tqe_next) { + TAILQ_FOREACH(rep, &nfs_reqq, r_chain) { if (rep->r_mrep == NULL && rxid == rep->r_xid) { /* Found it.. */ rep->r_mrep = mrep; rep->r_md = md; rep->r_dpos = dpos; - if (nfsrtton) { - struct rttl *rt; - - rt = &nfsrtt.rttl[nfsrtt.pos]; - rt->proc = rep->r_procnum; - rt->rto = NFS_RTO(nmp, proct[rep->r_procnum]); - rt->sent = nmp->nm_sent; - rt->cwnd = nmp->nm_cwnd; - rt->srtt = nmp->nm_srtt[proct[rep->r_procnum] - 1]; - rt->sdrtt = nmp->nm_sdrtt[proct[rep->r_procnum] - 1]; - rt->fsid = nmp->nm_mountp->mnt_stat.f_fsid; - getmicrotime(&rt->tstamp); - if (rep->r_flags & R_TIMING) - rt->rtt = rep->r_rtt; - else - rt->rtt = 1000000; - nfsrtt.pos = (nfsrtt.pos + 1) % NFSRTTLOGSIZ; - } /* * Update congestion window. * Do the additive increase of @@ -937,34 +834,25 @@ nfsmout: * by mrep or error * nb: always frees up mreq mbuf list */ +/* XXX overloaded before */ +#define NQ_TRYLATERDEL 15 /* Initial try later delay (sec) */ + int -nfs_request(vp, mrest, procnum, td, cred, mrp, mdp, dposp) - struct vnode *vp; - struct mbuf *mrest; - int procnum; - struct thread *td; - struct ucred *cred; - struct mbuf **mrp; - struct mbuf **mdp; - caddr_t *dposp; +nfs_request(struct vnode *vp, struct mbuf *mrest, int procnum, + struct thread *td, struct ucred *cred, struct mbuf **mrp, + struct mbuf **mdp, caddr_t *dposp) { - register struct mbuf *mrep, *m2; - register struct nfsreq *rep; - register u_int32_t *tl; - register int i; + struct mbuf *mrep, *m2; + struct nfsreq *rep; + u_int32_t *tl; + int i; struct nfsmount *nmp; struct mbuf *m, *md, *mheadend; - struct nfsnode *np; - char nickv[RPCX_NICKVERF]; - time_t reqtime, waituntil; - caddr_t dpos, cp2; - int t1, nqlflag, cachable, s, error = 0, mrest_len, auth_len, auth_type; - int trylater_delay = NQ_TRYLATERDEL, trylater_cnt = 0, failed_auth = 0; - int verf_len, verf_type; + time_t waituntil; + caddr_t dpos; + int s, error = 0, mrest_len, auth_len, auth_type; + int trylater_delay = NQ_TRYLATERDEL, trylater_cnt = 0; u_int32_t xid; - u_quad_t frev; - char *auth_str, *verf_str; - NFSKERBKEY_T key; /* save session key */ nmp = VFSTONFS(vp->v_mount); MALLOC(rep, struct nfsreq *, sizeof(struct nfsreq), M_NFSREQ, M_WAITOK); @@ -983,35 +871,14 @@ nfs_request(vp, mrest, procnum, td, cred, mrp, mdp, dposp) /* * Get the RPC header with authorization. */ -kerbauth: - verf_str = auth_str = (char *)0; - if (nmp->nm_flag & NFSMNT_KERB) { - verf_str = nickv; - verf_len = sizeof (nickv); - auth_type = RPCAUTH_KERB4; - bzero((caddr_t)key, sizeof (key)); - if (failed_auth || nfs_getnickauth(nmp, cred, &auth_str, - &auth_len, verf_str, verf_len)) { - error = nfs_getauth(nmp, rep, cred, &auth_str, - &auth_len, verf_str, &verf_len, key); - if (error) { - free((caddr_t)rep, M_NFSREQ); - m_freem(mrest); - return (error); - } - } - } else { - auth_type = RPCAUTH_UNIX; - if (cred->cr_ngroups < 1) - panic("nfsreq nogrps"); - auth_len = ((((cred->cr_ngroups - 1) > nmp->nm_numgrps) ? - nmp->nm_numgrps : (cred->cr_ngroups - 1)) << 2) + - 5 * NFSX_UNSIGNED; - } + auth_type = RPCAUTH_UNIX; + if (cred->cr_ngroups < 1) + panic("nfsreq nogrps"); + auth_len = ((((cred->cr_ngroups - 1) > nmp->nm_numgrps) ? + nmp->nm_numgrps : (cred->cr_ngroups - 1)) << 2) + + 5 * NFSX_UNSIGNED; m = nfsm_rpchead(cred, nmp->nm_flag, procnum, auth_type, auth_len, - auth_str, verf_len, verf_str, mrest, mrest_len, &mheadend, &xid); - if (auth_str) - free(auth_str, M_TEMP); + mrest, mrest_len, &mheadend, &xid); /* * For stream protocols, insert a Sun RPC Record Mark. @@ -1046,9 +913,6 @@ tryagain: s = splsoftclock(); TAILQ_INSERT_TAIL(&nfs_reqq, rep, r_chain); - /* Get send time for nqnfs */ - reqtime = time_second; - /* * If backing off another request or avoiding congestion, don't * send this one now but let timer do it. If not timing a request, @@ -1119,16 +983,7 @@ tryagain: if (*tl++ == rpc_msgdenied) { if (*tl == rpc_mismatch) error = EOPNOTSUPP; - else if ((nmp->nm_flag & NFSMNT_KERB) && *tl++ == rpc_autherr) { - if (!failed_auth) { - failed_auth++; - mheadend->m_next = (struct mbuf *)0; - m_freem(mrep); - m_freem(rep->r_mreq); - goto kerbauth; - } else - error = EAUTH; - } else + else error = EACCES; m_freem(mrep); m_freem(rep->r_mreq); @@ -1137,15 +992,11 @@ tryagain: } /* - * Grab any Kerberos verifier, otherwise just throw it away. + * Just throw away any verifyer (ie: kerberos etc). */ - verf_type = fxdr_unsigned(int, *tl++); - i = fxdr_unsigned(int32_t, *tl); - if ((nmp->nm_flag & NFSMNT_KERB) && verf_type == RPCAUTH_KERB4) { - error = nfs_savenickauth(nmp, cred, i, key, &md, &dpos, mrep); - if (error) - goto nfsmout; - } else if (i > 0) + i = fxdr_unsigned(int, *tl++); /* verf type */ + i = fxdr_unsigned(int32_t, *tl); /* len */ + if (i > 0) nfsm_adv(nfsm_rndup(i)); nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); /* 0 == ok */ @@ -1185,24 +1036,6 @@ tryagain: return (error); } - /* - * For nqnfs, get any lease in reply - */ - if (nmp->nm_flag & NFSMNT_NQNFS) { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); - if (*tl) { - np = VTONFS(vp); - nqlflag = fxdr_unsigned(int, *tl); - nfsm_dissect(tl, u_int32_t *, 4*NFSX_UNSIGNED); - cachable = fxdr_unsigned(int, *tl++); - reqtime += fxdr_unsigned(int, *tl++); - if (reqtime > time_second) { - frev = fxdr_hyper(tl); - nqnfs_clientlease(nmp, np, nqlflag, - cachable, reqtime, frev); - } - } - } *mrp = mrep; *mdp = md; *dposp = dpos; @@ -1218,162 +1051,6 @@ nfsmout: return (error); } -#ifndef NFS_NOSERVER -/* - * Generate the rpc reply header - * siz arg. is used to decide if adding a cluster is worthwhile - */ -int -nfs_rephead(siz, nd, slp, err, cache, frev, mrq, mbp, bposp) - int siz; - struct nfsrv_descript *nd; - struct nfssvc_sock *slp; - int err; - int cache; - u_quad_t *frev; - struct mbuf **mrq; - struct mbuf **mbp; - caddr_t *bposp; -{ - register u_int32_t *tl; - register struct mbuf *mreq; - caddr_t bpos; - struct mbuf *mb, *mb2; - - MGETHDR(mreq, M_TRYWAIT, MT_DATA); - mb = mreq; - /* - * If this is a big reply, use a cluster else - * try and leave leading space for the lower level headers. - */ - siz += RPC_REPLYSIZ; - if ((max_hdr + siz) >= MINCLSIZE) { - MCLGET(mreq, M_TRYWAIT); - } else - mreq->m_data += max_hdr; - tl = mtod(mreq, u_int32_t *); - mreq->m_len = 6 * NFSX_UNSIGNED; - bpos = ((caddr_t)tl) + mreq->m_len; - *tl++ = txdr_unsigned(nd->nd_retxid); - *tl++ = rpc_reply; - if (err == ERPCMISMATCH || (err & NFSERR_AUTHERR)) { - *tl++ = rpc_msgdenied; - if (err & NFSERR_AUTHERR) { - *tl++ = rpc_autherr; - *tl = txdr_unsigned(err & ~NFSERR_AUTHERR); - mreq->m_len -= NFSX_UNSIGNED; - bpos -= NFSX_UNSIGNED; - } else { - *tl++ = rpc_mismatch; - *tl++ = txdr_unsigned(RPC_VER2); - *tl = txdr_unsigned(RPC_VER2); - } - } else { - *tl++ = rpc_msgaccepted; - - /* - * For Kerberos authentication, we must send the nickname - * verifier back, otherwise just RPCAUTH_NULL. - */ - if (nd->nd_flag & ND_KERBFULL) { - register struct nfsuid *nuidp; - struct timeval ktvin, ktvout; - - for (nuidp = NUIDHASH(slp, nd->nd_cr.cr_uid)->lh_first; - nuidp != 0; nuidp = nuidp->nu_hash.le_next) { - if (nuidp->nu_cr.cr_uid == nd->nd_cr.cr_uid && - (!nd->nd_nam2 || netaddr_match(NU_NETFAM(nuidp), - &nuidp->nu_haddr, nd->nd_nam2))) - break; - } - if (nuidp) { - ktvin.tv_sec = - txdr_unsigned(nuidp->nu_timestamp.tv_sec - 1); - ktvin.tv_usec = - txdr_unsigned(nuidp->nu_timestamp.tv_usec); - - /* - * Encrypt the timestamp in ecb mode using the - * session key. - */ -#ifdef NFSKERB - XXX -#endif - - *tl++ = rpc_auth_kerb; - *tl++ = txdr_unsigned(3 * NFSX_UNSIGNED); - *tl = ktvout.tv_sec; - nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); - *tl++ = ktvout.tv_usec; - *tl++ = txdr_unsigned(nuidp->nu_cr.cr_uid); - } else { - *tl++ = 0; - *tl++ = 0; - } - } else { - *tl++ = 0; - *tl++ = 0; - } - switch (err) { - case EPROGUNAVAIL: - *tl = txdr_unsigned(RPC_PROGUNAVAIL); - break; - case EPROGMISMATCH: - *tl = txdr_unsigned(RPC_PROGMISMATCH); - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - if (nd->nd_flag & ND_NQNFS) { - *tl++ = txdr_unsigned(3); - *tl = txdr_unsigned(3); - } else { - *tl++ = txdr_unsigned(2); - *tl = txdr_unsigned(3); - } - break; - case EPROCUNAVAIL: - *tl = txdr_unsigned(RPC_PROCUNAVAIL); - break; - case EBADRPC: - *tl = txdr_unsigned(RPC_GARBAGE); - break; - default: - *tl = 0; - if (err != NFSERR_RETVOID) { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); - if (err) - *tl = txdr_unsigned(nfsrv_errmap(nd, err)); - else - *tl = 0; - } - break; - }; - } - - /* - * For nqnfs, piggyback lease as requested. - */ - if ((nd->nd_flag & ND_NQNFS) && err == 0) { - if (nd->nd_flag & ND_LEASE) { - nfsm_build(tl, u_int32_t *, 5 * NFSX_UNSIGNED); - *tl++ = txdr_unsigned(nd->nd_flag & ND_LEASE); - *tl++ = txdr_unsigned(cache); - *tl++ = txdr_unsigned(nd->nd_duration); - txdr_hyper(*frev, tl); - } else { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = 0; - } - } - if (mrq != NULL) - *mrq = mreq; - *mbp = mb; - *bposp = bpos; - if (err != 0 && err != NFSERR_RETVOID) - nfsstats.srvrpc_errs++; - return (0); -} - - -#endif /* NFS_NOSERVER */ /* * Nfs timer routine * Scan the nfsreq list and retranmit any requests that have timed out @@ -1381,24 +1058,18 @@ nfs_rephead(siz, nd, slp, err, cache, frev, mrq, mbp, bposp) * sure to set the r_retry field to 0 (implies nm_retry == 0). */ void -nfs_timer(arg) - void *arg; /* never used */ +nfs_timer(void *arg) { - register struct nfsreq *rep; - register struct mbuf *m; - register struct socket *so; - register struct nfsmount *nmp; - register int timeo; + struct nfsreq *rep; + struct mbuf *m; + struct socket *so; + struct nfsmount *nmp; + int timeo; int s, error; -#ifndef NFS_NOSERVER - static long lasttime = 0; - register struct nfssvc_sock *slp; - u_quad_t cur_usec; -#endif /* NFS_NOSERVER */ struct thread *td = thread0; /* XXX for credentials, will break if sleep */ s = splnet(); - for (rep = nfs_reqq.tqh_first; rep != 0; rep = rep->r_chain.tqe_next) { + TAILQ_FOREACH(rep, &nfs_reqq, r_chain) { nmp = rep->r_nmp; if (rep->r_mrep || (rep->r_flags & R_SOFTTERM)) continue; @@ -1425,9 +1096,12 @@ nfs_timer(arg) */ if ((rep->r_flags & R_TPRINTFMSG) == 0 && rep->r_rexmit > nmp->nm_deadthresh) { + char buf[40]; + sprintf(buf, "not responding %d > %d", + rep->r_rexmit, nmp->nm_deadthresh); nfs_msg(rep->r_td, nmp->nm_mountp->mnt_stat.f_mntfromname, - "not responding"); + buf /* "not responding" */); rep->r_flags |= R_TPRINTFMSG; } if (rep->r_rexmit >= rep->r_retry) { /* too many */ @@ -1487,26 +1161,6 @@ nfs_timer(arg) } } } -#ifndef NFS_NOSERVER - /* - * Call the nqnfs server timer once a second to handle leases. - */ - if (lasttime != time_second) { - lasttime = time_second; - nqnfs_serverd(); - } - - /* - * Scan the write gathering queues for writes that need to be - * completed now. - */ - cur_usec = nfs_curusec(); - for (slp = nfssvc_sockhead.tqh_first; slp != 0; - slp = slp->ns_chain.tqe_next) { - if (slp->ns_tq.lh_first && slp->ns_tq.lh_first->nd_time<=cur_usec) - nfsrv_wakenfsd(slp); - } -#endif /* NFS_NOSERVER */ splx(s); nfs_timer_handle = timeout(nfs_timer, (void *)0, nfs_ticks); } @@ -1518,11 +1172,10 @@ nfs_timer(arg) */ static void -nfs_softterm(rep) - struct nfsreq *rep; +nfs_softterm(struct nfsreq *rep) { - rep->r_flags |= R_SOFTTERM; + rep->r_flags |= R_SOFTTERM; if (rep->r_flags & R_SENT) { rep->r_nmp->nm_sent -= NFS_CWNDSCALE; rep->r_flags &= ~R_SENT; @@ -1534,10 +1187,7 @@ nfs_softterm(rep) * This is used for NFSMNT_INT mounts. */ int -nfs_sigintr(nmp, rep, p) - struct nfsmount *nmp; - struct nfsreq *rep; - register struct proc *p; +nfs_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct proc *p) { sigset_t tmpset; @@ -1564,10 +1214,9 @@ nfs_sigintr(nmp, rep, p) * in progress when a reconnect is necessary. */ int -nfs_sndlock(rep) - struct nfsreq *rep; +nfs_sndlock(struct nfsreq *rep) { - register int *statep = &rep->r_nmp->nm_state; + int *statep = &rep->r_nmp->nm_state; struct thread *td; int slpflag = 0, slptimeo = 0; @@ -1596,10 +1245,9 @@ nfs_sndlock(rep) * Unlock the stream socket for others. */ void -nfs_sndunlock(rep) - struct nfsreq *rep; +nfs_sndunlock(struct nfsreq *rep) { - register int *statep = &rep->r_nmp->nm_state; + int *statep = &rep->r_nmp->nm_state; if ((*statep & NFSSTA_SNDLOCK) == 0) panic("nfs sndunlock"); @@ -1611,10 +1259,9 @@ nfs_sndunlock(rep) } static int -nfs_rcvlock(rep) - register struct nfsreq *rep; +nfs_rcvlock(struct nfsreq *rep) { - register int *statep = &rep->r_nmp->nm_state; + int *statep = &rep->r_nmp->nm_state; int slpflag, slptimeo = 0; if (rep->r_nmp->nm_flag & NFSMNT_INT) @@ -1649,10 +1296,9 @@ nfs_rcvlock(rep) * Unlock the stream socket for others. */ static void -nfs_rcvunlock(rep) - register struct nfsreq *rep; +nfs_rcvunlock(struct nfsreq *rep) { - register int *statep = &rep->r_nmp->nm_state; + int *statep = &rep->r_nmp->nm_state; if ((*statep & NFSSTA_RCVLOCK) == 0) panic("nfs rcvunlock"); @@ -1679,16 +1325,13 @@ nfs_rcvunlock(rep) * with TCP. Use vfs.nfs.realign_count and realign_test to check this. */ static void -nfs_realign(pm, hsiz) - register struct mbuf **pm; - int hsiz; +nfs_realign(struct mbuf **pm, int hsiz) { struct mbuf *m; struct mbuf *n = NULL; int off = 0; ++nfs_realign_test; - while ((m = *pm) != NULL) { if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) { MGET(n, M_TRYWAIT, MT_DATA); @@ -1700,7 +1343,6 @@ nfs_realign(pm, hsiz) } pm = &m->m_next; } - /* * If n is non-NULL, loop on m copying data, then replace the * portion of the chain that had to be realigned. @@ -1717,580 +1359,11 @@ nfs_realign(pm, hsiz) } } -#ifndef NFS_NOSERVER - -/* - * Parse an RPC request - * - verify it - * - fill in the cred struct. - */ -int -nfs_getreq(nd, nfsd, has_header) - register struct nfsrv_descript *nd; - struct nfsd *nfsd; - int has_header; -{ - register int len, i; - register u_int32_t *tl; - register int32_t t1; - struct uio uio; - struct iovec iov; - caddr_t dpos, cp2, cp; - u_int32_t nfsvers, auth_type; - uid_t nickuid; - int error = 0, nqnfs = 0, ticklen; - struct mbuf *mrep, *md; - register struct nfsuid *nuidp; - struct timeval tvin, tvout; -#if 0 /* until encrypted keys are implemented */ - NFSKERBKEYSCHED_T keys; /* stores key schedule */ -#endif - - mrep = nd->nd_mrep; - md = nd->nd_md; - dpos = nd->nd_dpos; - if (has_header) { - nfsm_dissect(tl, u_int32_t *, 10 * NFSX_UNSIGNED); - nd->nd_retxid = fxdr_unsigned(u_int32_t, *tl++); - if (*tl++ != rpc_call) { - m_freem(mrep); - return (EBADRPC); - } - } else - nfsm_dissect(tl, u_int32_t *, 8 * NFSX_UNSIGNED); - nd->nd_repstat = 0; - nd->nd_flag = 0; - if (*tl++ != rpc_vers) { - nd->nd_repstat = ERPCMISMATCH; - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - if (*tl != nfs_prog) { - if (*tl == nqnfs_prog) - nqnfs++; - else { - nd->nd_repstat = EPROGUNAVAIL; - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - } - tl++; - nfsvers = fxdr_unsigned(u_int32_t, *tl++); - if (((nfsvers < NFS_VER2 || nfsvers > NFS_VER3) && !nqnfs) || - (nfsvers != NQNFS_VER3 && nqnfs)) { - nd->nd_repstat = EPROGMISMATCH; - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - if (nqnfs) - nd->nd_flag = (ND_NFSV3 | ND_NQNFS); - else if (nfsvers == NFS_VER3) - nd->nd_flag = ND_NFSV3; - nd->nd_procnum = fxdr_unsigned(u_int32_t, *tl++); - if (nd->nd_procnum == NFSPROC_NULL) - return (0); - if (nd->nd_procnum >= NFS_NPROCS || - (!nqnfs && nd->nd_procnum >= NQNFSPROC_GETLEASE) || - (!nd->nd_flag && nd->nd_procnum > NFSV2PROC_STATFS)) { - nd->nd_repstat = EPROCUNAVAIL; - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - if ((nd->nd_flag & ND_NFSV3) == 0) - nd->nd_procnum = nfsv3_procid[nd->nd_procnum]; - auth_type = *tl++; - len = fxdr_unsigned(int, *tl++); - if (len < 0 || len > RPCAUTH_MAXSIZ) { - m_freem(mrep); - return (EBADRPC); - } - - nd->nd_flag &= ~ND_KERBAUTH; - /* - * Handle auth_unix or auth_kerb. - */ - if (auth_type == rpc_auth_unix) { - len = fxdr_unsigned(int, *++tl); - if (len < 0 || len > NFS_MAXNAMLEN) { - m_freem(mrep); - return (EBADRPC); - } - nfsm_adv(nfsm_rndup(len)); - nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); - bzero((caddr_t)&nd->nd_cr, sizeof (struct ucred)); - nd->nd_cr.cr_ref = 1; - nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++); - nd->nd_cr.cr_gid = fxdr_unsigned(gid_t, *tl++); - len = fxdr_unsigned(int, *tl); - if (len < 0 || len > RPCAUTH_UNIXGIDS) { - m_freem(mrep); - return (EBADRPC); - } - nfsm_dissect(tl, u_int32_t *, (len + 2) * NFSX_UNSIGNED); - for (i = 1; i <= len; i++) - if (i < NGROUPS) - nd->nd_cr.cr_groups[i] = fxdr_unsigned(gid_t, *tl++); - else - tl++; - nd->nd_cr.cr_ngroups = (len >= NGROUPS) ? NGROUPS : (len + 1); - if (nd->nd_cr.cr_ngroups > 1) - nfsrvw_sort(nd->nd_cr.cr_groups, nd->nd_cr.cr_ngroups); - len = fxdr_unsigned(int, *++tl); - if (len < 0 || len > RPCAUTH_MAXSIZ) { - m_freem(mrep); - return (EBADRPC); - } - if (len > 0) - nfsm_adv(nfsm_rndup(len)); - } else if (auth_type == rpc_auth_kerb) { - switch (fxdr_unsigned(int, *tl++)) { - case RPCAKN_FULLNAME: - ticklen = fxdr_unsigned(int, *tl); - *((u_int32_t *)nfsd->nfsd_authstr) = *tl; - uio.uio_resid = nfsm_rndup(ticklen) + NFSX_UNSIGNED; - nfsd->nfsd_authlen = uio.uio_resid + NFSX_UNSIGNED; - if (uio.uio_resid > (len - 2 * NFSX_UNSIGNED)) { - m_freem(mrep); - return (EBADRPC); - } - uio.uio_offset = 0; - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_segflg = UIO_SYSSPACE; - iov.iov_base = (caddr_t)&nfsd->nfsd_authstr[4]; - iov.iov_len = RPCAUTH_MAXSIZ - 4; - nfsm_mtouio(&uio, uio.uio_resid); - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - if (*tl++ != rpc_auth_kerb || - fxdr_unsigned(int, *tl) != 4 * NFSX_UNSIGNED) { - printf("Bad kerb verifier\n"); - nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF); - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - nfsm_dissect(cp, caddr_t, 4 * NFSX_UNSIGNED); - tl = (u_int32_t *)cp; - if (fxdr_unsigned(int, *tl) != RPCAKN_FULLNAME) { - printf("Not fullname kerb verifier\n"); - nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF); - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - cp += NFSX_UNSIGNED; - bcopy(cp, nfsd->nfsd_verfstr, 3 * NFSX_UNSIGNED); - nfsd->nfsd_verflen = 3 * NFSX_UNSIGNED; - nd->nd_flag |= ND_KERBFULL; - nfsd->nfsd_flag |= NFSD_NEEDAUTH; - break; - case RPCAKN_NICKNAME: - if (len != 2 * NFSX_UNSIGNED) { - printf("Kerb nickname short\n"); - nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADCRED); - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - nickuid = fxdr_unsigned(uid_t, *tl); - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - if (*tl++ != rpc_auth_kerb || - fxdr_unsigned(int, *tl) != 3 * NFSX_UNSIGNED) { - printf("Kerb nick verifier bad\n"); - nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF); - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); - tvin.tv_sec = *tl++; - tvin.tv_usec = *tl; - - for (nuidp = NUIDHASH(nfsd->nfsd_slp,nickuid)->lh_first; - nuidp != 0; nuidp = nuidp->nu_hash.le_next) { - if (nuidp->nu_cr.cr_uid == nickuid && - (!nd->nd_nam2 || - netaddr_match(NU_NETFAM(nuidp), - &nuidp->nu_haddr, nd->nd_nam2))) - break; - } - if (!nuidp) { - nd->nd_repstat = - (NFSERR_AUTHERR|AUTH_REJECTCRED); - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - - /* - * Now, decrypt the timestamp using the session key - * and validate it. - */ -#ifdef NFSKERB - XXX -#endif - - tvout.tv_sec = fxdr_unsigned(long, tvout.tv_sec); - tvout.tv_usec = fxdr_unsigned(long, tvout.tv_usec); - if (nuidp->nu_expire < time_second || - nuidp->nu_timestamp.tv_sec > tvout.tv_sec || - (nuidp->nu_timestamp.tv_sec == tvout.tv_sec && - nuidp->nu_timestamp.tv_usec > tvout.tv_usec)) { - nuidp->nu_expire = 0; - nd->nd_repstat = - (NFSERR_AUTHERR|AUTH_REJECTVERF); - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - nfsrv_setcred(&nuidp->nu_cr, &nd->nd_cr); - nd->nd_flag |= ND_KERBNICK; - }; - } else { - nd->nd_repstat = (NFSERR_AUTHERR | AUTH_REJECTCRED); - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - - /* - * For nqnfs, get piggybacked lease request. - */ - if (nqnfs && nd->nd_procnum != NQNFSPROC_EVICTED) { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); - nd->nd_flag |= fxdr_unsigned(int, *tl); - if (nd->nd_flag & ND_LEASE) { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); - nd->nd_duration = fxdr_unsigned(int32_t, *tl); - } else - nd->nd_duration = NQ_MINLEASE; - } else - nd->nd_duration = NQ_MINLEASE; - nd->nd_md = md; - nd->nd_dpos = dpos; - return (0); -nfsmout: - return (error); -} - -#endif static int -nfs_msg(td, server, msg) - struct thread *td; - char *server, *msg; +nfs_msg(struct thread *td, char *server, char *msg) { tprintf(td->td_proc, LOG_INFO, "nfs server %s: %s\n", server, msg); return (0); } - -#ifndef NFS_NOSERVER -/* - * Socket upcall routine for the nfsd sockets. - * The caddr_t arg is a pointer to the "struct nfssvc_sock". - * Essentially do as much as possible non-blocking, else punt and it will - * be called with M_TRYWAIT from an nfsd. - */ -void -nfsrv_rcv(so, arg, waitflag) - struct socket *so; - void *arg; - int waitflag; -{ - register struct nfssvc_sock *slp = (struct nfssvc_sock *)arg; - register struct mbuf *m; - struct mbuf *mp; - struct sockaddr *nam; - struct uio auio; - int flags, error; - - if ((slp->ns_flag & SLP_VALID) == 0) - return; -#ifdef notdef - /* - * Define this to test for nfsds handling this under heavy load. - */ - if (waitflag == M_DONTWAIT) { - slp->ns_flag |= SLP_NEEDQ; goto dorecs; - } -#endif - auio.uio_td = NULL; - if (so->so_type == SOCK_STREAM) { - /* - * If there are already records on the queue, defer soreceive() - * to an nfsd so that there is feedback to the TCP layer that - * the nfs servers are heavily loaded. - */ - if (STAILQ_FIRST(&slp->ns_rec) && waitflag == M_DONTWAIT) { - slp->ns_flag |= SLP_NEEDQ; - goto dorecs; - } - - /* - * Do soreceive(). - */ - auio.uio_resid = 1000000000; - flags = MSG_DONTWAIT; - error = so->so_proto->pr_usrreqs->pru_soreceive - (so, &nam, &auio, &mp, (struct mbuf **)0, &flags); - if (error || mp == (struct mbuf *)0) { - if (error == EWOULDBLOCK) - slp->ns_flag |= SLP_NEEDQ; - else - slp->ns_flag |= SLP_DISCONN; - goto dorecs; - } - m = mp; - if (slp->ns_rawend) { - slp->ns_rawend->m_next = m; - slp->ns_cc += 1000000000 - auio.uio_resid; - } else { - slp->ns_raw = m; - slp->ns_cc = 1000000000 - auio.uio_resid; - } - while (m->m_next) - m = m->m_next; - slp->ns_rawend = m; - - /* - * Now try and parse record(s) out of the raw stream data. - */ - error = nfsrv_getstream(slp, waitflag); - if (error) { - if (error == EPERM) - slp->ns_flag |= SLP_DISCONN; - else - slp->ns_flag |= SLP_NEEDQ; - } - } else { - do { - auio.uio_resid = 1000000000; - flags = MSG_DONTWAIT; - error = so->so_proto->pr_usrreqs->pru_soreceive - (so, &nam, &auio, &mp, - (struct mbuf **)0, &flags); - if (mp) { - struct nfsrv_rec *rec; - rec = malloc(sizeof(struct nfsrv_rec), - M_NFSRVDESC, waitflag); - if (!rec) { - if (nam) - FREE(nam, M_SONAME); - m_freem(mp); - continue; - } - nfs_realign(&mp, 10 * NFSX_UNSIGNED); - rec->nr_address = nam; - rec->nr_packet = mp; - STAILQ_INSERT_TAIL(&slp->ns_rec, rec, nr_link); - } - if (error) { - if ((so->so_proto->pr_flags & PR_CONNREQUIRED) - && error != EWOULDBLOCK) { - slp->ns_flag |= SLP_DISCONN; - goto dorecs; - } - } - } while (mp); - } - - /* - * Now try and process the request records, non-blocking. - */ -dorecs: - if (waitflag == M_DONTWAIT && - (STAILQ_FIRST(&slp->ns_rec) - || (slp->ns_flag & (SLP_NEEDQ | SLP_DISCONN)))) - nfsrv_wakenfsd(slp); -} - -/* - * Try and extract an RPC request from the mbuf data list received on a - * stream socket. The "waitflag" argument indicates whether or not it - * can sleep. - */ -static int -nfsrv_getstream(slp, waitflag) - register struct nfssvc_sock *slp; - int waitflag; -{ - register struct mbuf *m, **mpp; - register char *cp1, *cp2; - register int len; - struct mbuf *om, *m2, *recm = NULL; - u_int32_t recmark; - - if (slp->ns_flag & SLP_GETSTREAM) - panic("nfs getstream"); - slp->ns_flag |= SLP_GETSTREAM; - for (;;) { - if (slp->ns_reclen == 0) { - if (slp->ns_cc < NFSX_UNSIGNED) { - slp->ns_flag &= ~SLP_GETSTREAM; - return (0); - } - m = slp->ns_raw; - if (m->m_len >= NFSX_UNSIGNED) { - bcopy(mtod(m, caddr_t), (caddr_t)&recmark, NFSX_UNSIGNED); - m->m_data += NFSX_UNSIGNED; - m->m_len -= NFSX_UNSIGNED; - } else { - cp1 = (caddr_t)&recmark; - cp2 = mtod(m, caddr_t); - while (cp1 < ((caddr_t)&recmark) + NFSX_UNSIGNED) { - while (m->m_len == 0) { - m = m->m_next; - cp2 = mtod(m, caddr_t); - } - *cp1++ = *cp2++; - m->m_data++; - m->m_len--; - } - } - slp->ns_cc -= NFSX_UNSIGNED; - recmark = ntohl(recmark); - slp->ns_reclen = recmark & ~0x80000000; - if (recmark & 0x80000000) - slp->ns_flag |= SLP_LASTFRAG; - else - slp->ns_flag &= ~SLP_LASTFRAG; - if (slp->ns_reclen > NFS_MAXPACKET) { - slp->ns_flag &= ~SLP_GETSTREAM; - return (EPERM); - } - } - - /* - * Now get the record part. - */ - if (slp->ns_cc == slp->ns_reclen) { - recm = slp->ns_raw; - slp->ns_raw = slp->ns_rawend = (struct mbuf *)0; - slp->ns_cc = slp->ns_reclen = 0; - } else if (slp->ns_cc > slp->ns_reclen) { - len = 0; - m = slp->ns_raw; - om = (struct mbuf *)0; - while (len < slp->ns_reclen) { - if ((len + m->m_len) > slp->ns_reclen) { - m2 = m_copym(m, 0, slp->ns_reclen - len, - waitflag); - if (m2) { - if (om) { - om->m_next = m2; - recm = slp->ns_raw; - } else - recm = m2; - m->m_data += slp->ns_reclen - len; - m->m_len -= slp->ns_reclen - len; - len = slp->ns_reclen; - } else { - slp->ns_flag &= ~SLP_GETSTREAM; - return (EWOULDBLOCK); - } - } else if ((len + m->m_len) == slp->ns_reclen) { - om = m; - len += m->m_len; - m = m->m_next; - recm = slp->ns_raw; - om->m_next = (struct mbuf *)0; - } else { - om = m; - len += m->m_len; - m = m->m_next; - } - } - slp->ns_raw = m; - slp->ns_cc -= len; - slp->ns_reclen = 0; - } else { - slp->ns_flag &= ~SLP_GETSTREAM; - return (0); - } - - /* - * Accumulate the fragments into a record. - */ - mpp = &slp->ns_frag; - while (*mpp) - mpp = &((*mpp)->m_next); - *mpp = recm; - if (slp->ns_flag & SLP_LASTFRAG) { - struct nfsrv_rec *rec; - rec = malloc(sizeof(struct nfsrv_rec), M_NFSRVDESC, waitflag); - if (!rec) { - m_freem(slp->ns_frag); - } else { - nfs_realign(&slp->ns_frag, 10 * NFSX_UNSIGNED); - rec->nr_address = (struct sockaddr *)0; - rec->nr_packet = slp->ns_frag; - STAILQ_INSERT_TAIL(&slp->ns_rec, rec, nr_link); - } - slp->ns_frag = (struct mbuf *)0; - } - } -} - -/* - * Parse an RPC header. - */ -int -nfsrv_dorec(slp, nfsd, ndp) - register struct nfssvc_sock *slp; - struct nfsd *nfsd; - struct nfsrv_descript **ndp; -{ - struct nfsrv_rec *rec; - register struct mbuf *m; - struct sockaddr *nam; - register struct nfsrv_descript *nd; - int error; - - *ndp = NULL; - if ((slp->ns_flag & SLP_VALID) == 0 || !STAILQ_FIRST(&slp->ns_rec)) - return (ENOBUFS); - rec = STAILQ_FIRST(&slp->ns_rec); - STAILQ_REMOVE_HEAD(&slp->ns_rec, nr_link); - nam = rec->nr_address; - m = rec->nr_packet; - free(rec, M_NFSRVDESC); - MALLOC(nd, struct nfsrv_descript *, sizeof (struct nfsrv_descript), - M_NFSRVDESC, M_WAITOK); - nd->nd_md = nd->nd_mrep = m; - nd->nd_nam2 = nam; - nd->nd_dpos = mtod(m, caddr_t); - error = nfs_getreq(nd, nfsd, TRUE); - if (error) { - if (nam) { - FREE(nam, M_SONAME); - } - free((caddr_t)nd, M_NFSRVDESC); - return (error); - } - *ndp = nd; - nfsd->nfsd_nd = nd; - return (0); -} - -/* - * Search for a sleeping nfsd and wake it up. - * SIDE EFFECT: If none found, set NFSD_CHECKSLP flag, so that one of the - * running nfsds will go look for the work in the nfssvc_sock list. - */ -void -nfsrv_wakenfsd(slp) - struct nfssvc_sock *slp; -{ - register struct nfsd *nd; - - if ((slp->ns_flag & SLP_VALID) == 0) - return; - for (nd = nfsd_head.tqh_first; nd != 0; nd = nd->nfsd_chain.tqe_next) { - if (nd->nfsd_flag & NFSD_WAITING) { - nd->nfsd_flag &= ~NFSD_WAITING; - if (nd->nfsd_slp) - panic("nfsd wakeup"); - slp->ns_sref++; - nd->nfsd_slp = slp; - wakeup((caddr_t)nd); - return; - } - } - slp->ns_flag |= SLP_DOREC; - nfsd_head_flag |= NFSD_CHECKSLP; -} -#endif /* NFS_NOSERVER */ diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c index 4425129..c951115 100644 --- a/sys/nfsclient/nfs_subs.c +++ b/sys/nfsclient/nfs_subs.c @@ -34,14 +34,17 @@ * SUCH DAMAGE. * * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95 - * $FreeBSD$ */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + /* * These functions support the macros and help fiddle mbuf chains for * the nfs op functions. They do things like create the rpc header and * copy data between mbuf chains and uio lists. */ + #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> @@ -57,6 +60,7 @@ #include <sys/malloc.h> #include <sys/sysent.h> #include <sys/syscall.h> +#include <sys/sysproto.h> #include <vm/vm.h> #include <vm/vm_object.h> @@ -65,13 +69,11 @@ #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> -#include <nfs/nfs.h> -#include <nfs/nfsnode.h> +#include <nfsclient/nfs.h> +#include <nfsclient/nfsnode.h> #include <nfs/xdr_subs.h> -#include <nfs/nfsm_subs.h> -#include <nfs/nfsmount.h> -#include <nfs/nqnfs.h> -#include <nfs/nfsrtt.h> +#include <nfsclient/nfsm_subs.h> +#include <nfsclient/nfsmount.h> #include <netinet/in.h> @@ -79,75 +81,26 @@ * Data items converted to xdr at startup, since they are constant * This is kinda hokey, but may save a little time doing byte swaps */ -u_int32_t nfs_xdrneg1; -u_int32_t rpc_call, rpc_vers, rpc_reply, rpc_msgdenied, rpc_autherr, - rpc_mismatch, rpc_auth_unix, rpc_msgaccepted, - rpc_auth_kerb; -u_int32_t nfs_prog, nqnfs_prog, nfs_true, nfs_false; +u_int32_t nfs_xdrneg1; +u_int32_t rpc_call, rpc_vers, rpc_reply, rpc_msgdenied, rpc_autherr, + rpc_mismatch, rpc_auth_unix, rpc_msgaccepted; +u_int32_t nfs_true, nfs_false; /* And other global data */ static u_int32_t nfs_xid = 0; static enum vtype nv2tov_type[8]= { - VNON, VREG, VDIR, VBLK, VCHR, VLNK, VNON, VNON -}; -enum vtype nv3tov_type[8]= { - VNON, VREG, VDIR, VBLK, VCHR, VLNK, VSOCK, VFIFO + VNON, VREG, VDIR, VBLK, VCHR, VLNK, VNON, VNON }; -int nfs_ticks; -int nfs_pbuf_freecnt = -1; /* start out unlimited */ - -struct nfs_reqq nfs_reqq; -struct nfssvc_sockhead nfssvc_sockhead; -int nfssvc_sockhead_flag; -struct nfsd_head nfsd_head; -int nfsd_head_flag; -struct nfs_bufq nfs_bufq; -struct nqtimerhead nqtimerhead; -struct nqfhhashhead *nqfhhashtbl; -u_long nqfhhash; - -static void (*nfs_prev_lease_updatetime) __P((int)); -static int nfs_prev_nfssvc_sy_narg; -static sy_call_t *nfs_prev_nfssvc_sy_call; - -#ifndef NFS_NOSERVER +int nfs_ticks; +int nfs_pbuf_freecnt = -1; /* start out unlimited */ -static vop_t *nfs_prev_vop_lease_check; +struct nfs_reqq nfs_reqq; +struct nfs_bufq nfs_bufq; -/* - * Mapping of old NFS Version 2 RPC numbers to generic numbers. - */ -int nfsv3_procid[NFS_NPROCS] = { - NFSPROC_NULL, - NFSPROC_GETATTR, - NFSPROC_SETATTR, - NFSPROC_NOOP, - NFSPROC_LOOKUP, - NFSPROC_READLINK, - NFSPROC_READ, - NFSPROC_NOOP, - NFSPROC_WRITE, - NFSPROC_CREATE, - NFSPROC_REMOVE, - NFSPROC_RENAME, - NFSPROC_LINK, - NFSPROC_SYMLINK, - NFSPROC_MKDIR, - NFSPROC_RMDIR, - NFSPROC_READDIR, - NFSPROC_FSSTAT, - NFSPROC_NOOP, - NFSPROC_NOOP, - NFSPROC_NOOP, - NFSPROC_NOOP, - NFSPROC_NOOP, - NFSPROC_NOOP, - NFSPROC_NOOP, - NFSPROC_NOOP -}; +static int nfs_prev_nfsclnt_sy_narg; +static sy_call_t *nfs_prev_nfsclnt_sy_call; -#endif /* NFS_NOSERVER */ /* * and the reverse mapping from generic to Version 2 procedure numbers */ @@ -175,444 +128,24 @@ int nfsv2_procid[NFS_NPROCS] = { NFSV2PROC_NOOP, NFSV2PROC_NOOP, NFSV2PROC_NOOP, - NFSV2PROC_NOOP, - NFSV2PROC_NOOP, - NFSV2PROC_NOOP, -}; - -#ifndef NFS_NOSERVER -/* - * Maps errno values to nfs error numbers. - * Use NFSERR_IO as the catch all for ones not specifically defined in - * RFC 1094. - */ -static u_char nfsrv_v2errmap[ELAST] = { - NFSERR_PERM, NFSERR_NOENT, NFSERR_IO, NFSERR_IO, NFSERR_IO, - NFSERR_NXIO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, - NFSERR_IO, NFSERR_IO, NFSERR_ACCES, NFSERR_IO, NFSERR_IO, - NFSERR_IO, NFSERR_EXIST, NFSERR_IO, NFSERR_NODEV, NFSERR_NOTDIR, - NFSERR_ISDIR, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, - NFSERR_IO, NFSERR_FBIG, NFSERR_NOSPC, NFSERR_IO, NFSERR_ROFS, - NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, - NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, - NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, - NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, - NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, - NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, - NFSERR_IO, NFSERR_IO, NFSERR_NAMETOL, NFSERR_IO, NFSERR_IO, - NFSERR_NOTEMPTY, NFSERR_IO, NFSERR_IO, NFSERR_DQUOT, NFSERR_STALE, - NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, - NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, - NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, - NFSERR_IO /* << Last is 86 */ -}; - -/* - * Maps errno values to nfs error numbers. - * Although it is not obvious whether or not NFS clients really care if - * a returned error value is in the specified list for the procedure, the - * safest thing to do is filter them appropriately. For Version 2, the - * X/Open XNFS document is the only specification that defines error values - * for each RPC (The RFC simply lists all possible error values for all RPCs), - * so I have decided to not do this for Version 2. - * The first entry is the default error return and the rest are the valid - * errors for that RPC in increasing numeric order. - */ -static short nfsv3err_null[] = { - 0, - 0, -}; - -static short nfsv3err_getattr[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_setattr[] = { - NFSERR_IO, - NFSERR_PERM, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_INVAL, - NFSERR_NOSPC, - NFSERR_ROFS, - NFSERR_DQUOT, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOT_SYNC, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_lookup[] = { - NFSERR_IO, - NFSERR_NOENT, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_NOTDIR, - NFSERR_NAMETOL, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_access[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_readlink[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_INVAL, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOTSUPP, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_read[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_NXIO, - NFSERR_ACCES, - NFSERR_INVAL, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_write[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_INVAL, - NFSERR_FBIG, - NFSERR_NOSPC, - NFSERR_ROFS, - NFSERR_DQUOT, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_create[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_EXIST, - NFSERR_NOTDIR, - NFSERR_NOSPC, - NFSERR_ROFS, - NFSERR_NAMETOL, - NFSERR_DQUOT, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOTSUPP, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_mkdir[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_EXIST, - NFSERR_NOTDIR, - NFSERR_NOSPC, - NFSERR_ROFS, - NFSERR_NAMETOL, - NFSERR_DQUOT, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOTSUPP, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_symlink[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_EXIST, - NFSERR_NOTDIR, - NFSERR_NOSPC, - NFSERR_ROFS, - NFSERR_NAMETOL, - NFSERR_DQUOT, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOTSUPP, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_mknod[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_EXIST, - NFSERR_NOTDIR, - NFSERR_NOSPC, - NFSERR_ROFS, - NFSERR_NAMETOL, - NFSERR_DQUOT, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOTSUPP, - NFSERR_SERVERFAULT, - NFSERR_BADTYPE, - 0, -}; - -static short nfsv3err_remove[] = { - NFSERR_IO, - NFSERR_NOENT, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_NOTDIR, - NFSERR_ROFS, - NFSERR_NAMETOL, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_rmdir[] = { - NFSERR_IO, - NFSERR_NOENT, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_EXIST, - NFSERR_NOTDIR, - NFSERR_INVAL, - NFSERR_ROFS, - NFSERR_NAMETOL, - NFSERR_NOTEMPTY, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOTSUPP, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_rename[] = { - NFSERR_IO, - NFSERR_NOENT, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_EXIST, - NFSERR_XDEV, - NFSERR_NOTDIR, - NFSERR_ISDIR, - NFSERR_INVAL, - NFSERR_NOSPC, - NFSERR_ROFS, - NFSERR_MLINK, - NFSERR_NAMETOL, - NFSERR_NOTEMPTY, - NFSERR_DQUOT, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOTSUPP, - NFSERR_SERVERFAULT, - 0, }; -static short nfsv3err_link[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_EXIST, - NFSERR_XDEV, - NFSERR_NOTDIR, - NFSERR_INVAL, - NFSERR_NOSPC, - NFSERR_ROFS, - NFSERR_MLINK, - NFSERR_NAMETOL, - NFSERR_DQUOT, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOTSUPP, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_readdir[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_NOTDIR, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_BAD_COOKIE, - NFSERR_TOOSMALL, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_readdirplus[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_NOTDIR, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_BAD_COOKIE, - NFSERR_NOTSUPP, - NFSERR_TOOSMALL, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_fsstat[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_fsinfo[] = { - NFSERR_STALE, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_pathconf[] = { - NFSERR_STALE, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static short nfsv3err_commit[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static short *nfsrv_v3errmap[] = { - nfsv3err_null, - nfsv3err_getattr, - nfsv3err_setattr, - nfsv3err_lookup, - nfsv3err_access, - nfsv3err_readlink, - nfsv3err_read, - nfsv3err_write, - nfsv3err_create, - nfsv3err_mkdir, - nfsv3err_symlink, - nfsv3err_mknod, - nfsv3err_remove, - nfsv3err_rmdir, - nfsv3err_rename, - nfsv3err_link, - nfsv3err_readdir, - nfsv3err_readdirplus, - nfsv3err_fsstat, - nfsv3err_fsinfo, - nfsv3err_pathconf, - nfsv3err_commit, -}; - -#endif /* NFS_NOSERVER */ - -extern struct nfsrtt nfsrtt; -extern time_t nqnfsstarttime; -extern int nqsrv_clockskew; -extern int nqsrv_writeslack; -extern int nqsrv_maxlease; -extern struct nfsstats nfsstats; -extern int nqnfs_piggy[NFS_NPROCS]; -extern nfstype nfsv2_type[9]; -extern nfstype nfsv3_type[9]; -extern struct nfsnodehashhead *nfsnodehashtbl; -extern u_long nfsnodehash; - -struct nfssvc_args; -extern int nfssvc(struct thread *, struct nfssvc_args *, int *); - LIST_HEAD(nfsnodehashhead, nfsnode); -int nfs_webnamei __P((struct nameidata *, struct vnode *, struct thread *)); - -u_quad_t -nfs_curusec() -{ - struct timeval tv; - - getmicrotime(&tv); - return ((u_quad_t)tv.tv_sec * 1000000 + (u_quad_t)tv.tv_usec); -} - /* * Create the header for an rpc request packet * The hsiz is the size of the rest of the nfs request header. * (just used to decide if a cluster is a good idea) */ struct mbuf * -nfsm_reqh(vp, procid, hsiz, bposp) - struct vnode *vp; - u_long procid; - int hsiz; - caddr_t *bposp; +nfsm_reqhead(struct vnode *vp, u_long procid, int hsiz) { - register struct mbuf *mb; - register u_int32_t *tl; - register caddr_t bpos; - struct mbuf *mb2; - struct nfsmount *nmp; - int nqflag; + struct mbuf *mb; MGET(mb, M_TRYWAIT, MT_DATA); if (hsiz >= MINCLSIZE) MCLGET(mb, M_TRYWAIT); mb->m_len = 0; - bpos = mtod(mb, caddr_t); - - /* - * For NQNFS, add lease request. - */ - if (vp) { - nmp = VFSTONFS(vp->v_mount); - if (nmp->nm_flag & NFSMNT_NQNFS) { - nqflag = NQNFS_NEEDLEASE(vp, procid); - if (nqflag) { - nfsm_build(tl, u_int32_t *, 2*NFSX_UNSIGNED); - *tl++ = txdr_unsigned(nqflag); - *tl = txdr_unsigned(nmp->nm_leaseterm); - } else { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = 0; - } - } - } - /* Finally, return values */ - *bposp = bpos; return (mb); } @@ -623,27 +156,16 @@ nfsm_reqh(vp, procid, hsiz, bposp) * Returns the head of the mbuf list. */ struct mbuf * -nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len, - verf_str, mrest, mrest_len, mbp, xidp) - register struct ucred *cr; - int nmflag; - int procid; - int auth_type; - int auth_len; - char *auth_str; - int verf_len; - char *verf_str; - struct mbuf *mrest; - int mrest_len; - struct mbuf **mbp; - u_int32_t *xidp; +nfsm_rpchead(struct ucred *cr, int nmflag, int procid, int auth_type, + int auth_len, struct mbuf *mrest, int mrest_len, struct mbuf **mbp, + u_int32_t *xidp) { - register struct mbuf *mb; - register u_int32_t *tl; - register caddr_t bpos; - register int i; - struct mbuf *mreq, *mb2; - int siz, grpsiz, authsiz; + struct mbuf *mb; + u_int32_t *tl; + caddr_t bpos; + int i; + struct mbuf *mreq; + int grpsiz, authsiz; authsiz = nfsm_rndup(auth_len); MGETHDR(mb, M_TRYWAIT, MT_DATA); @@ -664,7 +186,7 @@ nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len, nfsm_build(tl, u_int32_t *, 8 * NFSX_UNSIGNED); /* Get a pretty random xid to start with */ - if (!nfs_xid) + if (!nfs_xid) nfs_xid = random(); /* * Skip zero xid if it should ever happen. @@ -675,20 +197,14 @@ nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len, *tl++ = *xidp = txdr_unsigned(nfs_xid); *tl++ = rpc_call; *tl++ = rpc_vers; - if (nmflag & NFSMNT_NQNFS) { - *tl++ = txdr_unsigned(NQNFS_PROG); - *tl++ = txdr_unsigned(NQNFS_VER3); - } else { - *tl++ = txdr_unsigned(NFS_PROG); - if (nmflag & NFSMNT_NFSV3) - *tl++ = txdr_unsigned(NFS_VER3); - else - *tl++ = txdr_unsigned(NFS_VER2); - } - if (nmflag & NFSMNT_NFSV3) + *tl++ = txdr_unsigned(NFS_PROG); + if (nmflag & NFSMNT_NFSV3) { + *tl++ = txdr_unsigned(NFS_VER3); *tl++ = txdr_unsigned(procid); - else + } else { + *tl++ = txdr_unsigned(NFS_VER2); *tl++ = txdr_unsigned(nfsv2_procid[procid]); + } /* * And then the authorization cred. @@ -707,67 +223,14 @@ nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len, for (i = 1; i <= grpsiz; i++) *tl++ = txdr_unsigned(cr->cr_groups[i]); break; - case RPCAUTH_KERB4: - siz = auth_len; - while (siz > 0) { - if (M_TRAILINGSPACE(mb) == 0) { - MGET(mb2, M_TRYWAIT, MT_DATA); - if (siz >= MINCLSIZE) - MCLGET(mb2, M_TRYWAIT); - mb->m_next = mb2; - mb = mb2; - mb->m_len = 0; - bpos = mtod(mb, caddr_t); - } - i = min(siz, M_TRAILINGSPACE(mb)); - bcopy(auth_str, bpos, i); - mb->m_len += i; - auth_str += i; - bpos += i; - siz -= i; - } - if ((siz = (nfsm_rndup(auth_len) - auth_len)) > 0) { - for (i = 0; i < siz; i++) - *bpos++ = '\0'; - mb->m_len += siz; - } - break; - }; + } /* * And the verifier... */ nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - if (verf_str) { - *tl++ = txdr_unsigned(RPCAUTH_KERB4); - *tl = txdr_unsigned(verf_len); - siz = verf_len; - while (siz > 0) { - if (M_TRAILINGSPACE(mb) == 0) { - MGET(mb2, M_TRYWAIT, MT_DATA); - if (siz >= MINCLSIZE) - MCLGET(mb2, M_TRYWAIT); - mb->m_next = mb2; - mb = mb2; - mb->m_len = 0; - bpos = mtod(mb, caddr_t); - } - i = min(siz, M_TRAILINGSPACE(mb)); - bcopy(verf_str, bpos, i); - mb->m_len += i; - verf_str += i; - bpos += i; - siz -= i; - } - if ((siz = (nfsm_rndup(verf_len) - verf_len)) > 0) { - for (i = 0; i < siz; i++) - *bpos++ = '\0'; - mb->m_len += siz; - } - } else { - *tl++ = txdr_unsigned(RPCAUTH_NULL); - *tl = 0; - } + *tl++ = txdr_unsigned(RPCAUTH_NULL); + *tl = 0; mb->m_next = mrest; mreq->m_pkthdr.len = authsiz + 10 * NFSX_UNSIGNED + mrest_len; mreq->m_pkthdr.rcvif = (struct ifnet *)0; @@ -776,94 +239,15 @@ nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len, } /* - * copies mbuf chain to the uio scatter/gather list - */ -int -nfsm_mbuftouio(mrep, uiop, siz, dpos) - struct mbuf **mrep; - register struct uio *uiop; - int siz; - caddr_t *dpos; -{ - register char *mbufcp, *uiocp; - register int xfer, left, len; - register struct mbuf *mp; - long uiosiz, rem; - int error = 0; - - mp = *mrep; - mbufcp = *dpos; - len = mtod(mp, caddr_t)+mp->m_len-mbufcp; - rem = nfsm_rndup(siz)-siz; - while (siz > 0) { - if (uiop->uio_iovcnt <= 0 || uiop->uio_iov == NULL) - return (EFBIG); - left = uiop->uio_iov->iov_len; - uiocp = uiop->uio_iov->iov_base; - if (left > siz) - left = siz; - uiosiz = left; - while (left > 0) { - while (len == 0) { - mp = mp->m_next; - if (mp == NULL) - return (EBADRPC); - mbufcp = mtod(mp, caddr_t); - len = mp->m_len; - } - xfer = (left > len) ? len : left; -#ifdef notdef - /* Not Yet.. */ - if (uiop->uio_iov->iov_op != NULL) - (*(uiop->uio_iov->iov_op)) - (mbufcp, uiocp, xfer); - else -#endif - if (uiop->uio_segflg == UIO_SYSSPACE) - bcopy(mbufcp, uiocp, xfer); - else - copyout(mbufcp, uiocp, xfer); - left -= xfer; - len -= xfer; - mbufcp += xfer; - uiocp += xfer; - uiop->uio_offset += xfer; - uiop->uio_resid -= xfer; - } - if (uiop->uio_iov->iov_len <= siz) { - uiop->uio_iovcnt--; - uiop->uio_iov++; - } else { - uiop->uio_iov->iov_base += uiosiz; - uiop->uio_iov->iov_len -= uiosiz; - } - siz -= uiosiz; - } - *dpos = mbufcp; - *mrep = mp; - if (rem > 0) { - if (len < rem) - error = nfs_adv(mrep, dpos, rem, len); - else - *dpos += rem; - } - return (error); -} - -/* * copies a uio scatter/gather list to an mbuf chain. * NOTE: can ony handle iovcnt == 1 */ int -nfsm_uiotombuf(uiop, mq, siz, bpos) - register struct uio *uiop; - struct mbuf **mq; - int siz; - caddr_t *bpos; +nfsm_uiotombuf(struct uio *uiop, struct mbuf **mq, int siz, caddr_t *bpos) { - register char *uiocp; - register struct mbuf *mp, *mp2; - register int xfer, left, mlen; + char *uiocp; + struct mbuf *mp, *mp2; + int xfer, left, mlen; int uiosiz, clflg, rem; char *cp; @@ -935,109 +319,12 @@ nfsm_uiotombuf(uiop, mq, siz, bpos) } /* - * Help break down an mbuf chain by setting the first siz bytes contiguous - * pointed to by returned val. - * This is used by the macros nfsm_dissect and nfsm_dissecton for tough - * cases. (The macros use the vars. dpos and dpos2) - */ -int -nfsm_disct(mdp, dposp, siz, left, cp2) - struct mbuf **mdp; - caddr_t *dposp; - int siz; - int left; - caddr_t *cp2; -{ - register struct mbuf *mp, *mp2; - register int siz2, xfer; - register caddr_t ptr; - - mp = *mdp; - while (left == 0) { - *mdp = mp = mp->m_next; - if (mp == NULL) - return (EBADRPC); - left = mp->m_len; - *dposp = mtod(mp, caddr_t); - } - if (left >= siz) { - *cp2 = *dposp; - *dposp += siz; - } else if (mp->m_next == NULL) { - return (EBADRPC); - } else if (siz > MHLEN) { - panic("nfs S too big"); - } else { - MGET(mp2, M_TRYWAIT, MT_DATA); - mp2->m_next = mp->m_next; - mp->m_next = mp2; - mp->m_len -= left; - mp = mp2; - *cp2 = ptr = mtod(mp, caddr_t); - bcopy(*dposp, ptr, left); /* Copy what was left */ - siz2 = siz-left; - ptr += left; - mp2 = mp->m_next; - /* Loop around copying up the siz2 bytes */ - while (siz2 > 0) { - if (mp2 == NULL) - return (EBADRPC); - xfer = (siz2 > mp2->m_len) ? mp2->m_len : siz2; - if (xfer > 0) { - bcopy(mtod(mp2, caddr_t), ptr, xfer); - NFSMADV(mp2, xfer); - mp2->m_len -= xfer; - ptr += xfer; - siz2 -= xfer; - } - if (siz2 > 0) - mp2 = mp2->m_next; - } - mp->m_len = siz; - *mdp = mp2; - *dposp = mtod(mp2, caddr_t); - } - return (0); -} - -/* - * Advance the position in the mbuf chain. - */ -int -nfs_adv(mdp, dposp, offs, left) - struct mbuf **mdp; - caddr_t *dposp; - int offs; - int left; -{ - register struct mbuf *m; - register int s; - - m = *mdp; - s = left; - while (s < offs) { - offs -= s; - m = m->m_next; - if (m == NULL) - return (EBADRPC); - s = m->m_len; - } - *mdp = m; - *dposp = mtod(m, caddr_t)+offs; - return (0); -} - -/* * Copy a string into mbufs for the hard cases... */ int -nfsm_strtmbuf(mb, bpos, cp, siz) - struct mbuf **mb; - char **bpos; - const char *cp; - long siz; +nfsm_strtmbuf(struct mbuf **mb, char **bpos, const char *cp, long siz) { - register struct mbuf *m1 = NULL, *m2; + struct mbuf *m1 = NULL, *m2; long left, xfer, len, tlen; u_int32_t *tl; int putsize; @@ -1097,15 +384,11 @@ nfsm_strtmbuf(mb, bpos, cp, siz) * Called once to initialize data structures... */ int -nfs_init(vfsp) - struct vfsconf *vfsp; +nfs_init(struct vfsconf *vfsp) { - register int i; + int i; nfsmount_zone = zinit("NFSMOUNT", sizeof(struct nfsmount), 0, 0, 1); - - nfs_mount_type = vfsp->vfc_typenum; - nfsrtt.pos = 0; rpc_vers = txdr_unsigned(RPC_VER2); rpc_call = txdr_unsigned(RPC_CALL); rpc_reply = txdr_unsigned(RPC_REPLY); @@ -1114,9 +397,6 @@ nfs_init(vfsp) rpc_mismatch = txdr_unsigned(RPC_MISMATCH); rpc_autherr = txdr_unsigned(RPC_AUTHERR); rpc_auth_unix = txdr_unsigned(RPCAUTH_UNIX); - rpc_auth_kerb = txdr_unsigned(RPCAUTH_KERB4); - nfs_prog = txdr_unsigned(NFS_PROG); - nqnfs_prog = txdr_unsigned(NQNFS_PROG); nfs_true = txdr_unsigned(TRUE); nfs_false = txdr_unsigned(FALSE); nfs_xdrneg1 = txdr_unsigned(-1); @@ -1129,21 +409,6 @@ nfs_init(vfsp) nfs_iodmount[i] = (struct nfsmount *)0; } nfs_nhinit(); /* Init the nfsnode table */ -#ifndef NFS_NOSERVER - nfsrv_init(0); /* Init server data structures */ - nfsrv_initcache(); /* Init the server request cache */ -#endif - - /* - * Initialize the nqnfs server stuff. - */ - if (nqnfsstarttime == 0) { - nqnfsstarttime = boottime.tv_sec + nqsrv_maxlease - + nqsrv_clockskew + nqsrv_writeslack; - NQLOADNOVRAM(nqnfsstarttime); - TAILQ_INIT(&nqtimerhead); - nqfhhashtbl = hashinit(NQLCHSZ, M_NQLEASE, &nqfhhash); - } /* * Initialize reply list and start timer @@ -1152,20 +417,10 @@ nfs_init(vfsp) nfs_timer(0); - /* - * Set up lease_check and lease_updatetime so that other parts - * of the system can call us, if we are loadable. - */ -#ifndef NFS_NOSERVER - nfs_prev_vop_lease_check = default_vnodeop_p[VOFFSET(vop_lease)]; - default_vnodeop_p[VOFFSET(vop_lease)] = (vop_t *)nqnfs_vop_lease_check; -#endif - nfs_prev_lease_updatetime = lease_updatetime; - lease_updatetime = nfs_lease_updatetime; - nfs_prev_nfssvc_sy_narg = sysent[SYS_nfssvc].sy_narg; - sysent[SYS_nfssvc].sy_narg = 2; - nfs_prev_nfssvc_sy_call = sysent[SYS_nfssvc].sy_call; - sysent[SYS_nfssvc].sy_call = (sy_call_t *)nfssvc; + nfs_prev_nfsclnt_sy_narg = sysent[SYS_nfsclnt].sy_narg; + sysent[SYS_nfsclnt].sy_narg = 2; + nfs_prev_nfsclnt_sy_call = sysent[SYS_nfsclnt].sy_call; + sysent[SYS_nfsclnt].sy_call = (sy_call_t *)nfsclnt; nfs_pbuf_freecnt = nswbuf / 2 + 1; @@ -1173,18 +428,12 @@ nfs_init(vfsp) } int -nfs_uninit(vfsp) - struct vfsconf *vfsp; +nfs_uninit(struct vfsconf *vfsp) { untimeout(nfs_timer, (void *)NULL, nfs_timer_handle); - nfs_mount_type = -1; -#ifndef NFS_NOSERVER - default_vnodeop_p[VOFFSET(vop_lease)] = nfs_prev_vop_lease_check; -#endif - lease_updatetime = nfs_prev_lease_updatetime; - sysent[SYS_nfssvc].sy_narg = nfs_prev_nfssvc_sy_narg; - sysent[SYS_nfssvc].sy_call = nfs_prev_nfssvc_sy_call; + sysent[SYS_nfsclnt].sy_narg = nfs_prev_nfsclnt_sy_narg; + sysent[SYS_nfsclnt].sy_call = nfs_prev_nfsclnt_sy_call; return (0); } @@ -1203,18 +452,14 @@ nfs_uninit(vfsp) * copy the attributes to *vaper */ int -nfs_loadattrcache(vpp, mdp, dposp, vaper, dontshrink) - struct vnode **vpp; - struct mbuf **mdp; - caddr_t *dposp; - struct vattr *vaper; - int dontshrink; +nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp, + struct vattr *vaper, int dontshrink) { - register struct vnode *vp = *vpp; - register struct vattr *vap; - register struct nfs_fattr *fp; - register struct nfsnode *np; - register int32_t t1; + struct vnode *vp = *vpp; + struct vattr *vap; + struct nfs_fattr *fp; + struct nfsnode *np; + int32_t t1; caddr_t cp2; int error = 0, rdev; struct mbuf *md; @@ -1321,7 +566,7 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper, dontshrink) vap->va_ctime.tv_sec = fxdr_unsigned(u_int32_t, fp->fa2_ctime.nfsv2_sec); vap->va_ctime.tv_nsec = 0; - vap->va_gen = fxdr_unsigned(u_int32_t,fp->fa2_ctime.nfsv2_usec); + vap->va_gen = fxdr_unsigned(u_int32_t, fp->fa2_ctime.nfsv2_usec); vap->va_filerev = 0; } np->n_attrstamp = time_second; @@ -1373,12 +618,10 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, acdebug, CTLFLAG_RW, &nfs_acdebug, 0, ""); * otherwise return an error */ int -nfs_getattrcache(vp, vaper) - register struct vnode *vp; - struct vattr *vaper; +nfs_getattrcache(struct vnode *vp, struct vattr *vaper) { - register struct nfsnode *np; - register struct vattr *vap; + struct nfsnode *np; + struct vattr *vap; struct nfsmount *nmp; int timeo; @@ -1446,613 +689,16 @@ nfs_getattrcache(vp, vaper) return (0); } -#ifndef NFS_NOSERVER -/* - * Set up nameidata for a lookup() call and do it. - * - * If pubflag is set, this call is done for a lookup operation on the - * public filehandle. In that case we allow crossing mountpoints and - * absolute pathnames. However, the caller is expected to check that - * the lookup result is within the public fs, and deny access if - * it is not. - * - * nfs_namei() clears out garbage fields that namei() might leave garbage. - * This is mainly ni_vp and ni_dvp when an error occurs, and ni_dvp when no - * error occurs but the parent was not requested. - * - * dirp may be set whether an error is returned or not, and must be - * released by the caller. - */ -int -nfs_namei(ndp, fhp, len, slp, nam, mdp, dposp, retdirp, td, kerbflag, pubflag) - register struct nameidata *ndp; - fhandle_t *fhp; - int len; - struct nfssvc_sock *slp; - struct sockaddr *nam; - struct mbuf **mdp; - caddr_t *dposp; - struct vnode **retdirp; - struct thread *td; - int kerbflag, pubflag; -{ - register int i, rem; - register struct mbuf *md; - register char *fromcp, *tocp, *cp; - struct iovec aiov; - struct uio auio; - struct vnode *dp; - int error, rdonly, linklen; - struct componentname *cnp = &ndp->ni_cnd; - - *retdirp = (struct vnode *)0; - cnp->cn_pnbuf = zalloc(namei_zone); - - /* - * Copy the name from the mbuf list to ndp->ni_pnbuf - * and set the various ndp fields appropriately. - */ - fromcp = *dposp; - tocp = cnp->cn_pnbuf; - md = *mdp; - rem = mtod(md, caddr_t) + md->m_len - fromcp; - for (i = 0; i < len; i++) { - while (rem == 0) { - md = md->m_next; - if (md == NULL) { - error = EBADRPC; - goto out; - } - fromcp = mtod(md, caddr_t); - rem = md->m_len; - } - if (*fromcp == '\0' || (!pubflag && *fromcp == '/')) { - error = EACCES; - goto out; - } - *tocp++ = *fromcp++; - rem--; - } - *tocp = '\0'; - *mdp = md; - *dposp = fromcp; - len = nfsm_rndup(len)-len; - if (len > 0) { - if (rem >= len) - *dposp += len; - else if ((error = nfs_adv(mdp, dposp, len, rem)) != 0) - goto out; - } - - /* - * Extract and set starting directory. - */ - error = nfsrv_fhtovp(fhp, FALSE, &dp, ndp->ni_cnd.cn_cred, slp, - nam, &rdonly, kerbflag, pubflag); - if (error) - goto out; - if (dp->v_type != VDIR) { - vrele(dp); - error = ENOTDIR; - goto out; - } - - if (rdonly) - cnp->cn_flags |= RDONLY; - - /* - * Set return directory. Reference to dp is implicitly transfered - * to the returned pointer - */ - *retdirp = dp; - - if (pubflag) { - /* - * Oh joy. For WebNFS, handle those pesky '%' escapes, - * and the 'native path' indicator. - */ - cp = zalloc(namei_zone); - fromcp = cnp->cn_pnbuf; - tocp = cp; - if ((unsigned char)*fromcp >= WEBNFS_SPECCHAR_START) { - switch ((unsigned char)*fromcp) { - case WEBNFS_NATIVE_CHAR: - /* - * 'Native' path for us is the same - * as a path according to the NFS spec, - * just skip the escape char. - */ - fromcp++; - break; - /* - * More may be added in the future, range 0x80-0xff - */ - default: - error = EIO; - zfree(namei_zone, cp); - goto out; - } - } - /* - * Translate the '%' escapes, URL-style. - */ - while (*fromcp != '\0') { - if (*fromcp == WEBNFS_ESC_CHAR) { - if (fromcp[1] != '\0' && fromcp[2] != '\0') { - fromcp++; - *tocp++ = HEXSTRTOI(fromcp); - fromcp += 2; - continue; - } else { - error = ENOENT; - zfree(namei_zone, cp); - goto out; - } - } else - *tocp++ = *fromcp++; - } - *tocp = '\0'; - zfree(namei_zone, cnp->cn_pnbuf); - cnp->cn_pnbuf = cp; - } - - ndp->ni_pathlen = (tocp - cnp->cn_pnbuf) + 1; - ndp->ni_segflg = UIO_SYSSPACE; - - if (pubflag) { - ndp->ni_rootdir = rootvnode; - ndp->ni_loopcnt = 0; - if (cnp->cn_pnbuf[0] == '/') - dp = rootvnode; - } else { - cnp->cn_flags |= NOCROSSMOUNT; - } - - /* - * Initialize for scan, set ni_startdir and bump ref on dp again - * becuase lookup() will dereference ni_startdir. - */ - - cnp->cn_thread = td; - VREF(dp); - ndp->ni_startdir = dp; - - for (;;) { - cnp->cn_nameptr = cnp->cn_pnbuf; - /* - * Call lookup() to do the real work. If an error occurs, - * ndp->ni_vp and ni_dvp are left uninitialized or NULL and - * we do not have to dereference anything before returning. - * In either case ni_startdir will be dereferenced and NULLed - * out. - */ - error = lookup(ndp); - if (error) - break; - - /* - * Check for encountering a symbolic link. Trivial - * termination occurs if no symlink encountered. - * Note: zfree is safe because error is 0, so we will - * not zfree it again when we break. - */ - if ((cnp->cn_flags & ISSYMLINK) == 0) { - nfsrv_object_create(ndp->ni_vp); - if (cnp->cn_flags & (SAVENAME | SAVESTART)) - cnp->cn_flags |= HASBUF; - else - zfree(namei_zone, cnp->cn_pnbuf); - break; - } - - /* - * Validate symlink - */ - if ((cnp->cn_flags & LOCKPARENT) && ndp->ni_pathlen == 1) - VOP_UNLOCK(ndp->ni_dvp, 0, td); - if (!pubflag) { - error = EINVAL; - goto badlink2; - } - - if (ndp->ni_loopcnt++ >= MAXSYMLINKS) { - error = ELOOP; - goto badlink2; - } - if (ndp->ni_pathlen > 1) - cp = zalloc(namei_zone); - else - cp = cnp->cn_pnbuf; - aiov.iov_base = cp; - aiov.iov_len = MAXPATHLEN; - auio.uio_iov = &aiov; - auio.uio_iovcnt = 1; - auio.uio_offset = 0; - auio.uio_rw = UIO_READ; - auio.uio_segflg = UIO_SYSSPACE; - auio.uio_td = (struct thread *)0; - auio.uio_resid = MAXPATHLEN; - error = VOP_READLINK(ndp->ni_vp, &auio, cnp->cn_cred); - if (error) { - badlink1: - if (ndp->ni_pathlen > 1) - zfree(namei_zone, cp); - badlink2: - vrele(ndp->ni_dvp); - vput(ndp->ni_vp); - break; - } - linklen = MAXPATHLEN - auio.uio_resid; - if (linklen == 0) { - error = ENOENT; - goto badlink1; - } - if (linklen + ndp->ni_pathlen >= MAXPATHLEN) { - error = ENAMETOOLONG; - goto badlink1; - } - - /* - * Adjust or replace path - */ - if (ndp->ni_pathlen > 1) { - bcopy(ndp->ni_next, cp + linklen, ndp->ni_pathlen); - zfree(namei_zone, cnp->cn_pnbuf); - cnp->cn_pnbuf = cp; - } else - cnp->cn_pnbuf[linklen] = '\0'; - ndp->ni_pathlen += linklen; - - /* - * Cleanup refs for next loop and check if root directory - * should replace current directory. Normally ni_dvp - * becomes the new base directory and is cleaned up when - * we loop. Explicitly null pointers after invalidation - * to clarify operation. - */ - vput(ndp->ni_vp); - ndp->ni_vp = NULL; - - if (cnp->cn_pnbuf[0] == '/') { - vrele(ndp->ni_dvp); - ndp->ni_dvp = ndp->ni_rootdir; - VREF(ndp->ni_dvp); - } - ndp->ni_startdir = ndp->ni_dvp; - ndp->ni_dvp = NULL; - } - - /* - * nfs_namei() guarentees that fields will not contain garbage - * whether an error occurs or not. This allows the caller to track - * cleanup state trivially. - */ -out: - if (error) { - zfree(namei_zone, cnp->cn_pnbuf); - ndp->ni_vp = NULL; - ndp->ni_dvp = NULL; - ndp->ni_startdir = NULL; - cnp->cn_flags &= ~HASBUF; - } else if ((ndp->ni_cnd.cn_flags & (WANTPARENT|LOCKPARENT)) == 0) { - ndp->ni_dvp = NULL; - } - return (error); -} - -/* - * A fiddled version of m_adj() that ensures null fill to a long - * boundary and only trims off the back end - */ -void -nfsm_adj(mp, len, nul) - struct mbuf *mp; - register int len; - int nul; -{ - register struct mbuf *m; - register int count, i; - register char *cp; - - /* - * Trim from tail. Scan the mbuf chain, - * calculating its length and finding the last mbuf. - * If the adjustment only affects this mbuf, then just - * adjust and return. Otherwise, rescan and truncate - * after the remaining size. - */ - count = 0; - m = mp; - for (;;) { - count += m->m_len; - if (m->m_next == (struct mbuf *)0) - break; - m = m->m_next; - } - if (m->m_len > len) { - m->m_len -= len; - if (nul > 0) { - cp = mtod(m, caddr_t)+m->m_len-nul; - for (i = 0; i < nul; i++) - *cp++ = '\0'; - } - return; - } - count -= len; - if (count < 0) - count = 0; - /* - * Correct length for chain is "count". - * Find the mbuf with last data, adjust its length, - * and toss data from remaining mbufs on chain. - */ - for (m = mp; m; m = m->m_next) { - if (m->m_len >= count) { - m->m_len = count; - if (nul > 0) { - cp = mtod(m, caddr_t)+m->m_len-nul; - for (i = 0; i < nul; i++) - *cp++ = '\0'; - } - break; - } - count -= m->m_len; - } - for (m = m->m_next;m;m = m->m_next) - m->m_len = 0; -} - -/* - * Make these functions instead of macros, so that the kernel text size - * doesn't get too big... - */ -void -nfsm_srvwcc(nfsd, before_ret, before_vap, after_ret, after_vap, mbp, bposp) - struct nfsrv_descript *nfsd; - int before_ret; - register struct vattr *before_vap; - int after_ret; - struct vattr *after_vap; - struct mbuf **mbp; - char **bposp; -{ - register struct mbuf *mb = *mbp, *mb2; - register char *bpos = *bposp; - register u_int32_t *tl; - - if (before_ret) { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = nfs_false; - } else { - nfsm_build(tl, u_int32_t *, 7 * NFSX_UNSIGNED); - *tl++ = nfs_true; - txdr_hyper(before_vap->va_size, tl); - tl += 2; - txdr_nfsv3time(&(before_vap->va_mtime), tl); - tl += 2; - txdr_nfsv3time(&(before_vap->va_ctime), tl); - } - *bposp = bpos; - *mbp = mb; - nfsm_srvpostopattr(nfsd, after_ret, after_vap, mbp, bposp); -} - -void -nfsm_srvpostopattr(nfsd, after_ret, after_vap, mbp, bposp) - struct nfsrv_descript *nfsd; - int after_ret; - struct vattr *after_vap; - struct mbuf **mbp; - char **bposp; -{ - register struct mbuf *mb = *mbp, *mb2; - register char *bpos = *bposp; - register u_int32_t *tl; - register struct nfs_fattr *fp; - - if (after_ret) { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = nfs_false; - } else { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_V3FATTR); - *tl++ = nfs_true; - fp = (struct nfs_fattr *)tl; - nfsm_srvfattr(nfsd, after_vap, fp); - } - *mbp = mb; - *bposp = bpos; -} - -void -nfsm_srvfattr(nfsd, vap, fp) - register struct nfsrv_descript *nfsd; - register struct vattr *vap; - register struct nfs_fattr *fp; -{ - - fp->fa_nlink = txdr_unsigned(vap->va_nlink); - fp->fa_uid = txdr_unsigned(vap->va_uid); - fp->fa_gid = txdr_unsigned(vap->va_gid); - if (nfsd->nd_flag & ND_NFSV3) { - fp->fa_type = vtonfsv3_type(vap->va_type); - fp->fa_mode = vtonfsv3_mode(vap->va_mode); - txdr_hyper(vap->va_size, &fp->fa3_size); - txdr_hyper(vap->va_bytes, &fp->fa3_used); - fp->fa3_rdev.specdata1 = txdr_unsigned(umajor(vap->va_rdev)); - fp->fa3_rdev.specdata2 = txdr_unsigned(uminor(vap->va_rdev)); - fp->fa3_fsid.nfsuquad[0] = 0; - fp->fa3_fsid.nfsuquad[1] = txdr_unsigned(vap->va_fsid); - fp->fa3_fileid.nfsuquad[0] = 0; - fp->fa3_fileid.nfsuquad[1] = txdr_unsigned(vap->va_fileid); - txdr_nfsv3time(&vap->va_atime, &fp->fa3_atime); - txdr_nfsv3time(&vap->va_mtime, &fp->fa3_mtime); - txdr_nfsv3time(&vap->va_ctime, &fp->fa3_ctime); - } else { - fp->fa_type = vtonfsv2_type(vap->va_type); - fp->fa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode); - fp->fa2_size = txdr_unsigned(vap->va_size); - fp->fa2_blocksize = txdr_unsigned(vap->va_blocksize); - if (vap->va_type == VFIFO) - fp->fa2_rdev = 0xffffffff; - else - fp->fa2_rdev = txdr_unsigned(vap->va_rdev); - fp->fa2_blocks = txdr_unsigned(vap->va_bytes / NFS_FABLKSIZE); - fp->fa2_fsid = txdr_unsigned(vap->va_fsid); - fp->fa2_fileid = txdr_unsigned(vap->va_fileid); - txdr_nfsv2time(&vap->va_atime, &fp->fa2_atime); - txdr_nfsv2time(&vap->va_mtime, &fp->fa2_mtime); - txdr_nfsv2time(&vap->va_ctime, &fp->fa2_ctime); - } -} - -/* - * nfsrv_fhtovp() - convert a fh to a vnode ptr (optionally locked) - * - look up fsid in mount list (if not found ret error) - * - get vp and export rights by calling VFS_FHTOVP() - * - if cred->cr_uid == 0 or MNT_EXPORTANON set it to credanon - * - if not lockflag unlock it with VOP_UNLOCK() - */ -int -nfsrv_fhtovp(fhp, lockflag, vpp, cred, slp, nam, rdonlyp, kerbflag, pubflag) - fhandle_t *fhp; - int lockflag; - struct vnode **vpp; - struct ucred *cred; - struct nfssvc_sock *slp; - struct sockaddr *nam; - int *rdonlyp; - int kerbflag; - int pubflag; -{ - struct thread *td = curthread; /* XXX */ - register struct mount *mp; - register int i; - struct ucred *credanon; - int error, exflags; -#ifdef MNT_EXNORESPORT /* XXX needs mountd and /etc/exports help yet */ - struct sockaddr_int *saddr; -#endif - - *vpp = (struct vnode *)0; - - if (nfs_ispublicfh(fhp)) { - if (!pubflag || !nfs_pub.np_valid) - return (ESTALE); - fhp = &nfs_pub.np_handle; - } - - mp = vfs_getvfs(&fhp->fh_fsid); - if (!mp) - return (ESTALE); - error = VFS_CHECKEXP(mp, nam, &exflags, &credanon); - if (error) - return (error); - error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp); - if (error) - return (error); -#ifdef MNT_EXNORESPORT - if (!(exflags & (MNT_EXNORESPORT|MNT_EXPUBLIC))) { - saddr = (struct sockaddr_in *)nam; - if (saddr->sin_family == AF_INET && - ntohs(saddr->sin_port) >= IPPORT_RESERVED) { - vput(*vpp); - *vpp = NULL; - return (NFSERR_AUTHERR | AUTH_TOOWEAK); - } - } -#endif - /* - * Check/setup credentials. - */ - if (exflags & MNT_EXKERB) { - if (!kerbflag) { - vput(*vpp); - *vpp = NULL; - return (NFSERR_AUTHERR | AUTH_TOOWEAK); - } - } else if (kerbflag) { - vput(*vpp); - *vpp = NULL; - return (NFSERR_AUTHERR | AUTH_TOOWEAK); - } else if (cred->cr_uid == 0 || (exflags & MNT_EXPORTANON)) { - cred->cr_uid = credanon->cr_uid; - for (i = 0; i < credanon->cr_ngroups && i < NGROUPS; i++) - cred->cr_groups[i] = credanon->cr_groups[i]; - cred->cr_ngroups = i; - } - if (exflags & MNT_EXRDONLY) - *rdonlyp = 1; - else - *rdonlyp = 0; - - nfsrv_object_create(*vpp); - - if (!lockflag) - VOP_UNLOCK(*vpp, 0, td); - return (0); -} - - -/* - * WebNFS: check if a filehandle is a public filehandle. For v3, this - * means a length of 0, for v2 it means all zeroes. nfsm_srvmtofh has - * transformed this to all zeroes in both cases, so check for it. - */ -int -nfs_ispublicfh(fhp) - fhandle_t *fhp; -{ - char *cp = (char *)fhp; - int i; - - for (i = 0; i < NFSX_V3FH; i++) - if (*cp++ != 0) - return (FALSE); - return (TRUE); -} - -#endif /* NFS_NOSERVER */ -/* - * This function compares two net addresses by family and returns TRUE - * if they are the same host. - * If there is any doubt, return FALSE. - * The AF_INET family is handled as a special case so that address mbufs - * don't need to be saved to store "struct in_addr", which is only 4 bytes. - */ -int -netaddr_match(family, haddr, nam) - int family; - union nethostaddr *haddr; - struct sockaddr *nam; -{ - register struct sockaddr_in *inetaddr; - - switch (family) { - case AF_INET: - inetaddr = (struct sockaddr_in *)nam; - if (inetaddr->sin_family == AF_INET && - inetaddr->sin_addr.s_addr == haddr->had_inetaddr) - return (1); - break; - default: - break; - }; - return (0); -} - static nfsuint64 nfs_nullcookie = { { 0, 0 } }; /* * This function finds the directory cookie that corresponds to the * logical byte offset given. */ nfsuint64 * -nfs_getcookie(np, off, add) - register struct nfsnode *np; - off_t off; - int add; +nfs_getcookie(struct nfsnode *np, off_t off, int add) { - register struct nfsdmap *dp, *dp2; - register int pos; + struct nfsdmap *dp, *dp2; + int pos; pos = (uoff_t)off / NFS_DIRBLKSIZ; if (pos == 0 || off < 0) { @@ -2063,7 +709,7 @@ nfs_getcookie(np, off, add) return (&nfs_nullcookie); } pos--; - dp = np->n_cookies.lh_first; + dp = LIST_FIRST(&np->n_cookies); if (!dp) { if (add) { MALLOC(dp, struct nfsdmap *, sizeof (struct nfsdmap), @@ -2075,11 +721,11 @@ nfs_getcookie(np, off, add) } while (pos >= NFSNUMCOOKIES) { pos -= NFSNUMCOOKIES; - if (dp->ndm_list.le_next) { + if (LIST_NEXT(dp, ndm_list)) { if (!add && dp->ndm_eocookie < NFSNUMCOOKIES && pos >= dp->ndm_eocookie) return ((nfsuint64 *)0); - dp = dp->ndm_list.le_next; + dp = LIST_NEXT(dp, ndm_list); } else if (add) { MALLOC(dp2, struct nfsdmap *, sizeof (struct nfsdmap), M_NFSDIROFF, M_WAITOK); @@ -2104,10 +750,9 @@ nfs_getcookie(np, off, add) * Done mainly to avoid the use of stale offset cookies. */ void -nfs_invaldir(vp) - register struct vnode *vp; +nfs_invaldir(struct vnode *vp) { - register struct nfsnode *np = VTONFS(vp); + struct nfsnode *np = VTONFS(vp); #ifdef DIAGNOSTIC if (vp->v_type != VDIR) @@ -2116,8 +761,8 @@ nfs_invaldir(vp) np->n_direofoffset = 0; np->n_cookieverf.nfsuquad[0] = 0; np->n_cookieverf.nfsuquad[1] = 0; - if (np->n_cookies.lh_first) - np->n_cookies.lh_first->ndm_eocookie = 0; + if (LIST_FIRST(&np->n_cookies)) + LIST_FIRST(&np->n_cookies)->ndm_eocookie = 0; } /* @@ -2127,15 +772,14 @@ nfs_invaldir(vp) * and B_CLUSTEROK flags. Once done the new write verifier can be set for the * mount point. * - * B_CLUSTEROK must be cleared along with B_NEEDCOMMIT because stage 1 data + * B_CLUSTEROK must be cleared along with B_NEEDCOMMIT because stage 1 data * writes are not clusterable. */ void -nfs_clearcommit(mp) - struct mount *mp; +nfs_clearcommit(struct mount *mp) { - register struct vnode *vp, *nvp; - register struct buf *bp, *nbp; + struct vnode *vp, *nvp; + struct buf *bp, *nbp; int s; GIANT_REQUIRED; @@ -2159,85 +803,252 @@ loop: splx(s); } -#ifndef NFS_NOSERVER /* - * Map errnos to NFS error numbers. For Version 3 also filter out error - * numbers not specified for the associated procedure. + * Helper functions for former macros. Some of these should be + * moved to their callers. */ + int -nfsrv_errmap(nd, err) - struct nfsrv_descript *nd; - register int err; +nfsm_mtofh_xx(struct vnode *d, struct vnode **v, int v3, int *f, + u_int32_t **tl, struct mbuf **md, caddr_t *dpos) { - register short *defaulterrp, *errp; - - if (nd->nd_flag & ND_NFSV3) { - if (nd->nd_procnum <= NFSPROC_COMMIT) { - errp = defaulterrp = nfsrv_v3errmap[nd->nd_procnum]; - while (*++errp) { - if (*errp == err) - return (err); - else if (*errp > err) - break; + struct nfsnode *ttnp; + struct vnode *ttvp; + nfsfh_t *ttfhp; + int ttfhsize; + int t1; + + if (v3) { + t1 = nfsm_dissect_xx((void **)tl, NFSX_UNSIGNED, md, dpos); + if (t1) + return (t1); + *f = fxdr_unsigned(int, **tl); + } else + *f = 1; + if (*f) { + t1 = nfsm_getfh_xx(&ttfhp, &ttfhsize, (v3), tl, md, dpos); + if (t1 != 0) + return t1; + t1 = nfs_nget(d->v_mount, ttfhp, ttfhsize, &ttnp); + if (t1 != 0) + return t1; + *v = NFSTOV(ttnp); + } + if (v3) { + t1 = nfsm_dissect_xx((void **)tl, NFSX_UNSIGNED, md, dpos); + if (t1) + return t1; + if (*f) + *f = fxdr_unsigned(int, **tl); + else if (fxdr_unsigned(int, **tl)) + nfsm_adv_xx(NFSX_V3FATTR, tl, md, dpos); + } + if (*f) { + ttvp = *v; + t1 = nfs_loadattrcache(&ttvp, md, dpos, (struct vattr *)0, 0); + if (t1) + return t1; + *v = ttvp; + } + return 0; +} + +int +nfsm_getfh_xx(nfsfh_t **f, int *s, int v3, + u_int32_t **tl, struct mbuf **md, caddr_t *dpos) +{ + int t1; + + if (v3) { + t1 = nfsm_dissect_xx((void **)tl, NFSX_UNSIGNED, md, dpos); + if (t1) + return t1; + *s = fxdr_unsigned(int, **tl); + if (*s <= 0 || *s > NFSX_V3FHMAX) { + return EBADRPC; + } + } else + *s = NFSX_V2FH; + t1 = nfsm_dissect_xx((void **)f, nfsm_rndup(*s), md, dpos); + return t1; +} + + +int +nfsm_loadattr_xx(struct vnode **v, struct vattr *va, + u_int32_t **tl, struct mbuf **md, caddr_t *dpos) +{ + int t1; + + struct vnode *ttvp = *v; + t1 = nfs_loadattrcache(&ttvp, md, dpos, va, 0); + if (t1 != 0) + return t1; + *v = ttvp; + return 0; +} + +int +nfsm_postop_attr_xx(struct vnode **v, int *f, + u_int32_t **tl, struct mbuf **md, caddr_t *dpos) +{ + int t1; + + struct vnode *ttvp = *v; + t1 = nfsm_dissect_xx((void **)tl, NFSX_UNSIGNED, md, dpos); + if (t1 != 0) + return t1; + *f = fxdr_unsigned(int, *tl); + if (f != 0) { + t1 = nfs_loadattrcache(&ttvp, md, dpos, (struct vattr *)0, 1); + if (t1 != 0) { + *f = 0; + return t1; } - return ((int)*defaulterrp); - } else - return (err & 0xffff); + *v = ttvp; } - if (err <= ELAST) - return ((int)nfsrv_v2errmap[err - 1]); - return (NFSERR_IO); + return 0; } int -nfsrv_object_create(vp) - struct vnode *vp; +nfsm_wcc_data_xx(struct vnode **v, int *f, + u_int32_t **tl, struct mbuf **md, caddr_t *dpos) { + int ttattrf, ttretf = 0; + int t1; + + t1 = nfsm_dissect_xx((void **)tl, NFSX_UNSIGNED, md, dpos); + if (t1 != 0) + return t1; + if (**tl == nfs_true) { + t1 = nfsm_dissect_xx((void **)tl, 6 * NFSX_UNSIGNED, md, dpos); + if (t1 != 0) + return t1; + if (*f) + ttretf = (VTONFS(*v)->n_mtime == + fxdr_unsigned(u_int32_t, *((*tl) + 2))); + } + t1 = nfsm_postop_attr_xx(v, &ttattrf, tl, md, dpos); + if (t1) + return t1; + if (*f) + *f = ttretf; + else + *f = ttattrf; + return 0; +} - if (vp == NULL || vp->v_type != VREG) - return (1); - return (vfs_object_create(vp, curthread, - curthread ? curthread->td_proc->p_ucred : NULL)); +int +nfsm_strtom_xx(const char *a, int s, int m, + u_int32_t **tl, struct mbuf **mb, caddr_t *bpos) +{ + int t1; + + if (s > m) + return ENAMETOOLONG; + t1 = nfsm_rndup(s) + NFSX_UNSIGNED; + if (t1 <= M_TRAILINGSPACE(*mb)) { + nfsm_build_xx((void **)tl, t1, mb, bpos); + *(*tl)++ = txdr_unsigned(s); + *((*tl) + ((t1 >> 2) - 2)) = 0; + bcopy(a, *tl, s); + } else { + t1 = nfsm_strtmbuf(mb, bpos, a, s); + if (t1 != 0) + return t1; + } + return 0; } -/* - * Sort the group list in increasing numerical order. - * (Insertion sort by Chris Torek, who was grossed out by the bubble sort - * that used to be here.) - */ -void -nfsrvw_sort(list, num) - register gid_t *list; - register int num; +int +nfsm_fhtom_xx(struct vnode *v, int v3, + u_int32_t **tl, struct mbuf **mb, caddr_t *bpos) { - register int i, j; - gid_t v; - - /* Insertion sort. */ - for (i = 1; i < num; i++) { - v = list[i]; - /* find correct slot for value v, moving others up */ - for (j = i; --j >= 0 && v < list[j];) - list[j + 1] = list[j]; - list[j + 1] = v; + int t1; + caddr_t cp; + + if (v3) { + t1 = nfsm_rndup(VTONFS(v)->n_fhsize) + NFSX_UNSIGNED; + if (t1 < M_TRAILINGSPACE(*mb)) { + nfsm_build_xx((void **)tl, t1, mb, bpos); + *(*tl)++ = txdr_unsigned(VTONFS(v)->n_fhsize); + *((*tl) + ((t1 >> 2) - 2)) = 0; + bcopy(VTONFS(v)->n_fhp, *tl, VTONFS(v)->n_fhsize); + } else { + t1 = nfsm_strtmbuf(mb, bpos, + (const char *)VTONFS(v)->n_fhp, + VTONFS(v)->n_fhsize); + if (t1 != 0) + return t1; + } + } else { + nfsm_build_xx((void **)&cp, NFSX_V2FH, mb, bpos); + bcopy(VTONFS(v)->n_fhp, cp, NFSX_V2FH); } + return 0; } -/* - * copy credentials making sure that the result can be compared with bcmp(). - */ void -nfsrv_setcred(incred, outcred) - register struct ucred *incred, *outcred; +nfsm_v3attrbuild_xx(struct vattr *va, int full, + u_int32_t **tl, struct mbuf **mb, caddr_t *bpos) { - register int i; - - bzero((caddr_t)outcred, sizeof (struct ucred)); - outcred->cr_ref = 1; - outcred->cr_uid = incred->cr_uid; - outcred->cr_ngroups = incred->cr_ngroups; - for (i = 0; i < incred->cr_ngroups; i++) - outcred->cr_groups[i] = incred->cr_groups[i]; - nfsrvw_sort(outcred->cr_groups, outcred->cr_ngroups); + + if (va->va_mode != (mode_t)VNOVAL) { + nfsm_build_xx((void **)tl, 2 * NFSX_UNSIGNED, mb, bpos); + *(*tl)++ = nfs_true; + **tl = txdr_unsigned(va->va_mode); + } else { + nfsm_build_xx((void **)tl, NFSX_UNSIGNED, mb, bpos); + **tl = nfs_false; + } + if (full && va->va_uid != (uid_t)VNOVAL) { + nfsm_build_xx((void **)tl, 2 * NFSX_UNSIGNED, mb, bpos); + *(*tl)++ = nfs_true; + **tl = txdr_unsigned(va->va_uid); + } else { + nfsm_build_xx((void **)tl, NFSX_UNSIGNED, mb, bpos); + **tl = nfs_false; + } + if (full && va->va_gid != (gid_t)VNOVAL) { + nfsm_build_xx((void **)tl, 2 * NFSX_UNSIGNED, mb, bpos); + *(*tl)++ = nfs_true; + **tl = txdr_unsigned(va->va_gid); + } else { + nfsm_build_xx((void **)tl, NFSX_UNSIGNED, mb, bpos); + **tl = nfs_false; + } + if (full && va->va_size != VNOVAL) { + nfsm_build_xx((void **)tl, 3 * NFSX_UNSIGNED, mb, bpos); + *(*tl)++ = nfs_true; + txdr_hyper(va->va_size, *tl); + } else { + nfsm_build_xx((void **)tl, NFSX_UNSIGNED, mb, bpos); + **tl = nfs_false; + } + if (va->va_atime.tv_sec != VNOVAL) { + if (va->va_atime.tv_sec != time_second) { + nfsm_build_xx((void **)tl, 3 * NFSX_UNSIGNED, mb, bpos); + *(*tl)++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); + txdr_nfsv3time(&va->va_atime, *tl); + } else { + nfsm_build_xx((void **)tl, NFSX_UNSIGNED, mb, bpos); + **tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); + } + } else { + nfsm_build_xx((void **)tl, NFSX_UNSIGNED, mb, bpos); + **tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); + } + if (va->va_mtime.tv_sec != VNOVAL) { + if (va->va_mtime.tv_sec != time_second) { + nfsm_build_xx((void **)tl, 3 * NFSX_UNSIGNED, mb, bpos); + *(*tl)++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); + txdr_nfsv3time(&va->va_mtime, *tl); + } else { + nfsm_build_xx((void **)tl, NFSX_UNSIGNED, mb, bpos); + **tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); + } + } else { + nfsm_build_xx((void **)tl, NFSX_UNSIGNED, mb, bpos); + **tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); + } } -#endif /* NFS_NOSERVER */ diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c index c70600f..68d0b93 100644 --- a/sys/nfsclient/nfs_vfsops.c +++ b/sys/nfsclient/nfs_vfsops.c @@ -34,9 +34,11 @@ * SUCH DAMAGE. * * @(#)nfs_vfsops.c 8.12 (Berkeley) 5/20/95 - * $FreeBSD$ */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + #include "opt_bootp.h" #include <sys/param.h> @@ -63,25 +65,16 @@ #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> -#include <nfs/nfs.h> -#include <nfs/nfsnode.h> -#include <nfs/nfsmount.h> +#include <nfsclient/nfs.h> +#include <nfsclient/nfsnode.h> +#include <nfsclient/nfsmount.h> #include <nfs/xdr_subs.h> -#include <nfs/nfsm_subs.h> -#include <nfs/nfsdiskless.h> -#include <nfs/nqnfs.h> - -extern int nfs_mountroot __P((struct mount *mp)); - -extern int nfs_ticks; +#include <nfsclient/nfsm_subs.h> +#include <nfsclient/nfsdiskless.h> MALLOC_DEFINE(M_NFSREQ, "NFS req", "NFS request header"); MALLOC_DEFINE(M_NFSBIGFH, "NFSV3 bigfh", "NFS version 3 file handle"); -MALLOC_DEFINE(M_NFSD, "NFS daemon", "Nfs server daemon structure"); MALLOC_DEFINE(M_NFSDIROFF, "NFSV3 diroff", "NFS directory offset data"); -MALLOC_DEFINE(M_NFSRVDESC, "NFSV3 srvdesc", "NFS server socket descriptor"); -MALLOC_DEFINE(M_NFSUID, "NFS uid", "Nfs uid mapping structure"); -MALLOC_DEFINE(M_NQLEASE, "NQNFS Lease", "Nqnfs lease"); MALLOC_DEFINE(M_NFSHASH, "NFS hash", "NFS hash tables"); vm_zone_t nfsmount_zone; @@ -89,26 +82,24 @@ vm_zone_t nfsmount_zone; struct nfsstats nfsstats; SYSCTL_NODE(_vfs, OID_AUTO, nfs, CTLFLAG_RW, 0, "NFS filesystem"); SYSCTL_STRUCT(_vfs_nfs, NFS_NFSSTATS, nfsstats, CTLFLAG_RD, - &nfsstats, nfsstats, ""); + &nfsstats, nfsstats, "S,nfsstats"); #ifdef NFS_DEBUG int nfs_debug; SYSCTL_INT(_vfs_nfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0, ""); #endif -static int nfs_iosize __P((struct nfsmount *nmp)); -static void nfs_decode_args __P((struct nfsmount *nmp, - struct nfs_args *argp)); -static int mountnfs __P((struct nfs_args *,struct mount *, - struct sockaddr *,char *,char *,struct vnode **)); -static int nfs_mount __P(( struct mount *mp, char *path, caddr_t data, - struct nameidata *ndp, struct thread *p)); -static int nfs_unmount __P(( struct mount *mp, int mntflags, - struct thread *p)); -static int nfs_root __P(( struct mount *mp, struct vnode **vpp)); -static int nfs_statfs __P(( struct mount *mp, struct statfs *sbp, - struct thread *p)); -static int nfs_sync __P(( struct mount *mp, int waitfor, - struct ucred *cred, struct thread *p)); +static int nfs_iosize(struct nfsmount *nmp); +static void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp); +static int mountnfs(struct nfs_args *, struct mount *, + struct sockaddr *, char *, char *, struct vnode **); +static int nfs_mount(struct mount *mp, char *path, caddr_t data, + struct nameidata *ndp, struct thread *td); +static int nfs_unmount(struct mount *mp, int mntflags, struct thread *td); +static int nfs_root(struct mount *mp, struct vnode **vpp); +static int nfs_statfs(struct mount *mp, struct statfs *sbp, + struct thread *td); +static int nfs_sync(struct mount *mp, int waitfor, struct ucred *cred, + struct thread *td); /* * nfs vfs operations. @@ -140,7 +131,7 @@ struct nfs_diskless nfs_diskless = { { { 0 } } }; struct nfsv3_diskless nfsv3_diskless = { { { 0 } } }; int nfs_diskless_valid = 0; -SYSCTL_INT(_vfs_nfs, OID_AUTO, diskless_valid, CTLFLAG_RD, +SYSCTL_INT(_vfs_nfs, OID_AUTO, diskless_valid, CTLFLAG_RD, &nfs_diskless_valid, 0, ""); SYSCTL_STRING(_vfs_nfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD, @@ -154,22 +145,20 @@ SYSCTL_STRING(_vfs_nfs, OID_AUTO, diskless_swappath, CTLFLAG_RD, nfsv3_diskless.swap_hostnam, 0, ""); SYSCTL_OPAQUE(_vfs_nfs, OID_AUTO, diskless_swapaddr, CTLFLAG_RD, - &nfsv3_diskless.swap_saddr, sizeof nfsv3_diskless.swap_saddr, + &nfsv3_diskless.swap_saddr, sizeof nfsv3_diskless.swap_saddr, "%Ssockaddr_in",""); -void nfsargs_ntoh __P((struct nfs_args *)); -static int nfs_mountdiskless __P((char *, char *, int, - struct sockaddr_in *, struct nfs_args *, - struct thread *, struct vnode **, - struct mount **)); -static void nfs_convert_diskless __P((void)); -static void nfs_convert_oargs __P((struct nfs_args *args, - struct onfs_args *oargs)); +void nfsargs_ntoh(struct nfs_args *); +static int nfs_mountdiskless(char *, char *, int, + struct sockaddr_in *, struct nfs_args *, + struct thread *, struct vnode **, struct mount **); +static void nfs_convert_diskless(void); +static void nfs_convert_oargs(struct nfs_args *args, + struct onfs_args *oargs); static int -nfs_iosize(nmp) - struct nfsmount* nmp; +nfs_iosize(struct nfsmount *nmp) { int iosize; @@ -185,10 +174,9 @@ nfs_iosize(nmp) } static void -nfs_convert_oargs(args, oargs) - struct nfs_args *args; - struct onfs_args *oargs; +nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs) { + args->version = NFS_ARGSVERSION; args->addr = oargs->addr; args->addrlen = oargs->addrlen; @@ -204,35 +192,35 @@ nfs_convert_oargs(args, oargs) args->retrans = oargs->retrans; args->maxgrouplist = oargs->maxgrouplist; args->readahead = oargs->readahead; - args->leaseterm = oargs->leaseterm; args->deadthresh = oargs->deadthresh; args->hostname = oargs->hostname; } static void -nfs_convert_diskless() +nfs_convert_diskless(void) { + bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif, sizeof(struct ifaliasreq)); bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway, sizeof(struct sockaddr_in)); nfs_convert_oargs(&nfsv3_diskless.swap_args,&nfs_diskless.swap_args); nfsv3_diskless.swap_fhsize = NFSX_V2FH; - bcopy(nfs_diskless.swap_fh,nfsv3_diskless.swap_fh,NFSX_V2FH); + bcopy(nfs_diskless.swap_fh, nfsv3_diskless.swap_fh, NFSX_V2FH); bcopy(&nfs_diskless.swap_saddr,&nfsv3_diskless.swap_saddr, sizeof(struct sockaddr_in)); - bcopy(nfs_diskless.swap_hostnam,nfsv3_diskless.swap_hostnam, MNAMELEN); + bcopy(nfs_diskless.swap_hostnam, nfsv3_diskless.swap_hostnam, MNAMELEN); nfsv3_diskless.swap_nblks = nfs_diskless.swap_nblks; bcopy(&nfs_diskless.swap_ucred, &nfsv3_diskless.swap_ucred, sizeof(struct ucred)); nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args); nfsv3_diskless.root_fhsize = NFSX_V2FH; - bcopy(nfs_diskless.root_fh,nfsv3_diskless.root_fh,NFSX_V2FH); + bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH); bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr, sizeof(struct sockaddr_in)); - bcopy(nfs_diskless.root_hostnam,nfsv3_diskless.root_hostnam, MNAMELEN); + bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN); nfsv3_diskless.root_time = nfs_diskless.root_time; - bcopy(nfs_diskless.my_hostnam,nfsv3_diskless.my_hostnam, + bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam, MAXHOSTNAMELEN); nfs_diskless_valid = 3; } @@ -241,20 +229,15 @@ nfs_convert_diskless() * nfs statfs call */ int -nfs_statfs(mp, sbp, td) - struct mount *mp; - register struct statfs *sbp; - struct thread *td; +nfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) { - register struct vnode *vp; - register struct nfs_statfs *sfp; - register caddr_t cp; - register u_int32_t *tl; - register int32_t t1, t2; - caddr_t bpos, dpos, cp2; + struct vnode *vp; + struct nfs_statfs *sfp; + u_int32_t *tl; + caddr_t bpos, dpos; struct nfsmount *nmp = VFSTONFS(mp); int error = 0, v3 = (nmp->nm_flag & NFSMNT_NFSV3), retattr; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct mbuf *mreq, *mrep, *md, *mb; struct nfsnode *np; u_quad_t tquad; @@ -268,7 +251,9 @@ nfs_statfs(mp, sbp, td) if (v3 && (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) (void)nfs_fsinfo(nmp, vp, td->td_proc->p_ucred, td); nfsstats.rpccnt[NFSPROC_FSSTAT]++; - nfsm_reqhead(vp, NFSPROC_FSSTAT, NFSX_FH(v3)); + mreq = nfsm_reqhead(vp, NFSPROC_FSSTAT, NFSX_FH(v3)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(vp, v3); nfsm_request(vp, NFSPROC_FSSTAT, td, td->td_proc->p_ucred); if (v3) @@ -306,7 +291,8 @@ nfs_statfs(mp, sbp, td) bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); } - nfsm_reqdone; + m_freem(mrep); +nfsmout: vput(vp); return (error); } @@ -315,23 +301,20 @@ nfs_statfs(mp, sbp, td) * nfs version 3 fsinfo rpc call */ int -nfs_fsinfo(nmp, vp, cred, td) - register struct nfsmount *nmp; - register struct vnode *vp; - struct ucred *cred; - struct thread *td; +nfs_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred, + struct thread *td) { - register struct nfsv3_fsinfo *fsp; - register caddr_t cp; - register int32_t t1, t2; - register u_int32_t *tl, pref, max; - caddr_t bpos, dpos, cp2; + struct nfsv3_fsinfo *fsp; + u_int32_t *tl, pref, max; + caddr_t bpos, dpos; int error = 0, retattr; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct mbuf *mreq, *mrep, *md, *mb; u_int64_t maxfsize; nfsstats.rpccnt[NFSPROC_FSINFO]++; - nfsm_reqhead(vp, NFSPROC_FSINFO, NFSX_FH(1)); + mreq = nfsm_reqhead(vp, NFSPROC_FSINFO, NFSX_FH(1)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(vp, 1); nfsm_request(vp, NFSPROC_FSINFO, td, cred); nfsm_postop_attr(vp, retattr); @@ -371,7 +354,8 @@ nfs_fsinfo(nmp, vp, cred, td) nmp->nm_maxfilesize = maxfsize; nmp->nm_state |= NFSSTA_GOTFSINFO; } - nfsm_reqdone; + m_freem(mrep); +nfsmout: return (error); } @@ -387,8 +371,7 @@ nfs_fsinfo(nmp, vp, cred, td) * - build the rootfs mount point and call mountnfs() to do the rest. */ int -nfs_mountroot(mp) - struct mount *mp; +nfs_mountroot(struct mount *mp) { struct mount *swap_mp; struct nfsv3_diskless *nd = &nfsv3_diskless; @@ -410,8 +393,8 @@ nfs_mountroot(mp) while (time_second == 0) tsleep(&time_second, PZERO+8, "arpkludge", 10); - if (nfs_diskless_valid==1) - nfs_convert_diskless(); + if (nfs_diskless_valid==1) + nfs_convert_diskless(); /* * XXX splnet, so networks will receive... @@ -485,8 +468,8 @@ nfs_mountroot(mp) l = ntohl(nd->root_saddr.sin_addr.s_addr); snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s", (l >> 24) & 0xff, (l >> 16) & 0xff, - (l >> 8) & 0xff, (l >> 0) & 0xff,nd->root_hostnam); - printf("NFS ROOT: %s\n",buf); + (l >> 8) & 0xff, (l >> 0) & 0xff, nd->root_hostnam); + printf("NFS ROOT: %s\n", buf); if ((error = nfs_mountdiskless(buf, "/", MNT_RDONLY, &nd->root_saddr, &nd->root_args, td, &vp, &mp)) != 0) { if (swap_mp) { @@ -511,16 +494,15 @@ nfs_mountroot(mp) l = ntohl(nd->swap_saddr.sin_addr.s_addr); snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s", (l >> 24) & 0xff, (l >> 16) & 0xff, - (l >> 8) & 0xff, (l >> 0) & 0xff,nd->swap_hostnam); - printf("NFS SWAP: %s\n",buf); + (l >> 8) & 0xff, (l >> 0) & 0xff, nd->swap_hostnam); + printf("NFS SWAP: %s\n", buf); if ((error = nfs_mountdiskless(buf, "/swap", 0, &nd->swap_saddr, &nd->swap_args, td, &vp, &swap_mp)) != 0) return (error); vfs_unbusy(swap_mp, td); - VTONFS(vp)->n_size = VTONFS(vp)->n_vattr.va_size = + VTONFS(vp)->n_size = VTONFS(vp)->n_vattr.va_size = nd->swap_nblks * DEV_BSIZE ; - /* * Since the swap file is not the root dir of a file system, * hack it to a regular file. @@ -554,15 +536,9 @@ nfs_mountroot(mp) * Internal version of mount system call for diskless setup. */ static int -nfs_mountdiskless(path, which, mountflag, sin, args, td, vpp, mpp) - char *path; - char *which; - int mountflag; - struct sockaddr_in *sin; - struct nfs_args *args; - struct thread *td; - struct vnode **vpp; - struct mount **mpp; +nfs_mountdiskless(char *path, char *which, int mountflag, + struct sockaddr_in *sin, struct nfs_args *args, struct thread *td, + struct vnode **vpp, struct mount **mpp) { struct mount *mp; struct sockaddr *nam; @@ -592,9 +568,7 @@ nfs_mountdiskless(path, which, mountflag, sin, args, td, vpp, mpp) } static void -nfs_decode_args(nmp, argp) - struct nfsmount *nmp; - struct nfs_args *argp; +nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp) { int s; int adjsock; @@ -710,17 +684,11 @@ nfs_decode_args(nmp, argp) else nmp->nm_readahead = NFS_MAXRAHEAD; } - if ((argp->flags & NFSMNT_LEASETERM) && argp->leaseterm >= 2) { - if (argp->leaseterm <= NQ_MAXLEASE) - nmp->nm_leaseterm = argp->leaseterm; - else - nmp->nm_leaseterm = NQ_MAXLEASE; - } - if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 1) { - if (argp->deadthresh <= NQ_NEVERDEAD) + if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 0) { + if (argp->deadthresh <= NFS_MAXDEADTHRESH) nmp->nm_deadthresh = argp->deadthresh; else - nmp->nm_deadthresh = NQ_NEVERDEAD; + nmp->nm_deadthresh = NFS_MAXDEADTHRESH; } adjsock |= ((nmp->nm_sotype != argp->sotype) || @@ -750,12 +718,8 @@ nfs_decode_args(nmp, argp) */ /* ARGSUSED */ static int -nfs_mount(mp, path, data, ndp, td) - struct mount *mp; - char *path; - caddr_t data; - struct nameidata *ndp; - struct thread *td; +nfs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp, + struct thread *td) { int error; struct nfs_args args; @@ -789,18 +753,18 @@ nfs_mount(mp, path, data, ndp, td) #endif /* COMPAT_PRELITE2 */ } if (mp->mnt_flag & MNT_UPDATE) { - register struct nfsmount *nmp = VFSTONFS(mp); + struct nfsmount *nmp = VFSTONFS(mp); if (nmp == NULL) return (EIO); /* * When doing an update, we can't change from or to - * v3 and/or nqnfs, or change cookie translation + * v3, or change cookie translation */ args.flags = (args.flags & - ~(NFSMNT_NFSV3|NFSMNT_NQNFS /*|NFSMNT_XLATECOOKIE*/)) | + ~(NFSMNT_NFSV3 /*|NFSMNT_XLATECOOKIE*/)) | (nmp->nm_flag & - (NFSMNT_NFSV3|NFSMNT_NQNFS /*|NFSMNT_XLATECOOKIE*/)); + (NFSMNT_NFSV3 /*|NFSMNT_XLATECOOKIE*/)); nfs_decode_args(nmp, &args); return (0); } @@ -826,14 +790,10 @@ nfs_mount(mp, path, data, ndp, td) * Common code for mount and mountroot */ static int -mountnfs(argp, mp, nam, pth, hst, vpp) - register struct nfs_args *argp; - register struct mount *mp; - struct sockaddr *nam; - char *pth, *hst; - struct vnode **vpp; +mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, + char *pth, char *hst, struct vnode **vpp) { - register struct nfsmount *nmp; + struct nfsmount *nmp; struct nfsnode *np; int error; struct vattr attrs; @@ -846,20 +806,11 @@ mountnfs(argp, mp, nam, pth, hst, vpp) } else { nmp = zalloc(nfsmount_zone); bzero((caddr_t)nmp, sizeof (struct nfsmount)); - TAILQ_INIT(&nmp->nm_uidlruhead); TAILQ_INIT(&nmp->nm_bufq); mp->mnt_data = (qaddr_t)nmp; } vfs_getnewfsid(mp); nmp->nm_mountp = mp; - if (argp->flags & NFSMNT_NQNFS) - /* - * We have to set mnt_maxsymlink to a non-zero value so - * that COMPAT_43 routines will know that we are setting - * the d_type field in directories (and can zero it for - * unsuspecting binaries). - */ - mp->mnt_maxsymlinklen = 1; /* * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too @@ -883,10 +834,7 @@ mountnfs(argp, mp, nam, pth, hst, vpp) nmp->nm_readdirsize = NFS_READDIRSIZE; nmp->nm_numgrps = NFS_MAXGRPS; nmp->nm_readahead = NFS_DEFRAHEAD; - nmp->nm_leaseterm = NQ_DEFLEASE; - nmp->nm_deadthresh = NQ_DEADTHRESH; - TAILQ_INIT(&nmp->nm_timerhead); - nmp->nm_inprog = NULLVP; + nmp->nm_deadthresh = NFS_MAXDEADTHRESH; nmp->nm_fhsize = argp->fhsize; bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize); bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN); @@ -949,12 +897,9 @@ bad: * unmount system call */ static int -nfs_unmount(mp, mntflags, td) - struct mount *mp; - int mntflags; - struct thread *td; +nfs_unmount(struct mount *mp, int mntflags, struct thread *td) { - register struct nfsmount *nmp; + struct nfsmount *nmp; int error, flags = 0; if (mntflags & MNT_FORCE) @@ -966,32 +911,18 @@ nfs_unmount(mp, mntflags, td) * - Close the socket * - Free up the data structures */ - /* - * Must handshake with nqnfs_clientd() if it is active. - */ - nmp->nm_state |= NFSSTA_DISMINPROG; - while (nmp->nm_inprog != NULLVP) - (void) tsleep((caddr_t)&lbolt, PSOCK, "nfsdism", 0); - /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */ error = vflush(mp, 1, flags); - if (error) { - nmp->nm_state &= ~NFSSTA_DISMINPROG; + if (error) return (error); - } /* * We are now committed to the unmount. - * For NQNFS, let the server daemon free the nfsmount structure. */ - if (nmp->nm_flag & (NFSMNT_NQNFS | NFSMNT_KERB)) - nmp->nm_state |= NFSSTA_DISMNT; - nfs_disconnect(nmp); FREE(nmp->nm_nam, M_SONAME); - if ((nmp->nm_flag & (NFSMNT_NQNFS | NFSMNT_KERB)) == 0) - zfree(nfsmount_zone, nmp); + zfree(nfsmount_zone, nmp); return (0); } @@ -999,11 +930,9 @@ nfs_unmount(mp, mntflags, td) * Return root of a filesystem */ static int -nfs_root(mp, vpp) - struct mount *mp; - struct vnode **vpp; +nfs_root(struct mount *mp, struct vnode **vpp) { - register struct vnode *vp; + struct vnode *vp; struct nfsmount *nmp; struct nfsnode *np; int error; @@ -1020,18 +949,12 @@ nfs_root(mp, vpp) return (0); } -extern int syncprt; - /* * Flush out the buffer cache */ /* ARGSUSED */ static int -nfs_sync(mp, waitfor, cred, td) - struct mount *mp; - int waitfor; - struct ucred *cred; - struct thread *td; +nfs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct thread *td) { struct vnode *vp, *vnp; int error, allerror = 0; @@ -1072,4 +995,3 @@ loop: mtx_unlock(&mntvnode_mtx); return (allerror); } - diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index 8f9ff7d..4fc4521 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -34,9 +34,10 @@ * SUCH DAMAGE. * * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95 - * $FreeBSD$ */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); /* * vnode op calls for Sun NFS version 2 and 3 @@ -70,13 +71,12 @@ #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> -#include <nfs/nfs.h> -#include <nfs/nfsnode.h> -#include <nfs/nfsmount.h> +#include <nfsclient/nfs.h> +#include <nfsclient/nfsnode.h> +#include <nfsclient/nfsmount.h> +#include <nfsclient/nfs_lock.h> #include <nfs/xdr_subs.h> -#include <nfs/nfsm_subs.h> -#include <nfs/nqnfs.h> -#include <nfs/nfs_lock.h> +#include <nfsclient/nfsm_subs.h> #include <net/if.h> #include <netinet/in.h> @@ -95,40 +95,43 @@ #define vfs_busy_pages(bp, f) #endif -static int nfsspec_read __P((struct vop_read_args *)); -static int nfsspec_write __P((struct vop_write_args *)); -static int nfsfifo_read __P((struct vop_read_args *)); -static int nfsfifo_write __P((struct vop_write_args *)); -static int nfsspec_close __P((struct vop_close_args *)); -static int nfsfifo_close __P((struct vop_close_args *)); -#define nfs_poll vop_nopoll -static int nfs_flush __P((struct vnode *,struct ucred *,int,struct thread *,int)); -static int nfs_setattrrpc __P((struct vnode *,struct vattr *,struct ucred *,struct thread *)); -static int nfs_lookup __P((struct vop_lookup_args *)); -static int nfs_create __P((struct vop_create_args *)); -static int nfs_mknod __P((struct vop_mknod_args *)); -static int nfs_open __P((struct vop_open_args *)); -static int nfs_close __P((struct vop_close_args *)); -static int nfs_access __P((struct vop_access_args *)); -static int nfs_getattr __P((struct vop_getattr_args *)); -static int nfs_setattr __P((struct vop_setattr_args *)); -static int nfs_read __P((struct vop_read_args *)); -static int nfs_fsync __P((struct vop_fsync_args *)); -static int nfs_remove __P((struct vop_remove_args *)); -static int nfs_link __P((struct vop_link_args *)); -static int nfs_rename __P((struct vop_rename_args *)); -static int nfs_mkdir __P((struct vop_mkdir_args *)); -static int nfs_rmdir __P((struct vop_rmdir_args *)); -static int nfs_symlink __P((struct vop_symlink_args *)); -static int nfs_readdir __P((struct vop_readdir_args *)); -static int nfs_strategy __P((struct vop_strategy_args *)); -static int nfs_lookitup __P((struct vnode *, const char *, int, - struct ucred *, struct thread *, struct nfsnode **)); -static int nfs_sillyrename __P((struct vnode *,struct vnode *,struct componentname *)); -static int nfsspec_access __P((struct vop_access_args *)); -static int nfs_readlink __P((struct vop_readlink_args *)); -static int nfs_print __P((struct vop_print_args *)); -static int nfs_advlock __P((struct vop_advlock_args *)); +static int nfsspec_read(struct vop_read_args *); +static int nfsspec_write(struct vop_write_args *); +static int nfsfifo_read(struct vop_read_args *); +static int nfsfifo_write(struct vop_write_args *); +static int nfsspec_close(struct vop_close_args *); +static int nfsfifo_close(struct vop_close_args *); +static int nfs_flush(struct vnode *, struct ucred *, int, struct thread *, + int); +static int nfs_setattrrpc(struct vnode *, struct vattr *, struct ucred *, + struct thread *); +static int nfs_lookup(struct vop_lookup_args *); +static int nfs_create(struct vop_create_args *); +static int nfs_mknod(struct vop_mknod_args *); +static int nfs_open(struct vop_open_args *); +static int nfs_close(struct vop_close_args *); +static int nfs_access(struct vop_access_args *); +static int nfs_getattr(struct vop_getattr_args *); +static int nfs_setattr(struct vop_setattr_args *); +static int nfs_read(struct vop_read_args *); +static int nfs_fsync(struct vop_fsync_args *); +static int nfs_remove(struct vop_remove_args *); +static int nfs_link(struct vop_link_args *); +static int nfs_rename(struct vop_rename_args *); +static int nfs_mkdir(struct vop_mkdir_args *); +static int nfs_rmdir(struct vop_rmdir_args *); +static int nfs_symlink(struct vop_symlink_args *); +static int nfs_readdir(struct vop_readdir_args *); +static int nfs_strategy(struct vop_strategy_args *); +static int nfs_lookitup(struct vnode *, const char *, int, + struct ucred *, struct thread *, struct nfsnode **); +static int nfs_sillyrename(struct vnode *, struct vnode *, + struct componentname *); +static int nfsspec_access(struct vop_access_args *); +static int nfs_readlink(struct vop_readlink_args *); +static int nfs_print(struct vop_print_args *); +static int nfs_advlock(struct vop_advlock_args *); + /* * Global vfs data structures for nfs */ @@ -152,7 +155,6 @@ static struct vnodeopv_entry_desc nfsv2_vnodeop_entries[] = { { &vop_mkdir_desc, (vop_t *) nfs_mkdir }, { &vop_mknod_desc, (vop_t *) nfs_mknod }, { &vop_open_desc, (vop_t *) nfs_open }, - { &vop_poll_desc, (vop_t *) nfs_poll }, { &vop_print_desc, (vop_t *) nfs_print }, { &vop_read_desc, (vop_t *) nfs_read }, { &vop_readdir_desc, (vop_t *) nfs_readdir }, @@ -219,46 +221,39 @@ static struct vnodeopv_desc fifo_nfsv2nodeop_opv_desc = { &fifo_nfsv2nodeop_p, nfsv2_fifoop_entries }; VNODEOP_SET(fifo_nfsv2nodeop_opv_desc); -static int nfs_mknodrpc __P((struct vnode *dvp, struct vnode **vpp, - struct componentname *cnp, - struct vattr *vap)); -static int nfs_removerpc __P((struct vnode *dvp, const char *name, - int namelen, - struct ucred *cred, struct thread *td)); -static int nfs_renamerpc __P((struct vnode *fdvp, const char *fnameptr, - int fnamelen, struct vnode *tdvp, - const char *tnameptr, int tnamelen, - struct ucred *cred, struct thread *td)); -static int nfs_renameit __P((struct vnode *sdvp, - struct componentname *scnp, - struct sillyrename *sp)); +static int nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, + struct componentname *cnp, struct vattr *vap); +static int nfs_removerpc(struct vnode *dvp, const char *name, int namelen, + struct ucred *cred, struct thread *td); +static int nfs_renamerpc(struct vnode *fdvp, const char *fnameptr, + int fnamelen, struct vnode *tdvp, + const char *tnameptr, int tnamelen, + struct ucred *cred, struct thread *td); +static int nfs_renameit(struct vnode *sdvp, struct componentname *scnp, + struct sillyrename *sp); /* * Global variables */ -extern u_int32_t nfs_true, nfs_false; -extern u_int32_t nfs_xdrneg1; -extern struct nfsstats nfsstats; -extern nfstype nfsv3_type[9]; -struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; +struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; struct nfsmount *nfs_iodmount[NFS_MAXASYNCDAEMON]; -int nfs_numasync = 0; +int nfs_numasync = 0; #define DIRHDSIZ (sizeof (struct dirent) - (MAXNAMLEN + 1)) SYSCTL_DECL(_vfs_nfs); static int nfsaccess_cache_timeout = NFS_MAXATTRTIMO; -SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_timeout, CTLFLAG_RW, +SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_timeout, CTLFLAG_RW, &nfsaccess_cache_timeout, 0, "NFS ACCESS cache timeout"); static int nfsv3_commit_on_close = 0; -SYSCTL_INT(_vfs_nfs, OID_AUTO, nfsv3_commit_on_close, CTLFLAG_RW, +SYSCTL_INT(_vfs_nfs, OID_AUTO, nfsv3_commit_on_close, CTLFLAG_RW, &nfsv3_commit_on_close, 0, "write+commit on close, else only write"); #if 0 -SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_hits, CTLFLAG_RD, +SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_hits, CTLFLAG_RD, &nfsstats.accesscache_hits, 0, "NFS ACCESS cache hit count"); -SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_misses, CTLFLAG_RD, +SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_misses, CTLFLAG_RD, &nfsstats.accesscache_misses, 0, "NFS ACCESS cache miss count"); #endif @@ -266,27 +261,25 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_misses, CTLFLAG_RD, | NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE \ | NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP) static int -nfs3_access_otw(struct vnode *vp, - int wmode, - struct thread *td, - struct ucred *cred) +nfs3_access_otw(struct vnode *vp, int wmode, struct thread *td, + struct ucred *cred) { const int v3 = 1; u_int32_t *tl; int error = 0, attrflag; - - struct mbuf *mreq, *mrep, *md, *mb, *mb2; - caddr_t bpos, dpos, cp2; - register int32_t t1, t2; - register caddr_t cp; + + struct mbuf *mreq, *mrep, *md, *mb; + caddr_t bpos, dpos; u_int32_t rmode; struct nfsnode *np = VTONFS(vp); nfsstats.rpccnt[NFSPROC_ACCESS]++; - nfsm_reqhead(vp, NFSPROC_ACCESS, NFSX_FH(v3) + NFSX_UNSIGNED); + mreq = nfsm_reqhead(vp, NFSPROC_ACCESS, NFSX_FH(v3) + NFSX_UNSIGNED); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(vp, v3); nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(wmode); + *tl = txdr_unsigned(wmode); nfsm_request(vp, NFSPROC_ACCESS, td, cred); nfsm_postop_attr(vp, attrflag); if (!error) { @@ -296,7 +289,8 @@ nfs3_access_otw(struct vnode *vp, np->n_modeuid = cred->cr_uid; np->n_modestamp = time_second; } - nfsm_reqdone; + m_freem(mrep); +nfsmout: return error; } @@ -307,15 +301,9 @@ nfs3_access_otw(struct vnode *vp, * are changed on the server, accesses might still fail later. */ static int -nfs_access(ap) - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap; +nfs_access(struct vop_access_args *ap) { - register struct vnode *vp = ap->a_vp; + struct vnode *vp = ap->a_vp; int error = 0; u_int32_t mode, wmode; int v3 = NFS_ISV3(vp); @@ -363,8 +351,8 @@ nfs_access(ap) } /* XXX safety belt, only make blanket request if caching */ if (nfsaccess_cache_timeout > 0) { - wmode = NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY | - NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE | + wmode = NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY | + NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE | NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP; } else { wmode = mode; @@ -445,73 +433,47 @@ nfs_access(ap) */ /* ARGSUSED */ static int -nfs_open(ap) - struct vop_open_args /* { - struct vnode *a_vp; - int a_mode; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap; +nfs_open(struct vop_open_args *ap) { - register struct vnode *vp = ap->a_vp; + struct vnode *vp = ap->a_vp; struct nfsnode *np = VTONFS(vp); - struct nfsmount *nmp = VFSTONFS(vp->v_mount); struct vattr vattr; int error; if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) { #ifdef DIAGNOSTIC - printf("open eacces vtyp=%d\n",vp->v_type); + printf("open eacces vtyp=%d\n", vp->v_type); #endif return (EACCES); } /* * Get a valid lease. If cached data is stale, flush it. */ - if (nmp->nm_flag & NFSMNT_NQNFS) { - if (NQNFS_CKINVALID(vp, np, ND_READ)) { - do { - error = nqnfs_getlease(vp, ND_READ, ap->a_cred, - ap->a_td); - } while (error == NQNFS_EXPIRED); - if (error) + if (np->n_flag & NMODIFIED) { + if ((error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, + ap->a_td, 1)) == EINTR) return (error); - if (np->n_lrev != np->n_brev || - (np->n_flag & NQNFSNONCACHE)) { - if ((error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, - ap->a_td, 1)) == EINTR) - return (error); - np->n_brev = np->n_lrev; - } - } + np->n_attrstamp = 0; + if (vp->v_type == VDIR) + np->n_direofoffset = 0; + error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_td); + if (error) + return (error); + np->n_mtime = vattr.va_mtime.tv_sec; } else { - if (np->n_flag & NMODIFIED) { - if ((error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, - ap->a_td, 1)) == EINTR) - return (error); - np->n_attrstamp = 0; + error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_td); + if (error) + return (error); + if (np->n_mtime != vattr.va_mtime.tv_sec) { if (vp->v_type == VDIR) np->n_direofoffset = 0; - error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_td); - if (error) + if ((error = nfs_vinvalbuf(vp, V_SAVE, + ap->a_cred, ap->a_td, 1)) == EINTR) return (error); np->n_mtime = vattr.va_mtime.tv_sec; - } else { - error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_td); - if (error) - return (error); - if (np->n_mtime != vattr.va_mtime.tv_sec) { - if (vp->v_type == VDIR) - np->n_direofoffset = 0; - if ((error = nfs_vinvalbuf(vp, V_SAVE, - ap->a_cred, ap->a_td, 1)) == EINTR) - return (error); - np->n_mtime = vattr.va_mtime.tv_sec; - } } } - if ((nmp->nm_flag & NFSMNT_NQNFS) == 0) - np->n_attrstamp = 0; /* For Open/Close consistency */ + np->n_attrstamp = 0; /* For Open/Close consistency */ return (0); } @@ -541,28 +503,17 @@ nfs_open(ap) * enough". Changing the last argument to nfs_flush() to * a 1 would force a commit operation, if it is felt a * commit is necessary now. - * for NQNFS - do nothing now, since 2 is dealt with via leases and - * 1 should be dealt with via an fsync() system call for - * cases where write errors are important. */ /* ARGSUSED */ static int -nfs_close(ap) - struct vop_close_args /* { - struct vnodeop_desc *a_desc; - struct vnode *a_vp; - int a_fflag; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap; +nfs_close(struct vop_close_args *ap) { - register struct vnode *vp = ap->a_vp; - register struct nfsnode *np = VTONFS(vp); + struct vnode *vp = ap->a_vp; + struct nfsnode *np = VTONFS(vp); int error = 0; if (vp->v_type == VREG) { - if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NQNFS) == 0 && - (np->n_flag & NMODIFIED)) { + if (np->n_flag & NMODIFIED) { if (NFS_ISV3(vp)) { /* * Under NFSv3 we have dirty buffers to dispose of. We @@ -597,24 +548,16 @@ nfs_close(ap) * nfs getattr call from vfs. */ static int -nfs_getattr(ap) - struct vop_getattr_args /* { - struct vnode *a_vp; - struct vattr *a_vap; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap; +nfs_getattr(struct vop_getattr_args *ap) { - register struct vnode *vp = ap->a_vp; - register struct nfsnode *np = VTONFS(vp); - register caddr_t cp; - register u_int32_t *tl; - register int32_t t1, t2; + struct vnode *vp = ap->a_vp; + struct nfsnode *np = VTONFS(vp); + u_int32_t *tl; caddr_t bpos, dpos; int error = 0; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct mbuf *mreq, *mrep, *md, *mb; int v3 = NFS_ISV3(vp); - + /* * Update local times for special files. */ @@ -634,13 +577,16 @@ nfs_getattr(ap) } nfsstats.rpccnt[NFSPROC_GETATTR]++; - nfsm_reqhead(vp, NFSPROC_GETATTR, NFSX_FH(v3)); + mreq = nfsm_reqhead(vp, NFSPROC_GETATTR, NFSX_FH(v3)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(vp, v3); nfsm_request(vp, NFSPROC_GETATTR, ap->a_td, ap->a_cred); if (!error) { nfsm_loadattr(vp, ap->a_vap); } - nfsm_reqdone; + m_freem(mrep); +nfsmout: return (error); } @@ -648,18 +594,11 @@ nfs_getattr(ap) * nfs setattr call. */ static int -nfs_setattr(ap) - struct vop_setattr_args /* { - struct vnodeop_desc *a_desc; - struct vnode *a_vp; - struct vattr *a_vap; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap; +nfs_setattr(struct vop_setattr_args *ap) { - register struct vnode *vp = ap->a_vp; - register struct nfsnode *np = VTONFS(vp); - register struct vattr *vap = ap->a_vap; + struct vnode *vp = ap->a_vp; + struct nfsnode *np = VTONFS(vp); + struct vattr *vap = ap->a_vap; int error = 0; u_quad_t tsize; @@ -738,23 +677,20 @@ nfs_setattr(ap) * Do an nfs setattr rpc. */ static int -nfs_setattrrpc(vp, vap, cred, td) - register struct vnode *vp; - register struct vattr *vap; - struct ucred *cred; - struct thread *td; +nfs_setattrrpc(struct vnode *vp, struct vattr *vap, struct ucred *cred, + struct thread *td) { - register struct nfsv2_sattr *sp; - register caddr_t cp; - register int32_t t1, t2; - caddr_t bpos, dpos, cp2; + struct nfsv2_sattr *sp; + caddr_t bpos, dpos; u_int32_t *tl; int error = 0, wccflag = NFSV3_WCCRATTR; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct mbuf *mreq, *mrep, *md, *mb; int v3 = NFS_ISV3(vp); nfsstats.rpccnt[NFSPROC_SETATTR]++; - nfsm_reqhead(vp, NFSPROC_SETATTR, NFSX_FH(v3) + NFSX_SATTR(v3)); + mreq = nfsm_reqhead(vp, NFSPROC_SETATTR, NFSX_FH(v3) + NFSX_SATTR(v3)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(vp, v3); if (v3) { nfsm_v3attrbuild(vap, TRUE); @@ -783,7 +719,8 @@ nfs_setattrrpc(vp, vap, cred, td) nfsm_wcc_data(vp, wccflag); } else nfsm_loadattr(vp, (struct vattr *)0); - nfsm_reqdone; + m_freem(mrep); +nfsmout: return (error); } @@ -793,13 +730,7 @@ nfs_setattrrpc(vp, vap, cred, td) * If not found, unlock the directory nfsnode and do the rpc */ static int -nfs_lookup(ap) - struct vop_lookup_args /* { - struct vnodeop_desc *a_desc; - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - } */ *ap; +nfs_lookup(struct vop_lookup_args *ap) { struct componentname *cnp = ap->a_cnp; struct vnode *dvp = ap->a_dvp; @@ -807,11 +738,9 @@ nfs_lookup(ap) int flags = cnp->cn_flags; struct vnode *newvp; u_int32_t *tl; - caddr_t cp; - int32_t t1, t2; struct nfsmount *nmp; - caddr_t bpos, dpos, cp2; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + caddr_t bpos, dpos; + struct mbuf *mreq, *mrep, *md, *mb; long len; nfsfh_t *fhp; struct nfsnode *np; @@ -893,8 +822,10 @@ nfs_lookup(ap) nfsstats.lookupcache_misses++; nfsstats.rpccnt[NFSPROC_LOOKUP]++; len = cnp->cn_namelen; - nfsm_reqhead(dvp, NFSPROC_LOOKUP, + mreq = nfsm_reqhead(dvp, NFSPROC_LOOKUP, NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(dvp, v3); nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); nfsm_request(dvp, NFSPROC_LOOKUP, cnp->cn_thread, cnp->cn_cred); @@ -979,7 +910,8 @@ nfs_lookup(ap) cache_enter(dvp, newvp, cnp); } *vpp = newvp; - nfsm_reqdone; + m_freem(mrep); +nfsmout: if (error) { if (newvp != NULLVP) { vrele(newvp); @@ -1007,15 +939,9 @@ nfs_lookup(ap) * Just call nfs_bioread() to do the work. */ static int -nfs_read(ap) - struct vop_read_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap; +nfs_read(struct vop_read_args *ap) { - register struct vnode *vp = ap->a_vp; + struct vnode *vp = ap->a_vp; if (vp->v_type != VREG) return (EPERM); @@ -1026,14 +952,9 @@ nfs_read(ap) * nfs readlink call */ static int -nfs_readlink(ap) - struct vop_readlink_args /* { - struct vnode *a_vp; - struct uio *a_uio; - struct ucred *a_cred; - } */ *ap; +nfs_readlink(struct vop_readlink_args *ap) { - register struct vnode *vp = ap->a_vp; + struct vnode *vp = ap->a_vp; if (vp->v_type != VLNK) return (EINVAL); @@ -1045,21 +966,18 @@ nfs_readlink(ap) * Called by nfs_doio() from below the buffer cache. */ int -nfs_readlinkrpc(vp, uiop, cred) - register struct vnode *vp; - struct uio *uiop; - struct ucred *cred; +nfs_readlinkrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) { - register u_int32_t *tl; - register caddr_t cp; - register int32_t t1, t2; - caddr_t bpos, dpos, cp2; + u_int32_t *tl; + caddr_t bpos, dpos; int error = 0, len, attrflag; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct mbuf *mreq, *mrep, *md, *mb; int v3 = NFS_ISV3(vp); nfsstats.rpccnt[NFSPROC_READLINK]++; - nfsm_reqhead(vp, NFSPROC_READLINK, NFSX_FH(v3)); + mreq = nfsm_reqhead(vp, NFSPROC_READLINK, NFSX_FH(v3)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(vp, v3); nfsm_request(vp, NFSPROC_READLINK, uiop->uio_td, cred); if (v3) @@ -1073,7 +991,8 @@ nfs_readlinkrpc(vp, uiop, cred) } nfsm_mtouio(uiop, len); } - nfsm_reqdone; + m_freem(mrep); +nfsmout: return (error); } @@ -1082,16 +1001,11 @@ nfs_readlinkrpc(vp, uiop, cred) * Ditto above */ int -nfs_readrpc(vp, uiop, cred) - register struct vnode *vp; - struct uio *uiop; - struct ucred *cred; +nfs_readrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) { - register u_int32_t *tl; - register caddr_t cp; - register int32_t t1, t2; - caddr_t bpos, dpos, cp2; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + u_int32_t *tl; + caddr_t bpos, dpos; + struct mbuf *mreq, *mrep, *md, *mb; struct nfsmount *nmp; int error = 0, len, retlen, tsiz, eof, attrflag; int v3 = NFS_ISV3(vp); @@ -1106,7 +1020,9 @@ nfs_readrpc(vp, uiop, cred) while (tsiz > 0) { nfsstats.rpccnt[NFSPROC_READ]++; len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz; - nfsm_reqhead(vp, NFSPROC_READ, NFSX_FH(v3) + NFSX_UNSIGNED * 3); + mreq = nfsm_reqhead(vp, NFSPROC_READ, NFSX_FH(v3) + NFSX_UNSIGNED * 3); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(vp, v3); nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED * 3); if (v3) { @@ -1146,17 +1062,13 @@ nfsmout: * nfs write call */ int -nfs_writerpc(vp, uiop, cred, iomode, must_commit) - register struct vnode *vp; - register struct uio *uiop; - struct ucred *cred; - int *iomode, *must_commit; +nfs_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, + int *iomode, int *must_commit) { - register u_int32_t *tl; - register caddr_t cp; - register int32_t t1, t2, backup; - caddr_t bpos, dpos, cp2; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + u_int32_t *tl; + int32_t backup; + caddr_t bpos, dpos; + struct mbuf *mreq, *mrep, *md, *mb; struct nfsmount *nmp = VFSTONFS(vp->v_mount); int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR, rlen, commit; int v3 = NFS_ISV3(vp), committed = NFSV3WRITE_FILESYNC; @@ -1172,8 +1084,10 @@ nfs_writerpc(vp, uiop, cred, iomode, must_commit) while (tsiz > 0) { nfsstats.rpccnt[NFSPROC_WRITE]++; len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz; - nfsm_reqhead(vp, NFSPROC_WRITE, + mreq = nfsm_reqhead(vp, NFSPROC_WRITE, NFSX_FH(v3) + 5 * NFSX_UNSIGNED + nfsm_rndup(len)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(vp, v3); if (v3) { nfsm_build(tl, u_int32_t *, 5 * NFSX_UNSIGNED); @@ -1183,7 +1097,7 @@ nfs_writerpc(vp, uiop, cred, iomode, must_commit) *tl++ = txdr_unsigned(*iomode); *tl = txdr_unsigned(len); } else { - register u_int32_t x; + u_int32_t x; nfsm_build(tl, u_int32_t *, 4 * NFSX_UNSIGNED); /* Set both "begin" and "current" to non-garbage. */ @@ -1261,23 +1175,17 @@ nfsmout: * mode set to specify the file type and the size field for rdev. */ static int -nfs_mknodrpc(dvp, vpp, cnp, vap) - register struct vnode *dvp; - register struct vnode **vpp; - register struct componentname *cnp; - register struct vattr *vap; +nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, + struct vattr *vap) { - register struct nfsv2_sattr *sp; - register u_int32_t *tl; - register caddr_t cp; - register int32_t t1, t2; + struct nfsv2_sattr *sp; + u_int32_t *tl; struct vnode *newvp = (struct vnode *)0; struct nfsnode *np = (struct nfsnode *)0; struct vattr vattr; - char *cp2; caddr_t bpos, dpos; int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct mbuf *mreq, *mrep, *md, *mb; u_int32_t rdev; int v3 = NFS_ISV3(dvp); @@ -1292,8 +1200,10 @@ nfs_mknodrpc(dvp, vpp, cnp, vap) return (error); } nfsstats.rpccnt[NFSPROC_MKNOD]++; - nfsm_reqhead(dvp, NFSPROC_MKNOD, NFSX_FH(v3) + 4 * NFSX_UNSIGNED + + mreq = nfsm_reqhead(dvp, NFSPROC_MKNOD, NFSX_FH(v3) + 4 * NFSX_UNSIGNED + + nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(dvp, v3); nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); if (v3) { @@ -1330,7 +1240,8 @@ nfs_mknodrpc(dvp, vpp, cnp, vap) } if (v3) nfsm_wcc_data(dvp, wccflag); - nfsm_reqdone; + m_freem(mrep); +nfsmout: if (error) { if (newvp) vput(newvp); @@ -1351,14 +1262,9 @@ nfs_mknodrpc(dvp, vpp, cnp, vap) */ /* ARGSUSED */ static int -nfs_mknod(ap) - struct vop_mknod_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - struct vattr *a_vap; - } */ *ap; +nfs_mknod(struct vop_mknod_args *ap) { + return nfs_mknodrpc(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap); } @@ -1367,26 +1273,18 @@ static u_long create_verf; * nfs file create call */ static int -nfs_create(ap) - struct vop_create_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - struct vattr *a_vap; - } */ *ap; +nfs_create(struct vop_create_args *ap) { - register struct vnode *dvp = ap->a_dvp; - register struct vattr *vap = ap->a_vap; - register struct componentname *cnp = ap->a_cnp; - register struct nfsv2_sattr *sp; - register u_int32_t *tl; - register caddr_t cp; - register int32_t t1, t2; + struct vnode *dvp = ap->a_dvp; + struct vattr *vap = ap->a_vap; + struct componentname *cnp = ap->a_cnp; + struct nfsv2_sattr *sp; + u_int32_t *tl; struct nfsnode *np = (struct nfsnode *)0; struct vnode *newvp = (struct vnode *)0; - caddr_t bpos, dpos, cp2; + caddr_t bpos, dpos; int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0, fmode = 0; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct mbuf *mreq, *mrep, *md, *mb; struct vattr vattr; int v3 = NFS_ISV3(dvp); @@ -1403,8 +1301,10 @@ nfs_create(ap) fmode |= O_EXCL; again: nfsstats.rpccnt[NFSPROC_CREATE]++; - nfsm_reqhead(dvp, NFSPROC_CREATE, NFSX_FH(v3) + 2 * NFSX_UNSIGNED + + mreq = nfsm_reqhead(dvp, NFSPROC_CREATE, NFSX_FH(v3) + 2 * NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(dvp, v3); nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); if (v3) { @@ -1414,7 +1314,7 @@ again: nfsm_build(tl, u_int32_t *, NFSX_V3CREATEVERF); #ifdef INET if (!TAILQ_EMPTY(&in_ifaddrhead)) - *tl++ = IA_SIN(in_ifaddrhead.tqh_first)->sin_addr.s_addr; + *tl++ = IA_SIN(TAILQ_FIRST(&in_ifaddrhead))->sin_addr.s_addr; else #endif *tl++ = create_verf; @@ -1448,7 +1348,8 @@ again: } if (v3) nfsm_wcc_data(dvp, wccflag); - nfsm_reqdone; + m_freem(mrep); +nfsmout: if (error) { if (v3 && (fmode & O_EXCL) && error == NFSERR_NOTSUPP) { fmode &= ~O_EXCL; @@ -1494,18 +1395,12 @@ again: * do the remove rpc */ static int -nfs_remove(ap) - struct vop_remove_args /* { - struct vnodeop_desc *a_desc; - struct vnode * a_dvp; - struct vnode * a_vp; - struct componentname * a_cnp; - } */ *ap; +nfs_remove(struct vop_remove_args *ap) { - register struct vnode *vp = ap->a_vp; - register struct vnode *dvp = ap->a_dvp; - register struct componentname *cnp = ap->a_cnp; - register struct nfsnode *np = VTONFS(vp); + struct vnode *vp = ap->a_vp; + struct vnode *dvp = ap->a_dvp; + struct componentname *cnp = ap->a_cnp; + struct nfsnode *np = VTONFS(vp); int error = 0; struct vattr vattr; @@ -1555,8 +1450,7 @@ nfs_remove(ap) * nfs file remove rpc called from nfs_inactive */ int -nfs_removeit(sp) - register struct sillyrename *sp; +nfs_removeit(struct sillyrename *sp) { return (nfs_removerpc(sp->s_dvp, sp->s_name, sp->s_namlen, sp->s_cred, @@ -1567,30 +1461,27 @@ nfs_removeit(sp) * Nfs remove rpc, called from nfs_remove() and nfs_removeit(). */ static int -nfs_removerpc(dvp, name, namelen, cred, td) - register struct vnode *dvp; - const char *name; - int namelen; - struct ucred *cred; - struct thread *td; +nfs_removerpc(struct vnode *dvp, const char *name, int namelen, + struct ucred *cred, struct thread *td) { - register u_int32_t *tl; - register caddr_t cp; - register int32_t t1, t2; - caddr_t bpos, dpos, cp2; + u_int32_t *tl; + caddr_t bpos, dpos; int error = 0, wccflag = NFSV3_WCCRATTR; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct mbuf *mreq, *mrep, *md, *mb; int v3 = NFS_ISV3(dvp); nfsstats.rpccnt[NFSPROC_REMOVE]++; - nfsm_reqhead(dvp, NFSPROC_REMOVE, + mreq = nfsm_reqhead(dvp, NFSPROC_REMOVE, NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(namelen)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(dvp, v3); nfsm_strtom(name, namelen, NFS_MAXNAMLEN); nfsm_request(dvp, NFSPROC_REMOVE, td, cred); if (v3) nfsm_wcc_data(dvp, wccflag); - nfsm_reqdone; + m_freem(mrep); +nfsmout: VTONFS(dvp)->n_flag |= NMODIFIED; if (!wccflag) VTONFS(dvp)->n_attrstamp = 0; @@ -1601,22 +1492,14 @@ nfs_removerpc(dvp, name, namelen, cred, td) * nfs file rename call */ static int -nfs_rename(ap) - struct vop_rename_args /* { - struct vnode *a_fdvp; - struct vnode *a_fvp; - struct componentname *a_fcnp; - struct vnode *a_tdvp; - struct vnode *a_tvp; - struct componentname *a_tcnp; - } */ *ap; +nfs_rename(struct vop_rename_args *ap) { - register struct vnode *fvp = ap->a_fvp; - register struct vnode *tvp = ap->a_tvp; - register struct vnode *fdvp = ap->a_fdvp; - register struct vnode *tdvp = ap->a_tdvp; - register struct componentname *tcnp = ap->a_tcnp; - register struct componentname *fcnp = ap->a_fcnp; + struct vnode *fvp = ap->a_fvp; + struct vnode *tvp = ap->a_tvp; + struct vnode *fdvp = ap->a_fdvp; + struct vnode *tdvp = ap->a_tdvp; + struct componentname *tcnp = ap->a_tcnp; + struct componentname *fcnp = ap->a_fcnp; int error; #ifndef DIAGNOSTIC @@ -1686,41 +1569,34 @@ out: * nfs file rename rpc called from nfs_remove() above */ static int -nfs_renameit(sdvp, scnp, sp) - struct vnode *sdvp; - struct componentname *scnp; - register struct sillyrename *sp; +nfs_renameit(struct vnode *sdvp, struct componentname *scnp, + struct sillyrename *sp) { - return (nfs_renamerpc(sdvp, scnp->cn_nameptr, scnp->cn_namelen, - sdvp, sp->s_name, sp->s_namlen, scnp->cn_cred, scnp->cn_thread)); + + return (nfs_renamerpc(sdvp, scnp->cn_nameptr, scnp->cn_namelen, sdvp, + sp->s_name, sp->s_namlen, scnp->cn_cred, scnp->cn_thread)); } /* * Do an nfs rename rpc. Called from nfs_rename() and nfs_renameit(). */ static int -nfs_renamerpc(fdvp, fnameptr, fnamelen, tdvp, tnameptr, tnamelen, cred, td) - register struct vnode *fdvp; - const char *fnameptr; - int fnamelen; - register struct vnode *tdvp; - const char *tnameptr; - int tnamelen; - struct ucred *cred; - struct thread *td; +nfs_renamerpc(struct vnode *fdvp, const char *fnameptr, int fnamelen, + struct vnode *tdvp, const char *tnameptr, int tnamelen, struct ucred *cred, + struct thread *td) { - register u_int32_t *tl; - register caddr_t cp; - register int32_t t1, t2; - caddr_t bpos, dpos, cp2; + u_int32_t *tl; + caddr_t bpos, dpos; int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct mbuf *mreq, *mrep, *md, *mb; int v3 = NFS_ISV3(fdvp); nfsstats.rpccnt[NFSPROC_RENAME]++; - nfsm_reqhead(fdvp, NFSPROC_RENAME, + mreq = nfsm_reqhead(fdvp, NFSPROC_RENAME, (NFSX_FH(v3) + NFSX_UNSIGNED)*2 + nfsm_rndup(fnamelen) + nfsm_rndup(tnamelen)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(fdvp, v3); nfsm_strtom(fnameptr, fnamelen, NFS_MAXNAMLEN); nfsm_fhtom(tdvp, v3); @@ -1730,7 +1606,8 @@ nfs_renamerpc(fdvp, fnameptr, fnamelen, tdvp, tnameptr, tnamelen, cred, td) nfsm_wcc_data(fdvp, fwccflag); nfsm_wcc_data(tdvp, twccflag); } - nfsm_reqdone; + m_freem(mrep); +nfsmout: VTONFS(fdvp)->n_flag |= NMODIFIED; VTONFS(tdvp)->n_flag |= NMODIFIED; if (!fwccflag) @@ -1744,22 +1621,15 @@ nfs_renamerpc(fdvp, fnameptr, fnamelen, tdvp, tnameptr, tnamelen, cred, td) * nfs hard link create call */ static int -nfs_link(ap) - struct vop_link_args /* { - struct vnode *a_tdvp; - struct vnode *a_vp; - struct componentname *a_cnp; - } */ *ap; +nfs_link(struct vop_link_args *ap) { - register struct vnode *vp = ap->a_vp; - register struct vnode *tdvp = ap->a_tdvp; - register struct componentname *cnp = ap->a_cnp; - register u_int32_t *tl; - register caddr_t cp; - register int32_t t1, t2; - caddr_t bpos, dpos, cp2; + struct vnode *vp = ap->a_vp; + struct vnode *tdvp = ap->a_tdvp; + struct componentname *cnp = ap->a_cnp; + u_int32_t *tl; + caddr_t bpos, dpos; int error = 0, wccflag = NFSV3_WCCRATTR, attrflag = 0; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct mbuf *mreq, *mrep, *md, *mb; int v3; if (vp->v_mount != tdvp->v_mount) { @@ -1775,8 +1645,10 @@ nfs_link(ap) v3 = NFS_ISV3(vp); nfsstats.rpccnt[NFSPROC_LINK]++; - nfsm_reqhead(vp, NFSPROC_LINK, + mreq = nfsm_reqhead(vp, NFSPROC_LINK, NFSX_FH(v3)*2 + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(vp, v3); nfsm_fhtom(tdvp, v3); nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); @@ -1785,7 +1657,8 @@ nfs_link(ap) nfsm_postop_attr(vp, attrflag); nfsm_wcc_data(tdvp, wccflag); } - nfsm_reqdone; + m_freem(mrep); +nfsmout: VTONFS(tdvp)->n_flag |= NMODIFIED; if (!attrflag) VTONFS(vp)->n_attrstamp = 0; @@ -1803,32 +1676,25 @@ nfs_link(ap) * nfs symbolic link create call */ static int -nfs_symlink(ap) - struct vop_symlink_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - struct vattr *a_vap; - char *a_target; - } */ *ap; +nfs_symlink(struct vop_symlink_args *ap) { - register struct vnode *dvp = ap->a_dvp; - register struct vattr *vap = ap->a_vap; - register struct componentname *cnp = ap->a_cnp; - register struct nfsv2_sattr *sp; - register u_int32_t *tl; - register caddr_t cp; - register int32_t t1, t2; - caddr_t bpos, dpos, cp2; + struct vnode *dvp = ap->a_dvp; + struct vattr *vap = ap->a_vap; + struct componentname *cnp = ap->a_cnp; + struct nfsv2_sattr *sp; + u_int32_t *tl; + caddr_t bpos, dpos; int slen, error = 0, wccflag = NFSV3_WCCRATTR, gotvp; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct mbuf *mreq, *mrep, *md, *mb; struct vnode *newvp = (struct vnode *)0; int v3 = NFS_ISV3(dvp); nfsstats.rpccnt[NFSPROC_SYMLINK]++; slen = strlen(ap->a_target); - nfsm_reqhead(dvp, NFSPROC_SYMLINK, NFSX_FH(v3) + 2*NFSX_UNSIGNED + + mreq = nfsm_reqhead(dvp, NFSPROC_SYMLINK, NFSX_FH(v3) + 2*NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen) + nfsm_rndup(slen) + NFSX_SATTR(v3)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(dvp, v3); nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); if (v3) { @@ -1863,7 +1729,8 @@ nfs_symlink(ap) * out code jumps -> here, mrep is also freed. */ - nfsm_reqdone; + m_freem(mrep); +nfsmout: /* * If we get an EEXIST error, silently convert it to no-error @@ -1876,7 +1743,7 @@ nfs_symlink(ap) * If we do not have (or no longer have) an error, and we could * not extract the newvp from the response due to the request being * NFSv2 or the error being EEXIST. We have to do a lookup in order - * to obtain a newvp to return. + * to obtain a newvp to return. */ if (error == 0 && newvp == NULL) { struct nfsnode *np = NULL; @@ -1902,28 +1769,20 @@ nfs_symlink(ap) * nfs make dir call */ static int -nfs_mkdir(ap) - struct vop_mkdir_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - struct vattr *a_vap; - } */ *ap; +nfs_mkdir(struct vop_mkdir_args *ap) { - register struct vnode *dvp = ap->a_dvp; - register struct vattr *vap = ap->a_vap; - register struct componentname *cnp = ap->a_cnp; - register struct nfsv2_sattr *sp; - register u_int32_t *tl; - register caddr_t cp; - register int32_t t1, t2; - register int len; + struct vnode *dvp = ap->a_dvp; + struct vattr *vap = ap->a_vap; + struct componentname *cnp = ap->a_cnp; + struct nfsv2_sattr *sp; + u_int32_t *tl; + int len; struct nfsnode *np = (struct nfsnode *)0; struct vnode *newvp = (struct vnode *)0; - caddr_t bpos, dpos, cp2; + caddr_t bpos, dpos; int error = 0, wccflag = NFSV3_WCCRATTR; int gotvp = 0; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct mbuf *mreq, *mrep, *md, *mb; struct vattr vattr; int v3 = NFS_ISV3(dvp); @@ -1932,8 +1791,10 @@ nfs_mkdir(ap) } len = cnp->cn_namelen; nfsstats.rpccnt[NFSPROC_MKDIR]++; - nfsm_reqhead(dvp, NFSPROC_MKDIR, + mreq = nfsm_reqhead(dvp, NFSPROC_MKDIR, NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len) + NFSX_SATTR(v3)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(dvp, v3); nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); if (v3) { @@ -1952,7 +1813,8 @@ nfs_mkdir(ap) nfsm_mtofh(dvp, newvp, v3, gotvp); if (v3) nfsm_wcc_data(dvp, wccflag); - nfsm_reqdone; + m_freem(mrep); +nfsmout: VTONFS(dvp)->n_flag |= NMODIFIED; if (!wccflag) VTONFS(dvp)->n_attrstamp = 0; @@ -1985,35 +1847,31 @@ nfs_mkdir(ap) * nfs remove directory call */ static int -nfs_rmdir(ap) - struct vop_rmdir_args /* { - struct vnode *a_dvp; - struct vnode *a_vp; - struct componentname *a_cnp; - } */ *ap; +nfs_rmdir(struct vop_rmdir_args *ap) { - register struct vnode *vp = ap->a_vp; - register struct vnode *dvp = ap->a_dvp; - register struct componentname *cnp = ap->a_cnp; - register u_int32_t *tl; - register caddr_t cp; - register int32_t t1, t2; - caddr_t bpos, dpos, cp2; + struct vnode *vp = ap->a_vp; + struct vnode *dvp = ap->a_dvp; + struct componentname *cnp = ap->a_cnp; + u_int32_t *tl; + caddr_t bpos, dpos; int error = 0, wccflag = NFSV3_WCCRATTR; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct mbuf *mreq, *mrep, *md, *mb; int v3 = NFS_ISV3(dvp); if (dvp == vp) return (EINVAL); nfsstats.rpccnt[NFSPROC_RMDIR]++; - nfsm_reqhead(dvp, NFSPROC_RMDIR, + mreq = nfsm_reqhead(dvp, NFSPROC_RMDIR, NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(dvp, v3); nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); nfsm_request(dvp, NFSPROC_RMDIR, cnp->cn_thread, cnp->cn_cred); if (v3) nfsm_wcc_data(dvp, wccflag); - nfsm_reqdone; + m_freem(mrep); +nfsmout: VTONFS(dvp)->n_flag |= NMODIFIED; if (!wccflag) VTONFS(dvp)->n_attrstamp = 0; @@ -2031,16 +1889,11 @@ nfs_rmdir(ap) * nfs readdir call */ static int -nfs_readdir(ap) - struct vop_readdir_args /* { - struct vnode *a_vp; - struct uio *a_uio; - struct ucred *a_cred; - } */ *ap; +nfs_readdir(struct vop_readdir_args *ap) { - register struct vnode *vp = ap->a_vp; - register struct nfsnode *np = VTONFS(vp); - register struct uio *uio = ap->a_uio; + struct vnode *vp = ap->a_vp; + struct nfsnode *np = VTONFS(vp); + struct uio *uio = ap->a_uio; int tresid, error; struct vattr vattr; @@ -2051,12 +1904,7 @@ nfs_readdir(ap) */ if (np->n_direofoffset > 0 && uio->uio_offset >= np->n_direofoffset && (np->n_flag & NMODIFIED) == 0) { - if (VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NQNFS) { - if (NQNFS_CKCACHABLE(vp, ND_READ)) { - nfsstats.direofcache_hits++; - return (0); - } - } else if (VOP_GETATTR(vp, &vattr, ap->a_cred, uio->uio_td) == 0 && + if (VOP_GETATTR(vp, &vattr, ap->a_cred, uio->uio_td) == 0 && np->n_mtime == vattr.va_mtime.tv_sec) { nfsstats.direofcache_hits++; return (0); @@ -2079,20 +1927,15 @@ nfs_readdir(ap) * Called from below the buffer cache by nfs_doio(). */ int -nfs_readdirrpc(vp, uiop, cred) - struct vnode *vp; - register struct uio *uiop; - struct ucred *cred; - +nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) { - register int len, left; - register struct dirent *dp = NULL; - register u_int32_t *tl; - register caddr_t cp; - register int32_t t1, t2; - register nfsuint64 *cookiep; - caddr_t bpos, dpos, cp2; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + int len, left; + struct dirent *dp = NULL; + u_int32_t *tl; + caddr_t cp; + nfsuint64 *cookiep; + caddr_t bpos, dpos; + struct mbuf *mreq, *mrep, *md, *mb; nfsuint64 cookie; struct nfsmount *nmp = VFSTONFS(vp->v_mount); struct nfsnode *dnp = VTONFS(vp); @@ -2122,8 +1965,10 @@ nfs_readdirrpc(vp, uiop, cred) */ while (more_dirs && bigenough) { nfsstats.rpccnt[NFSPROC_READDIR]++; - nfsm_reqhead(vp, NFSPROC_READDIR, NFSX_FH(v3) + + mreq = nfsm_reqhead(vp, NFSPROC_READDIR, NFSX_FH(v3) + NFSX_READDIR(v3)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(vp, v3); if (v3) { nfsm_build(tl, u_int32_t *, 5 * NFSX_UNSIGNED); @@ -2151,7 +1996,7 @@ nfs_readdirrpc(vp, uiop, cred) } nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); more_dirs = fxdr_unsigned(int, *tl); - + /* loop thru the dir entries, doctoring them to 4bsd form */ while (more_dirs && bigenough) { if (v3) { @@ -2266,20 +2111,16 @@ nfsmout: * NFS V3 readdir plus RPC. Used in place of nfs_readdirrpc(). */ int -nfs_readdirplusrpc(vp, uiop, cred) - struct vnode *vp; - register struct uio *uiop; - struct ucred *cred; +nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) { - register int len, left; - register struct dirent *dp; - register u_int32_t *tl; - register caddr_t cp; - register int32_t t1, t2; - register struct vnode *newvp; - register nfsuint64 *cookiep; - caddr_t bpos, dpos, cp2, dpossav1, dpossav2; - struct mbuf *mreq, *mrep, *md, *mb, *mb2, *mdsav1, *mdsav2; + int len, left; + struct dirent *dp; + u_int32_t *tl; + caddr_t cp; + struct vnode *newvp; + nfsuint64 *cookiep; + caddr_t bpos, dpos, dpossav1, dpossav2; + struct mbuf *mreq, *mrep, *md, *mb, *mdsav1, *mdsav2; struct nameidata nami, *ndp = &nami; struct componentname *cnp = &ndp->ni_cnd; nfsuint64 cookie; @@ -2316,8 +2157,10 @@ nfs_readdirplusrpc(vp, uiop, cred) */ while (more_dirs && bigenough) { nfsstats.rpccnt[NFSPROC_READDIRPLUS]++; - nfsm_reqhead(vp, NFSPROC_READDIRPLUS, + mreq = nfsm_reqhead(vp, NFSPROC_READDIRPLUS, NFSX_FH(1) + 6 * NFSX_UNSIGNED); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(vp, 1); nfsm_build(tl, u_int32_t *, 6 * NFSX_UNSIGNED); *tl++ = cookie.nfsuquad[0]; @@ -2503,11 +2346,9 @@ nfsmout: * nfs_rename() completes, but... */ static int -nfs_sillyrename(dvp, vp, cnp) - struct vnode *dvp, *vp; - struct componentname *cnp; +nfs_sillyrename(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) { - register struct sillyrename *sp; + struct sillyrename *sp; struct nfsnode *np; int error; short pid; @@ -2560,28 +2401,23 @@ bad: * *npp != NULL --> update the file handle in the vnode */ static int -nfs_lookitup(dvp, name, len, cred, td, npp) - register struct vnode *dvp; - const char *name; - int len; - struct ucred *cred; - struct thread *td; - struct nfsnode **npp; +nfs_lookitup(struct vnode *dvp, const char *name, int len, struct ucred *cred, + struct thread *td, struct nfsnode **npp) { - register u_int32_t *tl; - register caddr_t cp; - register int32_t t1, t2; + u_int32_t *tl; struct vnode *newvp = (struct vnode *)0; struct nfsnode *np, *dnp = VTONFS(dvp); - caddr_t bpos, dpos, cp2; + caddr_t bpos, dpos; int error = 0, fhlen, attrflag; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct mbuf *mreq, *mrep, *md, *mb; nfsfh_t *nfhp; int v3 = NFS_ISV3(dvp); nfsstats.rpccnt[NFSPROC_LOOKUP]++; - nfsm_reqhead(dvp, NFSPROC_LOOKUP, + mreq = nfsm_reqhead(dvp, NFSPROC_LOOKUP, NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(dvp, v3); nfsm_strtom(name, len, NFS_MAXNAMLEN); nfsm_request(dvp, NFSPROC_LOOKUP, td, cred); @@ -2593,7 +2429,7 @@ nfs_lookitup(dvp, name, len, cred, td, npp) free((caddr_t)np->n_fhp, M_NFSBIGFH); np->n_fhp = &np->n_fh; } else if (np->n_fhsize <= NFS_SMALLFH && fhlen>NFS_SMALLFH) - np->n_fhp =(nfsfh_t *)malloc(fhlen,M_NFSBIGFH,M_WAITOK); + np->n_fhp =(nfsfh_t *)malloc(fhlen, M_NFSBIGFH, M_WAITOK); bcopy((caddr_t)nfhp, (caddr_t)np->n_fhp, fhlen); np->n_fhsize = fhlen; newvp = NFSTOV(np); @@ -2621,7 +2457,8 @@ nfs_lookitup(dvp, name, len, cred, td, npp) } else nfsm_loadattr(newvp, (struct vattr *)0); } - nfsm_reqdone; + m_freem(mrep); +nfsmout: if (npp && *npp == NULL) { if (error) { if (newvp) { @@ -2640,25 +2477,21 @@ nfs_lookitup(dvp, name, len, cred, td, npp) * Nfs Version 3 commit rpc */ int -nfs_commit(vp, offset, cnt, cred, td) - struct vnode *vp; - u_quad_t offset; - int cnt; - struct ucred *cred; - struct thread *td; +nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct ucred *cred, + struct thread *td) { - register caddr_t cp; - register u_int32_t *tl; - register int32_t t1, t2; - register struct nfsmount *nmp = VFSTONFS(vp->v_mount); - caddr_t bpos, dpos, cp2; + u_int32_t *tl; + struct nfsmount *nmp = VFSTONFS(vp->v_mount); + caddr_t bpos, dpos; int error = 0, wccflag = NFSV3_WCCRATTR; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; - + struct mbuf *mreq, *mrep, *md, *mb; + if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0) return (0); nfsstats.rpccnt[NFSPROC_COMMIT]++; - nfsm_reqhead(vp, NFSPROC_COMMIT, NFSX_FH(1)); + mreq = nfsm_reqhead(vp, NFSPROC_COMMIT, NFSX_FH(1)); + mb = mreq; + bpos = mtod(mb, caddr_t); nfsm_fhtom(vp, 1); nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); txdr_hyper(offset, tl); @@ -2675,7 +2508,8 @@ nfs_commit(vp, offset, cnt, cred, td) error = NFSERR_STALEWRITEVERF; } } - nfsm_reqdone; + m_freem(mrep); +nfsmout: return (error); } @@ -2686,10 +2520,9 @@ nfs_commit(vp, offset, cnt, cred, td) * request. */ static int -nfs_strategy(ap) - struct vop_strategy_args *ap; +nfs_strategy(struct vop_strategy_args *ap) { - register struct buf *bp = ap->a_bp; + struct buf *bp = ap->a_bp; struct ucred *cr; struct thread *td; int error = 0; @@ -2726,14 +2559,7 @@ nfs_strategy(ap) */ /* ARGSUSED */ static int -nfs_fsync(ap) - struct vop_fsync_args /* { - struct vnodeop_desc *a_desc; - struct vnode * a_vp; - struct ucred * a_cred; - int a_waitfor; - struct thread * a_td; - } */ *ap; +nfs_fsync(struct vop_fsync_args *ap) { return (nfs_flush(ap->a_vp, ap->a_cred, ap->a_waitfor, ap->a_td, 1)); @@ -2745,16 +2571,12 @@ nfs_fsync(ap) * associated with the vnode. */ static int -nfs_flush(vp, cred, waitfor, td, commit) - register struct vnode *vp; - struct ucred *cred; - int waitfor; - struct thread *td; - int commit; +nfs_flush(struct vnode *vp, struct ucred *cred, int waitfor, struct thread *td, + int commit) { - register struct nfsnode *np = VTONFS(vp); - register struct buf *bp; - register int i; + struct nfsnode *np = VTONFS(vp); + struct buf *bp; + int i; struct buf *nbp; struct nfsmount *nmp = VFSTONFS(vp->v_mount); int s, error = 0, slptimeo = 0, slpflag = 0, retv, bvecpos; @@ -2831,7 +2653,7 @@ again: * so we can deal with them all with one commit. * * NOTE: we are not clearing B_DONE here, so we have - * to do it later on in this routine if we intend to + * to do it later on in this routine if we intend to * initiate I/O on the bp. * * Note: to avoid loopback deadlocks, we do not @@ -2915,7 +2737,7 @@ again: /* * Success, remove B_DELWRI ( bundirty() ). * - * b_dirtyoff/b_dirtyend seem to be NFS + * b_dirtyoff/b_dirtyend seem to be NFS * specific. We should probably move that * into bundirty(). XXX */ @@ -3013,14 +2835,7 @@ done: * NFS advisory byte-level locks. */ static int -nfs_advlock(ap) - struct vop_advlock_args /* { - struct vnode *a_vp; - caddr_t a_id; - int a_op; - struct flock *a_fl; - int a_flags; - } */ *ap; +nfs_advlock(struct vop_advlock_args *ap) { return (nfs_dolock(ap)); @@ -3030,13 +2845,10 @@ nfs_advlock(ap) * Print out the contents of an nfsnode. */ static int -nfs_print(ap) - struct vop_print_args /* { - struct vnode *a_vp; - } */ *ap; +nfs_print(struct vop_print_args *ap) { - register struct vnode *vp = ap->a_vp; - register struct nfsnode *np = VTONFS(vp); + struct vnode *vp = ap->a_vp; + struct nfsnode *np = VTONFS(vp); printf("tag VT_NFS, fileid %ld fsid 0x%x", np->n_vattr.va_fileid, np->n_vattr.va_fsid); @@ -3048,15 +2860,12 @@ nfs_print(ap) /* * This is the "real" nfs::bwrite(struct buf*). - * B_WRITEINPROG isn't set unless the force flag is one and it + * B_WRITEINPROG isn't set unless the force flag is one and it * handles the B_NEEDCOMMIT flag. * We set B_CACHE if this is a VMIO buffer. */ int -nfs_writebp(bp, force, td) - register struct buf *bp; - int force; - struct thread *td; +nfs_writebp(struct buf *bp, int force, struct thread *td) { int s; int oldflags = bp->b_flags; @@ -3111,7 +2920,7 @@ nfs_writebp(bp, force, td) brelse(bp); return (rtval); - } + } return (0); } @@ -3122,21 +2931,15 @@ nfs_writebp(bp, force, td) * local to the client. */ static int -nfsspec_access(ap) - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap; +nfsspec_access(struct vop_access_args *ap) { - register struct vattr *vap; - register gid_t *gp; - register struct ucred *cred = ap->a_cred; + struct vattr *vap; + gid_t *gp; + struct ucred *cred = ap->a_cred; struct vnode *vp = ap->a_vp; mode_t mode = ap->a_mode; struct vattr vattr; - register int i; + int i; int error; /* @@ -3187,15 +2990,9 @@ found: * Read wrapper for special devices. */ static int -nfsspec_read(ap) - struct vop_read_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap; +nfsspec_read(struct vop_read_args *ap) { - register struct nfsnode *np = VTONFS(ap->a_vp); + struct nfsnode *np = VTONFS(ap->a_vp); /* * Set access flag. @@ -3209,15 +3006,9 @@ nfsspec_read(ap) * Write wrapper for special devices. */ static int -nfsspec_write(ap) - struct vop_write_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap; +nfsspec_write(struct vop_write_args *ap) { - register struct nfsnode *np = VTONFS(ap->a_vp); + struct nfsnode *np = VTONFS(ap->a_vp); /* * Set update flag. @@ -3233,16 +3024,10 @@ nfsspec_write(ap) * Update the times on the nfsnode then do device close. */ static int -nfsspec_close(ap) - struct vop_close_args /* { - struct vnode *a_vp; - int a_fflag; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap; +nfsspec_close(struct vop_close_args *ap) { - register struct vnode *vp = ap->a_vp; - register struct nfsnode *np = VTONFS(vp); + struct vnode *vp = ap->a_vp; + struct nfsnode *np = VTONFS(vp); struct vattr vattr; if (np->n_flag & (NACC | NUPD)) { @@ -3264,15 +3049,9 @@ nfsspec_close(ap) * Read wrapper for fifos. */ static int -nfsfifo_read(ap) - struct vop_read_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap; +nfsfifo_read(struct vop_read_args *ap) { - register struct nfsnode *np = VTONFS(ap->a_vp); + struct nfsnode *np = VTONFS(ap->a_vp); /* * Set access flag. @@ -3286,15 +3065,9 @@ nfsfifo_read(ap) * Write wrapper for fifos. */ static int -nfsfifo_write(ap) - struct vop_write_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap; +nfsfifo_write(struct vop_write_args *ap) { - register struct nfsnode *np = VTONFS(ap->a_vp); + struct nfsnode *np = VTONFS(ap->a_vp); /* * Set update flag. @@ -3310,16 +3083,10 @@ nfsfifo_write(ap) * Update the times on the nfsnode then do fifo close. */ static int -nfsfifo_close(ap) - struct vop_close_args /* { - struct vnode *a_vp; - int a_fflag; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap; +nfsfifo_close(struct vop_close_args *ap) { - register struct vnode *vp = ap->a_vp; - register struct nfsnode *np = VTONFS(vp); + struct vnode *vp = ap->a_vp; + struct nfsnode *np = VTONFS(vp); struct vattr vattr; struct timespec ts; diff --git a/sys/nfsclient/nfsargs.h b/sys/nfsclient/nfsargs.h index da808f4..d53e4e0 100644 --- a/sys/nfsclient/nfsargs.h +++ b/sys/nfsclient/nfsargs.h @@ -37,81 +37,8 @@ * $FreeBSD$ */ -#ifndef _NFS_NFS_H_ -#define _NFS_NFS_H_ - -#ifdef _KERNEL -#include "opt_nfs.h" -#endif - -/* - * Tunable constants for nfs - */ - -#define NFS_MAXIOVEC 34 -#define NFS_TICKINTVL 5 /* Desired time for a tick (msec) */ -#define NFS_HZ (hz / nfs_ticks) /* Ticks/sec */ -#define NFS_TIMEO (1 * NFS_HZ) /* Default timeout = 1 second */ -#define NFS_MINTIMEO (1 * NFS_HZ) /* Min timeout to use */ -#define NFS_MAXTIMEO (60 * NFS_HZ) /* Max timeout to backoff to */ -#define NFS_MINIDEMTIMEO (5 * NFS_HZ) /* Min timeout for non-idempotent ops*/ -#define NFS_MAXREXMIT 100 /* Stop counting after this many */ -#define NFS_MAXWINDOW 1024 /* Max number of outstanding requests */ -#define NFS_RETRANS 10 /* Num of retrans for soft mounts */ -#define NFS_MAXGRPS 16 /* Max. size of groups list */ -#ifndef NFS_MINATTRTIMO -#define NFS_MINATTRTIMO 3 /* VREG attrib cache timeout in sec */ -#endif -#ifndef NFS_MAXATTRTIMO -#define NFS_MAXATTRTIMO 60 -#endif -#ifndef NFS_MINDIRATTRTIMO -#define NFS_MINDIRATTRTIMO 30 /* VDIR attrib cache timeout in sec */ -#endif -#ifndef NFS_MAXDIRATTRTIMO -#define NFS_MAXDIRATTRTIMO 60 -#endif -#define NFS_WSIZE 8192 /* Def. write data size <= 8192 */ -#define NFS_RSIZE 8192 /* Def. read data size <= 8192 */ -#define NFS_READDIRSIZE 8192 /* Def. readdir size */ -#define NFS_DEFRAHEAD 1 /* Def. read ahead # blocks */ -#define NFS_MAXRAHEAD 4 /* Max. read ahead # blocks */ -#define NFS_MAXUIDHASH 64 /* Max. # of hashed uid entries/mp */ -#define NFS_MAXASYNCDAEMON 20 /* Max. number async_daemons runnable */ -#define NFS_MAXGATHERDELAY 100 /* Max. write gather delay (msec) */ -#ifndef NFS_GATHERDELAY -#define NFS_GATHERDELAY 10 /* Default write gather delay (msec) */ -#endif -#define NFS_DIRBLKSIZ 4096 /* Must be a multiple of DIRBLKSIZ */ -#ifdef _KERNEL -#define DIRBLKSIZ 512 /* XXX we used to use ufs's DIRBLKSIZ */ -#endif - -/* - * Oddballs - */ -#define NMOD(a) ((a) % nfs_asyncdaemons) -#define NFS_CMPFH(n, f, s) \ - ((n)->n_fhsize == (s) && !bcmp((caddr_t)(n)->n_fhp, (caddr_t)(f), (s))) -#define NFS_ISV3(v) (VFSTONFS((v)->v_mount)->nm_flag & NFSMNT_NFSV3) -#define NFS_SRVMAXDATA(n) \ - (((n)->nd_flag & ND_NFSV3) ? (((n)->nd_nam2) ? \ - NFS_MAXDGRAMDATA : NFS_MAXDATA) : NFS_V2MAXDATA) - -/* - * XXX - * The B_INVAFTERWRITE flag should be set to whatever is required by the - * buffer cache code to say "Invalidate the block after it is written back". - */ -#define B_INVAFTERWRITE B_NOCACHE - -/* - * The IO_METASYNC flag should be implemented for local file systems. - * (Until then, it is nothin at all.) - */ -#ifndef IO_METASYNC -#define IO_METASYNC 0 -#endif +#ifndef _NFSCLIENT_NFSARGS_H_ +#define _NFSCLIENT_NFSARGS_H_ /* * Arguments to mount NFS @@ -133,7 +60,7 @@ struct nfs_args { int retrans; /* times to retry send */ int maxgrouplist; /* Max. size of group list */ int readahead; /* # of blocks to readahead */ - int leaseterm; /* Term (sec) of lease */ + int __pad1; /* was "leaseterm" */ int deadthresh; /* Retrans threshold */ char *hostname; /* server's name */ int acregmin; /* cache attrs for reg files min time */ @@ -153,11 +80,11 @@ struct nfs_args { #define NFSMNT_MAXGRPS 0x00000020 /* set maximum grouplist size */ #define NFSMNT_INT 0x00000040 /* allow interrupts on hard mount */ #define NFSMNT_NOCONN 0x00000080 /* Don't Connect the socket */ -#define NFSMNT_NQNFS 0x00000100 /* Use Nqnfs protocol */ +/* 0x100 free, was NFSMNT_NQNFS */ #define NFSMNT_NFSV3 0x00000200 /* Use NFS Version 3 protocol */ -#define NFSMNT_KERB 0x00000400 /* Use Kerberos authentication */ +/* 0x400 free, was NFSMNT_KERB */ #define NFSMNT_DUMBTIMR 0x00000800 /* Don't estimate rtt dynamically */ -#define NFSMNT_LEASETERM 0x00001000 /* set lease term (nqnfs) */ +/* 0x1000 free, was NFSMNT_LEASETERM */ #define NFSMNT_READAHEAD 0x00002000 /* set read ahead */ #define NFSMNT_DEADTHRESH 0x00004000 /* set dead server retry thresh */ #define NFSMNT_RESVPORT 0x00008000 /* Allocate a reserved port */ @@ -168,560 +95,4 @@ struct nfs_args { #define NFSMNT_ACDIRMIN 0x00100000 #define NFSMNT_ACDIRMAX 0x00200000 -#define NFSSTA_HASWRITEVERF 0x00040000 /* Has write verifier for V3 */ -#define NFSSTA_GOTPATHCONF 0x00080000 /* Got the V3 pathconf info */ -#define NFSSTA_GOTFSINFO 0x00100000 /* Got the V3 fsinfo */ -#define NFSSTA_MNTD 0x00200000 /* Mnt server for mnt point */ -#define NFSSTA_DISMINPROG 0x00400000 /* Dismount in progress */ -#define NFSSTA_DISMNT 0x00800000 /* Dismounted */ -#define NFSSTA_SNDLOCK 0x01000000 /* Send socket lock */ -#define NFSSTA_WANTSND 0x02000000 /* Want above */ -#define NFSSTA_RCVLOCK 0x04000000 /* Rcv socket lock */ -#define NFSSTA_WANTRCV 0x08000000 /* Want above */ -#define NFSSTA_WAITAUTH 0x10000000 /* Wait for authentication */ -#define NFSSTA_HASAUTH 0x20000000 /* Has authenticator */ -#define NFSSTA_WANTAUTH 0x40000000 /* Wants an authenticator */ -#define NFSSTA_AUTHERR 0x80000000 /* Authentication error */ - -/* - * Structures for the nfssvc(2) syscall. Not that anyone but nfsd and mount_nfs - * should ever try and use it. - */ -struct nfsd_args { - int sock; /* Socket to serve */ - caddr_t name; /* Client addr for connection based sockets */ - int namelen; /* Length of name */ -}; - -struct nfsd_srvargs { - struct nfsd *nsd_nfsd; /* Pointer to in kernel nfsd struct */ - uid_t nsd_uid; /* Effective uid mapped to cred */ - u_int32_t nsd_haddr; /* Ip address of client */ - struct xucred nsd_cr; /* Cred. uid maps to */ - u_int nsd_authlen; /* Length of auth string (ret) */ - u_char *nsd_authstr; /* Auth string (ret) */ - u_int nsd_verflen; /* and the verfier */ - u_char *nsd_verfstr; - struct timeval nsd_timestamp; /* timestamp from verifier */ - u_int32_t nsd_ttl; /* credential ttl (sec) */ - NFSKERBKEY_T nsd_key; /* Session key */ -}; - -struct nfsd_cargs { - char *ncd_dirp; /* Mount dir path */ - uid_t ncd_authuid; /* Effective uid */ - int ncd_authtype; /* Type of authenticator */ - u_int ncd_authlen; /* Length of authenticator string */ - u_char *ncd_authstr; /* Authenticator string */ - u_int ncd_verflen; /* and the verifier */ - u_char *ncd_verfstr; - NFSKERBKEY_T ncd_key; /* Session key */ -}; - -/* - * XXX to allow amd to include nfs.h without nfsproto.h - */ -#ifdef NFS_NPROCS -/* - * Stats structure - */ -struct nfsstats { - int attrcache_hits; - int attrcache_misses; - int lookupcache_hits; - int lookupcache_misses; - int direofcache_hits; - int direofcache_misses; - int biocache_reads; - int read_bios; - int read_physios; - int biocache_writes; - int write_bios; - int write_physios; - int biocache_readlinks; - int readlink_bios; - int biocache_readdirs; - int readdir_bios; - int rpccnt[NFS_NPROCS]; - int rpcretries; - int srvrpccnt[NFS_NPROCS]; - int srvrpc_errs; - int srv_errs; - int rpcrequests; - int rpctimeouts; - int rpcunexpected; - int rpcinvalid; - int srvcache_inproghits; - int srvcache_idemdonehits; - int srvcache_nonidemdonehits; - int srvcache_misses; - int srvnqnfs_leases; - int srvnqnfs_maxleases; - int srvnqnfs_getleases; - int srvvop_writes; - int accesscache_hits; - int accesscache_misses; -}; -#endif - -/* - * Flags for nfssvc() system call. - */ -#define NFSSVC_BIOD 0x002 -#define NFSSVC_NFSD 0x004 -#define NFSSVC_ADDSOCK 0x008 -#define NFSSVC_AUTHIN 0x010 -#define NFSSVC_GOTAUTH 0x040 -#define NFSSVC_AUTHINFAIL 0x080 -#define NFSSVC_MNTD 0x100 -#define NFSSVC_LOCKDANS 0x200 - -/* - * fs.nfs sysctl(3) identifiers - */ -#define NFS_NFSSTATS 1 /* struct: struct nfsstats */ -#define NFS_NFSPRIVPORT 2 /* int: prohibit nfs to resvports */ - -#define FS_NFS_NAMES { \ - { 0, 0 }, \ - { "nfsstats", CTLTYPE_STRUCT }, \ - { "nfsprivport", CTLTYPE_INT }, \ -} - -#ifdef _KERNEL - -#ifdef MALLOC_DECLARE -MALLOC_DECLARE(M_NFSREQ); -MALLOC_DECLARE(M_NFSDIROFF); -MALLOC_DECLARE(M_NFSRVDESC); -MALLOC_DECLARE(M_NFSUID); -MALLOC_DECLARE(M_NQLEASE); -MALLOC_DECLARE(M_NFSD); -MALLOC_DECLARE(M_NFSBIGFH); -MALLOC_DECLARE(M_NFSHASH); -#endif - -#ifdef ZONE_INTERRUPT -extern vm_zone_t nfsmount_zone; -#endif - -extern struct callout_handle nfs_timer_handle; - -struct uio; struct buf; struct vattr; struct nameidata; /* XXX */ - -/* - * The set of signals the interrupt an I/O in progress for NFSMNT_INT mounts. - * What should be in this set is open to debate, but I believe that since - * I/O system calls on ufs are never interrupted by signals the set should - * be minimal. My reasoning is that many current programs that use signals - * such as SIGALRM will not expect file I/O system calls to be interrupted - * by them and break. - */ -#define NFSINT_SIGMASK(set) \ - (SIGISMEMBER(set, SIGINT) || SIGISMEMBER(set, SIGTERM) || \ - SIGISMEMBER(set, SIGHUP) || SIGISMEMBER(set, SIGKILL) || \ - SIGISMEMBER(set, SIGQUIT)) - -/* - * Socket errors ignored for connectionless sockets?? - * For now, ignore them all - */ -#define NFSIGNORE_SOERROR(s, e) \ - ((e) != EINTR && (e) != ERESTART && (e) != EWOULDBLOCK && \ - ((s) & PR_CONNREQUIRED) == 0) - -/* - * Nfs outstanding request list element - */ -struct nfsreq { - TAILQ_ENTRY(nfsreq) r_chain; - struct mbuf *r_mreq; - struct mbuf *r_mrep; - struct mbuf *r_md; - caddr_t r_dpos; - struct nfsmount *r_nmp; - struct vnode *r_vp; - u_int32_t r_xid; - int r_flags; /* flags on request, see below */ - int r_retry; /* max retransmission count */ - int r_rexmit; /* current retrans count */ - int r_timer; /* tick counter on reply */ - u_int32_t r_procnum; /* NFS procedure number */ - int r_rtt; /* RTT for rpc */ - struct thread *r_td; /* Proc that did I/O system call */ -}; - -/* - * Queue head for nfsreq's - */ -extern TAILQ_HEAD(nfs_reqq, nfsreq) nfs_reqq; - -/* Flag values for r_flags */ -#define R_TIMING 0x01 /* timing request (in mntp) */ -#define R_SENT 0x02 /* request has been sent */ -#define R_SOFTTERM 0x04 /* soft mnt, too many retries */ -#define R_INTR 0x08 /* intr mnt, signal pending */ -#define R_SOCKERR 0x10 /* Fatal error on socket */ -#define R_TPRINTFMSG 0x20 /* Did a tprintf msg. */ -#define R_MUSTRESEND 0x40 /* Must resend request */ -#define R_GETONEREP 0x80 /* Probe for one reply only */ - -/* - * A list of nfssvc_sock structures is maintained with all the sockets - * that require service by the nfsd. - * The nfsuid structs hang off of the nfssvc_sock structs in both lru - * and uid hash lists. - */ -#ifndef NFS_UIDHASHSIZ -#define NFS_UIDHASHSIZ 29 /* Tune the size of nfssvc_sock with this */ -#endif -#define NUIDHASH(sock, uid) \ - (&(sock)->ns_uidhashtbl[(uid) % NFS_UIDHASHSIZ]) -#ifndef NFS_WDELAYHASHSIZ -#define NFS_WDELAYHASHSIZ 16 /* and with this */ -#endif -#define NWDELAYHASH(sock, f) \ - (&(sock)->ns_wdelayhashtbl[(*((u_int32_t *)(f))) % NFS_WDELAYHASHSIZ]) -#ifndef NFS_MUIDHASHSIZ -#define NFS_MUIDHASHSIZ 63 /* Tune the size of nfsmount with this */ -#endif -#define NMUIDHASH(nmp, uid) \ - (&(nmp)->nm_uidhashtbl[(uid) % NFS_MUIDHASHSIZ]) -#define NFSNOHASH(fhsum) \ - (&nfsnodehashtbl[(fhsum) & nfsnodehash]) - -/* - * Network address hash list element - */ -union nethostaddr { - u_int32_t had_inetaddr; - struct sockaddr *had_nam; -}; - -struct nfsuid { - TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */ - LIST_ENTRY(nfsuid) nu_hash; /* Hash list */ - int nu_flag; /* Flags */ - union nethostaddr nu_haddr; /* Host addr. for dgram sockets */ - struct ucred nu_cr; /* Cred uid mapped to */ - int nu_expire; /* Expiry time (sec) */ - struct timeval nu_timestamp; /* Kerb. timestamp */ - u_int32_t nu_nickname; /* Nickname on server */ - NFSKERBKEY_T nu_key; /* and session key */ -}; - -#define nu_inetaddr nu_haddr.had_inetaddr -#define nu_nam nu_haddr.had_nam -/* Bits for nu_flag */ -#define NU_INETADDR 0x1 -#define NU_NAM 0x2 -#define NU_NETFAM(u) (((u)->nu_flag & NU_INETADDR) ? AF_INET : AF_ISO) - -struct nfsrv_rec { - STAILQ_ENTRY(nfsrv_rec) nr_link; - struct sockaddr *nr_address; - struct mbuf *nr_packet; -}; - -struct nfssvc_sock { - TAILQ_ENTRY(nfssvc_sock) ns_chain; /* List of all nfssvc_sock's */ - TAILQ_HEAD(, nfsuid) ns_uidlruhead; - struct file *ns_fp; - struct socket *ns_so; - struct sockaddr *ns_nam; - struct mbuf *ns_raw; - struct mbuf *ns_rawend; - STAILQ_HEAD(, nfsrv_rec) ns_rec; - struct mbuf *ns_frag; - int ns_flag; - int ns_solock; - int ns_cc; - int ns_reclen; - int ns_numuids; - u_int32_t ns_sref; - LIST_HEAD(, nfsrv_descript) ns_tq; /* Write gather lists */ - LIST_HEAD(, nfsuid) ns_uidhashtbl[NFS_UIDHASHSIZ]; - LIST_HEAD(nfsrvw_delayhash, nfsrv_descript) ns_wdelayhashtbl[NFS_WDELAYHASHSIZ]; -}; - -/* Bits for "ns_flag" */ -#define SLP_VALID 0x01 -#define SLP_DOREC 0x02 -#define SLP_NEEDQ 0x04 -#define SLP_DISCONN 0x08 -#define SLP_GETSTREAM 0x10 -#define SLP_LASTFRAG 0x20 -#define SLP_ALLFLAGS 0xff - -extern TAILQ_HEAD(nfssvc_sockhead, nfssvc_sock) nfssvc_sockhead; -extern int nfssvc_sockhead_flag; -#define SLP_INIT 0x01 -#define SLP_WANTINIT 0x02 - -/* - * One of these structures is allocated for each nfsd. - */ -struct nfsd { - TAILQ_ENTRY(nfsd) nfsd_chain; /* List of all nfsd's */ - int nfsd_flag; /* NFSD_ flags */ - struct nfssvc_sock *nfsd_slp; /* Current socket */ - int nfsd_authlen; /* Authenticator len */ - u_char nfsd_authstr[RPCAUTH_MAXSIZ]; /* Authenticator data */ - int nfsd_verflen; /* and the Verifier */ - u_char nfsd_verfstr[RPCVERF_MAXSIZ]; - struct thread *nfsd_td; /* daemon thread ptr */ - struct nfsrv_descript *nfsd_nd; /* Associated nfsrv_descript */ -}; - -/* Bits for "nfsd_flag" */ -#define NFSD_WAITING 0x01 -#define NFSD_REQINPROG 0x02 -#define NFSD_NEEDAUTH 0x04 -#define NFSD_AUTHFAIL 0x08 - -/* - * This structure is used by the server for describing each request. - * Some fields are used only when write request gathering is performed. - */ -struct nfsrv_descript { - u_quad_t nd_time; /* Write deadline (usec) */ - off_t nd_off; /* Start byte offset */ - off_t nd_eoff; /* and end byte offset */ - LIST_ENTRY(nfsrv_descript) nd_hash; /* Hash list */ - LIST_ENTRY(nfsrv_descript) nd_tq; /* and timer list */ - LIST_HEAD(,nfsrv_descript) nd_coalesce; /* coalesced writes */ - struct mbuf *nd_mrep; /* Request mbuf list */ - struct mbuf *nd_md; /* Current dissect mbuf */ - struct mbuf *nd_mreq; /* Reply mbuf list */ - struct sockaddr *nd_nam; /* and socket addr */ - struct sockaddr *nd_nam2; /* return socket addr */ - caddr_t nd_dpos; /* Current dissect pos */ - u_int32_t nd_procnum; /* RPC # */ - int nd_stable; /* storage type */ - int nd_flag; /* nd_flag */ - int nd_len; /* Length of this write */ - int nd_repstat; /* Reply status */ - u_int32_t nd_retxid; /* Reply xid */ - u_int32_t nd_duration; /* Lease duration */ - struct timeval nd_starttime; /* Time RPC initiated */ - fhandle_t nd_fh; /* File handle */ - struct ucred nd_cr; /* Credentials */ -}; - -/* Bits for "nd_flag" */ -#define ND_READ LEASE_READ -#define ND_WRITE LEASE_WRITE -#define ND_CHECK 0x04 -#define ND_LEASE (ND_READ | ND_WRITE | ND_CHECK) -#define ND_NFSV3 0x08 -#define ND_NQNFS 0x10 -#define ND_KERBNICK 0x20 -#define ND_KERBFULL 0x40 -#define ND_KERBAUTH (ND_KERBNICK | ND_KERBFULL) - -extern TAILQ_HEAD(nfsd_head, nfsd) nfsd_head; -extern int nfsd_head_flag; -#define NFSD_CHECKSLP 0x01 - -/* - * These macros compare nfsrv_descript structures. - */ -#define NFSW_CONTIG(o, n) \ - ((o)->nd_eoff >= (n)->nd_off && \ - !bcmp((caddr_t)&(o)->nd_fh, (caddr_t)&(n)->nd_fh, NFSX_V3FH)) - -#define NFSW_SAMECRED(o, n) \ - (((o)->nd_flag & ND_KERBAUTH) == ((n)->nd_flag & ND_KERBAUTH) && \ - !bcmp((caddr_t)&(o)->nd_cr, (caddr_t)&(n)->nd_cr, \ - sizeof (struct ucred))) - -/* - * Defines for WebNFS - */ - -#define WEBNFS_ESC_CHAR '%' -#define WEBNFS_SPECCHAR_START 0x80 - -#define WEBNFS_NATIVE_CHAR 0x80 -/* - * .. - * Possibly more here in the future. - */ - -/* - * Macro for converting escape characters in WebNFS pathnames. - * Should really be in libkern. - */ - -#define HEXTOC(c) \ - ((c) >= 'a' ? ((c) - ('a' - 10)) : \ - ((c) >= 'A' ? ((c) - ('A' - 10)) : ((c) - '0'))) -#define HEXSTRTOI(p) \ - ((HEXTOC(p[0]) << 4) + HEXTOC(p[1])) - -#ifdef NFS_DEBUG - -extern int nfs_debug; -#define NFS_DEBUG_ASYNCIO 1 /* asynchronous i/o */ -#define NFS_DEBUG_WG 2 /* server write gathering */ -#define NFS_DEBUG_RC 4 /* server request caching */ - -#define NFS_DPF(cat, args) \ - do { \ - if (nfs_debug & NFS_DEBUG_##cat) printf args; \ - } while (0) - -#else - -#define NFS_DPF(cat, args) - -#endif - -u_quad_t nfs_curusec __P((void)); -int nfs_init __P((struct vfsconf *vfsp)); -int nfs_uninit __P((struct vfsconf *vfsp)); -int nfs_reply __P((struct nfsreq *)); -int nfs_getreq __P((struct nfsrv_descript *,struct nfsd *,int)); -int nfs_send __P((struct socket *, struct sockaddr *, struct mbuf *, - struct nfsreq *)); -int nfs_rephead __P((int, struct nfsrv_descript *, struct nfssvc_sock *, - int, int, u_quad_t *, struct mbuf **, struct mbuf **, - caddr_t *)); -int nfs_sndlock __P((struct nfsreq *)); -void nfs_sndunlock __P((struct nfsreq *)); -int nfs_slplock __P((struct nfssvc_sock *, int)); -void nfs_slpunlock __P((struct nfssvc_sock *)); -int nfs_disct __P((struct mbuf **, caddr_t *, int, int, caddr_t *)); -int nfs_vinvalbuf __P((struct vnode *, int, struct ucred *, struct thread *, - int)); -int nfs_readrpc __P((struct vnode *, struct uio *, struct ucred *)); -int nfs_writerpc __P((struct vnode *, struct uio *, struct ucred *, int *, - int *)); -int nfs_commit __P((struct vnode *vp, u_quad_t offset, int cnt, - struct ucred *cred, struct thread *td)); -int nfs_readdirrpc __P((struct vnode *, struct uio *, struct ucred *)); -int nfs_asyncio __P((struct buf *, struct ucred *, struct thread *)); -int nfs_doio __P((struct buf *, struct ucred *, struct thread *)); -int nfs_readlinkrpc __P((struct vnode *, struct uio *, struct ucred *)); -int nfs_sigintr __P((struct nfsmount *, struct nfsreq *, struct proc *)); -int nfs_readdirplusrpc __P((struct vnode *, struct uio *, struct ucred *)); -int nfsm_disct __P((struct mbuf **, caddr_t *, int, int, caddr_t *)); -void nfsm_srvfattr __P((struct nfsrv_descript *, struct vattr *, - struct nfs_fattr *)); -void nfsm_srvwcc __P((struct nfsrv_descript *, int, struct vattr *, int, - struct vattr *, struct mbuf **, char **)); -void nfsm_srvpostopattr __P((struct nfsrv_descript *, int, struct vattr *, - struct mbuf **, char **)); -int netaddr_match __P((int, union nethostaddr *, struct sockaddr *)); -int nfs_request __P((struct vnode *, struct mbuf *, int, struct thread *, - struct ucred *, struct mbuf **, struct mbuf **, - caddr_t *)); -int nfs_loadattrcache __P((struct vnode **, struct mbuf **, caddr_t *, - struct vattr *, int)); -int nfs_namei __P((struct nameidata *, fhandle_t *, int, - struct nfssvc_sock *, struct sockaddr *, struct mbuf **, - caddr_t *, struct vnode **, struct thread *, int, int)); -void nfsm_adj __P((struct mbuf *, int, int)); -int nfsm_mbuftouio __P((struct mbuf **, struct uio *, int, caddr_t *)); -void nfsrv_initcache __P((void)); -int nfs_getauth __P((struct nfsmount *, struct nfsreq *, struct ucred *, - char **, int *, char *, int *, NFSKERBKEY_T)); -int nfs_getnickauth __P((struct nfsmount *, struct ucred *, char **, - int *, char *, int)); -int nfs_savenickauth __P((struct nfsmount *, struct ucred *, int, - NFSKERBKEY_T, struct mbuf **, char **, - struct mbuf *)); -int nfs_adv __P((struct mbuf **, caddr_t *, int, int)); -void nfs_nhinit __P((void)); -void nfs_timer __P((void*)); -int nfsrv_dorec __P((struct nfssvc_sock *, struct nfsd *, - struct nfsrv_descript **)); -int nfsrv_getcache __P((struct nfsrv_descript *, struct nfssvc_sock *, - struct mbuf **)); -void nfsrv_updatecache __P((struct nfsrv_descript *, int, struct mbuf *)); -void nfsrv_cleancache __P((void)); -int nfs_connect __P((struct nfsmount *, struct nfsreq *)); -void nfs_disconnect __P((struct nfsmount *)); -void nfs_safedisconnect __P((struct nfsmount *)); -int nfs_getattrcache __P((struct vnode *, struct vattr *)); -int nfsm_strtmbuf __P((struct mbuf **, char **, const char *, long)); -int nfs_bioread __P((struct vnode *, struct uio *, int, struct ucred *)); -int nfsm_uiotombuf __P((struct uio *, struct mbuf **, int, caddr_t *)); -void nfsrv_init __P((int)); -void nfs_clearcommit __P((struct mount *)); -int nfsrv_errmap __P((struct nfsrv_descript *, int)); -void nfsrvw_sort __P((gid_t *, int)); -void nfsrv_setcred __P((struct ucred *, struct ucred *)); -int nfs_writebp __P((struct buf *, int, struct thread *)); -int nfsrv_object_create __P((struct vnode *)); -void nfsrv_wakenfsd __P((struct nfssvc_sock *slp)); -int nfsrv_writegather __P((struct nfsrv_descript **, struct nfssvc_sock *, - struct thread *, struct mbuf **)); -int nfs_fsinfo __P((struct nfsmount *, struct vnode *, struct ucred *, - struct thread *td)); - -int nfsrv3_access __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_commit __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_create __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_fhtovp __P((fhandle_t *, int, struct vnode **, struct ucred *, - struct nfssvc_sock *, struct sockaddr *, int *, - int, int)); -int nfsrv_setpublicfs __P((struct mount *, struct netexport *, - struct export_args *)); -int nfs_ispublicfh __P((fhandle_t *)); -int nfsrv_fsinfo __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_getattr __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_link __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_lookup __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_mkdir __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_mknod __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_noop __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_null __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_pathconf __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, struct thread *td, - struct mbuf **mrq)); -int nfsrv_read __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_readdir __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_readdirplus __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, struct thread *td, - struct mbuf **mrq)); -int nfsrv_readlink __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, struct thread *td, - struct mbuf **mrq)); -int nfsrv_remove __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_rename __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_rmdir __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_setattr __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_statfs __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_symlink __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -void nfsrv_rcv __P((struct socket *so, void *arg, int waitflag)); -void nfsrv_slpderef __P((struct nfssvc_sock *slp)); -#endif /* _KERNEL */ - #endif diff --git a/sys/nfsclient/nfsdiskless.h b/sys/nfsclient/nfsdiskless.h index 487e0bf..9b74d5c 100644 --- a/sys/nfsclient/nfsdiskless.h +++ b/sys/nfsclient/nfsdiskless.h @@ -37,9 +37,8 @@ * $FreeBSD$ */ - -#ifndef _NFS_NFSDISKLESS_H_ -#define _NFS_NFSDISKLESS_H_ +#ifndef _NFSCLIENT_NFSDISKLESS_H_ +#define _NFSCLIENT_NFSDISKLESS_H_ /* * Structure that must be initialized for a diskless nfs client. @@ -121,4 +120,10 @@ struct nfs_diskless { char my_hostnam[MAXHOSTNAMELEN]; /* Client host name */ }; +#ifdef _KERNEL +extern struct nfsv3_diskless nfsv3_diskless; +extern struct nfs_diskless nfs_diskless; +extern int nfs_diskless_valid; +#endif + #endif diff --git a/sys/nfsclient/nfsm_subs.h b/sys/nfsclient/nfsm_subs.h index d58ef15..47ca520 100644 --- a/sys/nfsclient/nfsm_subs.h +++ b/sys/nfsclient/nfsm_subs.h @@ -37,9 +37,12 @@ * $FreeBSD$ */ +#ifndef _NFSCLIENT_NFSM_SUBS_H_ +#define _NFSCLIENT_NFSM_SUBS_H_ -#ifndef _NFS_NFSM_SUBS_H_ -#define _NFS_NFSM_SUBS_H_ +#include <nfs/nfs_common.h> + +#define nfsv2tov_type(a) nv2tov_type[fxdr_unsigned(u_int32_t,(a))&0x7] struct ucred; struct vnode; @@ -53,13 +56,11 @@ struct vnode; /* * First define what the actual subs. return */ -struct mbuf *nfsm_reqh __P((struct vnode *vp, u_long procid, int hsiz, - caddr_t *bposp)); -struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid, - int auth_type, int auth_len, char *auth_str, - int verf_len, char *verf_str, - struct mbuf *mrest, int mrest_len, - struct mbuf **mbp, u_int32_t *xidp)); +struct mbuf *nfsm_reqhead(struct vnode *vp, u_long procid, int hsiz); +struct mbuf *nfsm_rpchead(struct ucred *cr, int nmflag, int procid, + int auth_type, int auth_len, + struct mbuf *mrest, int mrest_len, + struct mbuf **mbp, u_int32_t *xidp); #define M_HASCL(m) ((m)->m_flags & M_EXT) #define NFSMINOFF(m) \ @@ -71,10 +72,6 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid, else \ (m)->m_data = (m)->m_dat; \ } while (0) -#define NFSMADV(m, s) \ - do { \ - (m)->m_data += (s); \ - } while (0) #define NFSMSIZ(m) ((M_HASCL(m))?MCLBYTES: \ (((m)->m_flags & M_PKTHDR)?MHLEN:MLEN)) @@ -91,474 +88,130 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid, * unions. */ -#define nfsm_build(a,c,s) \ - do { \ - if ((s) > M_TRAILINGSPACE(mb)) { \ - MGET(mb2, M_TRYWAIT, MT_DATA); \ - if ((s) > MLEN) \ - panic("build > MLEN"); \ - mb->m_next = mb2; \ - mb = mb2; \ - mb->m_len = 0; \ - bpos = mtod(mb, caddr_t); \ - } \ - (a) = (c)(bpos); \ - mb->m_len += (s); \ - bpos += (s); \ - } while (0) - -#define nfsm_dissect(a, c, s) \ - do { \ - t1 = mtod(md, caddr_t)+md->m_len-dpos; \ - if (t1 >= (s)) { \ - (a) = (c)(dpos); \ - dpos += (s); \ - } else if ((t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) != 0){ \ - error = t1; \ - m_freem(mrep); \ - goto nfsmout; \ - } else { \ - (a) = (c)cp2; \ - } \ - } while (0) +int nfsm_fhtom_xx(struct vnode *v, int v3, u_int32_t **tl, + struct mbuf **mb, caddr_t *bpos); +int nfsm_mtofh_xx(struct vnode *d, struct vnode **v, int v3, int *f, + u_int32_t **tl, struct mbuf **md, caddr_t *dpos); +int nfsm_getfh_xx(nfsfh_t **f, int *s, int v3, u_int32_t **tl, + struct mbuf **md, caddr_t *dpos); +void nfsm_v3attrbuild_xx(struct vattr *va, int full, u_int32_t **tl, + struct mbuf **mb, caddr_t *bpos); +int nfsm_loadattr_xx(struct vnode **v, struct vattr *va, u_int32_t **tl, + struct mbuf **md, caddr_t *dpos); +int nfsm_postop_attr_xx(struct vnode **v, int *f, u_int32_t **tl, + struct mbuf **md, caddr_t *dpos); +int nfsm_wcc_data_xx(struct vnode **v, int *f, u_int32_t **tl, + struct mbuf **md, caddr_t *dpos); +int nfsm_strtom_xx(const char *a, int s, int m, u_int32_t **tl, + struct mbuf **mb, caddr_t *bpos); #define nfsm_fhtom(v, v3) \ - do { \ - if (v3) { \ - t2 = nfsm_rndup(VTONFS(v)->n_fhsize) + NFSX_UNSIGNED; \ - if (t2 <= M_TRAILINGSPACE(mb)) { \ - nfsm_build(tl, u_int32_t *, t2); \ - *tl++ = txdr_unsigned(VTONFS(v)->n_fhsize); \ - *(tl + ((t2>>2) - 2)) = 0; \ - bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \ - VTONFS(v)->n_fhsize); \ - } else if ((t2 = nfsm_strtmbuf(&mb, &bpos, \ - (caddr_t)VTONFS(v)->n_fhp, \ - VTONFS(v)->n_fhsize)) != 0) { \ - error = t2; \ - m_freem(mreq); \ - goto nfsmout; \ - } \ - } else { \ - nfsm_build(cp, caddr_t, NFSX_V2FH); \ - bcopy((caddr_t)VTONFS(v)->n_fhp, cp, NFSX_V2FH); \ - } \ - } while (0) - -#define nfsm_srvfhtom(f, v3) \ - do { \ - if (v3) { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_V3FH);\ - *tl++ = txdr_unsigned(NFSX_V3FH); \ - bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \ - } else { \ - nfsm_build(cp, caddr_t, NFSX_V2FH); \ - bcopy((caddr_t)(f), cp, NFSX_V2FH); \ - } \ - } while (0) - -#define nfsm_srvpostop_fh(f) \ - do { \ - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED + NFSX_V3FH); \ - *tl++ = nfs_true; \ - *tl++ = txdr_unsigned(NFSX_V3FH); \ - bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \ - } while (0) +do { \ + int32_t t1; \ + t1 = nfsm_fhtom_xx((v), (v3), &tl, &mb, &bpos); \ + if (t1) { \ + error = t1; \ + m_freem(mreq); \ + goto nfsmout; \ + } \ +} while (0) #define nfsm_mtofh(d, v, v3, f) \ - do { \ - struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; \ - if (v3) { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - (f) = fxdr_unsigned(int, *tl); \ - } else \ - (f) = 1; \ - if (f) { \ - nfsm_getfh(ttfhp, ttfhsize, (v3)); \ - if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \ - &ttnp)) != 0) { \ - error = t1; \ - m_freem(mrep); \ - goto nfsmout; \ - } \ - (v) = NFSTOV(ttnp); \ - } \ - if (v3) { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (f) \ - (f) = fxdr_unsigned(int, *tl); \ - else if (fxdr_unsigned(int, *tl)) \ - nfsm_adv(NFSX_V3FATTR); \ - } \ - if (f) \ - nfsm_loadattr((v), (struct vattr *)0); \ - } while (0) +do { \ + int32_t t1; \ + t1 = nfsm_mtofh_xx((d), &(v), (v3), &(f), &tl, &md, &dpos); \ + if (t1) { \ + error = t1; \ + m_freem(mrep); \ + goto nfsmout; \ + } \ +} while (0) #define nfsm_getfh(f, s, v3) \ - do { \ - if (v3) { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (((s) = fxdr_unsigned(int, *tl)) <= 0 || \ - (s) > NFSX_V3FHMAX) { \ - m_freem(mrep); \ - error = EBADRPC; \ - goto nfsmout; \ - } \ - } else \ - (s) = NFSX_V2FH; \ - nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); \ - } while (0) +do { \ + int32_t t1; \ + t1 = nfsm_getfh_xx(&(f), &(s), (v3), &tl, &md, &dpos); \ + if (t1) { \ + error = t1; \ + m_freem(mrep); \ + goto nfsmout; \ + } \ +} while (0) #define nfsm_loadattr(v, a) \ - do { \ - struct vnode *ttvp = (v); \ - if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a), 0)) != 0) { \ - error = t1; \ - m_freem(mrep); \ - goto nfsmout; \ - } \ - (v) = ttvp; \ - } while (0) +do { \ + int32_t t1; \ + t1 = nfsm_loadattr_xx(&v, a, &tl, &md, &dpos); \ + if (t1 != 0) { \ + error = t1; \ + m_freem(mrep); \ + goto nfsmout; \ + } \ +} while (0) #define nfsm_postop_attr(v, f) \ - do { \ - struct vnode *ttvp = (v); \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (((f) = fxdr_unsigned(int, *tl)) != 0) { \ - if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \ - (struct vattr *)0, 1)) != 0) { \ - error = t1; \ - (f) = 0; \ - m_freem(mrep); \ - goto nfsmout; \ - } \ - (v) = ttvp; \ - } \ - } while (0) +do { \ + int32_t t1; \ + t1 = nfsm_postop_attr_xx(&v, &f, &tl, &md, &dpos); \ + if (t1 != 0) { \ + error = t1; \ + m_freem(mrep); \ + goto nfsmout; \ + } \ +} while (0) /* Used as (f) for nfsm_wcc_data() */ #define NFSV3_WCCRATTR 0 #define NFSV3_WCCCHK 1 #define nfsm_wcc_data(v, f) \ - do { \ - int ttattrf, ttretf = 0; \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (*tl == nfs_true) { \ - nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED); \ - if (f) \ - ttretf = (VTONFS(v)->n_mtime == \ - fxdr_unsigned(u_int32_t, *(tl + 2))); \ - } \ - nfsm_postop_attr((v), ttattrf); \ - if (f) { \ - (f) = ttretf; \ - } else { \ - (f) = ttattrf; \ - } \ - } while (0) +do { \ + int32_t t1; \ + t1 = nfsm_wcc_data_xx(&v, &f, &tl, &md, &dpos); \ + if (t1 != 0) { \ + error = t1; \ + m_freem(mrep); \ + goto nfsmout; \ + } \ +} while (0) /* If full is true, set all fields, otherwise just set mode and time fields */ #define nfsm_v3attrbuild(a, full) \ - do { \ - if ((a)->va_mode != (mode_t)VNOVAL) { \ - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ - *tl++ = nfs_true; \ - *tl = txdr_unsigned((a)->va_mode); \ - } else { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ - *tl = nfs_false; \ - } \ - if ((full) && (a)->va_uid != (uid_t)VNOVAL) { \ - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ - *tl++ = nfs_true; \ - *tl = txdr_unsigned((a)->va_uid); \ - } else { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ - *tl = nfs_false; \ - } \ - if ((full) && (a)->va_gid != (gid_t)VNOVAL) { \ - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ - *tl++ = nfs_true; \ - *tl = txdr_unsigned((a)->va_gid); \ - } else { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ - *tl = nfs_false; \ - } \ - if ((full) && (a)->va_size != VNOVAL) { \ - nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); \ - *tl++ = nfs_true; \ - txdr_hyper((a)->va_size, tl); \ - } else { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ - *tl = nfs_false; \ - } \ - if ((a)->va_atime.tv_sec != VNOVAL) { \ - if ((a)->va_atime.tv_sec != time_second) { \ - nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED);\ - *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT);\ - txdr_nfsv3time(&(a)->va_atime, tl); \ - } else { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ - *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); \ - } \ - } else { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ - *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); \ - } \ - if ((a)->va_mtime.tv_sec != VNOVAL) { \ - if ((a)->va_mtime.tv_sec != time_second) { \ - nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED);\ - *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT);\ - txdr_nfsv3time(&(a)->va_mtime, tl); \ - } else { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ - *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); \ - } \ - } else { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ - *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); \ - } \ - } while (0) - - -#define nfsm_strsiz(s,m) \ - do { \ - nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ - if (((s) = fxdr_unsigned(int32_t,*tl)) > (m)) { \ - m_freem(mrep); \ - error = EBADRPC; \ - goto nfsmout; \ - } \ - } while (0) - -#define nfsm_srvstrsiz(s,m) \ - do { \ - nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ - if (((s) = fxdr_unsigned(int32_t,*tl)) > (m) || (s) <= 0) { \ - error = EBADRPC; \ - nfsm_reply(0); \ - } \ - } while (0) - -#define nfsm_srvnamesiz(s) \ - do { \ - nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ - if (((s) = fxdr_unsigned(int32_t,*tl)) > NFS_MAXNAMLEN) \ - error = NFSERR_NAMETOL; \ - if ((s) <= 0) \ - error = EBADRPC; \ - if (error) \ - nfsm_reply(0); \ - } while (0) - -#define nfsm_mtouio(p,s) \ - do {\ - if ((s) > 0 && \ - (t1 = nfsm_mbuftouio(&md,(p),(s),&dpos)) != 0) { \ - error = t1; \ - m_freem(mrep); \ - goto nfsmout; \ - } \ - } while (0) - -#define nfsm_uiotom(p,s) \ - do { \ - if ((t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) != 0) { \ - error = t1; \ - m_freem(mreq); \ - goto nfsmout; \ - } \ - } while (0) - -#define nfsm_reqhead(v,a,s) \ - do { \ - mb = mreq = nfsm_reqh((v),(a),(s),&bpos); \ - } while (0) - -#define nfsm_reqdone \ - do { \ - m_freem(mrep); \ - nfsmout: \ - } while (0) - -#define nfsm_rndup(a) (((a)+3)&(~0x3)) +do { \ + nfsm_v3attrbuild_xx(a, full, &tl, &mb, &bpos); \ +} while(0) + +#define nfsm_uiotom(p, s) \ +do { \ + int t1; \ + t1 = nfsm_uiotombuf((p), &mb, (s), &bpos); \ + if (t1 != 0) { \ + error = t1; \ + m_freem(mreq); \ + goto nfsmout; \ + } \ +} while (0) #define nfsm_request(v, t, p, c) \ - do { \ - if ((error = nfs_request((v), mreq, (t), (p), \ - (c), &mrep, &md, &dpos)) != 0) { \ - if (error & NFSERR_RETERR) \ - error &= ~NFSERR_RETERR; \ - else \ - goto nfsmout; \ - } \ - } while (0) - -#define nfsm_strtom(a,s,m) \ - do {\ - if ((s) > (m)) { \ - m_freem(mreq); \ - error = ENAMETOOLONG; \ - goto nfsmout; \ - } \ - t2 = nfsm_rndup(s)+NFSX_UNSIGNED; \ - if (t2 <= M_TRAILINGSPACE(mb)) { \ - nfsm_build(tl,u_int32_t *,t2); \ - *tl++ = txdr_unsigned(s); \ - *(tl+((t2>>2)-2)) = 0; \ - bcopy((const char *)(a), (caddr_t)tl, (s)); \ - } else if ((t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) != 0) { \ - error = t2; \ - m_freem(mreq); \ - goto nfsmout; \ - } \ - } while (0) - -#define nfsm_srvdone \ - do { \ - nfsmout: \ - return (error); \ - } while (0) - -#define nfsm_reply(s) \ - do { \ - nfsd->nd_repstat = error; \ - if (error && !(nfsd->nd_flag & ND_NFSV3)) \ - (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \ - mrq, &mb, &bpos); \ +do { \ + error = nfs_request((v), mreq, (t), (p), (c), &mrep, &md, &dpos); \ + if (error != 0) { \ + if (error & NFSERR_RETERR) \ + error &= ~NFSERR_RETERR; \ else \ - (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \ - mrq, &mb, &bpos); \ - if (mrep != NULL) { \ - m_freem(mrep); \ - mrep = NULL; \ - } \ - mreq = *mrq; \ - if (error && (!(nfsd->nd_flag & ND_NFSV3) || \ - error == EBADRPC)) { \ - error = 0; \ goto nfsmout; \ - } \ - } while (0) - -#define nfsm_writereply(s, v3) \ - do { \ - nfsd->nd_repstat = error; \ - if (error && !(v3)) \ - (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \ - &mreq, &mb, &bpos); \ - else \ - (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \ - &mreq, &mb, &bpos); \ - } while (0) - -#define nfsm_adv(s) \ - do { \ - t1 = mtod(md, caddr_t)+md->m_len-dpos; \ - if (t1 >= (s)) { \ - dpos += (s); \ - } else if ((t1 = nfs_adv(&md, &dpos, (s), t1)) != 0) { \ - error = t1; \ - m_freem(mrep); \ - goto nfsmout; \ - } \ - } while (0) - -#define nfsm_srvmtofh(f) \ - do { \ - int fhlen; \ - if (nfsd->nd_flag & ND_NFSV3) { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - fhlen = fxdr_unsigned(int, *tl); \ - if (fhlen != 0 && fhlen != NFSX_V3FH) { \ - error = EBADRPC; \ - nfsm_reply(0); \ - } \ - } else { \ - fhlen = NFSX_V2FH; \ - } \ - if (fhlen != 0) { \ - nfsm_dissect(tl, u_int32_t *, fhlen); \ - bcopy((caddr_t)tl, (caddr_t)(f), fhlen); \ - } else {\ - bzero((caddr_t)(f), NFSX_V3FH); \ - } \ - } while (0) - -#define nfsm_clget \ - do { \ - if (bp >= be) { \ - if (mp == mb) \ - mp->m_len += bp-bpos; \ - MGET(mp, M_TRYWAIT, MT_DATA); \ - MCLGET(mp, M_TRYWAIT); \ - mp->m_len = NFSMSIZ(mp); \ - mp2->m_next = mp; \ - mp2 = mp; \ - bp = mtod(mp, caddr_t); \ - be = bp+mp->m_len; \ - } \ - tl = (u_int32_t *)bp; \ - } while (0) - -#define nfsm_srvfillattr(a, f) \ - do { \ - nfsm_srvfattr(nfsd, (a), (f)); \ - } while (0) - -#define nfsm_srvwcc_data(br, b, ar, a) \ - do { \ - nfsm_srvwcc(nfsd, (br), (b), (ar), (a), &mb, &bpos); \ - } while (0) - -#define nfsm_srvpostop_attr(r, a) \ - do { \ - nfsm_srvpostopattr(nfsd, (r), (a), &mb, &bpos); \ - } while (0) - -#define nfsm_srvsattr(a) \ - do { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (*tl == nfs_true) { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - (a)->va_mode = nfstov_mode(*tl); \ - } \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (*tl == nfs_true) { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - (a)->va_uid = fxdr_unsigned(uid_t, *tl); \ - } \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (*tl == nfs_true) { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - (a)->va_gid = fxdr_unsigned(gid_t, *tl); \ - } \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (*tl == nfs_true) { \ - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ - (a)->va_size = fxdr_hyper(tl); \ - } \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - switch (fxdr_unsigned(int, *tl)) { \ - case NFSV3SATTRTIME_TOCLIENT: \ - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ - fxdr_nfsv3time(tl, &(a)->va_atime); \ - break; \ - case NFSV3SATTRTIME_TOSERVER: \ - getnanotime(&(a)->va_atime); \ - break; \ - }; \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - switch (fxdr_unsigned(int, *tl)) { \ - case NFSV3SATTRTIME_TOCLIENT: \ - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ - fxdr_nfsv3time(tl, &(a)->va_mtime); \ - break; \ - case NFSV3SATTRTIME_TOSERVER: \ - getnanotime(&(a)->va_mtime); \ - break; \ - } \ - } while (0) + } \ +} while (0) + +#define nfsm_strtom(a, s, m) \ +do { \ + int t1; \ + t1 = nfsm_strtom_xx((a), (s), (m), &tl, &mb, &bpos); \ + if (t1 != 0) { \ + error = t1; \ + m_freem(mreq); \ + goto nfsmout; \ + } \ +} while (0) #endif diff --git a/sys/nfsclient/nfsmount.h b/sys/nfsclient/nfsmount.h index d6f8a8b..8c531cb 100644 --- a/sys/nfsclient/nfsmount.h +++ b/sys/nfsclient/nfsmount.h @@ -37,9 +37,8 @@ * $FreeBSD$ */ - -#ifndef _NFS_NFSMOUNT_H_ -#define _NFS_NFSMOUNT_H_ +#ifndef _NFSCLIENT_NFSMOUNT_H_ +#define _NFSCLIENT_NFSMOUNT_H_ /* * Mount structure. @@ -70,24 +69,11 @@ struct nfsmount { int nm_wsize; /* Max size of write rpc */ int nm_readdirsize; /* Size of a readdir rpc */ int nm_readahead; /* Num. of blocks to readahead */ - int nm_leaseterm; /* Term (sec) for NQNFS lease */ int nm_acdirmin; /* Directory attr cache min lifetime */ int nm_acdirmax; /* Directory attr cache max lifetime */ int nm_acregmin; /* Reg file attr cache min lifetime */ int nm_acregmax; /* Reg file attr cache max lifetime */ - TAILQ_HEAD(timhd, nfsnode) nm_timerhead; /* Head of lease timer queue */ - struct vnode *nm_inprog; /* Vnode in prog by nqnfs_clientd() */ - uid_t nm_authuid; /* Uid for authenticator */ - int nm_authtype; /* Authenticator type */ - int nm_authlen; /* and length */ - char *nm_authstr; /* Authenticator string */ - char *nm_verfstr; /* and the verifier */ - int nm_verflen; u_char nm_verf[NFSX_V3WRITEVERF]; /* V3 write verifier */ - NFSKERBKEY_T nm_key; /* and the session key */ - int nm_numuids; /* Number of nfsuid mappings */ - TAILQ_HEAD(, nfsuid) nm_uidlruhead; /* Lists of nfsuid mappings */ - LIST_HEAD(, nfsuid) nm_uidhashtbl[NFS_MUIDHASHSIZ]; TAILQ_HEAD(, buf) nm_bufq; /* async io buffer queue */ short nm_bufqlen; /* number of buffers in queue */ short nm_bufqwant; /* process wants to add to the queue */ diff --git a/sys/nfsclient/nfsnode.h b/sys/nfsclient/nfsnode.h index ba99fea..fcda484 100644 --- a/sys/nfsclient/nfsnode.h +++ b/sys/nfsclient/nfsnode.h @@ -37,11 +37,10 @@ * $FreeBSD$ */ +#ifndef _NFSCLIENT_NFSNODE_H_ +#define _NFSCLIENT_NFSNODE_H_ -#ifndef _NFS_NFSNODE_H_ -#define _NFS_NFSNODE_H_ - -#if !defined(_NFS_NFS_H_) && !defined(_KERNEL) +#if !defined(_NFSCLIENT_NFS_H_) && !defined(_KERNEL) #include <nfs/nfs.h> #endif @@ -87,7 +86,6 @@ struct nfsdmap { */ struct nfsnode { LIST_ENTRY(nfsnode) n_hash; /* Hash chain */ - TAILQ_ENTRY(nfsnode) n_timer; /* Nqnfs timer chain */ u_quad_t n_size; /* Current size of file */ u_quad_t n_brev; /* Modify rev when cached */ u_quad_t n_lrev; /* Modify rev for lease */ @@ -135,9 +133,7 @@ struct nfsnode { #define NFLUSHINPROG 0x0002 /* Avoid multiple calls to vinvalbuf() */ #define NMODIFIED 0x0004 /* Might have a modified buffer in bio */ #define NWRITEERR 0x0008 /* Flag write errors so close will know */ -#define NQNFSNONCACHE 0x0020 /* Non-cachable lease */ -#define NQNFSWRITE 0x0040 /* Write lease */ -#define NQNFSEVICTED 0x0080 /* Has been evicted */ +/* 0x20, 0x40, 0x80 free */ #define NACC 0x0100 /* Special file accessed */ #define NUPD 0x0200 /* Special file updated */ #define NCHG 0x0400 /* Special file times changed */ @@ -169,17 +165,18 @@ extern struct nfsmount *nfs_iodmount[NFS_MAXASYNCDAEMON]; * should not be obtained while other locks are being held. */ -static __inline -int +static __inline int nfs_rslock(struct nfsnode *np, struct thread *td) { - return(lockmgr(&np->n_rslock, LK_EXCLUSIVE | LK_CANRECURSE | LK_SLEEPFAIL, NULL, td)); + + return(lockmgr(&np->n_rslock, + LK_EXCLUSIVE | LK_CANRECURSE | LK_SLEEPFAIL, NULL, td)); } -static __inline -void +static __inline void nfs_rsunlock(struct nfsnode *np, struct thread *td) { + (void)lockmgr(&np->n_rslock, LK_RELEASE, NULL, td); } @@ -190,20 +187,17 @@ extern vop_t **spec_nfsv2nodeop_p; /* * Prototypes for NFS vnode operations */ -int nfs_getpages __P((struct vop_getpages_args *)); -int nfs_putpages __P((struct vop_putpages_args *)); -int nfs_write __P((struct vop_write_args *)); -int nqnfs_vop_lease_check __P((struct vop_lease_args *)); -int nfs_inactive __P((struct vop_inactive_args *)); -int nfs_reclaim __P((struct vop_reclaim_args *)); +int nfs_getpages(struct vop_getpages_args *); +int nfs_putpages(struct vop_putpages_args *); +int nfs_write(struct vop_write_args *); +int nfs_inactive(struct vop_inactive_args *); +int nfs_reclaim(struct vop_reclaim_args *); /* other stuff */ -int nfs_removeit __P((struct sillyrename *)); -int nfs_nget __P((struct mount *,nfsfh_t *,int,struct nfsnode **)); -nfsuint64 *nfs_getcookie __P((struct nfsnode *, off_t, int)); -void nfs_invaldir __P((struct vnode *)); - -#define nqnfs_lease_updatetime nfs_lease_updatetime +int nfs_removeit(struct sillyrename *); +int nfs_nget(struct mount *, nfsfh_t *, int, struct nfsnode **); +nfsuint64 *nfs_getcookie(struct nfsnode *, off_t, int); +void nfs_invaldir(struct vnode *); #endif /* _KERNEL */ diff --git a/sys/nfsclient/nfsstats.h b/sys/nfsclient/nfsstats.h index da808f4..03063e6 100644 --- a/sys/nfsclient/nfsstats.h +++ b/sys/nfsclient/nfsstats.h @@ -37,192 +37,10 @@ * $FreeBSD$ */ -#ifndef _NFS_NFS_H_ -#define _NFS_NFS_H_ - -#ifdef _KERNEL -#include "opt_nfs.h" -#endif +#ifndef _NFSCLIENT_NFSSTATS_H_ +#define _NFSCLIENT_NFSSTATS_H_ /* - * Tunable constants for nfs - */ - -#define NFS_MAXIOVEC 34 -#define NFS_TICKINTVL 5 /* Desired time for a tick (msec) */ -#define NFS_HZ (hz / nfs_ticks) /* Ticks/sec */ -#define NFS_TIMEO (1 * NFS_HZ) /* Default timeout = 1 second */ -#define NFS_MINTIMEO (1 * NFS_HZ) /* Min timeout to use */ -#define NFS_MAXTIMEO (60 * NFS_HZ) /* Max timeout to backoff to */ -#define NFS_MINIDEMTIMEO (5 * NFS_HZ) /* Min timeout for non-idempotent ops*/ -#define NFS_MAXREXMIT 100 /* Stop counting after this many */ -#define NFS_MAXWINDOW 1024 /* Max number of outstanding requests */ -#define NFS_RETRANS 10 /* Num of retrans for soft mounts */ -#define NFS_MAXGRPS 16 /* Max. size of groups list */ -#ifndef NFS_MINATTRTIMO -#define NFS_MINATTRTIMO 3 /* VREG attrib cache timeout in sec */ -#endif -#ifndef NFS_MAXATTRTIMO -#define NFS_MAXATTRTIMO 60 -#endif -#ifndef NFS_MINDIRATTRTIMO -#define NFS_MINDIRATTRTIMO 30 /* VDIR attrib cache timeout in sec */ -#endif -#ifndef NFS_MAXDIRATTRTIMO -#define NFS_MAXDIRATTRTIMO 60 -#endif -#define NFS_WSIZE 8192 /* Def. write data size <= 8192 */ -#define NFS_RSIZE 8192 /* Def. read data size <= 8192 */ -#define NFS_READDIRSIZE 8192 /* Def. readdir size */ -#define NFS_DEFRAHEAD 1 /* Def. read ahead # blocks */ -#define NFS_MAXRAHEAD 4 /* Max. read ahead # blocks */ -#define NFS_MAXUIDHASH 64 /* Max. # of hashed uid entries/mp */ -#define NFS_MAXASYNCDAEMON 20 /* Max. number async_daemons runnable */ -#define NFS_MAXGATHERDELAY 100 /* Max. write gather delay (msec) */ -#ifndef NFS_GATHERDELAY -#define NFS_GATHERDELAY 10 /* Default write gather delay (msec) */ -#endif -#define NFS_DIRBLKSIZ 4096 /* Must be a multiple of DIRBLKSIZ */ -#ifdef _KERNEL -#define DIRBLKSIZ 512 /* XXX we used to use ufs's DIRBLKSIZ */ -#endif - -/* - * Oddballs - */ -#define NMOD(a) ((a) % nfs_asyncdaemons) -#define NFS_CMPFH(n, f, s) \ - ((n)->n_fhsize == (s) && !bcmp((caddr_t)(n)->n_fhp, (caddr_t)(f), (s))) -#define NFS_ISV3(v) (VFSTONFS((v)->v_mount)->nm_flag & NFSMNT_NFSV3) -#define NFS_SRVMAXDATA(n) \ - (((n)->nd_flag & ND_NFSV3) ? (((n)->nd_nam2) ? \ - NFS_MAXDGRAMDATA : NFS_MAXDATA) : NFS_V2MAXDATA) - -/* - * XXX - * The B_INVAFTERWRITE flag should be set to whatever is required by the - * buffer cache code to say "Invalidate the block after it is written back". - */ -#define B_INVAFTERWRITE B_NOCACHE - -/* - * The IO_METASYNC flag should be implemented for local file systems. - * (Until then, it is nothin at all.) - */ -#ifndef IO_METASYNC -#define IO_METASYNC 0 -#endif - -/* - * Arguments to mount NFS - */ -#define NFS_ARGSVERSION 3 /* change when nfs_args changes */ -struct nfs_args { - int version; /* args structure version number */ - struct sockaddr *addr; /* file server address */ - int addrlen; /* length of address */ - int sotype; /* Socket type */ - int proto; /* and Protocol */ - u_char *fh; /* File handle to be mounted */ - int fhsize; /* Size, in bytes, of fh */ - int flags; /* flags */ - int wsize; /* write size in bytes */ - int rsize; /* read size in bytes */ - int readdirsize; /* readdir size in bytes */ - int timeo; /* initial timeout in .1 secs */ - int retrans; /* times to retry send */ - int maxgrouplist; /* Max. size of group list */ - int readahead; /* # of blocks to readahead */ - int leaseterm; /* Term (sec) of lease */ - int deadthresh; /* Retrans threshold */ - char *hostname; /* server's name */ - int acregmin; /* cache attrs for reg files min time */ - int acregmax; /* cache attrs for reg files max time */ - int acdirmin; /* cache attrs for dirs min time */ - int acdirmax; /* cache attrs for dirs max time */ -}; - -/* - * NFS mount option flags - */ -#define NFSMNT_SOFT 0x00000001 /* soft mount (hard is default) */ -#define NFSMNT_WSIZE 0x00000002 /* set write size */ -#define NFSMNT_RSIZE 0x00000004 /* set read size */ -#define NFSMNT_TIMEO 0x00000008 /* set initial timeout */ -#define NFSMNT_RETRANS 0x00000010 /* set number of request retries */ -#define NFSMNT_MAXGRPS 0x00000020 /* set maximum grouplist size */ -#define NFSMNT_INT 0x00000040 /* allow interrupts on hard mount */ -#define NFSMNT_NOCONN 0x00000080 /* Don't Connect the socket */ -#define NFSMNT_NQNFS 0x00000100 /* Use Nqnfs protocol */ -#define NFSMNT_NFSV3 0x00000200 /* Use NFS Version 3 protocol */ -#define NFSMNT_KERB 0x00000400 /* Use Kerberos authentication */ -#define NFSMNT_DUMBTIMR 0x00000800 /* Don't estimate rtt dynamically */ -#define NFSMNT_LEASETERM 0x00001000 /* set lease term (nqnfs) */ -#define NFSMNT_READAHEAD 0x00002000 /* set read ahead */ -#define NFSMNT_DEADTHRESH 0x00004000 /* set dead server retry thresh */ -#define NFSMNT_RESVPORT 0x00008000 /* Allocate a reserved port */ -#define NFSMNT_RDIRPLUS 0x00010000 /* Use Readdirplus for V3 */ -#define NFSMNT_READDIRSIZE 0x00020000 /* Set readdir size */ -#define NFSMNT_ACREGMIN 0x00040000 -#define NFSMNT_ACREGMAX 0x00080000 -#define NFSMNT_ACDIRMIN 0x00100000 -#define NFSMNT_ACDIRMAX 0x00200000 - -#define NFSSTA_HASWRITEVERF 0x00040000 /* Has write verifier for V3 */ -#define NFSSTA_GOTPATHCONF 0x00080000 /* Got the V3 pathconf info */ -#define NFSSTA_GOTFSINFO 0x00100000 /* Got the V3 fsinfo */ -#define NFSSTA_MNTD 0x00200000 /* Mnt server for mnt point */ -#define NFSSTA_DISMINPROG 0x00400000 /* Dismount in progress */ -#define NFSSTA_DISMNT 0x00800000 /* Dismounted */ -#define NFSSTA_SNDLOCK 0x01000000 /* Send socket lock */ -#define NFSSTA_WANTSND 0x02000000 /* Want above */ -#define NFSSTA_RCVLOCK 0x04000000 /* Rcv socket lock */ -#define NFSSTA_WANTRCV 0x08000000 /* Want above */ -#define NFSSTA_WAITAUTH 0x10000000 /* Wait for authentication */ -#define NFSSTA_HASAUTH 0x20000000 /* Has authenticator */ -#define NFSSTA_WANTAUTH 0x40000000 /* Wants an authenticator */ -#define NFSSTA_AUTHERR 0x80000000 /* Authentication error */ - -/* - * Structures for the nfssvc(2) syscall. Not that anyone but nfsd and mount_nfs - * should ever try and use it. - */ -struct nfsd_args { - int sock; /* Socket to serve */ - caddr_t name; /* Client addr for connection based sockets */ - int namelen; /* Length of name */ -}; - -struct nfsd_srvargs { - struct nfsd *nsd_nfsd; /* Pointer to in kernel nfsd struct */ - uid_t nsd_uid; /* Effective uid mapped to cred */ - u_int32_t nsd_haddr; /* Ip address of client */ - struct xucred nsd_cr; /* Cred. uid maps to */ - u_int nsd_authlen; /* Length of auth string (ret) */ - u_char *nsd_authstr; /* Auth string (ret) */ - u_int nsd_verflen; /* and the verfier */ - u_char *nsd_verfstr; - struct timeval nsd_timestamp; /* timestamp from verifier */ - u_int32_t nsd_ttl; /* credential ttl (sec) */ - NFSKERBKEY_T nsd_key; /* Session key */ -}; - -struct nfsd_cargs { - char *ncd_dirp; /* Mount dir path */ - uid_t ncd_authuid; /* Effective uid */ - int ncd_authtype; /* Type of authenticator */ - u_int ncd_authlen; /* Length of authenticator string */ - u_char *ncd_authstr; /* Authenticator string */ - u_int ncd_verflen; /* and the verifier */ - u_char *ncd_verfstr; - NFSKERBKEY_T ncd_key; /* Session key */ -}; - -/* - * XXX to allow amd to include nfs.h without nfsproto.h - */ -#ifdef NFS_NPROCS -/* * Stats structure */ struct nfsstats { @@ -232,6 +50,8 @@ struct nfsstats { int lookupcache_misses; int direofcache_hits; int direofcache_misses; + int accesscache_hits; + int accesscache_misses; int biocache_reads; int read_bios; int read_physios; @@ -242,486 +62,12 @@ struct nfsstats { int readlink_bios; int biocache_readdirs; int readdir_bios; - int rpccnt[NFS_NPROCS]; int rpcretries; - int srvrpccnt[NFS_NPROCS]; - int srvrpc_errs; - int srv_errs; int rpcrequests; int rpctimeouts; int rpcunexpected; int rpcinvalid; - int srvcache_inproghits; - int srvcache_idemdonehits; - int srvcache_nonidemdonehits; - int srvcache_misses; - int srvnqnfs_leases; - int srvnqnfs_maxleases; - int srvnqnfs_getleases; - int srvvop_writes; - int accesscache_hits; - int accesscache_misses; -}; -#endif - -/* - * Flags for nfssvc() system call. - */ -#define NFSSVC_BIOD 0x002 -#define NFSSVC_NFSD 0x004 -#define NFSSVC_ADDSOCK 0x008 -#define NFSSVC_AUTHIN 0x010 -#define NFSSVC_GOTAUTH 0x040 -#define NFSSVC_AUTHINFAIL 0x080 -#define NFSSVC_MNTD 0x100 -#define NFSSVC_LOCKDANS 0x200 - -/* - * fs.nfs sysctl(3) identifiers - */ -#define NFS_NFSSTATS 1 /* struct: struct nfsstats */ -#define NFS_NFSPRIVPORT 2 /* int: prohibit nfs to resvports */ - -#define FS_NFS_NAMES { \ - { 0, 0 }, \ - { "nfsstats", CTLTYPE_STRUCT }, \ - { "nfsprivport", CTLTYPE_INT }, \ -} - -#ifdef _KERNEL - -#ifdef MALLOC_DECLARE -MALLOC_DECLARE(M_NFSREQ); -MALLOC_DECLARE(M_NFSDIROFF); -MALLOC_DECLARE(M_NFSRVDESC); -MALLOC_DECLARE(M_NFSUID); -MALLOC_DECLARE(M_NQLEASE); -MALLOC_DECLARE(M_NFSD); -MALLOC_DECLARE(M_NFSBIGFH); -MALLOC_DECLARE(M_NFSHASH); -#endif - -#ifdef ZONE_INTERRUPT -extern vm_zone_t nfsmount_zone; -#endif - -extern struct callout_handle nfs_timer_handle; - -struct uio; struct buf; struct vattr; struct nameidata; /* XXX */ - -/* - * The set of signals the interrupt an I/O in progress for NFSMNT_INT mounts. - * What should be in this set is open to debate, but I believe that since - * I/O system calls on ufs are never interrupted by signals the set should - * be minimal. My reasoning is that many current programs that use signals - * such as SIGALRM will not expect file I/O system calls to be interrupted - * by them and break. - */ -#define NFSINT_SIGMASK(set) \ - (SIGISMEMBER(set, SIGINT) || SIGISMEMBER(set, SIGTERM) || \ - SIGISMEMBER(set, SIGHUP) || SIGISMEMBER(set, SIGKILL) || \ - SIGISMEMBER(set, SIGQUIT)) - -/* - * Socket errors ignored for connectionless sockets?? - * For now, ignore them all - */ -#define NFSIGNORE_SOERROR(s, e) \ - ((e) != EINTR && (e) != ERESTART && (e) != EWOULDBLOCK && \ - ((s) & PR_CONNREQUIRED) == 0) - -/* - * Nfs outstanding request list element - */ -struct nfsreq { - TAILQ_ENTRY(nfsreq) r_chain; - struct mbuf *r_mreq; - struct mbuf *r_mrep; - struct mbuf *r_md; - caddr_t r_dpos; - struct nfsmount *r_nmp; - struct vnode *r_vp; - u_int32_t r_xid; - int r_flags; /* flags on request, see below */ - int r_retry; /* max retransmission count */ - int r_rexmit; /* current retrans count */ - int r_timer; /* tick counter on reply */ - u_int32_t r_procnum; /* NFS procedure number */ - int r_rtt; /* RTT for rpc */ - struct thread *r_td; /* Proc that did I/O system call */ -}; - -/* - * Queue head for nfsreq's - */ -extern TAILQ_HEAD(nfs_reqq, nfsreq) nfs_reqq; - -/* Flag values for r_flags */ -#define R_TIMING 0x01 /* timing request (in mntp) */ -#define R_SENT 0x02 /* request has been sent */ -#define R_SOFTTERM 0x04 /* soft mnt, too many retries */ -#define R_INTR 0x08 /* intr mnt, signal pending */ -#define R_SOCKERR 0x10 /* Fatal error on socket */ -#define R_TPRINTFMSG 0x20 /* Did a tprintf msg. */ -#define R_MUSTRESEND 0x40 /* Must resend request */ -#define R_GETONEREP 0x80 /* Probe for one reply only */ - -/* - * A list of nfssvc_sock structures is maintained with all the sockets - * that require service by the nfsd. - * The nfsuid structs hang off of the nfssvc_sock structs in both lru - * and uid hash lists. - */ -#ifndef NFS_UIDHASHSIZ -#define NFS_UIDHASHSIZ 29 /* Tune the size of nfssvc_sock with this */ -#endif -#define NUIDHASH(sock, uid) \ - (&(sock)->ns_uidhashtbl[(uid) % NFS_UIDHASHSIZ]) -#ifndef NFS_WDELAYHASHSIZ -#define NFS_WDELAYHASHSIZ 16 /* and with this */ -#endif -#define NWDELAYHASH(sock, f) \ - (&(sock)->ns_wdelayhashtbl[(*((u_int32_t *)(f))) % NFS_WDELAYHASHSIZ]) -#ifndef NFS_MUIDHASHSIZ -#define NFS_MUIDHASHSIZ 63 /* Tune the size of nfsmount with this */ -#endif -#define NMUIDHASH(nmp, uid) \ - (&(nmp)->nm_uidhashtbl[(uid) % NFS_MUIDHASHSIZ]) -#define NFSNOHASH(fhsum) \ - (&nfsnodehashtbl[(fhsum) & nfsnodehash]) - -/* - * Network address hash list element - */ -union nethostaddr { - u_int32_t had_inetaddr; - struct sockaddr *had_nam; -}; - -struct nfsuid { - TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */ - LIST_ENTRY(nfsuid) nu_hash; /* Hash list */ - int nu_flag; /* Flags */ - union nethostaddr nu_haddr; /* Host addr. for dgram sockets */ - struct ucred nu_cr; /* Cred uid mapped to */ - int nu_expire; /* Expiry time (sec) */ - struct timeval nu_timestamp; /* Kerb. timestamp */ - u_int32_t nu_nickname; /* Nickname on server */ - NFSKERBKEY_T nu_key; /* and session key */ -}; - -#define nu_inetaddr nu_haddr.had_inetaddr -#define nu_nam nu_haddr.had_nam -/* Bits for nu_flag */ -#define NU_INETADDR 0x1 -#define NU_NAM 0x2 -#define NU_NETFAM(u) (((u)->nu_flag & NU_INETADDR) ? AF_INET : AF_ISO) - -struct nfsrv_rec { - STAILQ_ENTRY(nfsrv_rec) nr_link; - struct sockaddr *nr_address; - struct mbuf *nr_packet; -}; - -struct nfssvc_sock { - TAILQ_ENTRY(nfssvc_sock) ns_chain; /* List of all nfssvc_sock's */ - TAILQ_HEAD(, nfsuid) ns_uidlruhead; - struct file *ns_fp; - struct socket *ns_so; - struct sockaddr *ns_nam; - struct mbuf *ns_raw; - struct mbuf *ns_rawend; - STAILQ_HEAD(, nfsrv_rec) ns_rec; - struct mbuf *ns_frag; - int ns_flag; - int ns_solock; - int ns_cc; - int ns_reclen; - int ns_numuids; - u_int32_t ns_sref; - LIST_HEAD(, nfsrv_descript) ns_tq; /* Write gather lists */ - LIST_HEAD(, nfsuid) ns_uidhashtbl[NFS_UIDHASHSIZ]; - LIST_HEAD(nfsrvw_delayhash, nfsrv_descript) ns_wdelayhashtbl[NFS_WDELAYHASHSIZ]; -}; - -/* Bits for "ns_flag" */ -#define SLP_VALID 0x01 -#define SLP_DOREC 0x02 -#define SLP_NEEDQ 0x04 -#define SLP_DISCONN 0x08 -#define SLP_GETSTREAM 0x10 -#define SLP_LASTFRAG 0x20 -#define SLP_ALLFLAGS 0xff - -extern TAILQ_HEAD(nfssvc_sockhead, nfssvc_sock) nfssvc_sockhead; -extern int nfssvc_sockhead_flag; -#define SLP_INIT 0x01 -#define SLP_WANTINIT 0x02 - -/* - * One of these structures is allocated for each nfsd. - */ -struct nfsd { - TAILQ_ENTRY(nfsd) nfsd_chain; /* List of all nfsd's */ - int nfsd_flag; /* NFSD_ flags */ - struct nfssvc_sock *nfsd_slp; /* Current socket */ - int nfsd_authlen; /* Authenticator len */ - u_char nfsd_authstr[RPCAUTH_MAXSIZ]; /* Authenticator data */ - int nfsd_verflen; /* and the Verifier */ - u_char nfsd_verfstr[RPCVERF_MAXSIZ]; - struct thread *nfsd_td; /* daemon thread ptr */ - struct nfsrv_descript *nfsd_nd; /* Associated nfsrv_descript */ -}; - -/* Bits for "nfsd_flag" */ -#define NFSD_WAITING 0x01 -#define NFSD_REQINPROG 0x02 -#define NFSD_NEEDAUTH 0x04 -#define NFSD_AUTHFAIL 0x08 - -/* - * This structure is used by the server for describing each request. - * Some fields are used only when write request gathering is performed. - */ -struct nfsrv_descript { - u_quad_t nd_time; /* Write deadline (usec) */ - off_t nd_off; /* Start byte offset */ - off_t nd_eoff; /* and end byte offset */ - LIST_ENTRY(nfsrv_descript) nd_hash; /* Hash list */ - LIST_ENTRY(nfsrv_descript) nd_tq; /* and timer list */ - LIST_HEAD(,nfsrv_descript) nd_coalesce; /* coalesced writes */ - struct mbuf *nd_mrep; /* Request mbuf list */ - struct mbuf *nd_md; /* Current dissect mbuf */ - struct mbuf *nd_mreq; /* Reply mbuf list */ - struct sockaddr *nd_nam; /* and socket addr */ - struct sockaddr *nd_nam2; /* return socket addr */ - caddr_t nd_dpos; /* Current dissect pos */ - u_int32_t nd_procnum; /* RPC # */ - int nd_stable; /* storage type */ - int nd_flag; /* nd_flag */ - int nd_len; /* Length of this write */ - int nd_repstat; /* Reply status */ - u_int32_t nd_retxid; /* Reply xid */ - u_int32_t nd_duration; /* Lease duration */ - struct timeval nd_starttime; /* Time RPC initiated */ - fhandle_t nd_fh; /* File handle */ - struct ucred nd_cr; /* Credentials */ + int rpccnt[NFS_NPROCS]; }; -/* Bits for "nd_flag" */ -#define ND_READ LEASE_READ -#define ND_WRITE LEASE_WRITE -#define ND_CHECK 0x04 -#define ND_LEASE (ND_READ | ND_WRITE | ND_CHECK) -#define ND_NFSV3 0x08 -#define ND_NQNFS 0x10 -#define ND_KERBNICK 0x20 -#define ND_KERBFULL 0x40 -#define ND_KERBAUTH (ND_KERBNICK | ND_KERBFULL) - -extern TAILQ_HEAD(nfsd_head, nfsd) nfsd_head; -extern int nfsd_head_flag; -#define NFSD_CHECKSLP 0x01 - -/* - * These macros compare nfsrv_descript structures. - */ -#define NFSW_CONTIG(o, n) \ - ((o)->nd_eoff >= (n)->nd_off && \ - !bcmp((caddr_t)&(o)->nd_fh, (caddr_t)&(n)->nd_fh, NFSX_V3FH)) - -#define NFSW_SAMECRED(o, n) \ - (((o)->nd_flag & ND_KERBAUTH) == ((n)->nd_flag & ND_KERBAUTH) && \ - !bcmp((caddr_t)&(o)->nd_cr, (caddr_t)&(n)->nd_cr, \ - sizeof (struct ucred))) - -/* - * Defines for WebNFS - */ - -#define WEBNFS_ESC_CHAR '%' -#define WEBNFS_SPECCHAR_START 0x80 - -#define WEBNFS_NATIVE_CHAR 0x80 -/* - * .. - * Possibly more here in the future. - */ - -/* - * Macro for converting escape characters in WebNFS pathnames. - * Should really be in libkern. - */ - -#define HEXTOC(c) \ - ((c) >= 'a' ? ((c) - ('a' - 10)) : \ - ((c) >= 'A' ? ((c) - ('A' - 10)) : ((c) - '0'))) -#define HEXSTRTOI(p) \ - ((HEXTOC(p[0]) << 4) + HEXTOC(p[1])) - -#ifdef NFS_DEBUG - -extern int nfs_debug; -#define NFS_DEBUG_ASYNCIO 1 /* asynchronous i/o */ -#define NFS_DEBUG_WG 2 /* server write gathering */ -#define NFS_DEBUG_RC 4 /* server request caching */ - -#define NFS_DPF(cat, args) \ - do { \ - if (nfs_debug & NFS_DEBUG_##cat) printf args; \ - } while (0) - -#else - -#define NFS_DPF(cat, args) - -#endif - -u_quad_t nfs_curusec __P((void)); -int nfs_init __P((struct vfsconf *vfsp)); -int nfs_uninit __P((struct vfsconf *vfsp)); -int nfs_reply __P((struct nfsreq *)); -int nfs_getreq __P((struct nfsrv_descript *,struct nfsd *,int)); -int nfs_send __P((struct socket *, struct sockaddr *, struct mbuf *, - struct nfsreq *)); -int nfs_rephead __P((int, struct nfsrv_descript *, struct nfssvc_sock *, - int, int, u_quad_t *, struct mbuf **, struct mbuf **, - caddr_t *)); -int nfs_sndlock __P((struct nfsreq *)); -void nfs_sndunlock __P((struct nfsreq *)); -int nfs_slplock __P((struct nfssvc_sock *, int)); -void nfs_slpunlock __P((struct nfssvc_sock *)); -int nfs_disct __P((struct mbuf **, caddr_t *, int, int, caddr_t *)); -int nfs_vinvalbuf __P((struct vnode *, int, struct ucred *, struct thread *, - int)); -int nfs_readrpc __P((struct vnode *, struct uio *, struct ucred *)); -int nfs_writerpc __P((struct vnode *, struct uio *, struct ucred *, int *, - int *)); -int nfs_commit __P((struct vnode *vp, u_quad_t offset, int cnt, - struct ucred *cred, struct thread *td)); -int nfs_readdirrpc __P((struct vnode *, struct uio *, struct ucred *)); -int nfs_asyncio __P((struct buf *, struct ucred *, struct thread *)); -int nfs_doio __P((struct buf *, struct ucred *, struct thread *)); -int nfs_readlinkrpc __P((struct vnode *, struct uio *, struct ucred *)); -int nfs_sigintr __P((struct nfsmount *, struct nfsreq *, struct proc *)); -int nfs_readdirplusrpc __P((struct vnode *, struct uio *, struct ucred *)); -int nfsm_disct __P((struct mbuf **, caddr_t *, int, int, caddr_t *)); -void nfsm_srvfattr __P((struct nfsrv_descript *, struct vattr *, - struct nfs_fattr *)); -void nfsm_srvwcc __P((struct nfsrv_descript *, int, struct vattr *, int, - struct vattr *, struct mbuf **, char **)); -void nfsm_srvpostopattr __P((struct nfsrv_descript *, int, struct vattr *, - struct mbuf **, char **)); -int netaddr_match __P((int, union nethostaddr *, struct sockaddr *)); -int nfs_request __P((struct vnode *, struct mbuf *, int, struct thread *, - struct ucred *, struct mbuf **, struct mbuf **, - caddr_t *)); -int nfs_loadattrcache __P((struct vnode **, struct mbuf **, caddr_t *, - struct vattr *, int)); -int nfs_namei __P((struct nameidata *, fhandle_t *, int, - struct nfssvc_sock *, struct sockaddr *, struct mbuf **, - caddr_t *, struct vnode **, struct thread *, int, int)); -void nfsm_adj __P((struct mbuf *, int, int)); -int nfsm_mbuftouio __P((struct mbuf **, struct uio *, int, caddr_t *)); -void nfsrv_initcache __P((void)); -int nfs_getauth __P((struct nfsmount *, struct nfsreq *, struct ucred *, - char **, int *, char *, int *, NFSKERBKEY_T)); -int nfs_getnickauth __P((struct nfsmount *, struct ucred *, char **, - int *, char *, int)); -int nfs_savenickauth __P((struct nfsmount *, struct ucred *, int, - NFSKERBKEY_T, struct mbuf **, char **, - struct mbuf *)); -int nfs_adv __P((struct mbuf **, caddr_t *, int, int)); -void nfs_nhinit __P((void)); -void nfs_timer __P((void*)); -int nfsrv_dorec __P((struct nfssvc_sock *, struct nfsd *, - struct nfsrv_descript **)); -int nfsrv_getcache __P((struct nfsrv_descript *, struct nfssvc_sock *, - struct mbuf **)); -void nfsrv_updatecache __P((struct nfsrv_descript *, int, struct mbuf *)); -void nfsrv_cleancache __P((void)); -int nfs_connect __P((struct nfsmount *, struct nfsreq *)); -void nfs_disconnect __P((struct nfsmount *)); -void nfs_safedisconnect __P((struct nfsmount *)); -int nfs_getattrcache __P((struct vnode *, struct vattr *)); -int nfsm_strtmbuf __P((struct mbuf **, char **, const char *, long)); -int nfs_bioread __P((struct vnode *, struct uio *, int, struct ucred *)); -int nfsm_uiotombuf __P((struct uio *, struct mbuf **, int, caddr_t *)); -void nfsrv_init __P((int)); -void nfs_clearcommit __P((struct mount *)); -int nfsrv_errmap __P((struct nfsrv_descript *, int)); -void nfsrvw_sort __P((gid_t *, int)); -void nfsrv_setcred __P((struct ucred *, struct ucred *)); -int nfs_writebp __P((struct buf *, int, struct thread *)); -int nfsrv_object_create __P((struct vnode *)); -void nfsrv_wakenfsd __P((struct nfssvc_sock *slp)); -int nfsrv_writegather __P((struct nfsrv_descript **, struct nfssvc_sock *, - struct thread *, struct mbuf **)); -int nfs_fsinfo __P((struct nfsmount *, struct vnode *, struct ucred *, - struct thread *td)); - -int nfsrv3_access __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_commit __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_create __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_fhtovp __P((fhandle_t *, int, struct vnode **, struct ucred *, - struct nfssvc_sock *, struct sockaddr *, int *, - int, int)); -int nfsrv_setpublicfs __P((struct mount *, struct netexport *, - struct export_args *)); -int nfs_ispublicfh __P((fhandle_t *)); -int nfsrv_fsinfo __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_getattr __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_link __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_lookup __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_mkdir __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_mknod __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_noop __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_null __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_pathconf __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, struct thread *td, - struct mbuf **mrq)); -int nfsrv_read __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_readdir __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_readdirplus __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, struct thread *td, - struct mbuf **mrq)); -int nfsrv_readlink __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, struct thread *td, - struct mbuf **mrq)); -int nfsrv_remove __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_rename __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_rmdir __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_setattr __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_statfs __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_symlink __P((struct nfsrv_descript *nfsd, - struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct thread *td, struct mbuf **mrq)); -void nfsrv_rcv __P((struct socket *so, void *arg, int waitflag)); -void nfsrv_slpderef __P((struct nfssvc_sock *slp)); -#endif /* _KERNEL */ - #endif diff --git a/sys/nfsclient/nlminfo.h b/sys/nfsclient/nlminfo.h index 79c6e17..3dc55b4 100644 --- a/sys/nfsclient/nlminfo.h +++ b/sys/nfsclient/nlminfo.h @@ -41,5 +41,4 @@ struct nlminfo { struct timeval pid_start; /* process starting time */ }; -extern void nlminfo_release __P((struct proc *p)); - +extern void nlminfo_release(struct proc *p); |