diff options
Diffstat (limited to 'sys/fs/nfsserver/nfs_nfsdkrpc.c')
-rw-r--r-- | sys/fs/nfsserver/nfs_nfsdkrpc.c | 51 |
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); |