#include <sys/time.h>
#include <kern/clock.h>
+#include <sys/user.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <nfs/nfsrtt.h>
#include <nfs/nqnfs.h>
+#include <sys/kdebug.h>
+
+#define FSDBG(A, B, C, D, E) \
+ KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, (A))) | DBG_FUNC_NONE, \
+ (int)(B), (int)(C), (int)(D), (int)(E), 0)
+#define FSDBG_TOP(A, B, C, D, E) \
+ KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, (A))) | DBG_FUNC_START, \
+ (int)(B), (int)(C), (int)(D), (int)(E), 0)
+#define FSDBG_BOT(A, B, C, D, E) \
+ KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, (A))) | DBG_FUNC_END, \
+ (int)(B), (int)(C), (int)(D), (int)(E), 0)
+
#define TRUE 1
#define FALSE 0
extern struct nfsstats nfsstats;
extern int nfsv3_procid[NFS_NPROCS];
extern int nfs_ticks;
+extern u_long nfs_xidwrap;
/*
* Defines which timer to use for the procnum.
};
#endif /* NFS_NOSERVER */
+/*
+ * NFSTRACE points were changed to FSDBG (KERNEL_DEBUG)
+ * But some of this code may prove useful someday...
+ */
+#undef NFSDIAG
#if NFSDIAG
int nfstraceindx = 0;
struct nfstracerec nfstracebuf[NFSTBUFSIZ] = {{0,0,0,0}};
nmp->nm_sdrtt[3] = 0;
nmp->nm_cwnd = NFS_MAXCWND / 2; /* Initial send window */
nmp->nm_sent = 0;
- NFSTRACE4(NFSTRC_CWND_INIT, nmp, nmp->nm_flag, nmp->nm_soflags,
- nmp->nm_cwnd);
+ FSDBG(529, nmp, nmp->nm_flag, nmp->nm_soflags, nmp->nm_cwnd);
nmp->nm_timeouts = 0;
return (0);
*/
if (myrep->r_mrep != NULL) {
nfs_rcvunlock(&nmp->nm_flag);
- NFSTRACE4(NFSTRC_RCVALREADY, myrep->r_xid, myrep,
- myrep->r_nmp, 2);
+ FSDBG(530, myrep->r_xid, myrep, myrep->r_nmp, -1);
return (0);
}
/*
* Get the next Rpc reply off the socket. Assume myrep->r_nmp
- * is still in tact by checks done in nfs_rcvlock.
+ * is still intact by checks done in nfs_rcvlock.
*/
error = nfs_receive(myrep, &nam, &mrep);
/*
* Bailout asap if nfsmount struct gone (unmounted).
*/
- if (!myrep->r_nmp) {
- NFSTRACE4(NFSTRC_ECONN, myrep->r_xid, myrep, nmp, 2);
+ if (!myrep->r_nmp || !nmp->nm_so) {
+ FSDBG(530, myrep->r_xid, myrep, nmp, -2);
return (ECONNABORTED);
}
if (error) {
- NFSTRACE4(NFSTRC_RCVERR, myrep->r_xid, myrep, nmp,
- error);
+ FSDBG(530, myrep->r_xid, myrep, nmp, error);
nfs_rcvunlock(&nmp->nm_flag);
+ /* Bailout asap if nfsmount struct gone (unmounted). */
+ if (!myrep->r_nmp || !nmp->nm_so)
+ return (ECONNABORTED);
+
/*
* Ignore routing errors on connectionless protocols??
*/
* just check here and get out. (ekn)
*/
if (!mrep) {
- NFSTRACE4(NFSTRC_ECONN, myrep->r_xid, myrep, nmp, 3);
+ FSDBG(530, myrep->r_xid, myrep, nmp, -3);
return (ECONNABORTED); /* sounds good */
}
* Do the additive increase of
* one rpc/rtt.
*/
- NFSTRACE4(NFSTRC_CWND_REPLY, rep->r_xid, rep,
- nmp->nm_sent, nmp->nm_cwnd);
+ FSDBG(530, rep->r_xid, rep, nmp->nm_sent,
+ nmp->nm_cwnd);
if (nmp->nm_cwnd <= nmp->nm_sent) {
nmp->nm_cwnd +=
(NFS_CWNDSCALE * NFS_CWNDSCALE +
panic("nfs_reply: nil r_mrep");
return (0);
}
- NFSTRACE4(NFSTRC_NOTMINE, myrep->r_xid, myrep, rep,
- rep ? rep->r_xid : myrep->r_flags);
+ FSDBG(530, myrep->r_xid, myrep, rep,
+ rep ? rep->r_xid : myrep->r_flags);
if (myrep->r_flags & R_GETONEREP)
return (0); /* this path used by NQNFS */
}
* nb: always frees up mreq mbuf list
*/
int
-nfs_request(vp, mrest, procnum, procp, cred, mrp, mdp, dposp)
+nfs_request(vp, mrest, procnum, procp, cred, mrp, mdp, dposp, xidp)
struct vnode *vp;
struct mbuf *mrest;
int procnum;
struct mbuf **mrp;
struct mbuf **mdp;
caddr_t *dposp;
+ u_int64_t *xidp;
{
register struct mbuf *m, *mrep;
register struct nfsreq *rep, *rp;
char *auth_str, *verf_str;
NFSKERBKEY_T key; /* save session key */
+ if (xidp)
+ *xidp = 0;
nmp = VFSTONFS(vp->v_mount);
MALLOC_ZONE(rep, struct nfsreq *,
sizeof(struct nfsreq), M_NFSREQ, M_WAITOK);
- NFSTRACE4(NFSTRC_REQ, vp, procnum, nmp, rep);
+ FSDBG_TOP(531, vp, procnum, nmp, rep);
/*
* make sure if we blocked above, that the file system didn't get
*/
if (vp->v_type == VBAD) {
- NFSTRACE4(NFSTRC_VBAD, 1, vp, nmp, rep);
+ FSDBG_BOT(531, 1, vp, nmp, rep);
_FREE_ZONE((caddr_t)rep, sizeof (struct nfsreq), M_NFSREQ);
return (EINVAL);
}
error = nfs_getauth(nmp, rep, cred, &auth_str,
&auth_len, verf_str, &verf_len, key);
if (error) {
+ FSDBG_BOT(531, 2, vp, error, rep);
_FREE_ZONE((caddr_t)rep,
sizeof (struct nfsreq), M_NFSREQ);
m_freem(mrest);
}
m = nfsm_rpchead(cred, nmp->nm_flag, procnum, auth_type, auth_len,
auth_str, verf_len, verf_str, mrest, mrest_len, &mheadend, &xid);
+ if (xidp)
+ *xidp = ntohl(xid) + ((u_int64_t)nfs_xidwrap << 32);
if (auth_str)
_FREE(auth_str, M_TEMP);
*/
if (!error) {
if ((rep->r_flags & R_MUSTRESEND) == 0) {
- NFSTRACE4(NFSTRC_CWND_REQ1, rep->r_xid, rep,
- nmp->nm_sent, nmp->nm_cwnd);
+ FSDBG(531, rep->r_xid, rep, nmp->nm_sent,
+ nmp->nm_cwnd);
nmp->nm_sent += NFS_CWNDSCALE;
rep->r_flags |= R_SENT;
}
* Decrement the outstanding request count.
*/
if (rep->r_flags & R_SENT) {
- NFSTRACE4(NFSTRC_CWND_REQ2, rep->r_xid, rep, nmp->nm_sent,
- nmp->nm_cwnd);
+ FSDBG(531, rep->r_xid, rep, nmp->nm_sent, nmp->nm_cwnd);
rep->r_flags &= ~R_SENT; /* paranoia */
nmp->nm_sent -= NFS_CWNDSCALE;
}
dpos = rep->r_dpos;
if (error) {
m_freem(rep->r_mreq);
- NFSTRACE4(NFSTRC_REQERR, error, rep->r_xid, nmp, rep);
+ FSDBG_BOT(531, error, rep->r_xid, nmp, rep);
_FREE_ZONE((caddr_t)rep, sizeof (struct nfsreq), M_NFSREQ);
return (error);
}
error = EACCES;
m_freem(mrep);
m_freem(rep->r_mreq);
- NFSTRACE4(NFSTRC_RPCERR, error, rep->r_xid, nmp, rep);
+ FSDBG_BOT(531, error, rep->r_xid, nmp, rep);
_FREE_ZONE((caddr_t)rep, sizeof (struct nfsreq), M_NFSREQ);
return (error);
}
} else
m_freem(mrep);
m_freem(rep->r_mreq);
- NFSTRACE4(NFSTRC_DISSECTERR, error, rep->r_xid, nmp,
- rep);
+ FSDBG_BOT(531, error, rep->r_xid, nmp, rep);
_FREE_ZONE((caddr_t)rep,
sizeof (struct nfsreq), M_NFSREQ);
return (error);
*mdp = md;
*dposp = dpos;
m_freem(rep->r_mreq);
- NFSTRACE4(NFSTRC_REQFREE, 0xf0f0f0f0, rep->r_xid, nmp, rep);
+ FSDBG_BOT(531, 0xf0f0f0f0, rep->r_xid, nmp, rep);
FREE_ZONE((caddr_t)rep, sizeof (struct nfsreq), M_NFSREQ);
return (0);
}
error = EPROTONOSUPPORT;
nfsmout:
m_freem(rep->r_mreq);
- NFSTRACE4(NFSTRC_REQFREE, error, rep->r_xid, nmp, rep);
+ FSDBG_BOT(531, error, rep->r_xid, nmp, rep);
_FREE_ZONE((caddr_t)rep, sizeof (struct nfsreq), M_NFSREQ);
return (error);
}
{
rep->r_flags |= R_SOFTTERM;
if (rep->r_flags & R_SENT) {
- NFSTRACE4(NFSTRC_CWND_SOFT, rep->r_xid, rep,
- rep->r_nmp->nm_sent, rep->r_nmp->nm_cwnd);
+ FSDBG(532, rep->r_xid, rep, rep->r_nmp->nm_sent,
+ rep->r_nmp->nm_cwnd);
rep->r_nmp->nm_sent -= NFS_CWNDSCALE;
rep->r_flags &= ~R_SENT;
}
rep->r_flags |= R_SENT;
nmp->nm_sent += NFS_CWNDSCALE;
}
- NFSTRACE4(NFSTRC_CWND_TIMER, xid, rep,
- nmp->nm_sent, nmp->nm_cwnd);
+ FSDBG(535, xid, rep, nmp->nm_sent, nmp->nm_cwnd);
thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
- NFSTRACE4(NFSTRC_CWND_TIMER, xid, error, sent, cwnd);
+ FSDBG(535, xid, error, sent, cwnd);
/*
* This is to fix "nfs_sigintr" DSI panics.
* We may have slept during the send so the current
register struct proc *p;
{
+ struct uthread *ut;
+
+ ut = (struct uthread *)get_bsdthread_info(current_act());
+
if (rep && (rep->r_flags & R_SOFTTERM))
return (EINTR);
if (!(nmp->nm_flag & NFSMNT_INT))
return (0);
- if (p && p->p_siglist &&
- (((p->p_siglist & ~p->p_sigmask) & ~p->p_sigignore) &
+ if (p && ut && ut->uu_siglist &&
+ (((ut->uu_siglist & ~ut->uu_sigmask) & ~p->p_sigignore) &
NFSINT_SIGMASK))
return (EINTR);
return (0);
nfs_rcvlock(rep)
register struct nfsreq *rep;
{
- register int *flagp = &rep->r_nmp->nm_flag;
+ register int *flagp;
int slpflag, slptimeo = 0;
+ /* make sure we still have our mountpoint */
+ if (!rep->r_nmp) {
+ if (rep->r_mrep != NULL)
+ return (EALREADY);
+ return (ECONNABORTED);
+ }
+
+ flagp = &rep->r_nmp->nm_flag;
+ FSDBG_TOP(534, rep->r_xid, rep, rep->r_nmp, *flagp);
if (*flagp & NFSMNT_INT)
slpflag = PCATCH;
else
slpflag = 0;
while (*flagp & NFSMNT_RCVLOCK) {
if (nfs_sigintr(rep->r_nmp, rep, rep->r_procp)) {
- NFSTRACE4(NFSTRC_RCVLCKINTR, rep->r_xid, rep,
- rep->r_nmp, *flagp);
+ FSDBG_BOT(534, rep->r_xid, rep, rep->r_nmp, 0x100);
return (EINTR);
} else if (rep->r_mrep != NULL) {
/*
* Don't bother sleeping if reply already arrived
*/
- NFSTRACE4(NFSTRC_RCVALREADY, rep->r_xid, rep,
- rep->r_nmp, 1);
+ FSDBG_BOT(534, rep->r_xid, rep, rep->r_nmp, 0x101);
return (EALREADY);
}
- NFSTRACE4(NFSTRC_RCVLCKW, rep->r_xid, rep, rep->r_nmp, *flagp);
+ FSDBG(534, rep->r_xid, rep, rep->r_nmp, 0x102);
*flagp |= NFSMNT_WANTRCV;
(void) tsleep((caddr_t)flagp, slpflag | (PZERO - 1), "nfsrcvlk",
slptimeo);
}
/*
* Make sure while we slept that the mountpoint didn't go away.
- * nfs_sigintr and caller nfs_reply expect it in tact.
+ * nfs_sigintr and caller nfs_reply expect it intact.
*/
- if (!rep->r_nmp)
+ if (!rep->r_nmp) {
+ FSDBG_BOT(534, rep->r_xid, rep, rep->r_nmp, 0x103);
return (ECONNABORTED); /* don't have lock until out of loop */
+ }
}
/*
* nfs_reply will handle it if reply already arrived.
* (We may have slept or been preempted while on network funnel).
*/
- NFSTRACE4(NFSTRC_RCVLCK, rep->r_xid, rep, rep->r_nmp, *flagp);
+ FSDBG_BOT(534, rep->r_xid, rep, rep->r_nmp, *flagp);
*flagp |= NFSMNT_RCVLOCK;
return (0);
}
register int *flagp;
{
+ FSDBG(533, flagp, *flagp, 0, 0);
if ((*flagp & NFSMNT_RCVLOCK) == 0)
panic("nfs rcvunlock");
*flagp &= ~NFSMNT_RCVLOCK;
if (*flagp & NFSMNT_WANTRCV) {
- NFSTRACE(NFSTRC_RCVUNLW, flagp);
*flagp &= ~NFSMNT_WANTRCV;
wakeup((caddr_t)flagp);
- } else {
- NFSTRACE(NFSTRC_RCVUNL, flagp);
}
}
register struct mbuf *m, **mpp;
register char *cp1, *cp2;
register int len;
- struct mbuf *om, *m2, *recm = 0;
+ struct mbuf *om, *m2, *recm;
u_long recmark;
if (slp->ns_flag & SLP_GETSTREAM)
/*
* Now get the record part.
+ *
+ * Note that slp->ns_reclen may be 0. Linux sometimes
+ * generates 0-length RPCs
*/
+ recm = NULL;
if (slp->ns_cc == slp->ns_reclen) {
recm = slp->ns_raw;
slp->ns_raw = slp->ns_rawend = (struct mbuf *)0;