summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/nfs/nfs4_dispatch.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/fs/nfs/nfs4_dispatch.c')
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_dispatch.c100
1 files changed, 67 insertions, 33 deletions
diff --git a/usr/src/uts/common/fs/nfs/nfs4_dispatch.c b/usr/src/uts/common/fs/nfs/nfs4_dispatch.c
index 1fdfd0f601..0988dea0ef 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_dispatch.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_dispatch.c
@@ -26,6 +26,7 @@
/*
* Copyright 2018 Nexenta Systems, Inc.
+ * Copyright 2020 RackTop Systems, Inc.
*/
#include <sys/systm.h>
@@ -40,7 +41,7 @@
#include <nfs/nfs_dispatch.h>
#include <nfs/nfs4_drc.h>
-#define NFS4_MAX_MINOR_VERSION 0
+#define NFS4_MAX_MINOR_VERSION 2
/*
* The default size of the duplicate request cache
@@ -372,43 +373,28 @@ rfs4_find_dr(struct svc_req *req, rfs4_drc_t *drc, rfs4_dupreq_t **dup)
*
*/
int
-rfs4_dispatch(struct rpcdisp *disp, struct svc_req *req, SVCXPRT *xprt,
- char *ap)
+rfs40_dispatch(struct svc_req *req, SVCXPRT *xprt, char *ap)
{
COMPOUND4res res_buf;
COMPOUND4res *rbp;
COMPOUND4args *cap;
- cred_t *cr = NULL;
int error = 0;
int dis_flags = 0;
int dr_stat = NFS4_NOT_DUP;
rfs4_dupreq_t *drp = NULL;
int rv;
+ struct compound_state cs;
nfs4_srv_t *nsrv4 = nfs4_get_srv();
rfs4_drc_t *nfs4_drc = nsrv4->nfs4_drc;
- ASSERT(disp);
-
- /*
- * Short circuit the RPC_NULL proc.
- */
- if (disp->dis_proc == rpc_null) {
- DTRACE_NFSV4_1(null__start, struct svc_req *, req);
- if (!svc_sendreply(xprt, xdr_void, NULL)) {
- DTRACE_NFSV4_1(null__done, struct svc_req *, req);
- svcerr_systemerr(xprt);
- return (1);
- }
- DTRACE_NFSV4_1(null__done, struct svc_req *, req);
- return (0);
- }
-
/* Only NFSv4 Compounds from this point onward */
rbp = &res_buf;
cap = (COMPOUND4args *)ap;
+ rfs4_init_compound_state(&cs);
+
/*
* Figure out the disposition of the whole COMPOUND
* and record it's IDEMPOTENTCY.
@@ -445,9 +431,11 @@ rfs4_dispatch(struct rpcdisp *disp, struct svc_req *req, SVCXPRT *xprt,
case NFS4_DUP_NEW:
curthread->t_flag |= T_DONTPEND;
/* NON-IDEMPOTENT proc call */
- rfs4_compound(cap, rbp, NULL, req, cr, &rv);
+ rfs4_compound(cap, rbp, &cs, req, &rv);
curthread->t_flag &= ~T_DONTPEND;
+ rfs4_fini_compound_state(&cs);
+
if (rv) /* short ckt sendreply on error */
return (rv);
@@ -478,9 +466,11 @@ rfs4_dispatch(struct rpcdisp *disp, struct svc_req *req, SVCXPRT *xprt,
} else {
curthread->t_flag |= T_DONTPEND;
/* IDEMPOTENT proc call */
- rfs4_compound(cap, rbp, NULL, req, cr, &rv);
+ rfs4_compound(cap, rbp, &cs, req, &rv);
curthread->t_flag &= ~T_DONTPEND;
+ rfs4_fini_compound_state(&cs);
+
if (rv) /* short ckt sendreply on error */
return (rv);
@@ -528,19 +518,11 @@ rfs4_dispatch(struct rpcdisp *disp, struct svc_req *req, SVCXPRT *xprt,
return (error);
}
-bool_t
-rfs4_minorvers_mismatch(struct svc_req *req, SVCXPRT *xprt, void *args)
+static int
+rfs4_send_minor_mismatch(SVCXPRT *xprt, COMPOUND4args *argsp)
{
- COMPOUND4args *argsp;
COMPOUND4res res_buf, *resp;
-
- if (req->rq_vers != 4)
- return (FALSE);
-
- argsp = (COMPOUND4args *)args;
-
- if (argsp->minorversion <= NFS4_MAX_MINOR_VERSION)
- return (FALSE);
+ int err = 0;
resp = &res_buf;
@@ -563,8 +545,26 @@ rfs4_minorvers_mismatch(struct svc_req *req, SVCXPRT *xprt, void *args)
DTRACE_PROBE2(nfss__e__minorvers_mismatch,
SVCXPRT *, xprt, char *, resp);
svcerr_systemerr(xprt);
+ err = 1;
}
rfs4_compound_free(resp);
+ return (err);
+}
+
+bool_t
+rfs4_minorvers_mismatch(struct svc_req *req, SVCXPRT *xprt, void *args)
+{
+ COMPOUND4args *argsp;
+
+ if (req->rq_vers != 4)
+ return (FALSE);
+
+ argsp = (COMPOUND4args *)args;
+
+ if (argsp->minorversion <= NFS4_MAX_MINOR_VERSION)
+ return (FALSE);
+
+ (void) rfs4_send_minor_mismatch(xprt, argsp);
return (TRUE);
}
@@ -619,3 +619,37 @@ rfs4_resource_err(struct svc_req *req, COMPOUND4args *argsp)
UTF8STRING_FREE(rbp->tag);
kmem_free(rbp->array, rbp->array_len * sizeof (nfs_resop4));
}
+
+/* ARGSUSED */
+int
+rfs4_dispatch(struct rpcdisp *disp, struct svc_req *req,
+ SVCXPRT *xprt, char *ap)
+{
+ COMPOUND4args *cmp;
+ int error = 0;
+
+ /*
+ * Handle the NULL Proc here
+ */
+ if (req->rq_proc == RFS_NULL) {
+ return (!svc_sendreply(xprt, xdr_void, NULL));
+ }
+
+ cmp = (COMPOUND4args *)ap;
+ ASSERT(cmp != NULL);
+
+ switch (cmp->minorversion) {
+ case 1:
+ case 2:
+ error = rfs4x_dispatch(req, xprt, ap);
+ break;
+
+ case 0:
+ error = rfs40_dispatch(req, xprt, ap);
+ break;
+
+ default:
+ error = rfs4_send_minor_mismatch(xprt, cmp);
+ }
+ return (error);
+}