diff options
author | alfred <alfred@FreeBSD.org> | 2003-11-14 20:54:10 +0000 |
---|---|---|
committer | alfred <alfred@FreeBSD.org> | 2003-11-14 20:54:10 +0000 |
commit | 5b076fe9da6e7bfd69aca6e09e64d75d72477b92 (patch) | |
tree | 551663ad558af360faf7b32b0b3e67a667de012c /sys/nfsclient | |
parent | af7f62665d5a48d63d7f4c984c6511297dbb645c (diff) | |
download | FreeBSD-src-5b076fe9da6e7bfd69aca6e09e64d75d72477b92.zip FreeBSD-src-5b076fe9da6e7bfd69aca6e09e64d75d72477b92.tar.gz |
University of Michigan's Citi NFSv4 kernel client code.
Submitted by: Jim Rees <rees@umich.edu>
Diffstat (limited to 'sys/nfsclient')
-rw-r--r-- | sys/nfsclient/bootp_subr.c | 2 | ||||
-rw-r--r-- | sys/nfsclient/krpc_subr.c | 2 | ||||
-rw-r--r-- | sys/nfsclient/nfs.h | 19 | ||||
-rw-r--r-- | sys/nfsclient/nfs_bio.c | 53 | ||||
-rw-r--r-- | sys/nfsclient/nfs_diskless.c | 1 | ||||
-rw-r--r-- | sys/nfsclient/nfs_lock.c | 2 | ||||
-rw-r--r-- | sys/nfsclient/nfs_nfsiod.c | 3 | ||||
-rw-r--r-- | sys/nfsclient/nfs_node.c | 11 | ||||
-rw-r--r-- | sys/nfsclient/nfs_socket.c | 8 | ||||
-rw-r--r-- | sys/nfsclient/nfs_subs.c | 6 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vfsops.c | 2 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vnops.c | 3 | ||||
-rw-r--r-- | sys/nfsclient/nfsargs.h | 2 | ||||
-rw-r--r-- | sys/nfsclient/nfsm_subs.h | 11 | ||||
-rw-r--r-- | sys/nfsclient/nfsmount.h | 9 | ||||
-rw-r--r-- | sys/nfsclient/nfsnode.h | 29 |
16 files changed, 148 insertions, 15 deletions
diff --git a/sys/nfsclient/bootp_subr.c b/sys/nfsclient/bootp_subr.c index 51a618e..c4d9eea 100644 --- a/sys/nfsclient/bootp_subr.c +++ b/sys/nfsclient/bootp_subr.c @@ -65,6 +65,8 @@ __FBSDID("$FreeBSD$"); #include <net/if_types.h> #include <net/if_dl.h> +#include <rpc/rpcclnt.h> + #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> #include <nfsclient/nfs.h> diff --git a/sys/nfsclient/krpc_subr.c b/sys/nfsclient/krpc_subr.c index b12bbc6..9ecee2c 100644 --- a/sys/nfsclient/krpc_subr.c +++ b/sys/nfsclient/krpc_subr.c @@ -57,6 +57,8 @@ __FBSDID("$FreeBSD$"); #include <net/if.h> #include <netinet/in.h> +#include <rpc/rpcclnt.h> + #include <nfs/rpcv2.h> #include <nfsclient/krpc.h> #include <nfs/xdr_subs.h> diff --git a/sys/nfsclient/nfs.h b/sys/nfsclient/nfs.h index f231fb9..f09fd65 100644 --- a/sys/nfsclient/nfs.h +++ b/sys/nfsclient/nfs.h @@ -242,13 +242,31 @@ extern int nfs_debug; #endif +/* + * File context information for nfsv4. Currently, there is only one + * lockowner for the whole machine "0." + */ +struct nfs4_fctx { + TAILQ_ENTRY(nfs4_fstate) next; + + pid_t pid; + uint32_t refcnt; + struct nfs4_lowner *lop; + struct nfsnode *np; + char stateid[NFSX_V4STATEID]; +}; + vfs_init_t nfs_init; vfs_uninit_t nfs_uninit; int nfs_mountroot(struct mount *mp, struct thread *td); + +#ifndef NFS4_USE_RPCCLNT int nfs_send(struct socket *, struct sockaddr *, struct mbuf *, struct nfsreq *); int nfs_sndlock(struct nfsreq *); void nfs_sndunlock(struct nfsreq *); +#endif /* ! NFS4_USE_RPCCLNT */ + int nfs_vinvalbuf(struct vnode *, int, struct ucred *, struct thread *, int); int nfs_readrpc(struct vnode *, struct uio *, struct ucred *); @@ -271,6 +289,7 @@ int nfsm_mbuftouio(struct mbuf **, struct uio *, int, caddr_t *); void nfs_nhinit(void); int nfs_nmcancelreqs(struct nfsmount *); void nfs_timer(void*); + int nfs_connect(struct nfsmount *, struct nfsreq *); void nfs_disconnect(struct nfsmount *); void nfs_safedisconnect(struct nfsmount *); diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index 442acbc..58ef852 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -58,24 +58,40 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_pager.h> #include <vm/vnode_pager.h> +#include <rpc/rpcclnt.h> + #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> #include <nfsclient/nfs.h> #include <nfsclient/nfsmount.h> #include <nfsclient/nfsnode.h> +#include <nfs4client/nfs4.h> + /* * Just call nfs_writebp() with the force argument set to 1. * * NOTE: B_DONE may or may not be set in a_bp on call. */ static int +nfs4_bwrite(struct buf *bp) +{ + + return (nfs4_writebp(bp, 1, curthread)); +} + +static int nfs_bwrite(struct buf *bp) { return (nfs_writebp(bp, 1, curthread)); } +struct buf_ops buf_ops_nfs4 = { + "buf_ops_nfs4", + nfs4_bwrite +}; + struct buf_ops buf_ops_nfs = { "buf_ops_nfs", nfs_bwrite @@ -118,6 +134,7 @@ nfs_getpages(struct vop_getpages_args *ap) if ((nmp->nm_flag & NFSMNT_NFSV3) != 0 && (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) { + /* We'll never get here for v4, because we always have fsinfo */ (void)nfs_fsinfo(nmp, vp, cred, td); } @@ -170,7 +187,10 @@ nfs_getpages(struct vop_getpages_args *ap) uio.uio_rw = UIO_READ; uio.uio_td = td; - error = nfs_readrpc(vp, &uio, cred); + if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) + error = nfs4_readrpc(vp, &uio, cred); + else + error = nfs_readrpc(vp, &uio, cred); pmap_qremove(kva, npages); relpbuf(bp, &nfs_pbuf_freecnt); @@ -332,7 +352,10 @@ nfs_putpages(struct vop_putpages_args *ap) else iomode = NFSV3WRITE_FILESYNC; - error = nfs_writerpc(vp, &uio, cred, &iomode, &must_commit); + if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) + error = nfs4_writerpc(vp, &uio, cred, &iomode, &must_commit); + else + error = nfs_writerpc(vp, &uio, cred, &iomode, &must_commit); pmap_qremove(kva, npages); relpbuf(bp, &nfs_pbuf_freecnt); @@ -837,7 +860,10 @@ again: allocbuf(bp, bcount); bp->b_flags |= save; bp->b_magic = B_MAGIC_NFS; - bp->b_op = &buf_ops_nfs; + if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) + bp->b_op = &buf_ops_nfs4; + else + bp->b_op = &buf_ops_nfs; } } else { /* @@ -996,7 +1022,10 @@ again: break; } else if ((n + on) == biosize) { bp->b_flags |= B_ASYNC; - (void)nfs_writebp(bp, 0, 0); + if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) + (void)nfs4_writebp(bp, 0, 0); + else + (void)nfs_writebp(bp, 0, 0); } else { bdwrite(bp); } @@ -1339,13 +1368,17 @@ nfs_doio(struct buf *bp, struct ucred *cr, struct thread *td) case VDIR: nfsstats.readdir_bios++; 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_NFSV4) != 0) + error = nfs4_readdirrpc(vp, uiop, cr); + else { + if ((nmp->nm_flag & NFSMNT_RDIRPLUS) != 0) { + 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); } - if ((nmp->nm_flag & NFSMNT_RDIRPLUS) == 0) - error = nfs_readdirrpc(vp, uiop, cr); /* * end-of-directory sets B_INVAL but does not generate an * error. diff --git a/sys/nfsclient/nfs_diskless.c b/sys/nfsclient/nfs_diskless.c index 4e09bde..e2c199a 100644 --- a/sys/nfsclient/nfs_diskless.c +++ b/sys/nfsclient/nfs_diskless.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include <net/if_var.h> #include <net/ethernet.h> #include <netinet/in.h> +#include <rpc/rpcclnt.h> #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> #include <nfsclient/nfs.h> diff --git a/sys/nfsclient/nfs_lock.c b/sys/nfsclient/nfs_lock.c index 374bbf9..88b9609 100644 --- a/sys/nfsclient/nfs_lock.c +++ b/sys/nfsclient/nfs_lock.c @@ -51,6 +51,8 @@ __FBSDID("$FreeBSD$"); #include <net/if.h> +#include <rpc/rpcclnt.h> + #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> #include <nfsclient/nfs.h> diff --git a/sys/nfsclient/nfs_nfsiod.c b/sys/nfsclient/nfs_nfsiod.c index c33b950..6ebd053 100644 --- a/sys/nfsclient/nfs_nfsiod.c +++ b/sys/nfsclient/nfs_nfsiod.c @@ -66,6 +66,9 @@ __FBSDID("$FreeBSD$"); #include <netinet/in.h> #include <netinet/tcp.h> + +#include <rpc/rpcclnt.h> + #include <nfs/xdr_subs.h> #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c index fc3520f..3dd3d03 100644 --- a/sys/nfsclient/nfs_node.c +++ b/sys/nfsclient/nfs_node.c @@ -53,6 +53,8 @@ __FBSDID("$FreeBSD$"); #include <vm/uma.h> +#include <rpc/rpcclnt.h> + #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> #include <nfsclient/nfs.h> @@ -182,7 +184,7 @@ nfs_nget(struct mount *mntp, nfsfh_t *fhp, int fhsize, struct nfsnode **npp) /* * Calculate nfs mount point and figure out whether the rslock should - * be interruptable or not. + * be interruptible or not. */ nmp = VFSTONFS(mntp); if (nmp->nm_flag & NFSMNT_INT) @@ -226,7 +228,10 @@ loop: */ np = uma_zalloc(nfsnode_zone, M_WAITOK); - error = getnewvnode("nfs", mntp, nfs_vnodeop_p, &nvp); + if (nmp->nm_flag & NFSMNT_NFSV4) + error = getnewvnode("nfs4", mntp, nfs4_vnodeop_p, &nvp); + else + error = getnewvnode("nfs", mntp, nfs_vnodeop_p, &nvp); if (error) { if (nfs_node_hash_lock < 0) wakeup(&nfs_node_hash_lock); @@ -295,7 +300,7 @@ nfs_inactive(struct vop_inactive_args *ap) /* * Remove the silly file that was rename'd earlier */ - nfs_removeit(sp); + (sp->s_removeit)(sp); crfree(sp->s_cred); vrele(sp->s_dvp); FREE((caddr_t)sp, M_NFSREQ); diff --git a/sys/nfsclient/nfs_socket.c b/sys/nfsclient/nfs_socket.c index 9c82759..d74ae8e 100644 --- a/sys/nfsclient/nfs_socket.c +++ b/sys/nfsclient/nfs_socket.c @@ -65,6 +65,8 @@ __FBSDID("$FreeBSD$"); #include <netinet/in.h> #include <netinet/tcp.h> +#include <rpc/rpcclnt.h> + #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> #include <nfsclient/nfs.h> @@ -73,6 +75,8 @@ __FBSDID("$FreeBSD$"); #include <nfsclient/nfsmount.h> #include <nfsclient/nfsnode.h> +#include <nfs4client/nfs4.h> + #define TRUE 1 #define FALSE 0 @@ -874,6 +878,8 @@ nfs_request(struct vnode *vp, struct mbuf *mrest, int procnum, return (ESTALE); } nmp = VFSTONFS(vp->v_mount); + if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) + return nfs4_request(vp, mrest, procnum, td, cred, mrp, mdp, dposp); MALLOC(rep, struct nfsreq *, sizeof(struct nfsreq), M_NFSREQ, M_WAITOK); rep->r_nmp = nmp; rep->r_vp = vp; @@ -1235,6 +1241,8 @@ nfs_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct thread *td) struct proc *p; sigset_t tmpset; + if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) + return nfs4_sigintr(nmp, rep, td); if (rep && (rep->r_flags & R_SOFTTERM)) return (EINTR); /* Terminate all requests while attempting a forced unmount. */ diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c index 7b8866e..8d4a3df 100644 --- a/sys/nfsclient/nfs_subs.c +++ b/sys/nfsclient/nfs_subs.c @@ -67,6 +67,8 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_extern.h> #include <vm/uma.h> +#include <rpc/rpcclnt.h> + #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> #include <nfsclient/nfs.h> @@ -761,6 +763,10 @@ nfs_invaldir(struct vnode *vp) if (vp->v_type != VDIR) panic("nfs: invaldir not dir"); #endif + if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NFSV4) != 0) { + nfs4_invaldir(vp); + return; + } np->n_direofoffset = 0; np->n_cookieverf.nfsuquad[0] = 0; np->n_cookieverf.nfsuquad[1] = 0; diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c index b53a200..7ee48ab 100644 --- a/sys/nfsclient/nfs_vfsops.c +++ b/sys/nfsclient/nfs_vfsops.c @@ -66,6 +66,8 @@ __FBSDID("$FreeBSD$"); #include <net/route.h> #include <netinet/in.h> +#include <rpc/rpcclnt.h> + #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> #include <nfsclient/nfs.h> diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index 692ab89..60acab0 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -69,6 +69,8 @@ __FBSDID("$FreeBSD$"); #include <fs/fifofs/fifo.h> +#include <rpc/rpcclnt.h> + #include <nfs/rpcv2.h> #include <nfs/nfsproto.h> #include <nfsclient/nfs.h> @@ -2397,6 +2399,7 @@ nfs_sillyrename(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) M_NFSREQ, M_WAITOK); sp->s_cred = crhold(cnp->cn_cred); sp->s_dvp = dvp; + sp->s_removeit = nfs_removeit; VREF(dvp); /* Fudge together a funny name */ diff --git a/sys/nfsclient/nfsargs.h b/sys/nfsclient/nfsargs.h index 7f4c636..5cd0e9e 100644 --- a/sys/nfsclient/nfsargs.h +++ b/sys/nfsclient/nfsargs.h @@ -95,5 +95,7 @@ struct nfs_args { #define NFSMNT_ACDIRMIN 0x00100000 #define NFSMNT_ACDIRMAX 0x00200000 #define NFSMNT_NOLOCKD 0x00400000 /* Locks are local */ +#define NFSMNT_NFSV4 0x00800000 /* Use NFS Version 4 protocol */ +#define NFSMNT_HASWRITEVERF 0x01000000 /* NFSv4 Write verifier */ #endif diff --git a/sys/nfsclient/nfsm_subs.h b/sys/nfsclient/nfsm_subs.h index f626dd4..ee9d215 100644 --- a/sys/nfsclient/nfsm_subs.h +++ b/sys/nfsclient/nfsm_subs.h @@ -147,6 +147,17 @@ do { \ } \ } while (0) +#define nfsm_request_mnt(n, t, p, c) \ +do { \ + error = nfs4_request_mnt((n), mreq, (t), (p), (c), &mrep, &md, &dpos); \ + if (error != 0) { \ + if (error & NFSERR_RETERR) \ + error &= ~NFSERR_RETERR; \ + else \ + goto nfsmout; \ + } \ +} while (0) + /* *********************************** */ /* Reply interpretation phase macros */ diff --git a/sys/nfsclient/nfsmount.h b/sys/nfsclient/nfsmount.h index 8c531cb..485885a 100644 --- a/sys/nfsclient/nfsmount.h +++ b/sys/nfsclient/nfsmount.h @@ -50,8 +50,9 @@ struct nfsmount { int nm_state; /* Internal state flags */ struct mount *nm_mountp; /* Vfs structure for this filesystem */ int nm_numgrps; /* Max. size of groupslist */ - u_char nm_fh[NFSX_V3FHMAX]; /* File handle of root dir */ + u_char nm_fh[NFSX_V4FH]; /* File handle of root dir */ int nm_fhsize; /* Size of root file handle */ + struct rpcclnt nm_rpcclnt; /* rpc state */ struct socket *nm_so; /* Rpc socket */ int nm_sotype; /* Type of socket */ int nm_soproto; /* and protocol */ @@ -79,6 +80,12 @@ struct nfsmount { short nm_bufqwant; /* process wants to add to the queue */ int nm_bufqiods; /* number of iods processing queue */ u_int64_t nm_maxfilesize; /* maximum file size */ + + /* NFSv4 */ + uint64_t nm_clientid; + fsid_t nm_fsid; + u_int nm_lease_time; + time_t nm_last_renewal; }; #if defined(_KERNEL) diff --git a/sys/nfsclient/nfsnode.h b/sys/nfsclient/nfsnode.h index f74d99f..76019cd 100644 --- a/sys/nfsclient/nfsnode.h +++ b/sys/nfsclient/nfsnode.h @@ -51,6 +51,7 @@ struct sillyrename { struct ucred *s_cred; struct vnode *s_dvp; + int (*s_removeit)(struct sillyrename *sp); long s_namlen; char s_name[20]; }; @@ -68,9 +69,15 @@ struct sillyrename { struct nfsdmap { LIST_ENTRY(nfsdmap) ndm_list; int ndm_eocookie; - nfsuint64 ndm_cookies[NFSNUMCOOKIES]; + union { + nfsuint64 ndmu3_cookies[NFSNUMCOOKIES]; + uint64_t ndmu4_cookies[NFSNUMCOOKIES]; + } ndm_un1; }; +#define ndm_cookies ndm_un1.ndmu3_cookies +#define ndm4_cookies ndm_un1.ndmu4_cookies + /* * The nfsnode is the nfs equivalent to ufs's inode. Any similarity * is purely coincidental. @@ -99,11 +106,13 @@ struct nfsnode { time_t n_expiry; /* Lease expiry time */ nfsfh_t *n_fhp; /* NFS File Handle */ struct vnode *n_vnode; /* associated vnode */ + struct vnode *n_dvp; /* parent 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) */ + u_char nd4_cookieverf[NFSX_V4VERF]; } n_un1; union { struct timespec nf_mtim; @@ -117,12 +126,21 @@ struct nfsnode { short n_flag; /* Flag for locking.. */ nfsfh_t n_fh; /* Small File Handle */ struct lock n_rslock; + struct nfs4_fctx n_rfc; + struct nfs4_fctx n_wfc; + /* + * The last component name is needed for the NFSv4 OPEN + * operation. + */ + u_char *n_name; + uint32_t n_namelen; }; #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 n4_cookieverf n_un1.nd4_cookieverf #define n_direofoffset n_un2.nd_direof #define n_cookies n_un3.nd_cook @@ -137,6 +155,8 @@ struct nfsnode { #define NACC 0x0100 /* Special file accessed */ #define NUPD 0x0200 /* Special file updated */ #define NCHG 0x0400 /* Special file times changed */ +#define NCREATED 0x0800 /* Opened by nfs_create() */ +#define NTRUNCATE 0x1000 /* Opened by nfs_setattr() */ /* * Convert between nfsnode pointers and vnode pointers @@ -182,6 +202,10 @@ extern vop_t **fifo_nfsnodeop_p; extern vop_t **nfs_vnodeop_p; extern vop_t **spec_nfsnodeop_p; +extern vop_t **fifo_nfs4nodeop_p; +extern vop_t **nfs4_vnodeop_p; +extern vop_t **spec_nfs4nodeop_p; + /* * Prototypes for NFS vnode operations */ @@ -193,9 +217,12 @@ int nfs_reclaim(struct vop_reclaim_args *); /* other stuff */ int nfs_removeit(struct sillyrename *); +int nfs4_removeit(struct sillyrename *); int nfs_nget(struct mount *, nfsfh_t *, int, struct nfsnode **); nfsuint64 *nfs_getcookie(struct nfsnode *, off_t, int); +uint64_t *nfs4_getcookie(struct nfsnode *, off_t, int); void nfs_invaldir(struct vnode *); +void nfs4_invaldir(struct vnode *); #endif /* _KERNEL */ |