Bring in a merge of Rick Macklem's NFSv3 code from Lite2

This commit is contained in:
fvdl 1996-02-18 11:53:36 +00:00
parent e5730c4a73
commit 5ac7df1caf
25 changed files with 7530 additions and 3118 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: krpc_subr.c,v 1.11 1995/12/19 23:07:19 cgd Exp $ */
/* $NetBSD: krpc_subr.c,v 1.12 1996/02/18 11:53:36 fvdl Exp $ */
/*
* Copyright (c) 1995 Gordon Ross, Adam Glass
@ -97,8 +97,8 @@ struct rpc_call {
struct rpc_reply {
u_int32_t rp_xid; /* request transaction id */
int32_t rp_direction; /* call direction (1) */
int32_t rp_astatus; /* accept status (0: accepted) */
int32_t rp_direction; /* call direction (1) */
int32_t rp_astatus; /* accept status (0: accepted) */
union {
u_int32_t rpu_errno;
struct {

View File

@ -1,7 +1,6 @@
/* $NetBSD: nfs.h,v 1.9 1995/12/19 23:07:21 cgd Exp $ */
/* $NetBSD: nfs.h,v 1.10 1996/02/18 11:53:38 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
* Copyright (c) 1989, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@ -35,34 +34,93 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfs.h 8.1 (Berkeley) 6/10/93
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
*/
#ifndef _NFS_NFS_H_
#define _NFS_NFS_H_
/*
* Tunable constants for nfs
*/
#define NFS_MAXIOVEC 34
#define NFS_HZ 25 /* Ticks per second for NFS timeouts */
#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_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 5 /* Attribute cache timeout in sec */
#endif
#ifndef NFS_MAXATTRTIMO
#define NFS_MAXATTRTIMO 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_MAXREADDIR NFS_MAXDATA /* Max. size of directory read */
#define NFS_MAXUIDHASH 64 /* Max. # of hashed uid entries/mp */
#define NFS_MAXASYNCDAEMON 20 /* Max. number async_daemons runable */
#define NFS_DIRBLKSIZ 1024 /* Size of an NFS directory block */
#define NFS_MAXASYNCDAEMON 20 /* Max. number async_daemons runable */
#define NFS_MAXGATHERDELAY 100 /* Max. write gather delay (msec) */
#ifndef NFS_GATHERDELAY
#define NFS_GATHERDELAY 10 /* Default write gather delay (msec) */
#endif
/*
* Ideally, NFS_DIRBLKSIZ should be bigger, but I've seen servers with
* broken NFS/ethernet drivers that won't work with anything bigger (Linux..)
*/
#define NFS_DIRBLKSIZ 1024 /* Must be a multiple of DIRBLKSIZ */
#define NFS_READDIRBLKSIZ 512 /* Size of read dir blocks. XXX */
/*
* 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)
/*
* sys/malloc.h needs M_NFSDIROFF, M_NFSRVDESC and M_NFSBIGFH added.
* The VA_EXCLUSIVE flag should be added for va_vaflags and set for an
* exclusive create.
*/
#ifndef M_NFSRVDESC
#define M_NFSRVDESC M_TEMP
#endif
#ifndef M_NFSDIROFF
#define M_NFSDIROFF M_TEMP
#endif
#ifndef M_NFSBIGFH
#define M_NFSBIGFH M_TEMP
#endif
#ifndef VA_EXCLUSIVE
#define VA_EXCLUSIVE 0
#endif
/*
* 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_INVAL
/*
* 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
/*
* Set the attribute timeout based on how recently the file has been modified.
@ -73,13 +131,27 @@
((time.tv_sec - (np)->n_mtime) / 10 > NFS_MAXATTRTIMO ? NFS_MAXATTRTIMO : \
(time.tv_sec - (np)->n_mtime) / 10))
/*
* Expected allocation sizes for major data structures. If the actual size
* of the structure exceeds these sizes, then malloc() will be allocating
* almost twice the memory required. This is used in nfs_init() to warn
* the sysadmin that the size of a structure should be reduced.
* (These sizes are always a power of 2. If the kernel malloc() changes
* to one that does not allocate space in powers of 2 size, then this all
* becomes bunk!)
*/
#define NFS_NODEALLOC 256
#define NFS_MNTALLOC 512
#define NFS_SVCALLOC 256
#define NFS_UIDALLOC 128
/*
* 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 address for connection based sockets */
caddr_t name; /* Client addr for connection based sockets */
int namelen; /* Length of name */
};
@ -89,7 +161,12 @@ struct nfsd_srvargs {
u_int32_t nsd_haddr; /* Ip address of client */
struct ucred nsd_cr; /* Cred. uid maps to */
int nsd_authlen; /* Length of auth string (ret) */
char *nsd_authstr; /* Auth string (ret) */
u_char *nsd_authstr; /* Auth string (ret) */
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 {
@ -97,7 +174,10 @@ struct nfsd_cargs {
uid_t ncd_authuid; /* Effective uid */
int ncd_authtype; /* Type of authenticator */
int ncd_authlen; /* Length of authenticator string */
char *ncd_authstr; /* Authenticator string */
u_char *ncd_authstr; /* Authenticator string */
int ncd_verflen; /* and the verifier */
u_char *ncd_verfstr;
NFSKERBKEY_T ncd_key; /* Session key */
};
/*
@ -136,6 +216,7 @@ struct nfsstats {
int srvnqnfs_leases;
int srvnqnfs_maxleases;
int srvnqnfs_getleases;
int srvvop_writes;
};
/*
@ -149,6 +230,16 @@ struct nfsstats {
#define NFSSVC_AUTHINFAIL 0x080
#define NFSSVC_MNTD 0x100
/*
* fs.nfs sysctl(3) identifiers
*/
#define NFS_NFSSTATS 1 /* struct: struct nfsstats */
#define FS_NFS_NAMES { \
{ 0, 0 }, \
{ "nfsstats", CTLTYPE_STRUCT }, \
}
/*
* 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
@ -158,6 +249,9 @@ struct nfsstats {
* by them and break.
*/
#ifdef _KERNEL
struct uio; struct buf; struct vattr; struct nameidata; /* XXX */
#define NFSINT_SIGMASK (sigmask(SIGINT)|sigmask(SIGTERM)|sigmask(SIGKILL)| \
sigmask(SIGHUP)|sigmask(SIGQUIT))
@ -205,17 +299,29 @@ TAILQ_HEAD(, nfsreq) nfs_reqq;
#define R_MUSTRESEND 0x40 /* Must resend request */
#define R_GETONEREP 0x80 /* Probe for one reply only */
struct nfsstats nfsstats;
/*
* 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.
*/
#define NUIDHASHSIZ 32
#ifndef NFS_UIDHASHSIZ
#define NFS_UIDHASHSIZ 29 /* Tune the size of nfssvc_sock with this */
#endif
#define NUIDHASH(sock, uid) \
(&(sock)->ns_uidhashtbl[(uid) & (sock)->ns_uidhash])
(&(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_long *)(f))) % NFS_WDELAYHASHSIZ])
#ifndef NFS_MUIDHASHSIZ
#define NFS_MUIDHASHSIZ 67 /* 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
@ -229,35 +335,41 @@ struct nfsuid {
TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */
LIST_ENTRY(nfsuid) nu_hash; /* Hash list */
int nu_flag; /* Flags */
uid_t nu_uid; /* Uid mapped by this entry */
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 nfssvc_sock {
TAILQ_ENTRY(nfssvc_sock) ns_chain; /* List of all nfssvc_sock's */
TAILQ_HEAD(, nfsuid) ns_uidlruhead;
LIST_HEAD(, nfsuid) *ns_uidhashtbl;
u_long ns_uidhash;
int ns_flag;
u_int32_t ns_sref;
struct file *ns_fp;
struct socket *ns_so;
int ns_solock;
struct mbuf *ns_nam;
int ns_cc;
struct mbuf *ns_raw;
struct mbuf *ns_rawend;
int ns_reclen;
struct mbuf *ns_rec;
struct mbuf *ns_recend;
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" */
@ -266,6 +378,7 @@ struct nfssvc_sock {
#define SLP_NEEDQ 0x04
#define SLP_DISCONN 0x08
#define SLP_GETSTREAM 0x10
#define SLP_LASTFRAG 0x20
#define SLP_ALLFLAGS 0xff
TAILQ_HEAD(, nfssvc_sock) nfssvc_sockhead;
@ -277,32 +390,79 @@ int nfssvc_sockhead_flag;
* One of these structures is allocated for each nfsd.
*/
struct nfsd {
TAILQ_ENTRY(nfsd) nd_chain; /* List of all nfsd's */
int nd_flag; /* NFSD_ flags */
struct nfssvc_sock *nd_slp; /* Current socket */
struct mbuf *nd_nam; /* Client addr for datagram req. */
struct mbuf *nd_mrep; /* Req. mbuf list */
struct mbuf *nd_md;
caddr_t nd_dpos; /* Position in list */
int nd_procnum; /* RPC procedure number */
u_int32_t nd_retxid; /* RPC xid */
int nd_repstat; /* Reply status value */
struct ucred nd_cr; /* Credentials for req. */
int nd_nqlflag; /* Leasing flag */
int nd_duration; /* Lease duration */
int nd_authlen; /* Authenticator len */
u_char nd_authstr[RPCAUTH_MAXSIZ]; /* Authenticator data */
struct proc *nd_procp; /* Proc ptr */
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 proc *nfsd_procp; /* Proc ptr */
struct nfsrv_descript *nfsd_nd; /* Associated nfsrv_descript */
};
/* Bits for "nd_flag" */
/* 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 mbuf *nd_nam; /* and socket addr */
struct mbuf *nd_nam2; /* return socket addr */
caddr_t nd_dpos; /* Current dissect pos */
int 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)
TAILQ_HEAD(, nfsd) nfsd_head;
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)))
#endif /* _KERNEL */
#endif /* _NFS_NFS_H */

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_bio.c,v 1.23 1996/02/09 21:48:19 christos Exp $ */
/* $NetBSD: nfs_bio.c,v 1.24 1996/02/18 11:53:39 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
@ -35,12 +35,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfs_bio.c 8.5 (Berkeley) 1/4/94
* @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/resourcevar.h>
#include <sys/signalvar.h>
#include <sys/proc.h>
#include <sys/buf.h>
#include <sys/vnode.h>
@ -48,20 +50,20 @@
#include <sys/mount.h>
#include <sys/kernel.h>
#include <sys/namei.h>
#include <sys/signalvar.h>
#include <vm/vm.h>
#include <nfs/nfsnode.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsv2.h>
#include <nfs/nfsproto.h>
#include <nfs/nfs.h>
#include <nfs/nfsmount.h>
#include <nfs/nqnfs.h>
#include <nfs/nfsnode.h>
#include <nfs/nfs_var.h>
extern struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON];
extern int nfs_numasync;
extern struct nfsstats nfsstats;
/*
* Vnode op for read using bio
@ -75,29 +77,27 @@ nfs_bioread(vp, uio, ioflag, cred)
struct ucred *cred;
{
register struct nfsnode *np = VTONFS(vp);
register int biosize, diff;
register int biosize, diff, i;
struct buf *bp = NULL, *rabp;
struct vattr vattr;
struct proc *p;
struct nfsmount *nmp;
struct nfsmount *nmp = VFSTONFS(vp->v_mount);
daddr_t lbn, bn, rabn;
caddr_t baddr;
int got_buf = 0, nra, error = 0, n = 0, on = 0, not_readin;
#ifdef lint
ioflag = ioflag;
#endif /* lint */
#ifdef DIAGNOSTIC
if (uio->uio_rw != UIO_READ)
panic("nfs_read mode");
#endif
if (uio->uio_resid == 0)
return (0);
if (uio->uio_offset < 0 && vp->v_type != VDIR)
if (uio->uio_offset < 0)
return (EINVAL);
nmp = VFSTONFS(vp->v_mount);
biosize = nmp->nm_rsize;
p = uio->uio_procp;
if ((nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_GOTFSINFO)) == NFSMNT_NFSV3)
(void)nfs_fsinfo(nmp, vp, cred, p);
biosize = nmp->nm_rsize;
/*
* For nfs, cache consistency can only be maintained approximately.
* Although RFC1094 does not specify the criteria, the following is
@ -110,8 +110,6 @@ nfs_bioread(vp, uio, ioflag, cred)
* server, so flush all of the file's data out of the cache.
* Then force a getattr rpc to ensure that you have up to date
* attributes.
* The mount flag NFSMNT_MYWRITE says "Assume that my writes are
* the ones changing the modify time.
* NB: This implies that cache data can be read when up to
* NFS_ATTRTIMEO seconds out of date. If you find that you need current
* attributes this could be forced by setting n_attrstamp to 0 before
@ -119,23 +117,26 @@ nfs_bioread(vp, uio, ioflag, cred)
*/
if ((nmp->nm_flag & NFSMNT_NQNFS) == 0 && vp->v_type != VLNK) {
if (np->n_flag & NMODIFIED) {
if ((nmp->nm_flag & NFSMNT_MYWRITE) == 0 ||
vp->v_type != VREG) {
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, p, 1);
if (error)
return (error);
}
np->n_attrstamp = 0;
np->n_direofoffset = 0;
error = VOP_GETATTR(vp, &vattr, cred, p);
if (error)
return (error);
np->n_mtime = vattr.va_mtime.tv_sec;
} else {
if ((error = VOP_GETATTR(vp, &vattr, cred, p)) != 0)
error = VOP_GETATTR(vp, &vattr, cred, p);
if (error)
return (error);
if (np->n_mtime != vattr.va_mtime.tv_sec) {
np->n_direofoffset = 0;
if (vp->v_type == VDIR)
nfs_invaldir(vp);
error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
if (error)
return (error);
@ -149,27 +150,24 @@ nfs_bioread(vp, uio, ioflag, cred)
* Get a valid lease. If cached data is stale, flush it.
*/
if (nmp->nm_flag & NFSMNT_NQNFS) {
if (NQNFS_CKINVALID(vp, np, NQL_READ)) {
if (NQNFS_CKINVALID(vp, np, ND_READ)) {
do {
error = nqnfs_getlease(vp, NQL_READ, cred, p);
error = nqnfs_getlease(vp, ND_READ, cred, p);
} while (error == NQNFS_EXPIRED);
if (error)
return (error);
if (np->n_lrev != np->n_brev ||
(np->n_flag & NQNFSNONCACHE) ||
((np->n_flag & NMODIFIED) && vp->v_type == VDIR)) {
if (vp->v_type == VDIR) {
np->n_direofoffset = 0;
cache_purge(vp);
}
if (vp->v_type == VDIR)
nfs_invaldir(vp);
error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
if (error)
return (error);
np->n_brev = np->n_lrev;
}
} else if (vp->v_type == VDIR && (np->n_flag & NMODIFIED)) {
np->n_direofoffset = 0;
cache_purge(vp);
nfs_invaldir(vp);
error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
if (error)
return (error);
@ -178,38 +176,29 @@ nfs_bioread(vp, uio, ioflag, cred)
if (np->n_flag & NQNFSNONCACHE) {
switch (vp->v_type) {
case VREG:
error = nfs_readrpc(vp, uio, cred);
break;
return (nfs_readrpc(vp, uio, cred));
case VLNK:
error = nfs_readlinkrpc(vp, uio, cred);
break;
return (nfs_readlinkrpc(vp, uio, cred));
case VDIR:
error = nfs_readdirrpc(vp, uio, cred);
break;
case VCHR:
case VSOCK:
case VFIFO:
case VBAD:
case VNON:
case VBLK:
break;
default:
printf(" NQNFSNONCACHE: type %x unexpected\n",
vp->v_type);
};
return (error);
}
baddr = (caddr_t)0;
switch (vp->v_type) {
case VREG:
nfsstats.biocache_reads++;
lbn = uio->uio_offset / biosize;
on = uio->uio_offset & (biosize-1);
on = uio->uio_offset & (biosize - 1);
bn = lbn * (biosize / DEV_BSIZE);
not_readin = 1;
/*
* Start the read ahead(s), as required.
*/
if (nfs_numasync > 0 && nmp->nm_readahead > 0 &&
lbn == vp->v_lastr + 1) {
if (nfs_numasync > 0 && nmp->nm_readahead > 0) {
for (nra = 0; nra < nmp->nm_readahead &&
(lbn + 1 + nra) * biosize < np->n_size; nra++) {
rabn = (lbn + 1 + nra) * (biosize / DEV_BSIZE);
@ -267,7 +256,7 @@ again:
return (EINTR);
got_buf = 1;
}
bp->b_flags |= B_INVAL;
bp->b_flags |= B_INVAFTERWRITE;
if (bp->b_dirtyend > 0) {
if ((bp->b_flags & B_DELWRI) == 0)
panic("nfsbioread");
@ -290,7 +279,8 @@ again:
return (EINTR);
if ((bp->b_flags & B_DONE) == 0) {
bp->b_flags |= B_READ;
if ((error = nfs_doio(bp, cred, p)) != 0) {
error = nfs_doio(bp, cred, p);
if (error) {
brelse(bp);
return (error);
}
@ -300,31 +290,56 @@ again:
on = 0;
break;
case VDIR:
if (uio->uio_resid < NFS_DIRBLKSIZ)
if (uio->uio_resid < NFS_READDIRBLKSIZ)
return (0);
nfsstats.biocache_readdirs++;
bn = (daddr_t)uio->uio_offset;
bp = nfs_getcacheblk(vp, bn, NFS_DIRBLKSIZ, p);
lbn = uio->uio_offset / NFS_DIRBLKSIZ;
on = uio->uio_offset & (NFS_DIRBLKSIZ - 1);
bp = nfs_getcacheblk(vp, lbn, NFS_DIRBLKSIZ, p);
if (!bp)
return (EINTR);
return (EINTR);
if ((bp->b_flags & B_DONE) == 0) {
bp->b_flags |= B_READ;
if ((error = nfs_doio(bp, cred, p)) != 0) {
brelse(bp);
return (error);
bp->b_flags |= B_READ;
error = nfs_doio(bp, cred, p);
if (error) {
brelse(bp);
while (error == NFSERR_BAD_COOKIE) {
nfs_invaldir(vp);
error = nfs_vinvalbuf(vp, 0, cred, p, 1);
/*
* Yuck! The directory has been modified on the
* server. The only way to get the block is by
* reading from the beginning to get all the
* offset cookies.
*/
for (i = 0; i <= lbn && !error; i++) {
bp = nfs_getcacheblk(vp, i, NFS_DIRBLKSIZ, p);
if (!bp)
return (EINTR);
if ((bp->b_flags & B_DONE) == 0) {
bp->b_flags |= B_READ;
error = nfs_doio(bp, cred, p);
if (error)
brelse(bp);
}
}
}
if (error)
return (error);
}
}
/*
* If not eof and read aheads are enabled, start one.
* (You need the current block first, so that you have the
* directory offset cookie of the next block.
* directory offset cookie of the next block.)
*/
rabn = bp->b_blkno;
if (nfs_numasync > 0 && nmp->nm_readahead > 0 &&
rabn != 0 && rabn != np->n_direofoffset &&
!incore(vp, rabn)) {
rabp = nfs_getcacheblk(vp, rabn, NFS_DIRBLKSIZ, p);
(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, p);
if (rabp) {
if ((rabp->b_flags & (B_DONE | B_DELWRI)) == 0) {
rabp->b_flags |= (B_READ | B_ASYNC);
@ -336,16 +351,11 @@ again:
brelse(rabp);
}
}
on = 0;
n = min(uio->uio_resid, NFS_DIRBLKSIZ - bp->b_resid);
n = min(uio->uio_resid, NFS_DIRBLKSIZ - bp->b_resid - on);
got_buf = 1;
break;
case VBAD:
case VSOCK:
case VCHR:
case VBLK:
case VNON:
case VFIFO:
default:
printf(" nfsbioread: type %x unexpected\n",vp->v_type);
break;
};
@ -355,21 +365,18 @@ again:
error = uiomove(baddr + on, (int)n, uio);
}
switch (vp->v_type) {
case VREG:
break;
case VLNK:
n = 0;
break;
case VDIR:
uio->uio_offset = bp->b_blkno;
if (np->n_flag & NQNFSNONCACHE)
bp->b_flags |= B_INVAL;
break;
case VREG:
case VBAD:
case VFIFO:
case VSOCK:
case VCHR:
case VBLK:
case VNON:
break;
};
default:
printf(" nfsbioread: type %x unexpected\n",vp->v_type);
}
if (got_buf)
brelse(bp);
} while (error == 0 && uio->uio_resid > 0 && n > 0);
@ -384,7 +391,7 @@ nfs_write(v)
void *v;
{
struct vop_write_args /* {
struct vnode a_vp;
struct vnode *a_vp;
struct uio *a_uio;
int a_ioflag;
struct ucred *a_cred;
@ -398,9 +405,9 @@ nfs_write(v)
int ioflag = ap->a_ioflag;
struct buf *bp;
struct vattr vattr;
struct nfsmount *nmp;
struct nfsmount *nmp = VFSTONFS(vp->v_mount);
daddr_t lbn, bn;
int n, on, error = 0;
int n, on, error = 0, iomode, must_commit;
#ifdef DIAGNOSTIC
if (uio->uio_rw != UIO_WRITE)
@ -414,6 +421,8 @@ nfs_write(v)
np->n_flag &= ~NWRITEERR;
return (np->n_error);
}
if ((nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_GOTFSINFO)) == NFSMNT_NFSV3)
(void)nfs_fsinfo(nmp, vp, cred, p);
if (ioflag & (IO_APPEND | IO_SYNC)) {
if (np->n_flag & NMODIFIED) {
np->n_attrstamp = 0;
@ -429,7 +438,6 @@ nfs_write(v)
uio->uio_offset = np->n_size;
}
}
nmp = VFSTONFS(vp->v_mount);
if (uio->uio_offset < 0)
return (EINVAL);
if (uio->uio_resid == 0)
@ -458,12 +466,11 @@ nfs_write(v)
/*
* Check for a valid write lease.
* If non-cachable, just do the rpc
*/
if ((nmp->nm_flag & NFSMNT_NQNFS) &&
NQNFS_CKINVALID(vp, np, NQL_WRITE)) {
NQNFS_CKINVALID(vp, np, ND_WRITE)) {
do {
error = nqnfs_getlease(vp, NQL_WRITE, cred, p);
error = nqnfs_getlease(vp, ND_WRITE, cred, p);
} while (error == NQNFS_EXPIRED);
if (error)
return (error);
@ -475,8 +482,13 @@ nfs_write(v)
np->n_brev = np->n_lrev;
}
}
if (np->n_flag & NQNFSNONCACHE)
return (nfs_writerpc(vp, uio, cred, ioflag));
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);
return (error);
}
nfsstats.biocache_writes++;
lbn = uio->uio_offset / biosize;
on = uio->uio_offset & (biosize-1);
@ -514,9 +526,9 @@ again:
* In case getblk() and/or bwrite() delayed us.
*/
if ((nmp->nm_flag & NFSMNT_NQNFS) &&
NQNFS_CKINVALID(vp, np, NQL_WRITE)) {
NQNFS_CKINVALID(vp, np, ND_WRITE)) {
do {
error = nqnfs_getlease(vp, NQL_WRITE, cred, p);
error = nqnfs_getlease(vp, ND_WRITE, cred, p);
} while (error == NQNFS_EXPIRED);
if (error) {
brelse(bp);
@ -545,7 +557,6 @@ again:
bp->b_dirtyoff = on;
bp->b_dirtyend = on + n;
}
#ifndef notdef
if (bp->b_validend == 0 || bp->b_validend < bp->b_dirtyoff ||
bp->b_validoff > bp->b_dirtyend) {
bp->b_validoff = bp->b_dirtyoff;
@ -554,26 +565,27 @@ again:
bp->b_validoff = min(bp->b_validoff, bp->b_dirtyoff);
bp->b_validend = max(bp->b_validend, bp->b_dirtyend);
}
#else
bp->b_validoff = bp->b_dirtyoff;
bp->b_validend = bp->b_dirtyend;
#endif
if (ioflag & IO_APPEND)
bp->b_flags |= B_APPENDWRITE;
/*
* If the lease is non-cachable or IO_SYNC do bwrite().
*/
if ((np->n_flag & NQNFSNONCACHE) || (ioflag & IO_SYNC)) {
bp->b_proc = p;
if ((error = VOP_BWRITE(bp)) != 0)
error = VOP_BWRITE(bp);
if (error)
return (error);
if (np->n_flag & NQNFSNONCACHE) {
error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
if (error)
return (error);
}
} else if ((n + on) == biosize &&
(nmp->nm_flag & NFSMNT_NQNFS) == 0) {
bp->b_proc = (struct proc *)0;
bawrite(bp);
} else
bp->b_flags |= B_ASYNC;
(void)nfs_writebp(bp, 0);
} else {
bdwrite(bp);
}
} while (uio->uio_resid > 0 && n > 0);
return (0);
}
@ -689,6 +701,7 @@ nfs_asyncio(bp, cred)
bp->b_rcred = cred;
}
} else {
bp->b_flags |= B_WRITEINPROG;
if (bp->b_wcred == NOCRED && cred != NOCRED) {
crhold(cred);
bp->b_wcred = cred;
@ -700,7 +713,25 @@ nfs_asyncio(bp, cred)
wakeup((caddr_t)&nfs_iodwant[i]);
return (0);
}
return (EIO);
/*
* If it is a read or a write already marked B_WRITEINPROG or B_NOCACHE
* return EIO so the process will call nfs_doio() and do it
* synchronously.
*/
if (bp->b_flags & (B_READ | B_WRITEINPROG | B_NOCACHE))
return (EIO);
/*
* Just turn the async write into a delayed write, instead of
* doing in synchronously. Hopefully, at least one of the nfsiods
* is currently doing a write for this file and will pick up the
* delayed writes before going back to sleep.
*/
bp->b_flags |= B_DELWRI;
reassignbuf(bp, bp->b_vp);
biodone(bp);
return (0);
}
/*
@ -717,7 +748,7 @@ nfs_doio(bp, cr, p)
register struct vnode *vp;
struct nfsnode *np;
struct nfsmount *nmp;
int error = 0, diff, len;
int error = 0, diff, len, iomode, must_commit = 0;
struct uio uio;
struct iovec io;
@ -740,15 +771,16 @@ nfs_doio(bp, cr, p)
io.iov_len = uiop->uio_resid = bp->b_bcount;
/* mapping was done by vmapbuf() */
io.iov_base = bp->b_data;
uiop->uio_offset = bp->b_blkno * DEV_BSIZE;
uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE;
if (bp->b_flags & B_READ) {
uiop->uio_rw = UIO_READ;
nfsstats.read_physios++;
error = nfs_readrpc(vp, uiop, cr);
} else {
iomode = NFSV3WRITE_DATASYNC;
uiop->uio_rw = UIO_WRITE;
nfsstats.write_physios++;
error = nfs_writerpc(vp, uiop, cr, 0);
error = nfs_writerpc(vp, uiop, cr, &iomode, &must_commit);
}
if (error) {
bp->b_flags |= B_ERROR;
@ -760,7 +792,7 @@ nfs_doio(bp, cr, p)
uiop->uio_rw = UIO_READ;
switch (vp->v_type) {
case VREG:
uiop->uio_offset = bp->b_blkno * DEV_BSIZE;
uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE;
nfsstats.read_bios++;
error = nfs_readrpc(vp, uiop, cr);
if (!error) {
@ -773,7 +805,7 @@ nfs_doio(bp, cr, p)
* Just zero fill the rest of the valid area.
*/
diff = bp->b_bcount - uiop->uio_resid;
len = np->n_size - (bp->b_blkno * DEV_BSIZE
len = np->n_size - (((u_quad_t)bp->b_blkno) * DEV_BSIZE
+ diff);
if (len > 0) {
len = min(len, uiop->uio_resid);
@ -786,7 +818,7 @@ nfs_doio(bp, cr, p)
}
if (p && (vp->v_flag & VTEXT) &&
(((nmp->nm_flag & NFSMNT_NQNFS) &&
NQNFS_CKINVALID(vp, np, NQL_READ) &&
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))) {
@ -796,28 +828,24 @@ nfs_doio(bp, cr, p)
}
break;
case VLNK:
uiop->uio_offset = 0;
uiop->uio_offset = (off_t)0;
nfsstats.readlink_bios++;
error = nfs_readlinkrpc(vp, uiop, cr);
break;
case VDIR:
uiop->uio_offset = bp->b_lblkno;
nfsstats.readdir_bios++;
if (VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NQNFS)
error = nfs_readdirlookrpc(vp, uiop, cr);
else
error = nfs_readdirrpc(vp, uiop, cr);
/*
* Save offset cookie in b_blkno.
*/
bp->b_blkno = uiop->uio_offset;
uiop->uio_offset = ((u_quad_t)bp->b_lblkno) * NFS_DIRBLKSIZ;
if (nmp->nm_flag & NFSMNT_RDIRPLUS) {
error = nfs_readdirplusrpc(vp, uiop, cr);
if (error == NFSERR_NOTSUPP)
nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
}
if ((nmp->nm_flag & NFSMNT_RDIRPLUS) == 0)
error = nfs_readdirrpc(vp, uiop, cr);
break;
default:
printf("nfs_doio: type %x unexpected\n",vp->v_type);
break;
case VNON:
case VBLK:
case VCHR:
case VFIFO:
case VBAD:
case VSOCK:
};
if (error) {
bp->b_flags |= B_ERROR;
@ -826,16 +854,26 @@ nfs_doio(bp, cr, p)
} else {
io.iov_len = uiop->uio_resid = bp->b_dirtyend
- bp->b_dirtyoff;
uiop->uio_offset = (bp->b_blkno * DEV_BSIZE)
uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE
+ bp->b_dirtyoff;
io.iov_base = (char *)bp->b_data + bp->b_dirtyoff;
uiop->uio_rw = UIO_WRITE;
nfsstats.write_bios++;
if (bp->b_flags & B_APPENDWRITE)
error = nfs_writerpc(vp, uiop, cr, IO_APPEND);
if ((bp->b_flags & (B_ASYNC | B_NEEDCOMMIT | B_NOCACHE)) == B_ASYNC)
iomode = NFSV3WRITE_UNSTABLE;
else
error = nfs_writerpc(vp, uiop, cr, 0);
bp->b_flags &= ~(B_WRITEINPROG | B_APPENDWRITE);
iomode = NFSV3WRITE_FILESYNC;
bp->b_flags |= B_WRITEINPROG;
#ifdef fvdl_debug
printf("nfs_doio(%x): bp %x doff %d dend %d\n",
vp, bp, bp->b_dirtyoff, bp->b_dirtyend);
#endif
error = nfs_writerpc(vp, uiop, cr, &iomode, &must_commit);
if (!error && iomode == NFSV3WRITE_UNSTABLE)
bp->b_flags |= B_NEEDCOMMIT;
else
bp->b_flags &= ~B_NEEDCOMMIT;
bp->b_flags &= ~B_WRITEINPROG;
/*
* For an interrupted write, the buffer is still valid and the
@ -843,9 +881,13 @@ nfs_doio(bp, cr, p)
* B_ERROR and report the interruption by setting B_EINTR. For
* the B_ASYNC case, B_EINTR is not relevant, so the rpc attempt
* is essentially a noop.
* For the case of a V3 write rpc not being committed to stable
* storage, the block is still dirty and requires either a commit
* rpc or another write rpc with iomode == NFSV3WRITE_FILESYNC
* before the block is reused. This is indicated by setting the
* B_DELWRI and B_NEEDCOMMIT flags.
*/
if (error == EINTR) {
bp->b_flags &= ~B_INVAL;
if (error == EINTR || (!error && (bp->b_flags & B_NEEDCOMMIT))) {
bp->b_flags |= B_DELWRI;
/*
@ -867,6 +909,8 @@ nfs_doio(bp, cr, p)
}
}
bp->b_resid = uiop->uio_resid;
if (must_commit)
nfs_clearcommit(vp->v_mount);
biodone(bp);
return (error);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_boot.c,v 1.24 1996/02/16 15:18:19 gwr Exp $ */
/* $NetBSD: nfs_boot.c,v 1.25 1996/02/18 11:53:41 fvdl Exp $ */
/*
* Copyright (c) 1995 Adam Glass, Gordon Ross
@ -46,7 +46,7 @@
#include <netinet/if_ether.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsv2.h>
#include <nfs/nfsproto.h>
#include <nfs/nfs.h>
#include <nfs/nfsdiskless.h>
#include <nfs/krpc.h>
@ -104,10 +104,6 @@ static int bp_getfile __P((struct sockaddr_in *bpsin, char *key,
static int md_mount __P((struct sockaddr_in *mdsin, char *path,
u_char *fh));
/* other helpers */
static void get_path_and_handle __P((struct sockaddr_in *bpsin,
char *key, struct nfs_dlmount *ndmntp));
char *nfsbootdevname;
/*
@ -172,7 +168,7 @@ nfs_boot_init(nd, procp)
*/
if ((error = revarpwhoami(&my_ip, ifp)) != 0)
panic("revarp failed, error=%d", error);
printf("nfs_boot: client_addr=0x%x\n", ntohl(my_ip.s_addr));
printf("nfs_boot: client_addr=0x%x\n", (u_int32_t)ntohl(my_ip.s_addr));
/*
* Do enough of ifconfig(8) so that the chosen interface
@ -208,7 +204,7 @@ nfs_boot_init(nd, procp)
if (error)
panic("nfs_boot: bootparam whoami, error=%d", error);
printf("nfs_boot: server_addr=0x%x\n",
ntohl(bp_sin.sin_addr.s_addr));
(u_int32_t)ntohl(bp_sin.sin_addr.s_addr));
printf("nfs_boot: hostname=%s\n", hostname);
#ifdef NFS_BOOT_GATEWAY
@ -271,8 +267,7 @@ nfs_boot_getfh(bpsin, key, ndmntp)
* Get server:pathname for "key" (root or swap)
* using RPC to bootparam/getfile
*/
error = bp_getfile(bpsin, key, sin,
ndmntp->ndm_host, pathname);
error = bp_getfile(bpsin, key, sin, ndmntp->ndm_host, pathname);
if (error)
panic("nfs_boot: bootparam get %s: %d", key, error);
@ -513,7 +508,7 @@ md_mount(mdsin, path, fhp)
/* The RPC structures */
struct rdata {
u_int32_t errno;
u_int8_t fh[NFS_FHSIZE];
u_int8_t fh[NFSX_V2FH];
} *rdata;
struct mbuf *m;
int error;
@ -525,7 +520,7 @@ md_mount(mdsin, path, fhp)
m = xdr_string_encode(path, strlen(path));
if (m == NULL)
return (ENOMEM);
return ENOMEM;
/* Do RPC to mountd. */
error = krpc_call(mdsin, RPCPROG_MNT, RPCMNT_VER1,
@ -542,14 +537,14 @@ md_mount(mdsin, path, fhp)
if (error)
goto out;
/* Have errno==0, so the fh must be there. */
/* Have errno==0, so the fh must be there. */
if (m->m_len < sizeof(*rdata)) {
m = m_pullup(m, sizeof(*rdata));
if (m == NULL)
goto bad;
rdata = mtod(m, struct rdata *);
}
bcopy(rdata->fh, fhp, NFS_FHSIZE);
bcopy(rdata->fh, fhp, NFSX_V2FH);
goto out;
bad:

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_node.c,v 1.15 1996/02/09 21:48:24 christos Exp $ */
/* $NetBSD: nfs_node.c,v 1.16 1996/02/18 11:53:42 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
@ -35,9 +35,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfs_node.c 8.2 (Berkeley) 12/30/93
* @(#)nfs_node.c 8.6 (Berkeley) 5/22/95
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
@ -48,15 +49,13 @@
#include <sys/malloc.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsv2.h>
#include <nfs/nfsproto.h>
#include <nfs/nfs.h>
#include <nfs/nfsnode.h>
#include <nfs/nfsmount.h>
#include <nfs/nqnfs.h>
#include <nfs/nfs_var.h>
#define NFSNOHASH(fhsum) \
(&nfsnodehashtbl[(fhsum) & nfsnodehash])
LIST_HEAD(nfsnodehashhead, nfsnode) *nfsnodehashtbl;
u_long nfsnodehash;
@ -77,19 +76,20 @@ nfs_nhinit()
/*
* Compute an entry in the NFS hash table structure
*/
struct nfsnodehashhead *
nfs_hash(fhp)
register nfsv2fh_t *fhp;
u_long
nfs_hash(fhp, fhsize)
register nfsfh_t *fhp;
int fhsize;
{
register u_char *fhpp;
register u_long fhsum;
int i;
register int i;
fhpp = &fhp->fh_bytes[0];
fhsum = 0;
for (i = 0; i < NFSX_FH; i++)
for (i = 0; i < fhsize; i++)
fhsum += *fhpp++;
return (NFSNOHASH(fhsum));
return (fhsum);
}
/*
@ -99,25 +99,34 @@ nfs_hash(fhp)
* nfsnode structure is returned.
*/
int
nfs_nget(mntp, fhp, npp)
nfs_nget(mntp, fhp, fhsize, npp)
struct mount *mntp;
register nfsv2fh_t *fhp;
register nfsfh_t *fhp;
int fhsize;
struct nfsnode **npp;
{
#ifdef Lite2_integrated
struct proc *p = curproc; /* XXX */
#endif
register struct nfsnode *np;
struct nfsnodehashhead *nhpp;
register struct vnode *vp;
extern int (**nfsv2_vnodeop_p)__P((void *));
struct vnode *nvp;
int error;
nhpp = nfs_hash(fhp);
nhpp = NFSNOHASH(nfs_hash(fhp, fhsize));
loop:
for (np = nhpp->lh_first; np != 0; np = np->n_hash.le_next) {
if (mntp != NFSTOV(np)->v_mount ||
bcmp((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH))
if (mntp != NFSTOV(np)->v_mount || np->n_fhsize != fhsize ||
bcmp((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize))
continue;
vp = NFSTOV(np);
#ifdef Lite2_integrated
if (vget(vp, LK_EXCLUSIVE, p))
#else
if (vget(vp, 1))
#endif
goto loop;
*npp = np;
return(0);
@ -129,26 +138,19 @@ loop:
}
vp = nvp;
MALLOC(np, struct nfsnode *, sizeof *np, M_NFSNODE, M_WAITOK);
bzero((caddr_t)np, sizeof *np);
vp->v_data = np;
np->n_vnode = vp;
/*
* Insert the nfsnode in the hash queue for its new file handle
*/
np->n_flag = 0;
LIST_INSERT_HEAD(nhpp, np, n_hash);
bcopy((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH);
np->n_attrstamp = 0;
np->n_direofoffset = 0;
np->n_sillyrename = (struct sillyrename *)0;
np->n_size = 0;
np->n_mtime = 0;
np->n_lockf = 0;
if (VFSTONFS(mntp)->nm_flag & NFSMNT_NQNFS) {
np->n_brev = 0;
np->n_lrev = 0;
np->n_expiry = (time_t)0;
np->n_timer.cqe_next = (struct nfsnode *)0;
}
if (fhsize > NFS_SMALLFH) {
MALLOC(np->n_fhp, nfsfh_t *, fhsize, M_NFSBIGFH, M_WAITOK);
} else
np->n_fhp = &np->n_fh;
bcopy((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize);
np->n_fhsize = fhsize;
*npp = np;
return (0);
}
@ -159,6 +161,9 @@ nfs_inactive(v)
{
struct vop_inactive_args /* {
struct vnode *a_vp;
#ifdef Lite2_integrated
struct proc *a_p;
#endif
} */ *ap = v;
register struct nfsnode *np;
register struct sillyrename *sp;
@ -168,7 +173,10 @@ nfs_inactive(v)
np = VTONFS(ap->a_vp);
if (prtactive && ap->a_vp->v_usecount != 0)
vprint("nfs_inactive: pushing active", ap->a_vp);
sp = np->n_sillyrename;
if (ap->a_vp->v_type != VDIR)
sp = np->n_sillyrename;
else
sp = (struct sillyrename *)0;
np->n_sillyrename = (struct sillyrename *)0;
if (sp) {
/*
@ -178,12 +186,13 @@ nfs_inactive(v)
nfs_removeit(sp);
crfree(sp->s_cred);
vrele(sp->s_dvp);
#ifdef SILLYSEPARATE
free((caddr_t)sp, M_NFSREQ);
#endif
FREE((caddr_t)sp, M_NFSREQ);
}
np->n_flag &= (NMODIFIED | NFLUSHINPROG | NFLUSHWANT | NQNFSEVICTED |
NQNFSNONCACHE | NQNFSWRITE);
#ifdef Lite2_integrated
VOP_UNLOCK(ap->a_vp, 0, ap->a_p);
#endif
return (0);
}
@ -200,10 +209,12 @@ nfs_reclaim(v)
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;
extern int prtactive;
if (prtactive && vp->v_usecount != 0)
vprint("nfs_reclaim: pushing active", vp);
LIST_REMOVE(np, n_hash);
/*
@ -212,12 +223,31 @@ nfs_reclaim(v)
if ((nmp->nm_flag & NFSMNT_NQNFS) && np->n_timer.cqe_next != 0) {
CIRCLEQ_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;
while (dp) {
dp2 = dp;
dp = dp->ndm_list.le_next;
FREE((caddr_t)dp2, M_NFSDIROFF);
}
}
if (np->n_fhsize > NFS_SMALLFH) {
FREE((caddr_t)np->n_fhp, M_NFSBIGFH);
}
cache_purge(vp);
FREE(vp->v_data, M_NFSNODE);
vp->v_data = (void *)0;
return (0);
}
#ifndef Lite2_integrated
/*
* Lock an nfsnode
*/
@ -237,7 +267,7 @@ nfs_lock(v)
*/
while (vp->v_flag & VXLOCK) {
vp->v_flag |= VXWANT;
sleep((caddr_t)vp, PINOD);
(void) tsleep((caddr_t)vp, PINOD, "nfslck", 0);
}
if (vp->v_tag == VT_NON)
return (ENOENT);
@ -271,9 +301,9 @@ nfs_islocked(v)
struct vnode *a_vp;
} */ *ap = v;
#endif
return (0);
}
#endif /* Lite2_integrated */
/*
* Nfs abort op, called after namei() when a CREATE/DELETE isn't actually

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_nqlease.c,v 1.12 1996/02/09 21:48:26 christos Exp $ */
/* $NetBSD: nfs_nqlease.c,v 1.13 1996/02/18 11:53:43 fvdl Exp $ */
/*
* Copyright (c) 1992, 1993
@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfs_nqlease.c 8.5 (Berkeley) 8/18/94
* @(#)nfs_nqlease.c 8.9 (Berkeley) 5/20/95
*/
/*
@ -67,7 +67,7 @@
#include <netinet/in.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsv2.h>
#include <nfs/nfsproto.h>
#include <nfs/nfs.h>
#include <nfs/nfsm_subs.h>
#include <nfs/xdr_subs.h>
@ -77,7 +77,6 @@
#include <nfs/nfs_var.h>
time_t nqnfsstarttime = (time_t)0;
u_int32_t nqnfs_prog, nqnfs_vers;
int nqsrv_clockskew = NQ_CLOCKSKEW;
int nqsrv_writeslack = NQ_WRITESLACK;
int nqsrv_maxlease = NQ_MAXLEASE;
@ -88,14 +87,13 @@ int nqsrv_maxnumlease = NQ_MAXNUMLEASE;
*/
int nqnfs_piggy[NFS_NPROCS] = {
0,
NQL_READ,
NQL_WRITE,
0,
NQL_READ,
NQL_READ,
NQL_READ,
ND_WRITE,
ND_READ,
0,
NQL_WRITE,
ND_READ,
ND_READ,
ND_WRITE,
0,
0,
0,
@ -103,24 +101,31 @@ int nqnfs_piggy[NFS_NPROCS] = {
0,
0,
0,
NQL_READ,
0,
NQL_READ,
ND_READ,
ND_READ,
0,
0,
0,
0,
0,
0,
0,
0,
};
extern nfstype nfs_type[9];
extern nfstype nfsv2_type[9];
extern nfstype nfsv3_type[9];
extern struct nfssvc_sock *nfs_udpsock, *nfs_cltpsock;
extern int nfsd_waiting;
extern struct nfsstats nfsstats;
#define TRUE 1
#define FALSE 0
/*
* Get or check for a lease for "vp", based on NQL_CHECK flag.
* Get or check for a lease for "vp", based on ND_CHECK flag.
* The rules are as follows:
* - if a current non-caching lease, reply non-caching
* - if a current lease for same host only, extend lease
@ -143,11 +148,12 @@ extern int nfsd_waiting;
* queue yet. (Ditto for the splsoftclock() and splx(s) calls)
*/
int
nqsrv_getlease(vp, duration, flags, nd, nam, cachablep, frev, cred)
nqsrv_getlease(vp, duration, flags, slp, procp, nam, cachablep, frev, cred)
struct vnode *vp;
u_int *duration;
u_int32_t *duration;
int flags;
struct nfsd *nd;
struct nfssvc_sock *slp;
struct proc *procp;
struct mbuf *nam;
int *cachablep;
u_quad_t *frev;
@ -166,19 +172,21 @@ nqsrv_getlease(vp, duration, flags, nd, nam, cachablep, frev, cred)
return (0);
if (*duration > nqsrv_maxlease)
*duration = nqsrv_maxlease;
if ((error = VOP_GETATTR(vp, &vattr, cred, nd->nd_procp)) != 0)
error = VOP_GETATTR(vp, &vattr, cred, procp);
if (error)
return (error);
*frev = vattr.va_filerev;
s = splsoftclock();
tlp = vp->v_lease;
if ((flags & NQL_CHECK) == 0)
if ((flags & ND_CHECK) == 0)
nfsstats.srvnqnfs_getleases++;
if (tlp == 0) {
/*
* Find the lease by searching the hash list.
*/
fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
if ((error = VFS_VPTOFH(vp, &fh.fh_fid)) != 0) {
VFS_VPTOFH(vp, &fh.fh_fid);
if (error) {
splx(s);
return (error);
}
@ -199,12 +207,12 @@ nqsrv_getlease(vp, duration, flags, nd, nam, cachablep, frev, cred)
if (lp != 0) {
if ((lp->lc_flag & LC_NONCACHABLE) ||
(lp->lc_morehosts == (struct nqm *)0 &&
nqsrv_cmpnam(nd->nd_slp, nam, &lp->lc_host)))
nqsrv_cmpnam(slp, nam, &lp->lc_host)))
goto doreply;
if ((flags & NQL_READ) && (lp->lc_flag & LC_WRITE) == 0) {
if (flags & NQL_CHECK)
if ((flags & ND_READ) && (lp->lc_flag & LC_WRITE) == 0) {
if (flags & ND_CHECK)
goto doreply;
if (nqsrv_cmpnam(nd->nd_slp, nam, &lp->lc_host))
if (nqsrv_cmpnam(slp, nam, &lp->lc_host))
goto doreply;
i = 0;
if (lp->lc_morehosts) {
@ -216,7 +224,7 @@ nqsrv_getlease(vp, duration, flags, nd, nam, cachablep, frev, cred)
ok = 0;
}
while (ok && (lph->lph_flag & LC_VALID)) {
if (nqsrv_cmpnam(nd->nd_slp, nam, lph))
if (nqsrv_cmpnam(slp, nam, lph))
goto doreply;
if (++i == LC_MOREHOSTSIZ) {
i = 0;
@ -236,12 +244,12 @@ nqsrv_getlease(vp, duration, flags, nd, nam, cachablep, frev, cred)
bzero((caddr_t)*lphp, sizeof (struct nqm));
lph = (*lphp)->lpm_hosts;
}
nqsrv_addhost(lph, nd->nd_slp, nam);
nqsrv_addhost(lph, slp, nam);
nqsrv_unlocklease(lp);
} else {
lp->lc_flag |= LC_NONCACHABLE;
nqsrv_locklease(lp);
nqsrv_send_eviction(vp, lp, nd->nd_slp, nam, cred);
nqsrv_send_eviction(vp, lp, slp, nam, cred);
nqsrv_waitfor_expiry(lp);
nqsrv_unlocklease(lp);
}
@ -249,20 +257,20 @@ doreply:
/*
* Update the lease and return
*/
if ((flags & NQL_CHECK) == 0)
if ((flags & ND_CHECK) == 0)
nqsrv_instimeq(lp, *duration);
if (lp->lc_flag & LC_NONCACHABLE)
*cachablep = 0;
else {
*cachablep = 1;
if (flags & NQL_WRITE)
if (flags & ND_WRITE)
lp->lc_flag |= LC_WRITTEN;
}
splx(s);
return (0);
}
splx(s);
if (flags & NQL_CHECK)
if (flags & ND_CHECK)
return (0);
/*
@ -279,13 +287,15 @@ doreply:
}
MALLOC(lp, struct nqlease *, sizeof (struct nqlease), M_NQLEASE, M_WAITOK);
bzero((caddr_t)lp, sizeof (struct nqlease));
if (flags & NQL_WRITE)
if (flags & ND_WRITE)
lp->lc_flag |= (LC_WRITE | LC_WRITTEN);
nqsrv_addhost(&lp->lc_host, nd->nd_slp, nam);
nqsrv_addhost(&lp->lc_host, slp, nam);
lp->lc_vp = vp;
lp->lc_fsid = fh.fh_fsid;
bcopy(fh.fh_fid.fid_data, lp->lc_fiddata,
fh.fh_fid.fid_len - sizeof (int32_t));
if(!lpp)
panic("nfs_nqlease.c: Phoney lpp");
LIST_INSERT_HEAD(lpp, lp, lc_hash);
vp->v_lease = lp;
s = splsoftclock();
@ -302,7 +312,7 @@ doreply:
* Just set up args and let nqsrv_getlease() do the rest.
*/
int
lease_check(v)
nqnfs_vop_lease_check(v)
void *v;
{
struct vop_lease_args /* {
@ -311,15 +321,13 @@ lease_check(v)
struct ucred *a_cred;
int a_flag;
} */ *ap = v;
int duration = 0, cache;
struct nfsd nfsd;
u_int32_t duration = 0;
int cache;
u_quad_t frev;
nfsd.nd_slp = NQLOCALSLP;
nfsd.nd_procp = ap->a_p;
(void) nqsrv_getlease(ap->a_vp, &duration, NQL_CHECK | ap->a_flag,
&nfsd, (struct mbuf *)0, &cache, &frev, ap->a_cred);
return 0;
(void) nqsrv_getlease(ap->a_vp, &duration, ND_CHECK | ap->a_flag,
NQLOCALSLP, ap->a_p, (struct mbuf *)0, &cache, &frev, ap->a_cred);
return (0);
}
/*
@ -356,7 +364,7 @@ nqsrv_addhost(lph, slp, nam)
void
nqsrv_instimeq(lp, duration)
register struct nqlease *lp;
u_long duration;
u_int32_t duration;
{
register struct nqlease *tlp;
time_t newexpiry;
@ -374,8 +382,10 @@ nqsrv_instimeq(lp, duration)
tlp = nqtimerhead.cqh_last;
while (tlp != (void *)&nqtimerhead && tlp->lc_expiry > newexpiry)
tlp = tlp->lc_timer.cqe_prev;
#ifdef HASNVRAM
if (tlp == nqtimerhead.cqh_last)
NQSTORENOVRAM(newexpiry);
#endif /* HASNVRAM */
if (tlp == (void *)&nqtimerhead) {
CIRCLEQ_INSERT_HEAD(&nqtimerhead, lp, lc_timer);
} else {
@ -478,9 +488,9 @@ nqsrv_send_eviction(vp, lp, slp, nam, cred)
else
solockp = (int *)0;
nfsm_reqhead((struct vnode *)0, NQNFSPROC_EVICTED,
NFSX_FH);
nfsm_build(cp, caddr_t, NFSX_FH);
bzero(cp, NFSX_FH);
NFSX_V3FH);
nfsm_build(cp, caddr_t, NFSX_V3FH);
bzero(cp, NFSX_V3FH);
fhp = (fhandle_t *)cp;
fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid;
VFS_VPTOFH(vp, &fhp->fh_fid);
@ -494,9 +504,10 @@ nqsrv_send_eviction(vp, lp, slp, nam, cred)
printf("mbuf siz=%d\n",siz);
panic("Bad nfs svc reply");
}
m = nfsm_rpchead(cred, TRUE, NQNFSPROC_EVICTED,
RPCAUTH_UNIX, 5*NFSX_UNSIGNED, (char *)0,
mreq, siz, &mheadend, &xid);
m = nfsm_rpchead(cred, (NFSMNT_NFSV3 | NFSMNT_NQNFS),
NQNFSPROC_EVICTED,
RPCAUTH_UNIX, 5 * NFSX_UNSIGNED, (char *)0,
0, (char *)0, mreq, siz, &mheadend, &xid);
/*
* For stream protocols, prepend a Sun RPC
* Record Mark.
@ -670,17 +681,20 @@ nqnfs_serverd()
* do the real work.
*/
int
nqnfsrv_getlease(nfsd, mrep, md, dpos, cred, nam, mrq)
struct nfsd *nfsd;
struct mbuf *mrep, *md;
caddr_t dpos;
struct ucred *cred;
struct mbuf *nam, **mrq;
nqnfsrv_getlease(nfsd, slp, procp, mrq)
struct nfsrv_descript *nfsd;
struct nfssvc_sock *slp;
struct proc *procp;
struct mbuf **mrq;
{
register struct nfsv2_fattr *fp;
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
struct mbuf *nam = nfsd->nd_nam;
caddr_t dpos = nfsd->nd_dpos;
struct ucred *cred = &nfsd->nd_cr;
register struct nfs_fattr *fp;
struct vattr va;
struct vnode *vp;
nfsv2fh_t nfh;
nfsfh_t nfh;
fhandle_t *fhp;
register u_int32_t *tl;
register int32_t t1;
@ -693,28 +707,29 @@ nqnfsrv_getlease(nfsd, mrep, md, dpos, cred, nam, mrq)
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
nfsm_dissect(tl, u_int32_t *, 2*NFSX_UNSIGNED);
nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
flags = fxdr_unsigned(int, *tl++);
nfsd->nd_duration = fxdr_unsigned(int, *tl);
error = nfsrv_fhtovp(fhp,
TRUE, &vp, cred, nfsd->nd_slp, nam, &rdonly);
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly,
(nfsd->nd_flag & ND_KERBAUTH));
if (error)
nfsm_reply(0);
if (rdonly && flags == NQL_WRITE) {
if (rdonly && flags == ND_WRITE) {
vput(vp);
error = EROFS;
nfsm_reply(0);
}
(void) nqsrv_getlease(vp, &nfsd->nd_duration, flags, nfsd,
(void) nqsrv_getlease(vp, &nfsd->nd_duration, flags, slp, procp,
nam, &cache, &frev, cred);
error = VOP_GETATTR(vp, &va, cred, nfsd->nd_procp);
error = VOP_GETATTR(vp, &va, cred, procp);
vput(vp);
nfsm_reply(NFSX_NQFATTR + 4*NFSX_UNSIGNED);
nfsm_build(tl, u_int32_t *, 4*NFSX_UNSIGNED);
nfsm_reply(NFSX_V3FATTR + 4 * NFSX_UNSIGNED);
nfsm_build(tl, u_int32_t *, 4 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(cache);
*tl++ = txdr_unsigned(nfsd->nd_duration);
txdr_hyper(&frev, tl);
nfsm_build(fp, struct nfsv2_fattr *, NFSX_NQFATTR);
nfsm_srvfillattr;
nfsm_build(fp, struct nfs_fattr *, NFSX_V3FATTR);
nfsm_srvfillattr(&va, fp);
nfsm_srvdone;
}
@ -723,23 +738,27 @@ nqnfsrv_getlease(nfsd, mrep, md, dpos, cred, nam, mrq)
* client. Find the entry and expire it.
*/
int
nqnfsrv_vacated(nfsd, mrep, md, dpos, cred, nam, mrq)
struct nfsd *nfsd;
struct mbuf *mrep, *md;
caddr_t dpos;
struct ucred *cred;
struct mbuf *nam, **mrq;
nqnfsrv_vacated(nfsd, slp, procp, mrq)
struct nfsrv_descript *nfsd;
struct nfssvc_sock *slp;
struct proc *procp;
struct mbuf **mrq;
{
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
struct mbuf *nam = nfsd->nd_nam;
caddr_t dpos = nfsd->nd_dpos;
register struct nqlease *lp;
register struct nqhost *lph;
struct nqlease *tlp = (struct nqlease *)0;
nfsv2fh_t nfh;
nfsfh_t nfh;
fhandle_t *fhp;
register u_int32_t *tl;
register int32_t t1;
struct nqm *lphnext;
int error = 0, i, len, ok, gotit = 0;
char *cp2;
struct mbuf *mreq, *mb;
int error = 0, i, len, ok, gotit = 0, cache = 0;
char *cp2, *bpos;
u_quad_t frev;
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
@ -765,7 +784,7 @@ nqnfsrv_vacated(nfsd, mrep, md, dpos, cred, nam, mrq)
lphnext = lp->lc_morehosts;
ok = 1;
while (ok && (lph->lph_flag & LC_VALID)) {
if (nqsrv_cmpnam(nfsd->nd_slp, nam, lph)) {
if (nqsrv_cmpnam(slp, nam, lph)) {
lph->lph_flag |= LC_VACATED;
gotit++;
break;
@ -805,7 +824,7 @@ nqnfs_getlease(vp, rwflag, cred, p)
{
register u_int32_t *tl;
register caddr_t cp;
register int32_t t1;
register int32_t t1, t2;
register struct nfsnode *np;
struct nfsmount *nmp = VFSTONFS(vp->v_mount);
caddr_t bpos, dpos, cp2;
@ -816,16 +835,16 @@ nqnfs_getlease(vp, rwflag, cred, p)
u_quad_t frev;
nfsstats.rpccnt[NQNFSPROC_GETLEASE]++;
mb = mreq = nfsm_reqh(vp, NQNFSPROC_GETLEASE, NFSX_FH+2*NFSX_UNSIGNED,
mb = mreq = nfsm_reqh(vp, NQNFSPROC_GETLEASE, NFSX_V3FH+2*NFSX_UNSIGNED,
&bpos);
nfsm_fhtom(vp);
nfsm_build(tl, u_int32_t *, 2*NFSX_UNSIGNED);
nfsm_fhtom(vp, 1);
nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(rwflag);
*tl = txdr_unsigned(nmp->nm_leaseterm);
reqtime = time.tv_sec;
nfsm_request(vp, NQNFSPROC_GETLEASE, p, cred);
np = VTONFS(vp);
nfsm_dissect(tl, u_int32_t *, 4*NFSX_UNSIGNED);
nfsm_dissect(tl, u_int32_t *, 4 * NFSX_UNSIGNED);
cachable = fxdr_unsigned(int, *tl++);
reqtime += fxdr_unsigned(int, *tl++);
if (reqtime > time.tv_sec) {
@ -849,6 +868,8 @@ nqnfs_vacated(vp, cred)
register caddr_t cp;
register struct mbuf *m;
register int i;
register u_int32_t *tl;
register int32_t t2;
caddr_t bpos;
u_int32_t xid;
int error = 0;
@ -858,17 +879,17 @@ nqnfs_vacated(vp, cred)
nmp = VFSTONFS(vp->v_mount);
nfsstats.rpccnt[NQNFSPROC_VACATED]++;
nfsm_reqhead(vp, NQNFSPROC_VACATED, NFSX_FH);
nfsm_fhtom(vp);
nfsm_reqhead(vp, NQNFSPROC_VACATED, NFSX_V3FH);
nfsm_fhtom(vp, 1);
m = mreq;
i = 0;
while (m) {
i += m->m_len;
m = m->m_next;
}
m = nfsm_rpchead(cred, TRUE, NQNFSPROC_VACATED,
RPCAUTH_UNIX, 5*NFSX_UNSIGNED, (char *)0,
mreq, i, &mheadend, &xid);
m = nfsm_rpchead(cred, nmp->nm_flag, NQNFSPROC_VACATED,
RPCAUTH_UNIX, 5 * NFSX_UNSIGNED, (char *)0,
0, (char *)0, mreq, i, &mheadend, &xid);
if (nmp->nm_sotype == SOCK_STREAM) {
M_PREPEND(m, NFSX_UNSIGNED, M_WAIT);
*mtod(m, u_int32_t *) = htonl(0x80000000 | (m->m_pkthdr.len -
@ -881,6 +902,7 @@ nqnfs_vacated(vp, cred)
(void) nfs_send(nmp->nm_so, nmp->nm_nam, m, &myrep);
if (nmp->nm_soflags & PR_CONNREQUIRED)
nfs_sndunlock(&nmp->nm_flag);
nfsmout:
return (error);
}
@ -896,28 +918,37 @@ nqnfs_callback(nmp, mrep, md, dpos)
register struct vnode *vp;
register u_int32_t *tl;
register int32_t t1;
nfsv2fh_t nfh;
nfsfh_t nfh;
fhandle_t *fhp;
struct nfsnode *np;
struct nfsd nd;
int error;
char *cp2;
struct nfsd tnfsd;
struct nfssvc_sock *slp;
struct nfsrv_descript ndesc;
register struct nfsrv_descript *nfsd = &ndesc;
struct mbuf **mrq = (struct mbuf **)0, *mb, *mreq;
int error = 0, cache = 0;
char *cp2, *bpos;
u_quad_t frev;
nd.nd_mrep = mrep;
nd.nd_md = md;
nd.nd_dpos = dpos;
if ((error = nfs_getreq(&nd, FALSE)) != 0)
#ifndef nolint
slp = NULL;
#endif
nfsd->nd_mrep = mrep;
nfsd->nd_md = md;
nfsd->nd_dpos = dpos;
error = nfs_getreq(nfsd, &tnfsd, FALSE);
if (error)
return (error);
md = nd.nd_md;
dpos = nd.nd_dpos;
if (nd.nd_procnum != NQNFSPROC_EVICTED) {
md = nfsd->nd_md;
dpos = nfsd->nd_dpos;
if (nfsd->nd_procnum != NQNFSPROC_EVICTED) {
m_freem(mrep);
return (EPERM);
}
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
m_freem(mrep);
error = nfs_nget(nmp->nm_mountp, (nfsv2fh_t *) fhp, &np);
error = nfs_nget(nmp->nm_mountp, (nfsfh_t *)fhp, NFSX_V3FH, &np);
if (error)
return (error);
vp = NFSTOV(np);
@ -952,35 +983,39 @@ nqnfs_clientd(nmp, cred, ncd, flag, argp, p)
register struct nfsnode *np;
struct vnode *vp;
struct nfsreq myrep;
struct nfsuid *nuidp, *nnuidp;
int error = 0, vpid;
/*
* First initialize some variables
*/
nqnfs_prog = txdr_unsigned(NQNFS_PROG);
nqnfs_vers = txdr_unsigned(NQNFS_VER1);
/*
* If an authorization string is being passed in, get it.
*/
if ((flag & NFSSVC_GOTAUTH) &&
(nmp->nm_flag & (NFSMNT_WAITAUTH | NFSMNT_DISMNT)) == 0) {
if (nmp->nm_flag & NFSMNT_HASAUTH)
panic("cld kerb");
if ((flag & NFSSVC_AUTHINFAIL) == 0) {
if (ncd->ncd_authlen <= RPCAUTH_MAXSIZ &&
copyin(ncd->ncd_authstr, nmp->nm_authstr,
ncd->ncd_authlen) == 0) {
nmp->nm_authtype = ncd->ncd_authtype;
nmp->nm_authlen = ncd->ncd_authlen;
} else
nmp->nm_flag |= NFSMNT_AUTHERR;
(nmp->nm_flag & (NFSMNT_WAITAUTH | NFSMNT_DISMNT)) == 0) {
if (nmp->nm_flag & NFSMNT_HASAUTH)
panic("cld kerb");
if ((flag & NFSSVC_AUTHINFAIL) == 0) {
if (ncd->ncd_authlen <= nmp->nm_authlen &&
ncd->ncd_verflen <= nmp->nm_verflen &&
!copyin(ncd->ncd_authstr,nmp->nm_authstr,ncd->ncd_authlen)&&
!copyin(ncd->ncd_verfstr,nmp->nm_verfstr,ncd->ncd_verflen)){
nmp->nm_authtype = ncd->ncd_authtype;
nmp->nm_authlen = ncd->ncd_authlen;
nmp->nm_verflen = ncd->ncd_verflen;
#ifdef NFSKERB
nmp->nm_key = ncd->ncd_key;
#endif
} else
nmp->nm_flag |= NFSMNT_AUTHERR;
nmp->nm_flag |= NFSMNT_HASAUTH;
wakeup((caddr_t)&nmp->nm_authlen);
nmp->nm_flag |= NFSMNT_AUTHERR;
} else
nmp->nm_flag |= NFSMNT_AUTHERR;
nmp->nm_flag |= NFSMNT_HASAUTH;
wakeup((caddr_t)&nmp->nm_authlen);
} else
nmp->nm_flag |= NFSMNT_WAITAUTH;
nmp->nm_flag |= NFSMNT_WAITAUTH;
/*
* Loop every second updating queue until there is a termination sig.
@ -1008,15 +1043,15 @@ nqnfs_clientd(nmp, cred, ncd, flag, argp, p)
while (np != (void *)&nmp->nm_timerhead &&
(nmp->nm_flag & NFSMNT_DISMINPROG) == 0) {
vp = NFSTOV(np);
if (strncmp(&vp->v_mount->mnt_stat.f_fstypename[0], MOUNT_NFS, MFSNAMELEN))
panic("trash2");
vpid = vp->v_id;
if (np->n_expiry < time.tv_sec) {
#ifdef Lite2_integrated
if (vget(vp, LK_EXCLUSIVE, p) == 0) {
#else
if (vget(vp, 1) == 0) {
#endif
nmp->nm_inprog = vp;
if (vpid == vp->v_id) {
if (strncmp(&vp->v_mount->mnt_stat.f_fstypename[0], MOUNT_NFS, MFSNAMELEN))
panic("trash3");
CIRCLEQ_REMOVE(&nmp->nm_timerhead, np, n_timer);
np->n_timer.cqe_next = 0;
if ((np->n_flag & (NMODIFIED | NQNFSEVICTED))
@ -1039,11 +1074,14 @@ if (strncmp(&vp->v_mount->mnt_stat.f_fstypename[0], MOUNT_NFS, MFSNAMELEN))
} else if ((np->n_expiry - NQ_RENEWAL) < time.tv_sec) {
if ((np->n_flag & (NQNFSWRITE | NQNFSNONCACHE))
== NQNFSWRITE && vp->v_dirtyblkhd.lh_first &&
#ifdef Lite2_integrated
vget(vp, LK_EXCLUSIVE, p) == 0) {
#else
vget(vp, 1) == 0) {
#endif
nmp->nm_inprog = vp;
if (strncmp(&vp->v_mount->mnt_stat.f_fstypename[0], MOUNT_NFS, MFSNAMELEN)) panic("trash4");
if (vpid == vp->v_id &&
nqnfs_getlease(vp, NQL_WRITE, cred, p)==0)
nqnfs_getlease(vp, ND_WRITE, cred, p)==0)
np->n_brev = np->n_lrev;
vrele(vp);
nmp->nm_inprog = NULLVP;
@ -1078,6 +1116,16 @@ if (strncmp(&vp->v_mount->mnt_stat.f_fstypename[0], MOUNT_NFS, MFSNAMELEN)) pani
(void) dounmount(nmp->nm_mountp, MNT_FORCE, p);
}
}
/*
* Finally, we can free up the mount structure.
*/
for (nuidp = nmp->nm_uidlruhead.tqh_first; nuidp != 0; nuidp = nnuidp) {
nnuidp = nuidp->nu_lru.tqe_next;
LIST_REMOVE(nuidp, nu_hash);
TAILQ_REMOVE(&nmp->nm_uidlruhead, nuidp, nu_lru);
free((caddr_t)nuidp, M_NFSUID);
}
free((caddr_t)nmp, M_NFSMNT);
if (error == EWOULDBLOCK)
error = 0;
@ -1099,9 +1147,9 @@ nqnfs_clientlease(nmp, np, rwflag, cachable, expiry, frev)
if (np->n_timer.cqe_next != 0) {
CIRCLEQ_REMOVE(&nmp->nm_timerhead, np, n_timer);
if (rwflag == NQL_WRITE)
if (rwflag == ND_WRITE)
np->n_flag |= NQNFSWRITE;
} else if (rwflag == NQL_READ)
} else if (rwflag == ND_READ)
np->n_flag &= ~NQNFSWRITE;
else
np->n_flag |= NQNFSWRITE;
@ -1127,7 +1175,7 @@ nqnfs_clientlease(nmp, np, rwflag, cachable, expiry, frev)
* Called from the settimeofday() syscall.
*/
void
lease_updatetime(deltat)
nqnfs_lease_updatetime(deltat)
register int deltat;
{
register struct nqlease *lp;
@ -1135,6 +1183,10 @@ lease_updatetime(deltat)
struct mount *mp;
struct nfsmount *nmp;
int s;
#ifdef Lite2_integrated
struct proc *p = curproc; /* XXX */
struct mount *nxtmp;
#endif
if (nqnfsstarttime != 0)
nqnfsstarttime += deltat;
@ -1148,6 +1200,30 @@ lease_updatetime(deltat)
* Search the mount list for all nqnfs mounts and do their timer
* queues.
*/
#ifdef Lite2_integrated
simple_lock(&mountlist_slock);
for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nxtmp) {
if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) {
nxtmp = mp->mnt_list.cqe_next;
continue;
}
if (!strncmp(&mp->mnt_stat.f_fstypename[0], MOUNT_NFS,
MFSNAMELEN)) {
nmp = VFSTONFS(mp);
if (nmp->nm_flag & NFSMNT_NQNFS) {
for (np = nmp->nm_timerhead.cqh_first;
np != (void *)&nmp->nm_timerhead;
np = np->n_timer.cqe_next) {
np->n_expiry += deltat;
}
}
}
simple_lock(&mountlist_slock);
nxtmp = mp->mnt_list.cqe_next;
vfs_unbusy(mp, p);
}
simple_unlock(&mountlist_slock);
#else /* Lite2_integrated */
for (mp = mountlist.cqh_first; mp != (void *)&mountlist;
mp = mp->mnt_list.cqe_next) {
if (!strncmp(&mp->mnt_stat.f_fstypename[0], MOUNT_NFS,
@ -1162,6 +1238,7 @@ lease_updatetime(deltat)
}
}
}
#endif
}
/*

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* $NetBSD: nfs_socket.c,v 1.23 1996/02/09 21:48:29 christos Exp $ */
/* $NetBSD: nfs_socket.c,v 1.24 1996/02/18 11:53:48 fvdl Exp $ */
/*
* Copyright (c) 1989, 1991, 1993
* Copyright (c) 1989, 1991, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfs_socket.c 8.3 (Berkeley) 1/12/94
* @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
*/
/*
@ -59,8 +59,9 @@
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsv2.h>
#include <nfs/nfsproto.h>
#include <nfs/nfs.h>
#include <nfs/xdr_subs.h>
#include <nfs/nfsm_subs.h>
@ -96,36 +97,13 @@
* 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_rejectedcred,
rpc_auth_unix, rpc_msgaccepted, rpc_call, rpc_autherr,
rpc_auth_kerb;
extern u_int32_t nfs_prog, nfs_vers, nqnfs_prog, nqnfs_vers;
extern u_int32_t nfs_prog, nqnfs_prog;
extern time_t nqnfsstarttime;
extern int nonidempotent[NFS_NPROCS];
/*
* Maps errno values to nfs error numbers.
* Use NFSERR_IO as the catch all for ones not specifically defined in
* RFC 1094.
*/
static int nfsrv_errmap[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,
};
extern struct nfsstats nfsstats;
extern int nfsv3_procid[NFS_NPROCS];
extern int nfs_ticks;
/*
* Defines which timer to use for the procnum.
@ -136,7 +114,8 @@ static int nfsrv_errmap[ELAST] = {
* 4 - write
*/
static int proct[NFS_NPROCS] = {
0, 1, 0, 0, 2, 3, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 0, 0, 0,
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,
};
/*
@ -176,8 +155,8 @@ nfs_connect(nmp, rep)
nmp->nm_so = (struct socket *)0;
saddr = mtod(nmp->nm_nam, struct sockaddr *);
error = socreate(saddr->sa_family,
&nmp->nm_so, nmp->nm_sotype, nmp->nm_soproto);
error = socreate(saddr->sa_family, &nmp->nm_so, nmp->nm_sotype,
nmp->nm_soproto);
if (error)
goto bad;
so = nmp->nm_so;
@ -212,7 +191,8 @@ nfs_connect(nmp, rep)
goto bad;
}
} else {
if ((error = soconnect(so, nmp->nm_nam)) != 0)
error = soconnect(so, nmp->nm_nam);
if (error)
goto bad;
/*
@ -226,7 +206,7 @@ nfs_connect(nmp, rep)
"nfscon", 2 * hz);
if ((so->so_state & SS_ISCONNECTING) &&
so->so_error == 0 && rep &&
(error = nfs_sigintr(nmp, rep, rep->r_procp))) {
(error = nfs_sigintr(nmp, rep, rep->r_procp)) != 0){
so->so_state &= ~SS_ISCONNECTING;
splx(s);
goto bad;
@ -273,7 +253,8 @@ nfs_connect(nmp, rep)
rcvreserve = (nmp->nm_rsize + NFS_MAXPKTHDR +
sizeof (u_int32_t)) * 2;
}
if ((error = soreserve(so, sndreserve, rcvreserve)) != 0)
error = soreserve(so, sndreserve, rcvreserve);
if (error)
goto bad;
so->so_rcv.sb_flags |= SB_NOINTR;
so->so_snd.sb_flags |= SB_NOINTR;
@ -459,7 +440,8 @@ nfs_receive(rep, aname, mp)
* until we have an entire rpc request/reply.
*/
if (sotype != SOCK_DGRAM) {
if ((error = nfs_sndlock(&rep->r_nmp->nm_flag, rep)) != 0)
error = nfs_sndlock(&rep->r_nmp->nm_flag, rep);
if (error)
return (error);
tryagain:
/*
@ -475,8 +457,10 @@ tryagain:
nfs_sndunlock(&rep->r_nmp->nm_flag);
return (EINTR);
}
if ((so = rep->r_nmp->nm_so) == NULL) {
if ((error = nfs_reconnect(rep)) != 0) {
so = rep->r_nmp->nm_so;
if (!so) {
error = nfs_reconnect(rep);
if (error) {
nfs_sndunlock(&rep->r_nmp->nm_flag);
return (error);
}
@ -488,7 +472,7 @@ tryagain:
error = nfs_send(so, rep->r_nmp->nm_nam, m, rep);
if (error) {
if (error == EINTR || error == ERESTART ||
(error = nfs_reconnect(rep))) {
(error = nfs_reconnect(rep)) != 0) {
nfs_sndunlock(&rep->r_nmp->nm_flag);
return (error);
}
@ -657,7 +641,8 @@ nfs_reply(myrep)
* Also necessary for connection based protocols to avoid
* race conditions during a reconnect.
*/
if ((error = nfs_rcvlock(myrep)) != 0)
error = nfs_rcvlock(myrep);
if (error)
return (error);
/* Already received, bye bye */
if (myrep->r_mrep != NULL) {
@ -819,13 +804,16 @@ nfs_request(vp, mrest, procnum, procp, cred, mrp, mdp, dposp)
struct nfsmount *nmp;
struct mbuf *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;
u_int32_t xid;
u_quad_t frev;
char *auth_str;
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);
@ -845,19 +833,21 @@ nfs_request(vp, mrest, procnum, procp, cred, mrp, mdp, dposp)
* Get the RPC header with authorization.
*/
kerbauth:
auth_str = (char *)0;
verf_str = auth_str = (char *)0;
if (nmp->nm_flag & NFSMNT_KERB) {
if (failed_auth) {
error = nfs_getauth(nmp, rep, cred, &auth_type,
&auth_str, &auth_len);
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;
auth_len = 5 * NFSX_UNSIGNED;
}
} else {
auth_type = RPCAUTH_UNIX;
@ -865,8 +855,8 @@ kerbauth:
nmp->nm_numgrps : cred->cr_ngroups) << 2) +
5 * NFSX_UNSIGNED;
}
m = nfsm_rpchead(cred, (nmp->nm_flag & NFSMNT_NQNFS), procnum,
auth_type, auth_len, auth_str, mrest, mrest_len, &mheadend, &xid);
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);
@ -972,12 +962,12 @@ tryagain:
/*
* break down the rpc header and check if ok
*/
nfsm_dissect(tl, u_int32_t *, 3*NFSX_UNSIGNED);
nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
if (*tl++ == rpc_msgdenied) {
if (*tl == rpc_mismatch)
error = EOPNOTSUPP;
else if ((nmp->nm_flag & NFSMNT_KERB) && *tl++ == rpc_autherr) {
if (*tl == rpc_rejectedcred && failed_auth == 0) {
if (!failed_auth) {
failed_auth++;
mheadend->m_next = (struct mbuf *)0;
m_freem(mrep);
@ -994,22 +984,25 @@ tryagain:
}
/*
* skip over the auth_verf, someday we may want to cache auth_short's
* for nfs_reqhead(), but for now just dump it
* Grab any Kerberos verifier, otherwise just throw it away.
*/
if (*++tl != 0) {
i = nfsm_rndup(fxdr_unsigned(int32_t, *tl));
nfsm_adv(i);
}
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)
nfsm_adv(nfsm_rndup(i));
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
/* 0 == ok */
if (*tl == 0) {
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
if (*tl != 0) {
error = fxdr_unsigned(int, *tl);
m_freem(mrep);
if ((nmp->nm_flag & NFSMNT_NQNFS) &&
error == NQNFS_TRYLATER) {
if ((nmp->nm_flag & NFSMNT_NFSV3) &&
error == NFSERR_TRYLATER) {
m_freem(mrep);
error = 0;
waituntil = time.tv_sec + trylater_delay;
while (time.tv_sec < waituntil)
@ -1027,6 +1020,13 @@ tryagain:
*/
if (error == ESTALE)
cache_purge(vp);
if (nmp->nm_flag & NFSMNT_NFSV3) {
*mrp = mrep;
*mdp = md;
*dposp = dpos;
error |= NFSERR_RETERR;
} else
m_freem(mrep);
m_freem(rep->r_mreq);
free((caddr_t)rep, M_NFSREQ);
return (error);
@ -1058,10 +1058,10 @@ tryagain:
return (0);
}
m_freem(mrep);
m_freem(rep->r_mreq);
free((caddr_t)rep, M_NFSREQ);
error = EPROTONOSUPPORT;
nfsmout:
m_freem(rep->r_mreq);
free((caddr_t)rep, M_NFSREQ);
return (error);
}
#endif /* NFSCLIENT */
@ -1071,9 +1071,10 @@ nfsmout:
* siz arg. is used to decide if adding a cluster is worthwhile
*/
int
nfs_rephead(siz, nd, err, cache, frev, mrq, mbp, bposp)
nfs_rephead(siz, nd, slp, err, cache, frev, mrq, mbp, bposp)
int siz;
struct nfsd *nd;
struct nfsrv_descript *nd;
struct nfssvc_sock *slp;
int err;
int cache;
u_quad_t *frev;
@ -1098,47 +1099,97 @@ nfs_rephead(siz, nd, err, cache, frev, mrq, mbp, bposp)
} 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;
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 == NQNFS_AUTHERR) {
if (err == ERPCMISMATCH || (err & NFSERR_AUTHERR)) {
*tl++ = rpc_msgdenied;
if (err == NQNFS_AUTHERR) {
if (err & NFSERR_AUTHERR) {
*tl++ = rpc_autherr;
*tl = rpc_rejectedcred;
*tl = txdr_unsigned(err & ~NFSERR_AUTHERR);
mreq->m_len -= NFSX_UNSIGNED;
bpos -= NFSX_UNSIGNED;
} else {
*tl++ = rpc_mismatch;
*tl++ = txdr_unsigned(2);
*tl = txdr_unsigned(2);
*tl++ = txdr_unsigned(RPC_VER2);
*tl = txdr_unsigned(RPC_VER2);
}
} else {
*tl++ = rpc_msgaccepted;
*tl++ = 0;
*tl++ = 0;
/*
* 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);
*tl++ = txdr_unsigned(2);
*tl = txdr_unsigned(2); /* someday 3 */
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 != VNOVAL) {
if (err != NFSERR_RETVOID) {
nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);
if (err)
*tl = txdr_unsigned(nfsrv_errmap[err - 1]);
*tl = txdr_unsigned(nfsrv_errmap(nd, err));
else
*tl = 0;
*tl = 0;
}
break;
};
@ -1147,16 +1198,14 @@ nfs_rephead(siz, nd, err, cache, frev, mrq, mbp, bposp)
/*
* For nqnfs, piggyback lease as requested.
*/
if (nd->nd_nqlflag != NQL_NOVAL && err == 0) {
if (nd->nd_nqlflag) {
nfsm_build(tl, u_int32_t *, 5*NFSX_UNSIGNED);
*tl++ = txdr_unsigned(nd->nd_nqlflag);
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 {
if (nd->nd_nqlflag != 0)
panic("nqreph");
nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);
*tl = 0;
}
@ -1164,7 +1213,7 @@ nfs_rephead(siz, nd, err, cache, frev, mrq, mbp, bposp)
*mrq = mreq;
*mbp = mb;
*bposp = bpos;
if (err != 0 && err != VNOVAL)
if (err != 0 && err != NFSERR_RETVOID)
nfsstats.srvrpc_errs++;
return (0);
}
@ -1177,17 +1226,19 @@ nfs_rephead(siz, nd, err, cache, frev, mrq, mbp, bposp)
*/
void
nfs_timer(arg)
void *arg;
void *arg; /* never used */
{
register struct nfsreq *rep;
register struct mbuf *m;
register struct socket *so;
register struct nfsmount *nmp;
register int timeo;
register struct nfssvc_sock *slp;
#ifdef NFSSERVER
static long lasttime = 0;
#endif
int s, error;
u_quad_t cur_usec;
s = splsoftnet();
for (rep = nfs_reqq.tqh_first; rep != 0; rep = rep->r_chain.tqe_next) {
@ -1285,9 +1336,20 @@ nfs_timer(arg)
lasttime = time.tv_sec;
nqnfs_serverd();
}
/*
* Scan the write gathering queues for writes that need to be
* completed now.
*/
cur_usec = (u_quad_t)time.tv_sec * 1000000 + (u_quad_t)time.tv_usec;
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 /* NFSSERVER */
splx(s);
timeout(nfs_timer, (void *)0, hz / NFS_HZ);
timeout(nfs_timer, (void *)0, nfs_ticks);
}
/*
@ -1503,8 +1565,9 @@ nfs_realign(m, hsiz)
* - fill in the cred struct.
*/
int
nfs_getreq(nd, has_header)
register struct nfsd *nd;
nfs_getreq(nd, nfsd, has_header)
register struct nfsrv_descript *nd;
struct nfsd *nfsd;
int has_header;
{
register int len, i;
@ -1512,57 +1575,66 @@ nfs_getreq(nd, has_header)
register int32_t t1;
struct uio uio;
struct iovec iov;
caddr_t dpos, cp2;
caddr_t dpos, cp2, cp;
u_int32_t nfsvers, auth_type;
int error = 0, nqnfs = 0;
uid_t nickuid;
int error = 0, nqnfs = 0, ticklen;
struct mbuf *mrep, *md;
register struct nfsuid *nuidp;
struct timeval tvin, tvout;
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++);
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);
}
} 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);
}
nfsvers = nfs_vers;
if (*tl != nfs_prog) {
if (*tl == nqnfs_prog) {
if (*tl == nqnfs_prog)
nqnfs++;
nfsvers = nqnfs_vers;
} else {
else {
nd->nd_repstat = EPROGUNAVAIL;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
}
tl++;
if (*tl++ != nfsvers) {
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);
}
nd->nd_procnum = fxdr_unsigned(u_int32_t , *tl++);
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 > NFSPROC_STATFS) ||
(*tl != rpc_auth_unix && *tl != rpc_auth_kerb)) {
(!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) {
@ -1570,6 +1642,7 @@ nfs_getreq(nd, has_header)
return (EBADRPC);
}
nd->nd_flag &= ~ND_KERBAUTH;
/*
* Handle auth_unix or auth_kerb.
*/
@ -1580,7 +1653,9 @@ nfs_getreq(nd, has_header)
return (EBADRPC);
}
nfsm_adv(nfsm_rndup(len));
nfsm_dissect(tl, u_int32_t *, 3*NFSX_UNSIGNED);
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);
@ -1588,45 +1663,124 @@ nfs_getreq(nd, has_header)
m_freem(mrep);
return (EBADRPC);
}
nfsm_dissect(tl, u_int32_t *, (len + 2)*NFSX_UNSIGNED);
nfsm_dissect(tl, u_int32_t *, (len + 2) * NFSX_UNSIGNED);
for (i = 0; i < len; i++)
if (i < NGROUPS)
nd->nd_cr.cr_groups[i] = fxdr_unsigned(gid_t, *tl++);
else
tl++;
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;
} else if (auth_type == rpc_auth_kerb) {
nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++);
nd->nd_authlen = fxdr_unsigned(int, *tl);
uio.uio_resid = nfsm_rndup(nd->nd_authlen);
if (uio.uio_resid > (len - 2 * NFSX_UNSIGNED)) {
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);
}
uio.uio_offset = 0;
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
uio.uio_segflg = UIO_SYSSPACE;
iov.iov_base = (caddr_t)nd->nd_authstr;
iov.iov_len = RPCAUTH_MAXSIZ;
nfsm_mtouio(&uio, uio.uio_resid);
nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
nd->nd_flag |= NFSD_NEEDAUTH;
}
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;
/*
* Do we have any use for the verifier.
* According to the "Remote Procedure Call Protocol Spec." it
* should be AUTH_NULL, but some clients make it AUTH_UNIX?
* For now, just skip over it
*/
len = fxdr_unsigned(int, *++tl);
if (len < 0 || len > RPCAUTH_MAXSIZ) {
m_freem(mrep);
return (EBADRPC);
}
if (len > 0) {
nfsm_adv(nfsm_rndup(len));
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.tv_sec ||
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);
}
/*
@ -1634,16 +1788,14 @@ nfs_getreq(nd, has_header)
*/
if (nqnfs && nd->nd_procnum != NQNFSPROC_EVICTED) {
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
nd->nd_nqlflag = fxdr_unsigned(int, *tl);
if (nd->nd_nqlflag) {
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(int, *tl);
nd->nd_duration = fxdr_unsigned(u_int32_t, *tl);
} else
nd->nd_duration = NQ_MINLEASE;
} else {
nd->nd_nqlflag = NQL_NOVAL;
} else
nd->nd_duration = NQ_MINLEASE;
}
nd->nd_md = md;
nd->nd_dpos = dpos;
return (0);
@ -1651,7 +1803,7 @@ nfsmout:
return (error);
}
void
int
nfs_msg(p, server, msg)
struct proc *p;
char *server, *msg;
@ -1664,35 +1816,39 @@ nfs_msg(p, server, msg)
tpr = NULL;
tprintf(tpr, "nfs server %s: %s\n", server, msg);
tprintf_close(tpr);
return (0);
}
#ifdef NFSSERVER
int (*nfsrv_procs[NFS_NPROCS]) __P((struct nfsd *, struct mbuf *, struct mbuf *,
caddr_t, struct ucred *, struct mbuf *,
int (*nfsrv3_procs[NFS_NPROCS]) __P((struct nfsrv_descript *,
struct nfssvc_sock *, struct proc *,
struct mbuf **)) = {
nfsrv_null,
nfsrv_getattr,
nfsrv_setattr,
nfsrv_noop,
nfsrv_lookup,
nfsrv3_access,
nfsrv_readlink,
nfsrv_read,
nfsrv_noop,
nfsrv_write,
nfsrv_create,
nfsrv_mkdir,
nfsrv_symlink,
nfsrv_mknod,
nfsrv_remove,
nfsrv_rmdir,
nfsrv_rename,
nfsrv_link,
nfsrv_symlink,
nfsrv_mkdir,
nfsrv_rmdir,
nfsrv_readdir,
nfsrv_readdirplus,
nfsrv_statfs,
nqnfsrv_readdirlook,
nfsrv_fsinfo,
nfsrv_pathconf,
nfsrv_commit,
nqnfsrv_getlease,
nqnfsrv_vacated,
nfsrv_noop,
nqnfsrv_access,
nfsrv_noop
};
/*
@ -1763,7 +1919,8 @@ nfsrv_rcv(so, arg, waitflag)
/*
* Now try and parse record(s) out of the raw stream data.
*/
if ((error = nfsrv_getstream(slp, waitflag)) != 0) {
error = nfsrv_getstream(slp, waitflag);
if (error) {
if (error == EPERM)
slp->ns_flag |= SLP_DISCONN;
else
@ -1818,11 +1975,11 @@ nfsrv_getstream(slp, waitflag)
register struct nfssvc_sock *slp;
int waitflag;
{
register struct mbuf *m;
register struct mbuf *m, **mpp;
register char *cp1, *cp2;
register int len;
struct mbuf *om, *m2, *recm = NULL;
u_long recmark;
u_int32_t recmark;
if (slp->ns_flag & SLP_GETSTREAM)
panic("nfs getstream");
@ -1852,7 +2009,12 @@ nfsrv_getstream(slp, waitflag)
}
}
slp->ns_cc -= NFSX_UNSIGNED;
slp->ns_reclen = ntohl(recmark) & ~0x80000000;
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_MINPACKET || slp->ns_reclen > NFS_MAXPACKET) {
slp->ns_flag &= ~SLP_GETSTREAM;
return (EPERM);
@ -1906,12 +2068,23 @@ nfsrv_getstream(slp, waitflag)
slp->ns_flag &= ~SLP_GETSTREAM;
return (0);
}
nfs_realign(recm, 10 * NFSX_UNSIGNED);
if (slp->ns_recend)
slp->ns_recend->m_nextpkt = recm;
else
slp->ns_rec = recm;
slp->ns_recend = recm;
/*
* Accumulate the fragments into a record.
*/
mpp = &slp->ns_frag;
while (*mpp)
mpp = &((*mpp)->m_next);
*mpp = recm;
if (slp->ns_flag & SLP_LASTFRAG) {
nfs_realign(slp->ns_frag, 10 * NFSX_UNSIGNED);
if (slp->ns_recend)
slp->ns_recend->m_nextpkt = slp->ns_frag;
else
slp->ns_rec = slp->ns_frag;
slp->ns_recend = slp->ns_frag;
slp->ns_frag = (struct mbuf *)0;
}
}
}
@ -1919,36 +2092,47 @@ nfsrv_getstream(slp, waitflag)
* Parse an RPC header.
*/
int
nfsrv_dorec(slp, nd)
nfsrv_dorec(slp, nfsd, ndp)
register struct nfssvc_sock *slp;
register struct nfsd *nd;
struct nfsd *nfsd;
struct nfsrv_descript **ndp;
{
register struct mbuf *m;
register struct mbuf *m, *nam;
register struct nfsrv_descript *nd;
int error;
*ndp = NULL;
if ((slp->ns_flag & SLP_VALID) == 0 ||
(m = slp->ns_rec) == (struct mbuf *)0)
return (ENOBUFS);
if ((slp->ns_rec = m->m_nextpkt) != NULL)
slp->ns_rec = m->m_nextpkt;
if (slp->ns_rec)
m->m_nextpkt = (struct mbuf *)0;
else
slp->ns_recend = (struct mbuf *)0;
if (m->m_type == MT_SONAME) {
nd->nd_nam = m;
nd->nd_md = nd->nd_mrep = m->m_next;
m->m_next = (struct mbuf *)0;
} else {
nd->nd_nam = (struct mbuf *)0;
nd->nd_md = nd->nd_mrep = m;
}
nd->nd_dpos = mtod(nd->nd_md, caddr_t);
if ((error = nfs_getreq(nd, TRUE)) != 0) {
m_freem(nd->nd_nam);
nam = m;
m = m->m_next;
nam->m_next = NULL;
} else
nam = NULL;
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) {
m_freem(nam);
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
@ -1962,13 +2146,13 @@ nfsrv_wakenfsd(slp)
if ((slp->ns_flag & SLP_VALID) == 0)
return;
for (nd = nfsd_head.tqh_first; nd != 0; nd = nd->nd_chain.tqe_next) {
if (nd->nd_flag & NFSD_WAITING) {
nd->nd_flag &= ~NFSD_WAITING;
if (nd->nd_slp)
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->nd_slp = slp;
nd->nfsd_slp = slp;
wakeup((caddr_t)nd);
return;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_srvcache.c,v 1.11 1996/02/09 21:48:32 christos Exp $ */
/* $NetBSD: nfs_srvcache.c,v 1.12 1996/02/18 11:53:49 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfs_srvcache.c 8.2 (Berkeley) 8/18/94
* @(#)nfs_srvcache.c 8.3 (Berkeley) 3/30/95
*/
/*
@ -60,12 +60,14 @@
#endif
#include <nfs/nfsm_subs.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsv2.h>
#include <nfs/nfsproto.h>
#include <nfs/nfs.h>
#include <nfs/nfsrvcache.h>
#include <nfs/nqnfs.h>
#include <nfs/nfs_var.h>
extern struct nfsstats nfsstats;
extern int nfsv2_procid[NFS_NPROCS];
long numnfsrvcache, desirednfsrvcache = NFSRVCACHESIZ;
#define NFSRCHASH(xid) \
@ -91,15 +93,18 @@ int nonidempotent[NFS_NPROCS] = {
FALSE,
FALSE,
FALSE,
TRUE,
TRUE,
TRUE,
TRUE,
TRUE,
TRUE,
TRUE,
TRUE,
TRUE,
FALSE,
FALSE,
FALSE,
TRUE,
TRUE,
TRUE,
TRUE,
TRUE,
TRUE,
TRUE,
TRUE,
FALSE,
FALSE,
FALSE,
@ -110,7 +115,7 @@ int nonidempotent[NFS_NPROCS] = {
};
/* True iff the rpc reply is an nfs status ONLY! */
static int repliesstatus[NFS_NPROCS] = {
static int nfsv2_repstat[NFS_NPROCS] = {
FALSE,
FALSE,
FALSE,
@ -129,11 +134,6 @@ static int repliesstatus[NFS_NPROCS] = {
TRUE,
FALSE,
FALSE,
FALSE,
FALSE,
FALSE,
FALSE,
TRUE,
};
/*
@ -162,9 +162,9 @@ nfsrv_initcache()
* Update/add new request at end of lru list
*/
int
nfsrv_getcache(nam, nd, repp)
struct mbuf *nam;
register struct nfsd *nd;
nfsrv_getcache(nd, slp, repp)
register struct nfsrv_descript *nd;
struct nfssvc_sock *slp;
struct mbuf **repp;
{
register struct nfsrvcache *rp;
@ -173,13 +173,17 @@ nfsrv_getcache(nam, nd, repp)
caddr_t bpos;
int ret;
if (nd->nd_nqlflag != NQL_NOVAL)
/*
* Don't cache recent requests for reliable transport protocols.
* (Maybe we should for the case of a reconnect, but..)
*/
if (!nd->nd_nam2)
return (RC_DOIT);
loop:
for (rp = NFSRCHASH(nd->nd_retxid)->lh_first; rp != 0;
rp = rp->rc_hash.le_next) {
if (nd->nd_retxid == rp->rc_xid && nd->nd_procnum == rp->rc_proc &&
netaddr_match(NETFAMILY(rp), &rp->rc_haddr, nam)) {
netaddr_match(NETFAMILY(rp), &rp->rc_haddr, nd->nd_nam)) {
if ((rp->rc_flag & RC_LOCKED) != 0) {
rp->rc_flag |= RC_WANTED;
(void) tsleep((caddr_t)rp, PZERO-1, "nfsrc", 0);
@ -198,7 +202,7 @@ loop:
ret = RC_DROPIT;
} else if (rp->rc_flag & RC_REPSTATUS) {
nfsstats.srvcache_nonidemdonehits++;
nfs_rephead(0, nd, rp->rc_status,
nfs_rephead(0, nd, slp, rp->rc_status,
0, (u_quad_t *)0, repp, &mb, &bpos);
ret = RC_REPLY;
} else if (rp->rc_flag & RC_REPMBUF) {
@ -245,7 +249,7 @@ loop:
TAILQ_INSERT_TAIL(&nfsrvlruhead, rp, rc_lru);
rp->rc_state = RC_INPROG;
rp->rc_xid = nd->nd_retxid;
saddr = mtod(nam, struct sockaddr_in *);
saddr = mtod(nd->nd_nam, struct sockaddr_in *);
switch (saddr->sin_family) {
case AF_INET:
rp->rc_flag |= RC_INETADDR;
@ -254,7 +258,7 @@ loop:
case AF_ISO:
default:
rp->rc_flag |= RC_NAM;
rp->rc_nam = m_copym(nam, 0, M_COPYALL, M_WAIT);
rp->rc_nam = m_copym(nd->nd_nam, 0, M_COPYALL, M_WAIT);
break;
};
rp->rc_proc = nd->nd_procnum;
@ -271,21 +275,20 @@ loop:
* Update a request cache entry after the rpc has been done
*/
void
nfsrv_updatecache(nam, nd, repvalid, repmbuf)
struct mbuf *nam;
register struct nfsd *nd;
nfsrv_updatecache(nd, repvalid, repmbuf)
register struct nfsrv_descript *nd;
int repvalid;
struct mbuf *repmbuf;
{
register struct nfsrvcache *rp;
if (nd->nd_nqlflag != NQL_NOVAL)
if (!nd->nd_nam2)
return;
loop:
for (rp = NFSRCHASH(nd->nd_retxid)->lh_first; rp != 0;
rp = rp->rc_hash.le_next) {
if (nd->nd_retxid == rp->rc_xid && nd->nd_procnum == rp->rc_proc &&
netaddr_match(NETFAMILY(rp), &rp->rc_haddr, nam)) {
netaddr_match(NETFAMILY(rp), &rp->rc_haddr, nd->nd_nam)) {
if ((rp->rc_flag & RC_LOCKED) != 0) {
rp->rc_flag |= RC_WANTED;
(void) tsleep((caddr_t)rp, PZERO-1, "nfsrc", 0);
@ -298,7 +301,8 @@ loop:
* the reply for non-idempotent rpc's.
*/
if (repvalid && nonidempotent[nd->nd_procnum]) {
if (repliesstatus[nd->nd_procnum]) {
if ((nd->nd_flag & ND_NFSV3) == 0 &&
nfsv2_repstat[nfsv2_procid[nd->nd_procnum]]) {
rp->rc_status = nd->nd_repstat;
rp->rc_flag |= RC_REPSTATUS;
} else {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_var.h,v 1.2 1996/02/13 17:06:52 christos Exp $ */
/* $NetBSD: nfs_var.h,v 1.3 1996/02/18 11:53:54 fvdl Exp $ */
/*
* Copyright (c) 1996 Christos Zoulas. All rights reserved.
@ -29,6 +29,10 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* XXX needs <nfs/rpcv2.h> and <nfs/nfs.h> because of typedefs
*/
struct vnode;
struct uio;
struct ucred;
@ -53,11 +57,12 @@ struct nfsnode;
struct sillyrename;
struct componentname;
struct nfsd_srvargs;
struct nfsd_cargs;
struct nfsrv_descript;
struct nfs_fattr;
/* nfs_bio.c */
int nfs_bioread __P((struct vnode *, struct uio *, int, struct ucred *));
int nfs_write __P((void *));
struct buf *nfs_getcacheblk __P((struct vnode *, daddr_t, int, struct proc *));
int nfs_vinvalbuf __P((struct vnode *, int, struct ucred *, struct proc *,
int));
@ -70,91 +75,157 @@ int nfs_boot_init __P((struct nfs_diskless *, struct proc *));
/* nfs_node.c */
void nfs_nhinit __P((void));
struct nfsnodehashhead *nfs_hash __P((nfsv2fh_t *));
int nfs_nget __P((struct mount *, nfsv2fh_t *, struct nfsnode **));
u_long nfs_hash __P((nfsfh_t *, int));
int nfs_nget __P((struct mount *, nfsfh_t *, int, struct nfsnode **));
int nfs_inactive __P((void *));
int nfs_reclaim __P((void *));
int nfs_lock __P((void *));
int nfs_unlock __P((void *));
int nfs_islocked __P((void *));
int nfs_abortop __P((void *));
/* nfs_vnops.c */
int nfs_null __P((struct vnode *, struct ucred *, struct proc *));
int nfs_access __P((void *));
int nfs_open __P((void *));
int nfs_close __P((void *));
int nfs_getattr __P((void *));
int nfs_setattr __P((void *));
int nfs_setattrrpc __P((struct vnode *, struct vattr *, struct ucred *,
struct proc *));
int nfs_lookup __P((void *));
int nfs_read __P((void *));
int nfs_readlink __P((void *));
int nfs_readlinkrpc __P((struct vnode *, struct uio *, struct ucred *));
int nfs_readrpc __P((struct vnode *, struct uio *, struct ucred *));
int nfs_writerpc __P((struct vnode *, struct uio *, struct ucred *, int));
int nfs_writerpc __P((struct vnode *, struct uio *, struct ucred *, int *,
int *));
int nfs_mknodrpc __P((struct vnode *, struct vnode **, struct componentname *,
struct vattr *));
int nfs_mknod __P((void *));
int nfs_create __P((void *));
int nfs_remove __P((void *));
int nfs_removeit __P((struct sillyrename *));
int nfs_removerpc __P((struct vnode *, char *, int, struct ucred *,
struct proc *));
int nfs_rename __P((void *));
int nfs_renameit __P((struct vnode *, struct componentname *,
struct sillyrename *));
int nfs_renamerpc __P((struct vnode *, char *, int, struct vnode *, char *, int,
struct ucred *, struct proc *));
int nfs_link __P((void *));
int nfs_symlink __P((void *));
int nfs_mkdir __P((void *));
int nfs_rmdir __P((void *));
int nfs_readdir __P((void *));
int nfs_readdirrpc __P((struct vnode *, struct uio *, struct ucred *));
int nfs_readdirlookrpc __P((struct vnode *, struct uio *, struct ucred *));
int nfs_readdirplusrpc __P((struct vnode *, struct uio *, struct ucred *));
int nfs_sillyrename __P((struct vnode *, struct vnode *,
struct componentname *));
int nfs_lookitup __P((struct sillyrename *, nfsv2fh_t *, struct proc *));
int nfs_lookitup __P((struct vnode *, char *, int, struct ucred *,
struct proc *, struct nfsnode **));
int nfs_commit __P((struct vnode *, u_quad_t, int, struct ucred *,
struct proc *));
int nfs_bmap __P((void *));
int nfs_strategy __P((void *));
int nfs_mmap __P((void *));
int nfs_fsync __P((void *));
int nfs_flush __P((struct vnode *, struct ucred *, int, struct proc *, int));
int nfs_pathconf __P((void *));
int nfs_advlock __P((void *));
int nfs_print __P((void *));
int nfs_blkatoff __P((void *));
int nfs_valloc __P((void *));
int nfs_vfree __P((void *));
int nfs_truncate __P((void *));
int nfs_update __P((void *));
int nfs_bwrite __P((void *));
int nfs_writebp __P((struct buf *, int));
int nfsspec_access __P((void *));
int nfsspec_read __P((void *));
int nfsspec_write __P((void *));
int nfsspec_close __P((void *));
int nfsfifo_read __P((void *));
int nfsfifo_write __P((void *));
int nfsfifo_close __P((void *));
/* nfs_nqlease.c */
int nqsrv_getlease __P((struct vnode *, u_int *, int, struct nfsd *,
struct mbuf *, int *, u_quad_t *, struct ucred *));
int lease_check __P((void *));
void nqnfs_lease_updatetime __P((int));
void nqnfs_clientlease __P((struct nfsmount *, struct nfsnode *, int, int,
time_t, u_quad_t));
void nqsrv_locklease __P((struct nqlease *));
void nqsrv_unlocklease __P((struct nqlease *));
int nqsrv_getlease __P((struct vnode *, u_int32_t *, int, struct nfssvc_sock *,
struct proc *, struct mbuf *, int *, u_quad_t *,
struct ucred *));
int nqnfs_vop_lease_check __P((void *));
void nqsrv_addhost __P((struct nqhost *, struct nfssvc_sock *, struct mbuf *));
void nqsrv_instimeq __P((struct nqlease *, u_long));
void nqsrv_instimeq __P((struct nqlease *, u_int32_t));
int nqsrv_cmpnam __P((struct nfssvc_sock *, struct mbuf *, struct nqhost *));
void nqsrv_send_eviction __P((struct vnode *, struct nqlease *,
struct nfssvc_sock *, struct mbuf *,
struct ucred *));
void nqsrv_waitfor_expiry __P((struct nqlease *));
void nqnfs_serverd __P((void));
int nqnfsrv_getlease __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nqnfsrv_vacated __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nqnfsrv_getlease __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nqnfsrv_vacated __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nqnfs_getlease __P((struct vnode *, int, struct ucred *, struct proc *));
int nqnfs_vacated __P((struct vnode *, struct ucred *));
int nqnfs_callback __P((struct nfsmount *, struct mbuf *, struct mbuf *,
caddr_t));
int nqnfs_clientd __P((struct nfsmount *, struct ucred *, struct nfsd_cargs *,
int, caddr_t, struct proc *));
void nqnfs_clientlease __P((struct nfsmount *, struct nfsnode *, int, int ,
time_t, u_quad_t));
void lease_updatetime __P((int));
void nqsrv_locklease __P((struct nqlease *));
void nqsrv_unlocklease __P((struct nqlease *));
caddr_t));
/* nfs_serv.c */
int nqnfsrv_access __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv_getattr __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv_setattr __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv_lookup __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv_readlink __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv_read __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv_write __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv_create __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv_remove __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv_rename __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv_link __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv_symlink __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv_mkdir __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv_rmdir __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv_readdir __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nqnfsrv_readdirlook __P((struct nfsd *, struct mbuf *, struct mbuf *,
caddr_t, struct ucred *, struct mbuf *,
struct mbuf **));
int nfsrv_statfs __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv_null __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv_noop __P((struct nfsd *, struct mbuf *, struct mbuf *, caddr_t,
struct ucred *, struct mbuf *, struct mbuf **));
int nfsrv3_access __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_getattr __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_setattr __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_lookup __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_readlink __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_read __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_write __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_writegather __P((struct nfsrv_descript **, struct nfssvc_sock *,
struct proc *, struct mbuf **));
void nfsrvw_coalesce __P((struct nfsrv_descript *, struct nfsrv_descript *));
int nfsrv_create __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_mknod __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_remove __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_rename __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_link __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_symlink __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_mkdir __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_rmdir __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_readdir __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_readdirplus __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_commit __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_statfs __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_fsinfo __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_pathconf __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_null __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_noop __P((struct nfsrv_descript *, struct nfssvc_sock *,
struct proc *, struct mbuf **));
int nfsrv_access __P((struct vnode *, int, struct ucred *, int, struct proc *));
/* nfs_socket.c */
@ -168,8 +239,8 @@ int nfs_reply __P((struct nfsreq *));
int nfs_request __P((struct vnode *, struct mbuf *, int, struct proc *,
struct ucred *, struct mbuf **, struct mbuf **,
caddr_t *));
int nfs_rephead __P((int, struct nfsd *, int, int, u_quad_t *, struct mbuf **,
struct mbuf **, caddr_t *));
int nfs_rephead __P((int, struct nfsrv_descript *, struct nfssvc_sock *,
int, int, u_quad_t *, struct mbuf **, struct mbuf **, caddr_t *));
void nfs_timer __P((void *));
int nfs_sigintr __P((struct nfsmount *, struct nfsreq *, struct proc *));
int nfs_sndlock __P((int *, struct nfsreq *));
@ -177,40 +248,58 @@ void nfs_sndunlock __P((int *));
int nfs_rcvlock __P((struct nfsreq *));
void nfs_rcvunlock __P((int *));
void nfs_realign __P((struct mbuf *, int));
int nfs_getreq __P((struct nfsd *, int));
void nfs_msg __P((struct proc *, char *, char *));
int nfs_getreq __P((struct nfsrv_descript *, struct nfsd *, int));
int nfs_msg __P((struct proc *, char *, char *));
void nfsrv_rcv __P((struct socket *, caddr_t, int));
int nfsrv_getstream __P((struct nfssvc_sock *, int));
int nfsrv_dorec __P((struct nfssvc_sock *, struct nfsd *));
int nfsrv_dorec __P((struct nfssvc_sock *, struct nfsd *,
struct nfsrv_descript **));
void nfsrv_wakenfsd __P((struct nfssvc_sock *));
/* nfs_srvcache.c */
void nfsrv_initcache __P((void));
int nfsrv_getcache __P((struct mbuf *, struct nfsd *, struct mbuf **));
void nfsrv_updatecache __P((struct mbuf *, struct nfsd *, int, struct mbuf *));
void nfsrv_initcache __P((void ));
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));
/* nfs_subs.c */
struct mbuf *nfsm_reqh __P((struct vnode *, u_long, int, caddr_t *));
struct mbuf *nfsm_rpchead __P((struct ucred *, int, int, int, int, char *,
struct mbuf *, int, struct mbuf **,
struct mbuf *nfsm_rpchead __P((struct ucred *, int, int, int, int, char *, int,
char *, struct mbuf *, int, struct mbuf **,
u_int32_t *));
int nfsm_mbuftouio __P((struct mbuf **, struct uio *, int, caddr_t *));
int nfsm_uiotombuf __P((struct uio *, struct mbuf **, int, caddr_t *));
int nfsm_disct __P((struct mbuf **, caddr_t *, int, int, caddr_t *));
int nfs_adv __P((struct mbuf **, caddr_t *, int, int));
int nfsm_strtmbuf __P((struct mbuf **, char **, char *, long));
void nfs_init __P((void));
int nfs_loadattrcache __P((struct vnode **, struct mbuf **, caddr_t *,
struct vattr *));
int nfs_getattrcache __P((struct vnode *, struct vattr *));
int nfs_namei __P((struct nameidata *, fhandle_t *, int, struct nfssvc_sock *,
struct mbuf *, struct mbuf **, caddr_t *, struct proc *));
struct mbuf *, struct mbuf **, caddr_t *, struct vnode **,
struct proc *, int));
void nfsm_adj __P((struct mbuf *, int, int));
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 **));
void nfsm_srvfattr __P((struct nfsrv_descript *, struct vattr *,
struct nfs_fattr *));
int nfsrv_fhtovp __P((fhandle_t *, int, struct vnode **, struct ucred *,
struct nfssvc_sock *, struct mbuf *, int *));
struct nfssvc_sock *, struct mbuf *, int *, int));
int netaddr_match __P((int, union nethostaddr *, struct mbuf *));
nfsuint64 *nfs_getcookie __P((struct nfsnode *, off_t off, int));
void nfs_invaldir __P((struct vnode *));
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 *));
/* nfs_syscalls.c */
int sys_getfh __P((struct proc *, void *, register_t *));
int sys_nfssvc __P((struct proc *, void *, register_t *));
int nfssvc_addsock __P((struct file *, struct mbuf *));
int nfssvc_nfsd __P((struct nfsd_srvargs *, caddr_t, struct proc *));
void nfsrv_zapsock __P((struct nfssvc_sock *));
@ -218,5 +307,8 @@ void nfsrv_slpderef __P((struct nfssvc_sock *));
void nfsrv_init __P((int));
int nfssvc_iod __P((struct proc *));
int nfs_getauth __P((struct nfsmount *, struct nfsreq *, struct ucred *,
int *, char **, int *));
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 *));

View File

@ -1,7 +1,7 @@
/* $NetBSD: nfs_vfsops.c,v 1.42 1996/02/13 17:53:35 gwr Exp $ */
/* $NetBSD: nfs_vfsops.c,v 1.43 1996/02/18 11:53:56 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
* Copyright (c) 1989, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfs_vfsops.c 8.3 (Berkeley) 1/4/94
* @(#)nfs_vfsops.c 8.12 (Berkeley) 5/20/95
*/
#include <sys/param.h>
@ -58,16 +58,24 @@
#include <netinet/in.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsv2.h>
#include <nfs/nfsproto.h>
#include <nfs/nfsnode.h>
#include <nfs/nfsmount.h>
#include <nfs/nfs.h>
#include <nfs/nfsmount.h>
#include <nfs/xdr_subs.h>
#include <nfs/nfsm_subs.h>
#include <nfs/nfsdiskless.h>
#include <nfs/nqnfs.h>
#include <nfs/nfs_var.h>
struct nfsstats nfsstats;
extern int nfs_ticks;
#ifdef notyet
static int nfs_sysctl(int *, u_int, void *, size_t *, void *, size_t,
struct proc *);
#endif
/*
* nfs vfs operations.
*/
@ -84,11 +92,13 @@ struct vfsops nfs_vfsops = {
nfs_fhtovp,
nfs_vptofh,
nfs_init,
#ifdef notyet
nfs_sysctl
#endif
};
extern u_long nfs_procids[NFS_NPROCS];
extern u_long nfs_prog, nfs_vers;
void nfs_disconnect __P((struct nfsmount *));
extern u_int32_t nfs_procids[NFS_NPROCS];
extern u_int32_t nfs_prog, nfs_vers;
static struct mount *
nfs_mount_diskless __P((struct nfs_dlmount *, char *, int, struct vnode **));
@ -106,43 +116,61 @@ nfs_statfs(mp, sbp, p)
struct proc *p;
{
register struct vnode *vp;
register struct nfsv2_statfs *sfp;
register struct nfs_statfs *sfp;
register caddr_t cp;
register int32_t t1;
register u_int32_t *tl;
register int32_t t1, t2;
caddr_t bpos, dpos, cp2;
int error = 0, isnq;
struct nfsmount *nmp = VFSTONFS(mp);
int error = 0, v3 = (nmp->nm_flag & NFSMNT_NFSV3), retattr;
struct mbuf *mreq, *mrep, *md, *mb, *mb2;
struct nfsmount *nmp;
struct ucred *cred;
struct nfsnode *np;
u_quad_t tquad;
nmp = VFSTONFS(mp);
isnq = (nmp->nm_flag & NFSMNT_NQNFS);
if ((error = nfs_nget(mp, &nmp->nm_fh, &np)) != 0)
#ifndef nolint
sfp = (struct nfs_statfs *)0;
#endif
error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np);
if (error)
return (error);
vp = NFSTOV(np);
nfsstats.rpccnt[NFSPROC_STATFS]++;
cred = crget();
cred->cr_ngroups = 0;
nfsm_reqhead(vp, NFSPROC_STATFS, NFSX_FH);
nfsm_fhtom(vp);
nfsm_request(vp, NFSPROC_STATFS, p, cred);
nfsm_dissect(sfp, struct nfsv2_statfs *, NFSX_STATFS(isnq));
if (v3 && (nmp->nm_flag & NFSMNT_GOTFSINFO) == 0)
(void)nfs_fsinfo(nmp, vp, cred, p);
nfsstats.rpccnt[NFSPROC_FSSTAT]++;
nfsm_reqhead(vp, NFSPROC_FSSTAT, NFSX_FH(v3));
nfsm_fhtom(vp, v3);
nfsm_request(vp, NFSPROC_FSSTAT, p, cred);
if (v3)
nfsm_postop_attr(vp, retattr);
if (!error)
nfsm_dissect(sfp, struct nfs_statfs *, NFSX_STATFS(v3));
#ifdef COMPAT_09
sbp->f_type = 2;
#else
sbp->f_type = 0;
#endif
sbp->f_flags = nmp->nm_flag;
sbp->f_iosize = NFS_MAXDGRAMDATA;
sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize);
sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks);
sbp->f_bfree = fxdr_unsigned(int32_t, sfp->sf_bfree);
sbp->f_bavail = fxdr_unsigned(int32_t, sfp->sf_bavail);
if (isnq) {
sbp->f_files = fxdr_unsigned(int32_t, sfp->sf_files);
sbp->f_ffree = fxdr_unsigned(int32_t, sfp->sf_ffree);
sbp->f_iosize = min(nmp->nm_rsize, nmp->nm_wsize);
if (v3) {
sbp->f_bsize = NFS_FABLKSIZE;
fxdr_hyper(&sfp->sf_tbytes, &tquad);
sbp->f_blocks = (long)(tquad / ((u_quad_t)NFS_FABLKSIZE));
fxdr_hyper(&sfp->sf_fbytes, &tquad);
sbp->f_bfree = (long)(tquad / ((u_quad_t)NFS_FABLKSIZE));
fxdr_hyper(&sfp->sf_abytes, &tquad);
sbp->f_bavail = (long)(tquad / ((u_quad_t)NFS_FABLKSIZE));
sbp->f_files = (fxdr_unsigned(int32_t,
sfp->sf_tfiles.nfsuquad[1]) & 0x7fffffff);
sbp->f_ffree = (fxdr_unsigned(int32_t,
sfp->sf_ffiles.nfsuquad[1]) & 0x7fffffff);
} else {
sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize);
sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks);
sbp->f_bfree = fxdr_unsigned(int32_t, sfp->sf_bfree);
sbp->f_bavail = fxdr_unsigned(int32_t, sfp->sf_bavail);
sbp->f_files = 0;
sbp->f_ffree = 0;
}
@ -157,6 +185,66 @@ nfs_statfs(mp, sbp, p)
return (error);
}
/*
* nfs version 3 fsinfo rpc call
*/
int
nfs_fsinfo(nmp, vp, cred, p)
register struct nfsmount *nmp;
register struct vnode *vp;
struct ucred *cred;
struct proc *p;
{
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;
int error = 0, retattr;
struct mbuf *mreq, *mrep, *md, *mb, *mb2;
nfsstats.rpccnt[NFSPROC_FSINFO]++;
nfsm_reqhead(vp, NFSPROC_FSINFO, NFSX_FH(1));
nfsm_fhtom(vp, 1);
nfsm_request(vp, NFSPROC_FSINFO, p, cred);
nfsm_postop_attr(vp, retattr);
if (!error) {
nfsm_dissect(fsp, struct nfsv3_fsinfo *, NFSX_V3FSINFO);
pref = fxdr_unsigned(u_int32_t, fsp->fs_wtpref);
if (pref < nmp->nm_wsize)
nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) &
~(NFS_FABLKSIZE - 1);
max = fxdr_unsigned(u_int32_t, fsp->fs_wtmax);
if (max < nmp->nm_wsize) {
nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1);
if (nmp->nm_wsize == 0)
nmp->nm_wsize = max;
}
pref = fxdr_unsigned(u_int32_t, fsp->fs_rtpref);
if (pref < nmp->nm_rsize)
nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) &
~(NFS_FABLKSIZE - 1);
max = fxdr_unsigned(u_int32_t, fsp->fs_rtmax);
if (max < nmp->nm_rsize) {
nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1);
if (nmp->nm_rsize == 0)
nmp->nm_rsize = max;
}
pref = fxdr_unsigned(u_int32_t, fsp->fs_dtpref);
if (pref < nmp->nm_readdirsize)
nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) &
~(NFS_DIRBLKSIZ - 1);
if (max < nmp->nm_readdirsize) {
nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1);
if (nmp->nm_readdirsize == 0)
nmp->nm_readdirsize = max;
}
nmp->nm_flag |= NFSMNT_GOTFSINFO;
}
nfsm_reqdone;
return (error);
}
/*
* Mount a remote root fs via. NFS. It goes like this:
* - Call nfs_boot_init() to fill in the nfs_diskless struct
@ -204,12 +292,20 @@ nfs_mountroot()
/*
* Link it into the mount list.
*/
#ifdef Lite2_integrated
simple_lock(&mountlist_slock);
CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
simple_unlock(&mountlist_slock);
rootvp = vp;
vfs_unbusy(mp, procp);
#else
if (vfs_lock(mp))
panic("nfs_mountroot: vfs_lock");
CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
mp->mnt_vnodecovered = NULLVP;
vfs_unlock(mp);
rootvp = vp;
#endif
/* Get root attributes (for the time). */
error = VOP_GETATTR(vp, &attr, procp->p_ucred, procp);
@ -220,6 +316,11 @@ nfs_mountroot()
#endif
inittodr(n);
/*
* XXX splnet, so networks will receive...
*/
splnet();
#ifdef notyet
/* Set up swap credentials. */
proc0.p_ucred->cr_uid = ntohl(nd.swap_ucred.cr_uid);
@ -251,6 +352,9 @@ nfs_mountroot()
*/
nfs_boot_getfh(&nd.nd_boot, "swap", &nd.nd_swap);
mp = nfs_mount_diskless(&nd.nd_swap, "/swap", 0, &vp);
#ifdef Lite2_integrated
vfs_unbusy(mp, procp);
#endif
printf("swap on %s\n", nd.nd_swap.ndm_host);
/*
@ -291,12 +395,16 @@ nfs_mount_diskless(ndmntp, mntname, mntflag, vpp)
struct mbuf *m;
int error;
#ifdef Lite2_integrated
vfs_rootmountalloc("nfs", mntname, &mp);
#else
/* Create the mount point. */
mp = (struct mount *)malloc((u_long)sizeof(struct mount),
M_MOUNT, M_WAITOK);
if (mp == NULL)
panic("nfs_mountroot: malloc mount for %s", mntname);
bzero((char *)mp, (u_long)sizeof(struct mount));
#endif
mp->mnt_op = &nfs_vfsops;
mp->mnt_flag = mntflag;
@ -305,7 +413,8 @@ nfs_mount_diskless(ndmntp, mntname, mntflag, vpp)
args.addr = (struct sockaddr *)&ndmntp->ndm_saddr;
args.addrlen = args.addr->sa_len;
args.sotype = SOCK_DGRAM;
args.fh = (nfsv2fh_t *)ndmntp->ndm_fh;
args.fh = ndmntp->ndm_fh;
args.fhsize = NFSX_V2FH;
args.hostname = ndmntp->ndm_host;
args.flags = NFSMNT_RESVPORT;
@ -344,6 +453,7 @@ nfs_decode_args(nmp, argp)
{
int s;
int adjsock;
int maxio;
s = splsoftnet();
@ -370,17 +480,25 @@ nfs_decode_args(nmp, argp)
nmp->nm_retry = NFS_MAXREXMIT;
}
if (argp->flags & NFSMNT_NFSV3) {
if (argp->sotype == SOCK_DGRAM)
maxio = NFS_MAXDGRAMDATA;
else
maxio = NFS_MAXDATA;
} else
maxio = NFS_V2MAXDATA;
if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
int osize = nmp->nm_wsize;
nmp->nm_wsize = argp->wsize;
/* Round down to multiple of blocksize */
nmp->nm_wsize &= ~0x1ff;
nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
if (nmp->nm_wsize <= 0)
nmp->nm_wsize = 512;
else if (nmp->nm_wsize > NFS_MAXDATA)
nmp->nm_wsize = NFS_MAXDATA;
nmp->nm_wsize = NFS_FABLKSIZE;
adjsock |= (nmp->nm_wsize != osize);
}
if (nmp->nm_wsize > maxio)
nmp->nm_wsize = maxio;
if (nmp->nm_wsize > MAXBSIZE)
nmp->nm_wsize = MAXBSIZE;
@ -388,16 +506,26 @@ nfs_decode_args(nmp, argp)
int osize = nmp->nm_rsize;
nmp->nm_rsize = argp->rsize;
/* Round down to multiple of blocksize */
nmp->nm_rsize &= ~0x1ff;
nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
if (nmp->nm_rsize <= 0)
nmp->nm_rsize = 512;
else if (nmp->nm_rsize > NFS_MAXDATA)
nmp->nm_rsize = NFS_MAXDATA;
nmp->nm_rsize = NFS_FABLKSIZE;
adjsock |= (nmp->nm_rsize != osize);
}
if (nmp->nm_rsize > maxio)
nmp->nm_rsize = maxio;
if (nmp->nm_rsize > MAXBSIZE)
nmp->nm_rsize = MAXBSIZE;
if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
nmp->nm_readdirsize = argp->readdirsize;
/* Round down to multiple of blocksize */
nmp->nm_readdirsize &= ~(NFS_DIRBLKSIZ - 1);
if (nmp->nm_readdirsize < NFS_DIRBLKSIZ)
nmp->nm_readdirsize = NFS_DIRBLKSIZ;
}
if (nmp->nm_readdirsize > maxio)
nmp->nm_readdirsize = maxio;
if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0 &&
argp->maxgrouplist <= NFS_MAXGRPS)
nmp->nm_numgrps = argp->maxgrouplist;
@ -446,11 +574,13 @@ nfs_mount(mp, path, data, ndp, p)
struct vnode *vp;
char pth[MNAMELEN], hst[MNAMELEN];
size_t len;
nfsv2fh_t nfh;
u_char nfh[NFSX_V3FHMAX];
error = copyin(data, (caddr_t)&args, sizeof (struct nfs_args));
if (error)
return (error);
if (args.version != NFS_ARGSVERSION)
return (EPROGMISMATCH);
if (mp->mnt_flag & MNT_UPDATE) {
register struct nfsmount *nmp = VFSTONFS(mp);
@ -459,21 +589,22 @@ nfs_mount(mp, path, data, ndp, p)
nfs_decode_args(nmp, &args);
return (0);
}
error = copyin((caddr_t)args.fh, (caddr_t)&nfh, sizeof (nfsv2fh_t));
error = copyin((caddr_t)args.fh, (caddr_t)nfh, args.fhsize);
if (error)
return (error);
if ((error = copyinstr(path, pth, MNAMELEN-1, &len)) != 0)
error = copyinstr(path, pth, MNAMELEN-1, &len);
if (error)
return (error);
bzero(&pth[len], MNAMELEN - len);
if ((error = copyinstr(args.hostname, hst, MNAMELEN-1, &len)) != 0)
error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
if (error)
return (error);
bzero(&hst[len], MNAMELEN - len);
/* sockargs() call must be after above copyin() calls */
error = sockargs(&nam, (caddr_t)args.addr,
args.addrlen, MT_SONAME);
error = sockargs(&nam, (caddr_t)args.addr, args.addrlen, MT_SONAME);
if (error)
return (error);
args.fh = &nfh;
args.fh = nfh;
error = mountnfs(&args, mp, nam, pth, hst, &vp);
return (error);
}
@ -503,14 +634,14 @@ mountnfs(argp, mp, nam, pth, hst, vpp)
M_NFSMNT, M_WAITOK);
bzero((caddr_t)nmp, sizeof (struct nfsmount));
mp->mnt_data = (qaddr_t)nmp;
TAILQ_INIT(&nmp->nm_uidlruhead);
}
#ifdef Lite2_integrated
vfs_getnewfsid(mp, makefstype(MOUNT_NFS));
#else
getnewfsid(mp, makefstype(MOUNT_NFS));
#endif
nmp->nm_mountp = mp;
if ((argp->flags & (NFSMNT_NQNFS | NFSMNT_MYWRITE)) ==
(NFSMNT_NQNFS | NFSMNT_MYWRITE)) {
error = EPERM;
goto bad;
}
if (argp->flags & NFSMNT_NQNFS)
/*
* We have to set mnt_maxsymlink to a non-zero value so
@ -523,13 +654,15 @@ mountnfs(argp, mp, nam, pth, hst, vpp)
nmp->nm_retry = NFS_RETRANS;
nmp->nm_wsize = NFS_WSIZE;
nmp->nm_rsize = NFS_RSIZE;
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;
CIRCLEQ_INIT(&nmp->nm_timerhead);
nmp->nm_inprog = NULLVP;
bcopy((caddr_t)argp->fh, (caddr_t)&nmp->nm_fh, sizeof(nfsv2fh_t));
nmp->nm_fhsize = argp->fhsize;
bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
#ifdef COMPAT_09
mp->mnt_stat.f_type = 2;
#else
@ -568,7 +701,8 @@ mountnfs(argp, mp, nam, pth, hst, vpp)
* this problem, because one can identify root inodes by their
* number == ROOTINO (2).
*/
if ((error = nfs_nget(mp, &nmp->nm_fh, &np)) != 0)
error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np);
if (error)
goto bad;
*vpp = NFSTOV(np);
@ -611,7 +745,8 @@ nfs_unmount(mp, mntflags, p)
* the remote root. See comment in mountnfs(). The VFS unmount()
* has done vput on this vnode, otherwise we would get deadlock!
*/
if ((error = nfs_nget(mp, &nmp->nm_fh, &np)) != 0)
error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np);
if (error)
return(error);
vp = NFSTOV(np);
if (vp->v_usecount > 2) {
@ -625,7 +760,8 @@ nfs_unmount(mp, mntflags, p)
nmp->nm_flag |= NFSMNT_DISMINPROG;
while (nmp->nm_inprog != NULLVP)
(void) tsleep((caddr_t)&lbolt, PSOCK, "nfsdism", 0);
if ((error = vflush(mp, vp, flags)) != 0) {
error = vflush(mp, vp, flags);
if (error) {
vput(vp);
nmp->nm_flag &= ~NFSMNT_DISMINPROG;
return (error);
@ -666,7 +802,8 @@ nfs_root(mp, vpp)
int error;
nmp = VFSTONFS(mp);
if ((error = nfs_nget(mp, &nmp->nm_fh, &np)) != 0)
error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np);
if (error)
return (error);
vp = NFSTOV(np);
vp->v_type = VDIR;
@ -706,9 +843,14 @@ loop:
goto loop;
if (VOP_ISLOCKED(vp) || vp->v_dirtyblkhd.lh_first == NULL)
continue;
#ifdef Lite2_integrated
if (vget(vp, LK_EXCLUSIVE, p))
#else
if (vget(vp, 1))
#endif
goto loop;
if ((error = VOP_FSYNC(vp, cred, waitfor, p)) != 0)
error = VOP_FSYNC(vp, cred, waitfor, p);
if (error)
allerror = error;
vput(vp);
}
@ -730,6 +872,52 @@ nfs_vget(mp, ino, vpp)
return (EOPNOTSUPP);
}
#ifdef notyet
/*
* Do that sysctl thang...
*/
static int
nfs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
size_t newlen, struct proc *p)
{
int rv;
/*
* All names at this level are terminal.
*/
if(namelen > 1)
return ENOTDIR; /* overloaded */
switch(name[0]) {
case NFS_NFSSTATS:
if(!oldp) {
*oldlenp = sizeof nfsstats;
return 0;
}
if(*oldlenp < sizeof nfsstats) {
*oldlenp = sizeof nfsstats;
return ENOMEM;
}
rv = copyout(&nfsstats, oldp, sizeof nfsstats);
if(rv) return rv;
if(newp && newlen != sizeof nfsstats)
return EINVAL;
if(newp) {
return copyin(newp, &nfsstats, sizeof nfsstats);
}
return 0;
default:
return EOPNOTSUPP;
}
}
#endif
/*
* At this point, this should never happen
*/

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfsdiskless.h,v 1.8 1996/02/13 17:53:32 gwr Exp $ */
/* $NetBSD: nfsdiskless.h,v 1.9 1996/02/18 11:54:00 fvdl Exp $ */
/*
* Copyright (c) 1991, 1993
@ -52,7 +52,7 @@
struct nfs_dlmount {
struct sockaddr_in ndm_saddr; /* Address of file server */
char ndm_host[MNAMELEN]; /* Host name for mount pt */
u_char ndm_fh[NFS_FHSIZE]; /* The file's file handle */
u_char ndm_fh[NFSX_V2FH]; /* The file's file handle */
};
struct nfs_diskless {
struct sockaddr_in nd_boot; /* Address of boot server */

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfsm_subs.h,v 1.8 1996/02/09 21:48:43 christos Exp $ */
/* $NetBSD: nfsm_subs.h,v 1.9 1996/02/18 11:54:01 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
@ -35,9 +35,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfsm_subs.h 8.1 (Berkeley) 6/16/93
* @(#)nfsm_subs.h 8.2 (Berkeley) 3/30/95
*/
#ifndef _NFS_NFSM_SUBS_H_
#define _NFS_NFSM_SUBS_H_
/*
* These macros do strange and peculiar things to mbuf chains for
* the assistance of the nfs code. To attempt to use them for any
@ -47,6 +52,7 @@
/*
* First define what the actual subs. return
*/
#define M_HASCL(m) ((m)->m_flags & M_EXT)
#define NFSMINOFF(m) \
if (M_HASCL(m)) \
@ -86,45 +92,152 @@
mb->m_len += (s); \
bpos += (s); }
#define nfsm_dissect(a,c,s) \
#define nfsm_dissect(a, c, s) \
{ t1 = mtod(md, caddr_t)+md->m_len-dpos; \
if (t1 >= (s)) { \
(a) = (c)(dpos); \
dpos += (s); \
} else if ((error = nfsm_disct(&md, &dpos, \
(s), t1, &cp2)) != 0) { \
} else if ((t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) != 0){ \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
} else { \
(a) = (c)cp2; \
} }
#define nfsm_fhtom(v) \
nfsm_build(cp,caddr_t,NFSX_FH); \
bcopy((caddr_t)&(VTONFS(v)->n_fh), cp, NFSX_FH)
#define nfsm_fhtom(v, v3) \
{ 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); \
} }
#define nfsm_srvfhtom(f) \
nfsm_build(cp,caddr_t,NFSX_FH); \
bcopy((caddr_t)(f), cp, NFSX_FH)
#define nfsm_srvfhtom(f, v3) \
{ 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); \
} }
#define nfsm_mtofh(d,v) \
{ struct nfsnode *np; nfsv2fh_t *fhp; \
nfsm_dissect(fhp,nfsv2fh_t *,NFSX_FH); \
if ((error = nfs_nget((d)->v_mount, fhp, &np)) != 0) { \
m_freem(mrep); \
goto nfsmout; \
} \
(v) = NFSTOV(np); \
nfsm_loadattr(v, (struct vattr *)0); \
#define nfsm_srvpostop_fh(f) \
{ 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); \
}
#define nfsm_loadattr(v,a) \
{ struct vnode *tvp = (v); \
if ((error = nfs_loadattrcache(&tvp, &md, &dpos, (a))) != 0) { \
#define nfsm_mtofh(d, v, v3, f) \
{ 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); \
}
#define nfsm_getfh(f, s, v3) \
{ 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)); }
#define nfsm_loadattr(v, a) \
{ struct vnode *ttvp = (v); \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
} \
(v) = tvp; }
(v) = ttvp; }
#define nfsm_postop_attr(v, f) \
{ 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)) != 0) { \
error = t1; \
(f) = 0; \
m_freem(mrep); \
goto nfsmout; \
} \
(v) = ttvp; \
} }
/* Used as (f) for nfsm_wcc_data() */
#define NFSV3_WCCRATTR 0
#define NFSV3_WCCCHK 1
#define nfsm_wcc_data(v, f) \
{ 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; \
} }
#define nfsm_v3sattr(s, a) \
{ (s)->sa_modetrue = nfs_true; \
(s)->sa_mode = vtonfsv3_mode((a)->va_mode); \
(s)->sa_uidfalse = nfs_false; \
(s)->sa_gidfalse = nfs_false; \
(s)->sa_sizefalse = nfs_false; \
(s)->sa_atimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \
txdr_nfsv3time(&(a)->va_atime, &(s)->sa_atime); \
(s)->sa_mtimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \
txdr_nfsv3time(&(a)->va_mtime, &(s)->sa_mtime); \
}
#define nfsm_strsiz(s,m) \
{ nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \
@ -141,15 +254,27 @@
nfsm_reply(0); \
} }
#define nfsm_srvnamesiz(s) \
{ 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); \
}
#define nfsm_mtouio(p,s) \
if ((s) > 0 && \
(error = nfsm_mbuftouio(&md,(p),(s),&dpos)) != 0) { \
(t1 = nfsm_mbuftouio(&md,(p),(s),&dpos)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
}
#define nfsm_uiotom(p,s) \
if ((error = nfsm_uiotombuf((p),&mb,(s),&bpos)) != 0) { \
if ((t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) != 0) { \
error = t1; \
m_freem(mreq); \
goto nfsmout; \
}
@ -164,8 +289,12 @@
#define nfsm_request(v, t, p, c) \
if ((error = nfs_request((v), mreq, (t), (p), \
(c), &mrep, &md, &dpos)) != 0) \
goto nfsmout
(c), &mrep, &md, &dpos)) != 0) { \
if (error & NFSERR_RETERR) \
error &= ~NFSERR_RETERR; \
else \
goto nfsmout; \
}
#define nfsm_strtom(a,s,m) \
if ((s) > (m)) { \
@ -179,8 +308,8 @@
*tl++ = txdr_unsigned(s); \
*(tl+((t2>>2)-2)) = 0; \
bcopy((caddr_t)(a), (caddr_t)tl, (s)); \
} else if ((error = nfsm_strtmbuf(&mb, &bpos, \
(a), (s))) != 0) { \
} else if ((t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) != 0) { \
error = t2; \
m_freem(mreq); \
goto nfsmout; \
}
@ -192,30 +321,53 @@
#define nfsm_reply(s) \
{ \
nfsd->nd_repstat = error; \
if (error) \
(void) nfs_rephead(0, nfsd, error, cache, &frev, \
if (error && !(nfsd->nd_flag & ND_NFSV3)) \
(void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \
mrq, &mb, &bpos); \
else \
(void) nfs_rephead((s), nfsd, error, cache, &frev, \
(void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \
mrq, &mb, &bpos); \
m_freem(mrep); \
mreq = *mrq; \
if (error) \
if (error && (!(nfsd->nd_flag & ND_NFSV3) || \
error == EBADRPC)) \
return(0); \
}
#define nfsm_adv(s) \
t1 = mtod(md, caddr_t)+md->m_len-dpos; \
if (t1 >= (s)) { \
dpos += (s); \
} else if ((error = nfs_adv(&md, &dpos, (s), t1)) != 0) { \
m_freem(mrep); \
goto nfsmout; \
#define nfsm_writereply(s, v3) \
{ \
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); \
}
#define nfsm_adv(s) \
{ 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; \
} }
#define nfsm_srvmtofh(f) \
nfsm_dissect(tl, u_int32_t *, NFSX_FH); \
bcopy((caddr_t)tl, (caddr_t)f, NFSX_FH)
{ if (nfsd->nd_flag & ND_NFSV3) { \
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
if (fxdr_unsigned(int, *tl) != NFSX_V3FH) { \
error = EBADRPC; \
nfsm_reply(0); \
} \
} \
nfsm_dissect(tl, u_int32_t *, NFSX_V3FH); \
bcopy((caddr_t)tl, (caddr_t)(f), NFSX_V3FH); \
if ((nfsd->nd_flag & ND_NFSV3) == 0) \
nfsm_adv(NFSX_V2FH - NFSX_V3FH); \
}
#define nfsm_clget \
if (bp >= be) { \
@ -231,40 +383,57 @@
} \
tl = (u_int32_t *)bp
#define nfsm_srvfillattr \
fp->fa_type = vtonfs_type(va.va_type); \
fp->fa_mode = vtonfs_mode(va.va_type, va.va_mode); \
fp->fa_nlink = txdr_unsigned(va.va_nlink); \
fp->fa_uid = txdr_unsigned(va.va_uid); \
fp->fa_gid = txdr_unsigned(va.va_gid); \
if (nfsd->nd_nqlflag == NQL_NOVAL) { \
fp->fa_nfsblocksize = txdr_unsigned(va.va_blocksize); \
if (va.va_type == VFIFO) \
fp->fa_nfsrdev = 0xffffffff; \
else \
fp->fa_nfsrdev = txdr_unsigned(va.va_rdev); \
fp->fa_nfsfsid = txdr_unsigned(va.va_fsid); \
fp->fa_nfsfileid = txdr_unsigned(va.va_fileid); \
fp->fa_nfssize = txdr_unsigned(va.va_size); \
fp->fa_nfsblocks = txdr_unsigned(va.va_bytes / NFS_FABLKSIZE); \
txdr_nfstime(&va.va_atime, &fp->fa_nfsatime); \
txdr_nfstime(&va.va_mtime, &fp->fa_nfsmtime); \
txdr_nfstime(&va.va_ctime, &fp->fa_nfsctime); \
} else { \
fp->fa_nqblocksize = txdr_unsigned(va.va_blocksize); \
if (va.va_type == VFIFO) \
fp->fa_nqrdev = 0xffffffff; \
else \
fp->fa_nqrdev = txdr_unsigned(va.va_rdev); \
fp->fa_nqfsid = txdr_unsigned(va.va_fsid); \
fp->fa_nqfileid = txdr_unsigned(va.va_fileid); \
txdr_hyper(&va.va_size, &fp->fa_nqsize); \
txdr_hyper(&va.va_bytes, &fp->fa_nqbytes); \
txdr_nqtime(&va.va_atime, &fp->fa_nqatime); \
txdr_nqtime(&va.va_mtime, &fp->fa_nqmtime); \
txdr_nqtime(&va.va_ctime, &fp->fa_nqctime); \
fp->fa_nqflags = txdr_unsigned(va.va_flags); \
fp->fa_nqgen = txdr_unsigned(va.va_gen); \
txdr_hyper(&va.va_filerev, &fp->fa_nqfilerev); \
}
#define nfsm_srvfillattr(a, f) \
nfsm_srvfattr(nfsd, (a), (f))
#define nfsm_srvwcc_data(br, b, ar, a) \
nfsm_srvwcc(nfsd, (br), (b), (ar), (a), &mb, &bpos)
#define nfsm_srvpostop_attr(r, a) \
nfsm_srvpostopattr(nfsd, (r), (a), &mb, &bpos)
#define nfsm_srvsattr(a) \
{ 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); \
fxdr_hyper(tl, &(a)->va_size); \
} \
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: \
(a)->va_atime.tv_sec = time.tv_sec; \
(a)->va_atime.tv_nsec = time.tv_usec * 1000; \
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: \
(a)->va_mtime.tv_sec = time.tv_sec; \
(a)->va_mtime.tv_nsec = time.tv_usec * 1000; \
break; \
}; }
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfsmount.h,v 1.9 1996/02/09 21:48:44 christos Exp $ */
/* $NetBSD: nfsmount.h,v 1.10 1996/02/18 11:54:03 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
@ -35,9 +35,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfsmount.h 8.2 (Berkeley) 8/18/94
* @(#)nfsmount.h 8.3 (Berkeley) 3/30/95
*/
#ifndef _NFS_NFSMOUNT_H_
#define _NFS_NFSMOUNT_H_
/*
* Mount structure.
* One allocated on every NFS mount.
@ -47,7 +51,8 @@ struct nfsmount {
int nm_flag; /* Flags for soft/hard... */
struct mount *nm_mountp; /* Vfs structure for this filesystem */
int nm_numgrps; /* Max. size of groupslist */
nfsv2fh_t nm_fh; /* File handle of root dir */
u_char nm_fh[NFSX_V3FHMAX]; /* File handle of root dir */
int nm_fhsize; /* Size of root file handle */
struct socket *nm_so; /* Rpc socket */
int nm_sotype; /* Type of socket */
int nm_soproto; /* and protocol */
@ -63,6 +68,7 @@ struct nfsmount {
int nm_deadthresh; /* Threshold of timeouts-->dead server*/
int nm_rsize; /* Max size of read rpc */
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 */
CIRCLEQ_HEAD(, nfsnode) nm_timerhead; /* Head of lease timer queue */
@ -71,6 +77,13 @@ struct nfsmount {
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];
};
#ifdef _KERNEL
@ -78,26 +91,31 @@ struct nfsmount {
* Convert mount ptr to nfsmount ptr.
*/
#define VFSTONFS(mp) ((struct nfsmount *)((mp)->mnt_data))
#endif /* _KERNEL */
/*
* Prototypes for NFS mount operations
*/
int nfs_statfs __P((struct mount *, struct statfs *, struct proc *));
int nfs_mountroot __P((void));
void nfs_decode_args __P((struct nfsmount *, struct nfs_args *));
int nfs_mount __P((struct mount *, char *, caddr_t, struct nameidata *,
struct proc *));
int mountnfs __P((struct nfs_args *, struct mount *, struct mbuf *, char *,
char *, struct vnode **));
int nfs_unmount __P((struct mount *, int, struct proc *));
int nfs_root __P((struct mount *, struct vnode **));
int nfs_sync __P((struct mount *, int, struct ucred *, struct proc *));
int nfs_vget __P((struct mount *, ino_t, struct vnode **));
int nfs_fhtovp __P((struct mount *, struct fid *, struct mbuf *,
struct vnode **, int *, struct ucred **));
int nfs_vptofh __P((struct vnode *, struct fid *));
int nfs_start __P((struct mount *, int, struct proc *));
int nfs_quotactl __P((struct mount *, int, uid_t, caddr_t, struct proc *));
void nfs_init __P((void));
int nfs_mount __P((struct mount *mp, char *path, caddr_t data,
struct nameidata *ndp, struct proc *p));
int mountnfs __P((struct nfs_args *argp, struct mount *mp,
struct mbuf *nam, char *pth, char *hst, struct vnode **vpp));
int nfs_mountroot __P((void));
void nfs_decode_args __P((struct nfsmount *, struct nfs_args *));
int nfs_start __P((struct mount *mp, int flags, struct proc *p));
int nfs_unmount __P((struct mount *mp, int mntflags, struct proc *p));
int nfs_root __P((struct mount *mp, struct vnode **vpp));
int nfs_quotactl __P((struct mount *mp, int cmds, uid_t uid, caddr_t arg,
struct proc *p));
int nfs_statfs __P((struct mount *mp, struct statfs *sbp, struct proc *p));
int nfs_sync __P((struct mount *mp, int waitfor, struct ucred *cred,
struct proc *p));
int nfs_vget __P((struct mount *, ino_t, struct vnode **));
int nfs_fhtovp __P((struct mount *mp, struct fid *fhp, struct mbuf *nam,
struct vnode **vpp, int *exflagsp, struct ucred **credanonp));
int nfs_vptofh __P((struct vnode *vp, struct fid *fhp));
int nfs_fsinfo __P((struct nfsmount *, struct vnode *, struct ucred *,
struct proc *));
void nfs_init __P((void));
#endif /* _KERNEL */
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfsnode.h,v 1.15 1996/02/09 21:48:47 christos Exp $ */
/* $NetBSD: nfsnode.h,v 1.16 1996/02/18 11:54:04 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
@ -35,9 +35,17 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfsnode.h 8.6 (Berkeley) 8/18/94
* @(#)nfsnode.h 8.9 (Berkeley) 5/14/95
*/
#ifndef _NFS_NFSNODE_H_
#define _NFS_NFSNODE_H_
#ifndef _NFS_NFS_H_
#include <nfs/nfs.h>
#endif
/*
* Silly rename structure that hangs off the nfsnode until the name
* can be removed by nfs_inactive()
@ -49,37 +57,74 @@ struct sillyrename {
char s_name[20];
};
/*
* This structure is used to save the logical directory offset to
* NFS cookie mappings.
* The mappings are stored in a list headed
* by n_cookies, as required.
* There is one mapping for each NFS_DIRBLKSIZ bytes of directory information
* stored in increasing logical offset byte order.
*/
#define NFSNUMCOOKIES 31
struct nfsdmap {
LIST_ENTRY(nfsdmap) ndm_list;
int ndm_eocookie;
nfsuint64 ndm_cookies[NFSNUMCOOKIES];
};
/*
* The nfsnode is the nfs equivalent to ufs's inode. Any similarity
* is purely coincidental.
* There is a unique nfsnode allocated for each active file,
* each current directory, each mounted-on file, text file, and the root.
* An nfsnode is 'named' by its file handle. (nget/nfs_node.c)
* If this structure exceeds 256 bytes (it is currently 256 using 4.4BSD-Lite
* type definitions), file handles of > 32 bytes should probably be split out
* into a separate MALLOC()'d data structure. (Reduce the size of nfsfh_t by
* changing the definition in sys/mount.h of NFS_SMALLFH.)
* NB: Hopefully the current order of the fields is such that everything will
* be well aligned and, therefore, tightly packed.
*/
struct nfsnode {
LIST_ENTRY(nfsnode) n_hash; /* Hash chain */
CIRCLEQ_ENTRY(nfsnode) n_timer; /* Nqnfs timer chain */
nfsv2fh_t n_fh; /* NFS File Handle */
long n_flag; /* Flag for locking.. */
struct vnode *n_vnode; /* vnode associated with this node */
struct vattr n_vattr; /* Vnode attribute cache */
time_t n_attrstamp; /* Time stamp for cached attributes */
struct sillyrename *n_sillyrename; /* Ptr to silly rename struct */
u_quad_t n_size; /* Current size of file */
int n_error; /* Save write error value */
u_long n_direofoffset; /* Dir. EOF offset cache */
time_t n_mtime; /* Prev modify time. */
time_t n_ctime; /* Prev create time. */
u_quad_t n_brev; /* Modify rev when cached */
u_quad_t n_lrev; /* Modify rev for lease */
time_t n_expiry; /* Lease expiry time */
struct lockf *n_lockf; /* Advisory lock records */
struct sillyrename n_silly; /* Silly rename struct */
struct timeval n_atim; /* Special file times */
struct timeval n_mtim;
LIST_ENTRY(nfsnode) n_hash; /* Hash chain */
CIRCLEQ_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 */
struct vattr n_vattr; /* Vnode attribute cache */
time_t n_attrstamp; /* Attr. cache timestamp */
time_t n_mtime; /* Prev modify time. */
time_t n_ctime; /* Prev create time. */
time_t n_expiry; /* Lease expiry time */
nfsfh_t *n_fhp; /* NFS File Handle */
struct vnode *n_vnode; /* associated vnode */
struct lockf *n_lockf; /* Locking record of file */
int n_error; /* Save write error value */
union {
struct timespec nf_atim; /* Special file times */
nfsuint64 nd_cookieverf; /* Cookie verifier (dir only) */
} n_un1;
union {
struct timespec nf_mtim;
off_t nd_direof; /* Dir. EOF offset cache */
} n_un2;
union {
struct sillyrename *nf_silly; /* Ptr to silly rename struct */
LIST_HEAD(, nfsdmap) nd_cook; /* cookies */
} n_un3;
short n_fhsize; /* size in bytes, of fh */
short n_flag; /* Flag for locking.. */
nfsfh_t n_fh; /* Small File Handle */
};
#define n_atim n_un1.nf_atim
#define n_mtim n_un2.nf_mtim
#define n_sillyrename n_un3.nf_silly
#define n_cookieverf n_un1.nd_cookieverf
#define n_direofoffset n_un2.nd_direof
#define n_cookies n_un3.nd_cook
/*
* Flags for n_flag
*/
@ -109,60 +154,76 @@ TAILQ_HEAD(, buf) nfs_bufq;
/*
* Prototypes for NFS vnode operations
*/
int nfs_lookup __P((void *));
int nfs_create __P((void *));
int nfs_mknod __P((void *));
int nfs_open __P((void *));
int nfs_close __P((void *));
int nfsspec_close __P((void *));
#ifdef FIFO
int nfsfifo_close __P((void *));
#endif
int nfs_access __P((void *));
int nfsspec_access __P((void *));
int nfs_getattr __P((void *));
int nfs_setattr __P((void *));
int nfs_read __P((void *));
int nfs_write __P((void *));
#define nfs_lease_check (int (*) __P((void *))) nullop
int nfsspec_read __P((void *));
int nfsspec_write __P((void *));
#ifdef FIFO
int nfsfifo_read __P((void *));
int nfsfifo_write __P((void *));
#endif
#define nfs_ioctl (int (*) __P((void *))) enoioctl
#define nfs_select (int (*) __P((void *))) seltrue
int nfs_mmap __P((void *));
int nfs_fsync __P((void *));
#define nfs_seek (int (*) __P((void *))) nullop
int nfs_remove __P((void *));
int nfs_link __P((void *));
int nfs_rename __P((void *));
int nfs_mkdir __P((void *));
int nfs_rmdir __P((void *));
int nfs_symlink __P((void *));
int nfs_readdir __P((void *));
int nfs_readlink __P((void *));
int nfs_abortop __P((void *));
int nfs_inactive __P((void *));
int nfs_reclaim __P((void *));
int nfs_lock __P((void *));
int nfs_unlock __P((void *));
int nfs_bmap __P((void *));
int nfs_strategy __P((void *));
int nfs_print __P((void *));
int nfs_islocked __P((void *));
int nfs_pathconf __P((void *));
int nfs_advlock __P((void *));
int nfs_blkatoff __P((void *));
int nfs_valloc __P((void *));
#define nfs_reallocblks (int (*) __P((void *))) eopnotsupp
int nfs_vfree __P((void *));
int nfs_truncate __P((void *));
int nfs_update __P((void *));
int nfs_bwrite __P((void *));
int nfs_lookup __P((void *));
int nfs_create __P((void *));
int nfs_mknod __P((void *));
int nfs_open __P((void *));
int nfs_close __P((void *));
int nfsspec_close __P((void *));
int nfsfifo_close __P((void *));
int nfs_access __P((void *));
int nfsspec_access __P((void *));
int nfs_getattr __P((void *));
int nfs_setattr __P((void *));
int nfs_read __P((void *));
int nfs_write __P((void *));
#define nfs_lease_check ((int (*) __P((void *)))nullop)
#define nqnfs_vop_lease_check lease_check
int nfsspec_read __P((void *));
int nfsspec_write __P((void *));
int nfsfifo_read __P((void *));
int nfsfifo_write __P((void *));
#define nfs_ioctl ((int (*) __P((void *)))enoioctl)
#define nfs_select ((int (*) __P((void *)))seltrue)
#define nfs_revoke vop_revoke
int nfs_mmap __P((void *));
int nfs_fsync __P((void *));
#define nfs_seek ((int (*) __P((void *)))nullop)
int nfs_remove __P((void *));
int nfs_link __P((void *));
int nfs_rename __P((void *));
int nfs_mkdir __P((void *));
int nfs_rmdir __P((void *));
int nfs_symlink __P((void *));
int nfs_readdir __P((void *));
int nfs_readlink __P((void *));
int nfs_abortop __P((void *));
int nfs_inactive __P((void *));
int nfs_reclaim __P((void *));
#ifdef Lite2_integrated
#define nfs_lock ((int (*) __P((void *)))vop_nolock)
#define nfs_unlock ((int (*) __P((void *)))vop_nounlock)
#define nfs_islocked ((int (*) __P((void *)))vop_noislocked)
#else
int nfs_lock __P((void *));
int nfs_unlock __P((void *));
int nfs_islocked __P((void *));
#endif /* Lite2_integrated */
int nfs_bmap __P((void *));
int nfs_strategy __P((void *));
int nfs_print __P((void *));
int nfs_pathconf __P((void *));
int nfs_advlock __P((void *));
int nfs_blkatoff __P((void *));
int nfs_bwrite __P((void *));
int nfs_vget __P((struct mount *, ino_t, struct vnode **));
int nfs_valloc __P((void *));
#define nfs_reallocblks \
((int (*) __P((void *)))eopnotsupp)
int nfs_vfree __P((void *));
int nfs_truncate __P((void *));
int nfs_update __P((void *));
/* other stuff */
int nfs_removeit __P((struct sillyrename *));
int nfs_nget __P((struct mount *,nfsfh_t *,int,struct nfsnode **));
int nfs_lookitup __P((struct vnode *,char *,int,struct ucred *,struct proc *,struct nfsnode **));
int nfs_sillyrename __P((struct vnode *,struct vnode *,struct componentname *));
nfsuint64 *nfs_getcookie __P((struct nfsnode *, off_t, int));
void nfs_invaldir __P((struct vnode *));
extern int (**nfsv2_vnodeop_p) __P((void *));
#endif /* _KERNEL */
#endif

441
sys/nfs/nfsproto.h Normal file
View File

@ -0,0 +1,441 @@
/* $NetBSD: nfsproto.h,v 1.1 1996/02/18 11:54:06 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfsproto.h 8.2 (Berkeley) 3/30/95
*/
#ifndef _NFS_NFSPROTO_H_
#define _NFS_NFSPROTO_H_
/*
* nfs definitions as per the Version 2 and 3 specs
*/
/*
* Constants as defined in the Sun NFS Version 2 and 3 specs.
* "NFS: Network File System Protocol Specification" RFC1094
* and in the "NFS: Network File System Version 3 Protocol
* Specification"
*/
#define NFS_PORT 2049
#define NFS_PROG 100003
#define NFS_VER2 2
#define NFS_VER3 3
#define NFS_V2MAXDATA 8192
#define NFS_MAXDGRAMDATA 16384
#define NFS_MAXDATA 32768
#define NFS_MAXPATHLEN 1024
#define NFS_MAXNAMLEN 255
#define NFS_MAXPKTHDR 404
#define NFS_MAXPACKET (NFS_MAXPKTHDR + NFS_MAXDATA)
#define NFS_MINPACKET 20
#define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */
/* Stat numbers for rpc returns (version 2 and 3) */
#define NFS_OK 0
#define NFSERR_PERM 1
#define NFSERR_NOENT 2
#define NFSERR_IO 5
#define NFSERR_NXIO 6
#define NFSERR_ACCES 13
#define NFSERR_EXIST 17
#define NFSERR_XDEV 18 /* Version 3 only */
#define NFSERR_NODEV 19
#define NFSERR_NOTDIR 20
#define NFSERR_ISDIR 21
#define NFSERR_INVAL 22 /* Version 3 only */
#define NFSERR_FBIG 27
#define NFSERR_NOSPC 28
#define NFSERR_ROFS 30
#define NFSERR_MLINK 31 /* Version 3 only */
#define NFSERR_NAMETOL 63
#define NFSERR_NOTEMPTY 66
#define NFSERR_DQUOT 69
#define NFSERR_STALE 70
#define NFSERR_REMOTE 71 /* Version 3 only */
#define NFSERR_WFLUSH 99 /* Version 2 only */
#define NFSERR_BADHANDLE 10001 /* The rest Version 3 only */
#define NFSERR_NOT_SYNC 10002
#define NFSERR_BAD_COOKIE 10003
#define NFSERR_NOTSUPP 10004
#define NFSERR_TOOSMALL 10005
#define NFSERR_SERVERFAULT 10006
#define NFSERR_BADTYPE 10007
#define NFSERR_JUKEBOX 10008
#define NFSERR_TRYLATER NFSERR_JUKEBOX
#define NFSERR_STALEWRITEVERF 30001 /* Fake return for nfs_commit() */
#define NFSERR_RETVOID 0x20000000 /* Return void, not error */
#define NFSERR_AUTHERR 0x40000000 /* Mark an authentication error */
#define NFSERR_RETERR 0x80000000 /* Mark an error return for V3 */
/* Sizes in bytes of various nfs rpc components */
#define NFSX_UNSIGNED 4
/* specific to NFS Version 2 */
#define NFSX_V2FH 32
#define NFSX_V2FATTR 68
#define NFSX_V2SATTR 32
#define NFSX_V2COOKIE 4
#define NFSX_V2STATFS 20
/* specific to NFS Version 3 */
#define NFSX_V3FH (sizeof (fhandle_t)) /* size this server uses */
#define NFSX_V3FHMAX 64 /* max. allowed by protocol */
#define NFSX_V3FATTR 84
#define NFSX_V3SATTR 60 /* max. all fields filled in */
#define NFSX_V3SRVSATTR (sizeof (struct nfsv3_sattr))
#define NFSX_V3POSTOPATTR (NFSX_V3FATTR + NFSX_UNSIGNED)
#define NFSX_V3WCCDATA (NFSX_V3POSTOPATTR + 8 * NFSX_UNSIGNED)
#define NFSX_V3COOKIEVERF 8
#define NFSX_V3WRITEVERF 8
#define NFSX_V3CREATEVERF 8
#define NFSX_V3STATFS 52
#define NFSX_V3FSINFO 48
#define NFSX_V3PATHCONF 24
/* variants for both versions */
#define NFSX_FH(v3) ((v3) ? (NFSX_V3FHMAX + NFSX_UNSIGNED) : \
NFSX_V2FH)
#define NFSX_SRVFH(v3) ((v3) ? NFSX_V3FH : NFSX_V2FH)
#define NFSX_FATTR(v3) ((v3) ? NFSX_V3FATTR : NFSX_V2FATTR)
#define NFSX_PREOPATTR(v3) ((v3) ? (7 * NFSX_UNSIGNED) : 0)
#define NFSX_POSTOPATTR(v3) ((v3) ? (NFSX_V3FATTR + NFSX_UNSIGNED) : 0)
#define NFSX_POSTOPORFATTR(v3) ((v3) ? (NFSX_V3FATTR + NFSX_UNSIGNED) : \
NFSX_V2FATTR)
#define NFSX_WCCDATA(v3) ((v3) ? NFSX_V3WCCDATA : 0)
#define NFSX_WCCORFATTR(v3) ((v3) ? NFSX_V3WCCDATA : NFSX_V2FATTR)
#define NFSX_SATTR(v3) ((v3) ? NFSX_V3SATTR : NFSX_V2SATTR)
#define NFSX_COOKIEVERF(v3) ((v3) ? NFSX_V3COOKIEVERF : 0)
#define NFSX_WRITEVERF(v3) ((v3) ? NFSX_V3WRITEVERF : 0)
#define NFSX_READDIR(v3) ((v3) ? (5 * NFSX_UNSIGNED) : \
(2 * NFSX_UNSIGNED))
#define NFSX_STATFS(v3) ((v3) ? NFSX_V3STATFS : NFSX_V2STATFS)
/* nfs rpc procedure numbers (before version mapping) */
#define NFSPROC_NULL 0
#define NFSPROC_GETATTR 1
#define NFSPROC_SETATTR 2
#define NFSPROC_LOOKUP 3
#define NFSPROC_ACCESS 4
#define NFSPROC_READLINK 5
#define NFSPROC_READ 6
#define NFSPROC_WRITE 7
#define NFSPROC_CREATE 8
#define NFSPROC_MKDIR 9
#define NFSPROC_SYMLINK 10
#define NFSPROC_MKNOD 11
#define NFSPROC_REMOVE 12
#define NFSPROC_RMDIR 13
#define NFSPROC_RENAME 14
#define NFSPROC_LINK 15
#define NFSPROC_READDIR 16
#define NFSPROC_READDIRPLUS 17
#define NFSPROC_FSSTAT 18
#define NFSPROC_FSINFO 19
#define NFSPROC_PATHCONF 20
#define NFSPROC_COMMIT 21
/* And leasing (nqnfs) procedure numbers (must be last) */
#define NQNFSPROC_GETLEASE 22
#define NQNFSPROC_VACATED 23
#define NQNFSPROC_EVICTED 24
#define NFSPROC_NOOP 25
#define NFS_NPROCS 26
/* Actual Version 2 procedure numbers */
#define NFSV2PROC_NULL 0
#define NFSV2PROC_GETATTR 1
#define NFSV2PROC_SETATTR 2
#define NFSV2PROC_NOOP 3
#define NFSV2PROC_ROOT NFSV2PROC_NOOP /* Obsolete */
#define NFSV2PROC_LOOKUP 4
#define NFSV2PROC_READLINK 5
#define NFSV2PROC_READ 6
#define NFSV2PROC_WRITECACHE NFSV2PROC_NOOP /* Obsolete */
#define NFSV2PROC_WRITE 8
#define NFSV2PROC_CREATE 9
#define NFSV2PROC_REMOVE 10
#define NFSV2PROC_RENAME 11
#define NFSV2PROC_LINK 12
#define NFSV2PROC_SYMLINK 13
#define NFSV2PROC_MKDIR 14
#define NFSV2PROC_RMDIR 15
#define NFSV2PROC_READDIR 16
#define NFSV2PROC_STATFS 17
/*
* Constants used by the Version 3 protocol for various RPCs
*/
#define NFSV3SATTRTIME_DONTCHANGE 0
#define NFSV3SATTRTIME_TOSERVER 1
#define NFSV3SATTRTIME_TOCLIENT 2
#define NFSV3ACCESS_READ 0x01
#define NFSV3ACCESS_LOOKUP 0x02
#define NFSV3ACCESS_MODIFY 0x04
#define NFSV3ACCESS_EXTEND 0x08
#define NFSV3ACCESS_DELETE 0x10
#define NFSV3ACCESS_EXECUTE 0x20
#define NFSV3WRITE_UNSTABLE 0
#define NFSV3WRITE_DATASYNC 1
#define NFSV3WRITE_FILESYNC 2
#define NFSV3CREATE_UNCHECKED 0
#define NFSV3CREATE_GUARDED 1
#define NFSV3CREATE_EXCLUSIVE 2
#define NFSV3FSINFO_LINK 0x01
#define NFSV3FSINFO_SYMLINK 0x02
#define NFSV3FSINFO_HOMOGENEOUS 0x08
#define NFSV3FSINFO_CANSETTIME 0x10
/* Conversion macros */
#define vtonfsv2_mode(t,m) \
txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : \
MAKEIMODE((t), (m)))
#define vtonfsv3_mode(m) txdr_unsigned((m) & 07777)
#define nfstov_mode(a) (fxdr_unsigned(u_int16_t, (a))&07777)
#define vtonfsv2_type(a) txdr_unsigned(nfsv2_type[((int32_t)(a))])
#define vtonfsv3_type(a) txdr_unsigned(nfsv3_type[((int32_t)(a))])
#define nfsv2tov_type(a) nv2tov_type[fxdr_unsigned(u_int32_t,(a))&0x7]
#define nfsv3tov_type(a) nv3tov_type[fxdr_unsigned(u_int32_t,(a))&0x7]
/* File types */
typedef enum { NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5,
NFSOCK=6, NFFIFO=7 } nfstype;
/* Structs for common parts of the rpc's */
/*
* File Handle (32 bytes for version 2), variable up to 64 for version 3.
* File Handles of up to NFS_SMALLFH in size are stored directly in the
* nfs node, whereas larger ones are malloc'd. (This never happens when
* NFS_SMALLFH is set to 64.)
* NFS_SMALLFH should be in the range of 32 to 64 and be divisible by 4.
*/
#ifndef NFS_SMALLFH
#define NFS_SMALLFH 64
#endif
union nfsfh {
fhandle_t fh_generic;
u_char fh_bytes[NFS_SMALLFH];
};
typedef union nfsfh nfsfh_t;
struct nfsv2_time {
u_int32_t nfsv2_sec;
u_int32_t nfsv2_usec;
};
typedef struct nfsv2_time nfstime2;
struct nfsv3_time {
u_int32_t nfsv3_sec;
u_int32_t nfsv3_nsec;
};
typedef struct nfsv3_time nfstime3;
/*
* Quads are defined as arrays of 2 longs to ensure dense packing for the
* protocol and to facilitate xdr conversion.
*/
struct nfs_uquad {
u_int32_t nfsuquad[2];
};
typedef struct nfs_uquad nfsuint64;
/*
* Used to convert between two u_longs and a u_quad_t.
*/
union nfs_quadconvert {
u_int32_t lval[2];
u_quad_t qval;
};
typedef union nfs_quadconvert nfsquad_t;
/*
* NFS Version 3 special file number.
*/
struct nfsv3_spec {
u_int32_t specdata1;
u_int32_t specdata2;
};
typedef struct nfsv3_spec nfsv3spec;
/*
* File attributes and setable attributes. These structures cover both
* NFS version 2 and the version 3 protocol. Note that the union is only
* used so that one pointer can refer to both variants. These structures
* go out on the wire and must be densely packed, so no quad data types
* are used. (all fields are longs or u_longs or structures of same)
* NB: You can't do sizeof(struct nfs_fattr), you must use the
* NFSX_FATTR(v3) macro.
*/
struct nfs_fattr {
u_int32_t fa_type;
u_int32_t fa_mode;
u_int32_t fa_nlink;
u_int32_t fa_uid;
u_int32_t fa_gid;
union {
struct {
u_int32_t nfsv2fa_size;
u_int32_t nfsv2fa_blocksize;
u_int32_t nfsv2fa_rdev;
u_int32_t nfsv2fa_blocks;
u_int32_t nfsv2fa_fsid;
u_int32_t nfsv2fa_fileid;
nfstime2 nfsv2fa_atime;
nfstime2 nfsv2fa_mtime;
nfstime2 nfsv2fa_ctime;
} fa_nfsv2;
struct {
nfsuint64 nfsv3fa_size;
nfsuint64 nfsv3fa_used;
nfsv3spec nfsv3fa_rdev;
nfsuint64 nfsv3fa_fsid;
nfsuint64 nfsv3fa_fileid;
nfstime3 nfsv3fa_atime;
nfstime3 nfsv3fa_mtime;
nfstime3 nfsv3fa_ctime;
} fa_nfsv3;
} fa_un;
};
/* and some ugly defines for accessing union components */
#define fa2_size fa_un.fa_nfsv2.nfsv2fa_size
#define fa2_blocksize fa_un.fa_nfsv2.nfsv2fa_blocksize
#define fa2_rdev fa_un.fa_nfsv2.nfsv2fa_rdev
#define fa2_blocks fa_un.fa_nfsv2.nfsv2fa_blocks
#define fa2_fsid fa_un.fa_nfsv2.nfsv2fa_fsid
#define fa2_fileid fa_un.fa_nfsv2.nfsv2fa_fileid
#define fa2_atime fa_un.fa_nfsv2.nfsv2fa_atime
#define fa2_mtime fa_un.fa_nfsv2.nfsv2fa_mtime
#define fa2_ctime fa_un.fa_nfsv2.nfsv2fa_ctime
#define fa3_size fa_un.fa_nfsv3.nfsv3fa_size
#define fa3_used fa_un.fa_nfsv3.nfsv3fa_used
#define fa3_rdev fa_un.fa_nfsv3.nfsv3fa_rdev
#define fa3_fsid fa_un.fa_nfsv3.nfsv3fa_fsid
#define fa3_fileid fa_un.fa_nfsv3.nfsv3fa_fileid
#define fa3_atime fa_un.fa_nfsv3.nfsv3fa_atime
#define fa3_mtime fa_un.fa_nfsv3.nfsv3fa_mtime
#define fa3_ctime fa_un.fa_nfsv3.nfsv3fa_ctime
struct nfsv2_sattr {
u_int32_t sa_mode;
u_int32_t sa_uid;
u_int32_t sa_gid;
u_int32_t sa_size;
nfstime2 sa_atime;
nfstime2 sa_mtime;
};
/*
* NFS Version 3 sattr structure for the new node creation case.
*/
struct nfsv3_sattr {
u_int32_t sa_modetrue;
u_int32_t sa_mode;
u_int32_t sa_uidfalse;
u_int32_t sa_gidfalse;
u_int32_t sa_sizefalse;
u_int32_t sa_atimetype;
nfstime3 sa_atime;
u_int32_t sa_mtimetype;
nfstime3 sa_mtime;
};
struct nfs_statfs {
union {
struct {
u_int32_t nfsv2sf_tsize;
u_int32_t nfsv2sf_bsize;
u_int32_t nfsv2sf_blocks;
u_int32_t nfsv2sf_bfree;
u_int32_t nfsv2sf_bavail;
} sf_nfsv2;
struct {
nfsuint64 nfsv3sf_tbytes;
nfsuint64 nfsv3sf_fbytes;
nfsuint64 nfsv3sf_abytes;
nfsuint64 nfsv3sf_tfiles;
nfsuint64 nfsv3sf_ffiles;
nfsuint64 nfsv3sf_afiles;
u_int32_t nfsv3sf_invarsec;
} sf_nfsv3;
} sf_un;
};
#define sf_tsize sf_un.sf_nfsv2.nfsv2sf_tsize
#define sf_bsize sf_un.sf_nfsv2.nfsv2sf_bsize
#define sf_blocks sf_un.sf_nfsv2.nfsv2sf_blocks
#define sf_bfree sf_un.sf_nfsv2.nfsv2sf_bfree
#define sf_bavail sf_un.sf_nfsv2.nfsv2sf_bavail
#define sf_tbytes sf_un.sf_nfsv3.nfsv3sf_tbytes
#define sf_fbytes sf_un.sf_nfsv3.nfsv3sf_fbytes
#define sf_abytes sf_un.sf_nfsv3.nfsv3sf_abytes
#define sf_tfiles sf_un.sf_nfsv3.nfsv3sf_tfiles
#define sf_ffiles sf_un.sf_nfsv3.nfsv3sf_ffiles
#define sf_afiles sf_un.sf_nfsv3.nfsv3sf_afiles
#define sf_invarsec sf_un.sf_nfsv3.nfsv3sf_invarsec
struct nfsv3_fsinfo {
u_int32_t fs_rtmax;
u_int32_t fs_rtpref;
u_int32_t fs_rtmult;
u_int32_t fs_wtmax;
u_int32_t fs_wtpref;
u_int32_t fs_wtmult;
u_int32_t fs_dtpref;
nfsuint64 fs_maxfilesize;
nfstime3 fs_timedelta;
u_int32_t fs_properties;
};
struct nfsv3_pathconf {
u_int32_t pc_linkmax;
u_int32_t pc_namemax;
u_int32_t pc_notrunc;
u_int32_t pc_chownrestricted;
u_int32_t pc_caseinsensitive;
u_int32_t pc_casepreserving;
};
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfsrtt.h,v 1.3 1995/12/19 23:08:05 cgd Exp $ */
/* $NetBSD: nfsrtt.h,v 1.4 1996/02/18 11:54:07 fvdl Exp $ */
/*
* Copyright (c) 1992, 1993
@ -35,9 +35,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfsrtt.h 8.1 (Berkeley) 6/10/93
* @(#)nfsrtt.h 8.2 (Berkeley) 3/30/95
*/
#ifndef _NFS_NFSRTT_H_
#define _NFS_NFSRTT_H_
/*
* Definitions for performance monitor.
* The client and server logging are turned on by setting the global
@ -80,6 +84,7 @@ struct nfsrtt {
#define DRT_TCP 0x02 /* Client used TCP transport */
#define DRT_CACHEREPLY 0x04 /* Reply was from recent request cache */
#define DRT_CACHEDROP 0x08 /* Rpc request dropped, due to recent reply */
#define DRT_NFSV3 0x10 /* Rpc used NFS Version 3 */
/*
* Server log structure
@ -89,10 +94,12 @@ struct nfsrtt {
struct nfsdrt {
int pos; /* Position of next log entry */
struct drt {
int flag; /* Bits as defined above */
int proc; /* NFS procedure number */
u_int32_t ipadr; /* IP address of client */
int resptime; /* Response time (usec) */
int flag; /* Bits as defined above */
int proc; /* NFS procedure number */
u_int32_t ipadr; /* IP address of client */
int resptime; /* Response time (usec) */
struct timeval tstamp; /* Timestamp of log entry */
} drt[NFSRTTLOGSIZ];
};
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfsrvcache.h,v 1.9 1995/12/19 23:08:11 cgd Exp $ */
/* $NetBSD: nfsrvcache.h,v 1.10 1996/02/18 11:54:08 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
@ -35,27 +35,31 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfsrvcache.h 8.2 (Berkeley) 8/18/94
* @(#)nfsrvcache.h 8.3 (Berkeley) 3/30/95
*/
#ifndef _NFS_NFSRVCACHE_H_
#define _NFS_NFSRVCACHE_H_
/*
* Definitions for the server recent request cache
*/
#define NFSRVCACHESIZ 256
#define NFSRVCACHESIZ 64
struct nfsrvcache {
TAILQ_ENTRY(nfsrvcache) rc_lru; /* LRU chain */
LIST_ENTRY(nfsrvcache) rc_hash; /* Hash chain */
u_int32_t rc_xid; /* rpc id number */
u_int32_t rc_xid; /* rpc id number */
union {
struct mbuf *ru_repmb; /* Reply mbuf list OR */
int ru_repstat; /* Reply status */
} rc_un;
union nethostaddr rc_haddr; /* Host address */
u_int16_t rc_proc; /* rpc proc number */
u_char rc_state; /* Current state of request */
u_char rc_flag; /* Flag bits */
u_char rc_state; /* Current state of request */
u_char rc_flag; /* Flag bits */
};
#define rc_reply rc_un.ru_repmb
@ -82,3 +86,5 @@ struct nfsrvcache {
#define RC_NQNFS 0x10
#define RC_INETADDR 0x20
#define RC_NAM 0x40
#endif

View File

@ -1,262 +0,0 @@
/* $NetBSD: nfsv2.h,v 1.10 1995/12/19 23:08:15 cgd Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfsv2.h 8.1 (Berkeley) 6/10/93
*/
/*
* nfs definitions as per the version 2 specs
*/
/*
* Constants as defined in the Sun NFS Version 2 spec.
* "NFS: Network File System Protocol Specification" RFC1094
*/
#define NFS_PORT 2049
#define NFS_PROG 100003
#define NFS_VER2 2
#define NFS_MAXDGRAMDATA 8192
#define NFS_MAXDATA 32768
#define NFS_MAXPATHLEN 1024
#define NFS_MAXNAMLEN 255
#define NFS_FHSIZE 32
#define NFS_MAXPKTHDR 404
#define NFS_MAXPACKET (NFS_MAXPKTHDR+NFS_MAXDATA)
#define NFS_MINPACKET 20
#define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */
/* Stat numbers for rpc returns */
#define NFS_OK 0
#define NFSERR_PERM 1
#define NFSERR_NOENT 2
#define NFSERR_IO 5
#define NFSERR_NXIO 6
#define NFSERR_ACCES 13
#define NFSERR_EXIST 17
#define NFSERR_NODEV 19
#define NFSERR_NOTDIR 20
#define NFSERR_ISDIR 21
#define NFSERR_FBIG 27
#define NFSERR_NOSPC 28
#define NFSERR_ROFS 30
#define NFSERR_NAMETOL 63
#define NFSERR_NOTEMPTY 66
#define NFSERR_DQUOT 69
#define NFSERR_STALE 70
#define NFSERR_WFLUSH 99
/* Sizes in bytes of various nfs rpc components */
#define NFSX_FH 32
#define NFSX_UNSIGNED 4
#define NFSX_NFSFATTR 68
#define NFSX_NQFATTR 92
#define NFSX_NFSSATTR 32
#define NFSX_NQSATTR 44
#define NFSX_COOKIE 4
#define NFSX_NFSSTATFS 20
#define NFSX_NQSTATFS 28
#define NFSX_FATTR(isnq) ((isnq) ? NFSX_NQFATTR : NFSX_NFSFATTR)
#define NFSX_SATTR(isnq) ((isnq) ? NFSX_NQSATTR : NFSX_NFSSATTR)
#define NFSX_STATFS(isnq) ((isnq) ? NFSX_NQSTATFS : NFSX_NFSSTATFS)
/* nfs rpc procedure numbers */
#define NFSPROC_NULL 0
#define NFSPROC_GETATTR 1
#define NFSPROC_SETATTR 2
#define NFSPROC_NOOP 3
#define NFSPROC_ROOT NFSPROC_NOOP /* Obsolete */
#define NFSPROC_LOOKUP 4
#define NFSPROC_READLINK 5
#define NFSPROC_READ 6
#define NFSPROC_WRITECACHE NFSPROC_NOOP /* Obsolete */
#define NFSPROC_WRITE 8
#define NFSPROC_CREATE 9
#define NFSPROC_REMOVE 10
#define NFSPROC_RENAME 11
#define NFSPROC_LINK 12
#define NFSPROC_SYMLINK 13
#define NFSPROC_MKDIR 14
#define NFSPROC_RMDIR 15
#define NFSPROC_READDIR 16
#define NFSPROC_STATFS 17
/* NQ nfs numbers */
#define NQNFSPROC_READDIRLOOK 18
#define NQNFSPROC_GETLEASE 19
#define NQNFSPROC_VACATED 20
#define NQNFSPROC_EVICTED 21
#define NQNFSPROC_ACCESS 22
#define NFS_NPROCS 23
/* Conversion macros */
extern int vttoif_tab[];
#define vtonfs_mode(t,m) \
txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : \
MAKEIMODE((t), (m)))
#define nfstov_mode(a) (fxdr_unsigned(u_int16_t, (a))&07777)
#define vtonfs_type(a) txdr_unsigned(nfs_type[((int32_t)(a))])
#define nfstov_type(a) ntov_type[fxdr_unsigned(u_int32_t,(a))&0x7]
/* File types */
typedef enum { NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5 } nfstype;
/* Structs for common parts of the rpc's */
struct nfsv2_time {
u_int32_t nfs_sec;
u_int32_t nfs_usec;
};
struct nqnfs_time {
u_int32_t nq_sec;
u_int32_t nq_nsec;
};
/*
* File attributes and setable attributes. These structures cover both
* NFS version 2 and the NQNFS protocol. Note that the union is only
* used to that one pointer can refer to both variants. These structures
* go out on the wire and must be densely packed, so no quad data types
* are used. (all fields are int32_ts or u_int32_ts or structures of same)
* NB: You can't do sizeof(struct nfsv2_fattr), you must use the
* NFSX_FATTR(isnq) macro.
*/
struct nfsv2_fattr {
u_int32_t fa_type;
u_int32_t fa_mode;
u_int32_t fa_nlink;
u_int32_t fa_uid;
u_int32_t fa_gid;
union {
struct {
u_int32_t nfsfa_size;
u_int32_t nfsfa_blocksize;
u_int32_t nfsfa_rdev;
u_int32_t nfsfa_blocks;
u_int32_t nfsfa_fsid;
u_int32_t nfsfa_fileid;
struct nfsv2_time nfsfa_atime;
struct nfsv2_time nfsfa_mtime;
struct nfsv2_time nfsfa_ctime;
} fa_nfsv2;
struct {
struct {
u_int32_t nqfa_qsize[2];
} nqfa_size;
u_int32_t nqfa_blocksize;
u_int32_t nqfa_rdev;
struct {
u_int32_t nqfa_qbytes[2];
} nqfa_bytes;
u_int32_t nqfa_fsid;
u_int32_t nqfa_fileid;
struct nqnfs_time nqfa_atime;
struct nqnfs_time nqfa_mtime;
struct nqnfs_time nqfa_ctime;
u_int32_t nqfa_flags;
u_int32_t nqfa_gen;
struct {
u_int32_t nqfa_qfilerev[2];
} nqfa_filerev;
} fa_nqnfs;
} fa_un;
};
/* and some ugly defines for accessing union components */
#define fa_nfssize fa_un.fa_nfsv2.nfsfa_size
#define fa_nfsblocksize fa_un.fa_nfsv2.nfsfa_blocksize
#define fa_nfsrdev fa_un.fa_nfsv2.nfsfa_rdev
#define fa_nfsblocks fa_un.fa_nfsv2.nfsfa_blocks
#define fa_nfsfsid fa_un.fa_nfsv2.nfsfa_fsid
#define fa_nfsfileid fa_un.fa_nfsv2.nfsfa_fileid
#define fa_nfsatime fa_un.fa_nfsv2.nfsfa_atime
#define fa_nfsmtime fa_un.fa_nfsv2.nfsfa_mtime
#define fa_nfsctime fa_un.fa_nfsv2.nfsfa_ctime
#define fa_nqsize fa_un.fa_nqnfs.nqfa_size
#define fa_nqblocksize fa_un.fa_nqnfs.nqfa_blocksize
#define fa_nqrdev fa_un.fa_nqnfs.nqfa_rdev
#define fa_nqbytes fa_un.fa_nqnfs.nqfa_bytes
#define fa_nqfsid fa_un.fa_nqnfs.nqfa_fsid
#define fa_nqfileid fa_un.fa_nqnfs.nqfa_fileid
#define fa_nqatime fa_un.fa_nqnfs.nqfa_atime
#define fa_nqmtime fa_un.fa_nqnfs.nqfa_mtime
#define fa_nqctime fa_un.fa_nqnfs.nqfa_ctime
#define fa_nqflags fa_un.fa_nqnfs.nqfa_flags
#define fa_nqgen fa_un.fa_nqnfs.nqfa_gen
#define fa_nqfilerev fa_un.fa_nqnfs.nqfa_filerev
struct nfsv2_sattr {
u_int32_t sa_mode;
u_int32_t sa_uid;
u_int32_t sa_gid;
union {
struct {
u_int32_t nfssa_size;
struct nfsv2_time nfssa_atime;
struct nfsv2_time nfssa_mtime;
} sa_nfsv2;
struct {
struct {
u_int32_t nqsa_qsize[2];
} nqsa_size;
struct nqnfs_time nqsa_atime;
struct nqnfs_time nqsa_mtime;
u_int32_t nqsa_flags;
u_int32_t nqsa_rdev;
} sa_nqnfs;
} sa_un;
};
/* and some ugly defines for accessing the unions */
#define sa_nfssize sa_un.sa_nfsv2.nfssa_size
#define sa_nfsatime sa_un.sa_nfsv2.nfssa_atime
#define sa_nfsmtime sa_un.sa_nfsv2.nfssa_mtime
#define sa_nqsize sa_un.sa_nqnfs.nqsa_size
#define sa_nqatime sa_un.sa_nqnfs.nqsa_atime
#define sa_nqmtime sa_un.sa_nqnfs.nqsa_mtime
#define sa_nqflags sa_un.sa_nqnfs.nqsa_flags
#define sa_nqrdev sa_un.sa_nqnfs.nqsa_rdev
struct nfsv2_statfs {
u_int32_t sf_tsize;
u_int32_t sf_bsize;
u_int32_t sf_blocks;
u_int32_t sf_bfree;
u_int32_t sf_bavail;
u_int32_t sf_files; /* Nqnfs only */
u_int32_t sf_ffree; /* ditto */
};

View File

@ -1,4 +1,4 @@
/* $NetBSD: nqnfs.h,v 1.5 1995/12/19 23:08:21 cgd Exp $ */
/* $NetBSD: nqnfs.h,v 1.6 1996/02/18 11:54:10 fvdl Exp $ */
/*
* Copyright (c) 1992, 1993
@ -35,9 +35,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nqnfs.h 8.2 (Berkeley) 8/18/94
* @(#)nqnfs.h 8.3 (Berkeley) 3/30/95
*/
#ifndef _NFS_NQNFS_H_
#define _NFS_NQNFS_H_
/*
* Definitions for NQNFS (Not Quite NFS) cache consistency protocol.
*/
@ -56,7 +60,7 @@
#define NQLCHSZ 256 /* Server hash table size */
#define NQNFS_PROG 300105 /* As assigned by Sun */
#define NQNFS_VER1 1
#define NQNFS_VER3 3
#define NQNFS_EVICTSIZ 156 /* Size of eviction request in bytes */
/*
@ -64,6 +68,9 @@
* RAM on the server. The default definitions below assume that NOVRAM is not
* available.
*/
#ifdef HASNVRAM
# undef HASNVRAM
#endif
#define NQSTORENOVRAM(t)
#define NQLOADNOVRAM(t)
@ -83,7 +90,7 @@ struct nqhost {
union {
struct {
u_int16_t udp_flag;
u_int16_t udp_port;
u_int16_t udp_port;
union nethostaddr udp_haddr;
} un_udp;
struct {
@ -137,14 +144,6 @@ struct nqm {
struct nqhost lpm_hosts[LC_MOREHOSTSIZ];
};
/*
* Flag bits for flags argument to nqsrv_getlease.
*/
#define NQL_READ LEASE_READ /* Read Request */
#define NQL_WRITE LEASE_WRITE /* Write Request */
#define NQL_CHECK 0x4 /* Check for lease */
#define NQL_NOVAL 0xffffffff /* Invalid */
/*
* Special value for slp for local server calls.
*/
@ -155,9 +154,9 @@ struct nqm {
*/
#define nqsrv_getl(v, l) \
(void) nqsrv_getlease((v), &nfsd->nd_duration, \
((nfsd->nd_nqlflag != 0 && nfsd->nd_nqlflag != NQL_NOVAL) ? nfsd->nd_nqlflag : \
((l) | NQL_CHECK)), \
nfsd, nam, &cache, &frev, cred)
((nfsd->nd_flag & ND_LEASE) ? (nfsd->nd_flag & ND_LEASE) : \
((l) | ND_CHECK)), \
slp, procp, nfsd->nd_nam, &cache, &frev, cred)
/*
* Client side macros that check for a valid lease.
@ -165,13 +164,13 @@ struct nqm {
#define NQNFS_CKINVALID(v, n, f) \
((time.tv_sec > (n)->n_expiry && \
VFSTONFS((v)->v_mount)->nm_timeouts < VFSTONFS((v)->v_mount)->nm_deadthresh) \
|| ((f) == NQL_WRITE && ((n)->n_flag & NQNFSWRITE) == 0))
|| ((f) == ND_WRITE && ((n)->n_flag & NQNFSWRITE) == 0))
#define NQNFS_CKCACHABLE(v, f) \
((time.tv_sec <= VTONFS(v)->n_expiry || \
VFSTONFS((v)->v_mount)->nm_timeouts >= VFSTONFS((v)->v_mount)->nm_deadthresh) \
&& (VTONFS(v)->n_flag & NQNFSNONCACHE) == 0 && \
((f) == NQL_READ || (VTONFS(v)->n_flag & NQNFSWRITE)))
((f) == ND_READ || (VTONFS(v)->n_flag & NQNFSWRITE)))
#define NQNFS_NEEDLEASE(v, p) \
(time.tv_sec > VTONFS(v)->n_expiry ? \
@ -179,7 +178,7 @@ struct nqm {
(((time.tv_sec + NQ_RENEWAL) > VTONFS(v)->n_expiry && \
nqnfs_piggy[p]) ? \
((VTONFS(v)->n_flag & NQNFSWRITE) ? \
NQL_WRITE : nqnfs_piggy[p]) : 0))
ND_WRITE : nqnfs_piggy[p]) : 0))
/*
* List head for timer queue.
@ -199,4 +198,18 @@ u_long nqfhhash;
*/
#define NQNFS_EXPIRED 500
#define NQNFS_TRYLATER 501
#define NQNFS_AUTHERR 502
#ifdef _KERNEL
void nqnfs_lease_updatetime __P((int));
int nqsrv_cmpnam __P((struct nfssvc_sock *,struct mbuf *,struct nqhost *));
int nqsrv_getlease __P((struct vnode *, u_int32_t *, int,
struct nfssvc_sock *, struct proc *, struct mbuf *, int *,
u_quad_t *, struct ucred *));
int nqnfs_getlease __P((struct vnode *, int, struct ucred *,struct proc *));
int nqnfs_callback __P((struct nfsmount *, struct mbuf *, struct mbuf *,
caddr_t));
int nqnfs_clientd __P((struct nfsmount *, struct ucred *,
struct nfsd_cargs *, int, caddr_t, struct proc *));
#endif
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: rpcv2.h,v 1.7 1995/12/19 23:08:26 cgd Exp $ */
/* $NetBSD: rpcv2.h,v 1.8 1996/02/18 11:54:11 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
@ -35,9 +35,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)rpcv2.h 8.1 (Berkeley) 6/10/93
* @(#)rpcv2.h 8.2 (Berkeley) 3/30/95
*/
#ifndef _NFS_RPCV2_H_
#define _NFS_RPCV2_H_
/*
* Definitions for Sun RPC Version 2, from
* "RPC: Remote Procedure Call Protocol Specification" RFC1057
@ -50,10 +54,18 @@
#define RPCAUTH_NULL 0
#define RPCAUTH_UNIX 1
#define RPCAUTH_SHORT 2
#define RPCAUTH_KERB4 4
#define RPCAUTH_NQNFS 300000
#define RPCAUTH_MAXSIZ 400
#define RPCVERF_MAXSIZ 12 /* For Kerb, can actually be 400 */
#define RPCAUTH_UNIXGIDS 16
/*
* Constants associated with authentication flavours.
*/
#define RPCAKN_FULLNAME 0
#define RPCAKN_NICKNAME 1
/* Rpc Constants */
#define RPC_CALL 0
#define RPC_REPLY 1
@ -80,6 +92,7 @@
/* RPC Prog definitions */
#define RPCPROG_MNT 100005
#define RPCMNT_VER1 1
#define RPCMNT_VER3 3
#define RPCMNT_MOUNT 1
#define RPCMNT_DUMP 2
#define RPCMNT_UMOUNT 3
@ -88,9 +101,50 @@
#define RPCMNT_NAMELEN 255
#define RPCMNT_PATHLEN 1024
#define RPCPROG_NFS 100003
/* Structs for common parts of the rpc's */
struct rpcv2_time {
u_int32_t rpc_sec;
u_int32_t rpc_usec;
u_int32_t rpc_sec;
u_int32_t rpc_usec;
};
/*
* Structures used for RPCAUTH_KERB4.
*/
struct nfsrpc_fullverf {
u_int32_t t1;
u_int32_t t2;
u_int32_t w2;
};
struct nfsrpc_fullblock {
u_int32_t t1;
u_int32_t t2;
u_int32_t w1;
u_int32_t w2;
};
struct nfsrpc_nickverf {
u_int32_t kind;
struct nfsrpc_fullverf verf;
};
/*
* and their sizes in bytes.. If sizeof (struct nfsrpc_xx) != these
* constants, well then things will break in mount_nfs and nfsd.
*/
#define RPCX_FULLVERF 12
#define RPCX_FULLBLOCK 16
#define RPCX_NICKVERF 16
#ifdef NFSKERB
XXX
#else
typedef u_char NFSKERBKEY_T[2];
typedef u_char NFSKERBKEYSCHED_T[2];
#endif
#define NFS_KERBSRV "rcmd" /* Kerberos Service for NFS */
#define NFS_KERBTTL (30 * 60) /* Credential ttl (sec) */
#define NFS_KERBCLOCKSKEW (5 * 60) /* Clock skew (sec) */
#define NFS_KERBW1(t) (*((u_long *)(&((t).dat[((t).length + 3) & ~0x3]))))
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: xdr_subs.h,v 1.10 1996/02/01 00:41:32 jtc Exp $ */
/* $NetBSD: xdr_subs.h,v 1.11 1996/02/18 11:54:12 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
@ -35,9 +35,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)xdr_subs.h 8.1 (Berkeley) 6/10/93
* @(#)xdr_subs.h 8.3 (Berkeley) 3/30/95
*/
#ifndef _NFS_XDR_SUBS_H_
#define _NFS_XDR_SUBS_H_
/*
* Macros used for conversion to/from xdr representation by nfs...
* These use the MACHINE DEPENDENT routines ntohl, htonl
@ -52,25 +56,28 @@
#define fxdr_unsigned(t, v) ((t)ntohl((int32_t)(v)))
#define txdr_unsigned(v) (htonl((int32_t)(v)))
#define fxdr_nfstime(f, t) { \
(t)->tv_sec = ntohl((f)->nfs_sec); \
if ((f)->nfs_usec != 0xffffffff) \
(t)->tv_nsec = 1000 * ntohl((f)->nfs_usec); \
#define fxdr_nfsv2time(f, t) { \
(t)->tv_sec = ntohl(((struct nfsv2_time *)(f))->nfsv2_sec); \
if (((struct nfsv2_time *)(f))->nfsv2_usec != 0xffffffff) \
(t)->tv_nsec = 1000 * ntohl(((struct nfsv2_time *)(f))->nfsv2_usec); \
else \
(t)->tv_nsec = 0; \
}
#define txdr_nfstime(f, t) { \
(t)->nfs_sec = htonl((f)->tv_sec); \
(t)->nfs_usec = htonl((f)->tv_nsec) / 1000; \
#define txdr_nfsv2time(f, t) { \
((struct nfsv2_time *)(t))->nfsv2_sec = htonl((f)->tv_sec); \
if ((f)->tv_nsec != -1) \
((struct nfsv2_time *)(t))->nfsv2_usec = htonl((f)->tv_nsec / 1000); \
else \
((struct nfsv2_time *)(t))->nfsv2_usec = 0xffffffff; \
}
#define fxdr_nqtime(f, t) { \
(t)->tv_sec = ntohl((f)->nq_sec); \
(t)->tv_nsec = ntohl((f)->nq_nsec); \
#define fxdr_nfsv3time(f, t) { \
(t)->tv_sec = ntohl(((struct nfsv3_time *)(f))->nfsv3_sec); \
(t)->tv_nsec = ntohl(((struct nfsv3_time *)(f))->nfsv3_nsec); \
}
#define txdr_nqtime(f, t) { \
(t)->nq_sec = htonl((f)->tv_sec); \
(t)->nq_nsec = htonl((f)->tv_nsec); \
#define txdr_nfsv3time(f, t) { \
((struct nfsv3_time *)(t))->nfsv3_sec = htonl((f)->tv_sec); \
((struct nfsv3_time *)(t))->nfsv3_nsec = htonl((f)->tv_nsec); \
}
#define fxdr_hyper(f, t) { \
@ -81,3 +88,5 @@
((int32_t *)(t))[0] = htonl(((int32_t *)(f))[_QUAD_HIGHWORD]); \
((int32_t *)(t))[1] = htonl(((int32_t *)(f))[_QUAD_LOWWORD]); \
}
#endif