summaryrefslogtreecommitdiffstats
path: root/sys/nfsclient
diff options
context:
space:
mode:
Diffstat (limited to 'sys/nfsclient')
-rw-r--r--sys/nfsclient/bootp_subr.c2
-rw-r--r--sys/nfsclient/krpc_subr.c2
-rw-r--r--sys/nfsclient/nfs.h19
-rw-r--r--sys/nfsclient/nfs_bio.c53
-rw-r--r--sys/nfsclient/nfs_diskless.c1
-rw-r--r--sys/nfsclient/nfs_lock.c2
-rw-r--r--sys/nfsclient/nfs_nfsiod.c3
-rw-r--r--sys/nfsclient/nfs_node.c11
-rw-r--r--sys/nfsclient/nfs_socket.c8
-rw-r--r--sys/nfsclient/nfs_subs.c6
-rw-r--r--sys/nfsclient/nfs_vfsops.c2
-rw-r--r--sys/nfsclient/nfs_vnops.c3
-rw-r--r--sys/nfsclient/nfsargs.h2
-rw-r--r--sys/nfsclient/nfsm_subs.h11
-rw-r--r--sys/nfsclient/nfsmount.h9
-rw-r--r--sys/nfsclient/nfsnode.h29
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 */
OpenPOWER on IntegriCloud