summaryrefslogtreecommitdiffstats
path: root/sys/fs/nfsserver/nfs_nfsdsocket.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs/nfsserver/nfs_nfsdsocket.c')
-rw-r--r--sys/fs/nfsserver/nfs_nfsdsocket.c144
1 files changed, 109 insertions, 35 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c
index bd97336..0ae53ff 100644
--- a/sys/fs/nfsserver/nfs_nfsdsocket.c
+++ b/sys/fs/nfsserver/nfs_nfsdsocket.c
@@ -48,6 +48,7 @@ extern struct nfsv4lock nfsv4rootfs_lock;
extern struct nfsrv_stablefirst nfsrv_stablefirst;
extern struct nfsclienthashhead nfsclienthash[NFSCLIENTHASHSIZE];
extern int nfsrc_floodlevel, nfsrc_tcpsavedreplies;
+extern int nfsd_debuglevel;
NFSV4ROOTLOCKMUTEX;
NFSSTATESPINLOCK;
@@ -131,7 +132,7 @@ int (*nfsrv3_procs2[NFS_V3NPROCS])(struct nfsrv_descript *,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
};
-int (*nfsrv4_ops0[NFSV4OP_NOPS])(struct nfsrv_descript *,
+int (*nfsrv4_ops0[NFSV41_NOPS])(struct nfsrv_descript *,
int, vnode_t , NFSPROC_T *, struct nfsexstuff *) = {
(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
@@ -173,9 +174,28 @@ int (*nfsrv4_ops0[NFSV4OP_NOPS])(struct nfsrv_descript *,
nfsrvd_verify,
nfsrvd_write,
nfsrvd_releaselckown,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_exchangeid,
+ nfsrvd_createsession,
+ nfsrvd_destroysession,
+ nfsrvd_freestateid,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_sequence,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_destroyclientid,
+ nfsrvd_reclaimcomplete,
};
-int (*nfsrv4_ops1[NFSV4OP_NOPS])(struct nfsrv_descript *,
+int (*nfsrv4_ops1[NFSV41_NOPS])(struct nfsrv_descript *,
int, vnode_t , vnode_t *, fhandle_t *,
NFSPROC_T *, struct nfsexstuff *) = {
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
@@ -218,9 +238,28 @@ int (*nfsrv4_ops1[NFSV4OP_NOPS])(struct nfsrv_descript *,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
};
-int (*nfsrv4_ops2[NFSV4OP_NOPS])(struct nfsrv_descript *,
+int (*nfsrv4_ops2[NFSV41_NOPS])(struct nfsrv_descript *,
int, vnode_t , vnode_t , NFSPROC_T *,
struct nfsexstuff *, struct nfsexstuff *) = {
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
@@ -263,6 +302,25 @@ int (*nfsrv4_ops2[NFSV4OP_NOPS])(struct nfsrv_descript *,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
};
#endif /* !APPLEKEXT */
@@ -304,7 +362,7 @@ static int nfs_writerpc[NFS_NPROCS] = { 0, 0, 1, 0, 0, 0, 0,
/* local functions */
static void nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
- NFSPROC_T *p);
+ u_char *tag, int taglen, u_int32_t minorvers, NFSPROC_T *p);
/*
@@ -314,7 +372,7 @@ static void nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
static int nfs_retfh[NFS_V3NPROCS] = { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1,
1, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0 };
-extern struct nfsv4_opflag nfsv4_opflag[NFSV4OP_NOPS];
+extern struct nfsv4_opflag nfsv4_opflag[NFSV41_NOPS];
static int nfsv3to4op[NFS_V3NPROCS] = {
NFSPROC_NULL,
@@ -349,8 +407,8 @@ static int nfsv3to4op[NFS_V3NPROCS] = {
* The NFS V4 Compound RPC is performed separately by nfsrvd_compound().
*/
APPLESTATIC void
-nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram,
- NFSPROC_T *p)
+nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram, u_char *tag, int taglen,
+ u_int32_t minorvers, NFSPROC_T *p)
{
int error = 0, lktype;
vnode_t vp;
@@ -427,7 +485,7 @@ nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram,
* The group is indicated by the value in nfs_retfh[].
*/
if (nd->nd_flag & ND_NFSV4) {
- nfsrvd_compound(nd, isdgram, p);
+ nfsrvd_compound(nd, isdgram, tag, taglen, minorvers, p);
} else {
if (nfs_retfh[nd->nd_procnum] == 1) {
if (vp)
@@ -482,15 +540,14 @@ out:
* vnode pointer handling.
*/
static void
-nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
- NFSPROC_T *p)
+nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag,
+ int taglen, u_int32_t minorvers, NFSPROC_T *p)
{
- int i, op;
+ int i, op, op0 = 0;
u_int32_t *tl;
struct nfsclient *clp, *nclp;
- int numops, taglen = -1, error = 0, igotlock;
- u_int32_t minorvers, retops = 0, *retopsp = NULL, *repp;
- u_char tag[NFSV4_SMALLSTR + 1], *tagstr;
+ int numops, error = 0, igotlock;
+ u_int32_t retops = 0, *retopsp = NULL, *repp;
vnode_t vp, nvp, savevp;
struct nfsrvfh fh;
mount_t new_mp, temp_mp = NULL;
@@ -595,31 +652,17 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
savevp = vp = NULL;
save_fsid.val[0] = save_fsid.val[1] = 0;
cur_fsid.val[0] = cur_fsid.val[1] = 0;
- NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
- taglen = fxdr_unsigned(int, *tl);
+
+ /* If taglen < 0, there was a parsing error in nfsd_getminorvers(). */
if (taglen < 0) {
error = EBADRPC;
goto nfsmout;
}
- if (taglen <= NFSV4_SMALLSTR)
- tagstr = tag;
- else
- tagstr = malloc(taglen + 1, M_TEMP, M_WAITOK);
- error = nfsrv_mtostr(nd, tagstr, taglen);
- if (error) {
- if (taglen > NFSV4_SMALLSTR)
- free(tagstr, M_TEMP);
- taglen = -1;
- goto nfsmout;
- }
+
(void) nfsm_strtom(nd, tag, taglen);
- if (taglen > NFSV4_SMALLSTR) {
- free(tagstr, M_TEMP);
- }
NFSM_BUILD(retopsp, u_int32_t *, NFSX_UNSIGNED);
- NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
- minorvers = fxdr_unsigned(u_int32_t, *tl++);
- if (minorvers != NFSV4_MINORVERSION)
+ NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
+ if (minorvers != NFSV4_MINORVERSION && minorvers != NFSV41_MINORVERSION)
nd->nd_repstat = NFSERR_MINORVERMISMATCH;
if (nd->nd_repstat)
numops = 0;
@@ -638,7 +681,10 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
NFSM_BUILD(repp, u_int32_t *, 2 * NFSX_UNSIGNED);
*repp = *tl;
op = fxdr_unsigned(int, *tl);
- if (op < NFSV4OP_ACCESS || op >= NFSV4OP_NOPS) {
+ NFSD_DEBUG(4, "op=%d\n", op);
+ if (op < NFSV4OP_ACCESS ||
+ (op >= NFSV4OP_NOPS && (nd->nd_flag & ND_NFSV41) == 0) ||
+ (op >= NFSV41_NOPS && (nd->nd_flag & ND_NFSV41) != 0)) {
nd->nd_repstat = NFSERR_OPILLEGAL;
*repp++ = txdr_unsigned(NFSV4OP_OPILLEGAL);
*repp = nfsd_errmap(nd);
@@ -647,6 +693,10 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
} else {
repp++;
}
+ if (i == 0)
+ op0 = op;
+ if (i == numops - 1)
+ nd->nd_flag |= ND_LASTOP;
/*
* Check for a referral on the current FH and, if so, return
@@ -661,6 +711,29 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
break;
}
+ /*
+ * For NFSv4.1, check for a Sequence Operation being first
+ * or one of the other allowed operations by itself.
+ */
+ if ((nd->nd_flag & ND_NFSV41) != 0) {
+ if (i != 0 && op == NFSV4OP_SEQUENCE)
+ nd->nd_repstat = NFSERR_SEQUENCEPOS;
+ else if (i == 0 && op != NFSV4OP_SEQUENCE &&
+ op != NFSV4OP_EXCHANGEID &&
+ op != NFSV4OP_CREATESESSION &&
+ op != NFSV4OP_BINDCONNTOSESS &&
+ op != NFSV4OP_DESTROYCLIENTID &&
+ op != NFSV4OP_DESTROYSESSION)
+ nd->nd_repstat = NFSERR_OPNOTINSESS;
+ else if (i != 0 && op0 != NFSV4OP_SEQUENCE)
+ nd->nd_repstat = NFSERR_NOTONLYOP;
+ if (nd->nd_repstat != 0) {
+ *repp = nfsd_errmap(nd);
+ retops++;
+ break;
+ }
+ }
+
nd->nd_procnum = op;
/*
* If over flood level, reply NFSERR_RESOURCE, if at the first
@@ -672,7 +745,8 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
* If nfsrv_mallocmget_limit() returns True, the system is near
* to its limit for memory that malloc()/mget() can allocate.
*/
- if (i == 0 && nd->nd_rp->rc_refcnt == 0 &&
+ if (i == 0 && (nd->nd_rp == NULL ||
+ nd->nd_rp->rc_refcnt == 0) &&
(nfsrv_mallocmget_limit() ||
nfsrc_tcpsavedreplies > nfsrc_floodlevel)) {
if (nfsrc_tcpsavedreplies > nfsrc_floodlevel) {
OpenPOWER on IntegriCloud