summaryrefslogtreecommitdiffstats
path: root/sys/fs/nfsserver/nfs_nfsdkrpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs/nfsserver/nfs_nfsdkrpc.c')
-rw-r--r--sys/fs/nfsserver/nfs_nfsdkrpc.c51
1 files changed, 41 insertions, 10 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdkrpc.c b/sys/fs/nfsserver/nfs_nfsdkrpc.c
index 9649093..d2145cc 100644
--- a/sys/fs/nfsserver/nfs_nfsdkrpc.c
+++ b/sys/fs/nfsserver/nfs_nfsdkrpc.c
@@ -305,7 +305,10 @@ nfs_proc(struct nfsrv_descript *nd, u_int32_t xid, SVCXPRT *xprt,
struct nfsrvcache **rpp)
{
struct thread *td = curthread;
- int cacherep = RC_DOIT, isdgram;
+ int cacherep = RC_DOIT, isdgram, taglen = -1;
+ struct mbuf *m;
+ u_char tag[NFSV4_SMALLSTR + 1], *tagstr = NULL;
+ u_int32_t minorvers = 0;
uint32_t ack;
*rpp = NULL;
@@ -339,10 +342,18 @@ nfs_proc(struct nfsrv_descript *nd, u_int32_t xid, SVCXPRT *xprt,
nd->nd_retxid = xid;
nd->nd_tcpconntime = NFSD_MONOSEC;
nd->nd_sockref = xprt->xp_sockref;
- cacherep = nfsrvd_getcache(nd);
- ack = 0;
- SVC_ACK(xprt, &ack);
- nfsrc_trimcache(xprt->xp_sockref, ack, 0);
+ if ((nd->nd_flag & ND_NFSV4) != 0)
+ nfsd_getminorvers(nd, tag, &tagstr, &taglen,
+ &minorvers);
+ if ((nd->nd_flag & ND_NFSV41) != 0)
+ /* NFSv4.1 caches replies in the session slots. */
+ cacherep = RC_DOIT;
+ else {
+ cacherep = nfsrvd_getcache(nd);
+ ack = 0;
+ SVC_ACK(xprt, &ack);
+ nfsrc_trimcache(xprt->xp_sockref, ack, 0);
+ }
}
/*
@@ -352,13 +363,33 @@ nfs_proc(struct nfsrv_descript *nd, u_int32_t xid, SVCXPRT *xprt,
* RC_DROPIT - just throw the request away
*/
if (cacherep == RC_DOIT) {
- nfsrvd_dorpc(nd, isdgram, td);
- if (nd->nd_repstat == NFSERR_DONTREPLY)
- cacherep = RC_DROPIT;
- else
+ if ((nd->nd_flag & ND_NFSV41) != 0)
+ nd->nd_xprt = xprt;
+ nfsrvd_dorpc(nd, isdgram, tagstr, taglen, minorvers, td);
+ if ((nd->nd_flag & ND_NFSV41) != 0) {
+ if (nd->nd_repstat != NFSERR_REPLYFROMCACHE &&
+ (nd->nd_flag & ND_SAVEREPLY) != 0) {
+ /* Cache a copy of the reply. */
+ m = m_copym(nd->nd_mreq, 0, M_COPYALL,
+ M_WAITOK);
+ } else
+ m = NULL;
+ if ((nd->nd_flag & ND_HASSEQUENCE) != 0)
+ nfsrv_cache_session(nd->nd_sessionid,
+ nd->nd_slotid, nd->nd_repstat, &m);
+ if (nd->nd_repstat == NFSERR_REPLYFROMCACHE)
+ nd->nd_repstat = 0;
cacherep = RC_REPLY;
- *rpp = nfsrvd_updatecache(nd);
+ } else {
+ if (nd->nd_repstat == NFSERR_DONTREPLY)
+ cacherep = RC_DROPIT;
+ else
+ cacherep = RC_REPLY;
+ *rpp = nfsrvd_updatecache(nd);
+ }
}
+ if (tagstr != NULL && taglen > NFSV4_SMALLSTR)
+ free(tagstr, M_TEMP);
NFSEXITCODE2(0, nd);
return (cacherep);
OpenPOWER on IntegriCloud