From 8969d48c6a2e21220ae7000e4c28ee28457f6cfb Mon Sep 17 00:00:00 2001 From: jhb Date: Fri, 28 Jun 2002 21:53:08 +0000 Subject: In namei(), we use a NULL thread for uio_td when doing a VOP_READLINK(). nfs_readlink() calls nfs_bioread() which passes in uio_td as the thread argument to nfs_getcacheblk(). In nfs_getcacheblk() we dereference the thread pointer to get a process pointer to pass to nfs_sigintr(). This obviously results in a panic. :) Rather than change nfs_getcacheblk() to check if the thread pointer is NULL when calling nfs_sigintr() like other callers do, change nfs_sigintr() to take a thread as the last argument instead of a process so none of the callers have to care if the thread is NULL or not. --- sys/nfsclient/nfs.h | 2 +- sys/nfsclient/nfs_bio.c | 8 ++++---- sys/nfsclient/nfs_socket.c | 17 ++++++++--------- sys/nfsclient/nfs_vnops.c | 4 ++-- 4 files changed, 15 insertions(+), 16 deletions(-) (limited to 'sys') diff --git a/sys/nfsclient/nfs.h b/sys/nfsclient/nfs.h index 8836eb4..1be8608 100644 --- a/sys/nfsclient/nfs.h +++ b/sys/nfsclient/nfs.h @@ -267,7 +267,7 @@ int nfs_nfsiodnew(void); int nfs_asyncio(struct buf *, struct ucred *, struct thread *); int nfs_doio(struct buf *, struct ucred *, struct thread *); int nfs_readlinkrpc(struct vnode *, struct uio *, struct ucred *); -int nfs_sigintr(struct nfsmount *, struct nfsreq *, struct proc *); +int nfs_sigintr(struct nfsmount *, struct nfsreq *, struct thread *); int nfs_readdirplusrpc(struct vnode *, struct uio *, struct ucred *); int nfs_request(struct vnode *, struct mbuf *, int, struct thread *, struct ucred *, struct mbuf **, struct mbuf **, caddr_t *); diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index 40fac72..897346d 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -1026,7 +1026,7 @@ nfs_getcacheblk(struct vnode *vp, daddr_t bn, int size, struct thread *td) if (nmp->nm_flag & NFSMNT_INT) { bp = getblk(vp, bn, size, PCATCH, 0); while (bp == (struct buf *)0) { - if (nfs_sigintr(nmp, (struct nfsreq *)0, td->td_proc)) + if (nfs_sigintr(nmp, (struct nfsreq *)0, td)) return ((struct buf *)0); bp = getblk(vp, bn, size, 0, 2 * hz); } @@ -1076,7 +1076,7 @@ nfs_vinvalbuf(struct vnode *vp, int flags, struct ucred *cred, error = tsleep((caddr_t)&np->n_flag, PRIBIO + 2, "nfsvinval", slptimeo); if (error && intrflg && - nfs_sigintr(nmp, (struct nfsreq *)0, td->td_proc)) + nfs_sigintr(nmp, (struct nfsreq *)0, td)) return (EINTR); } @@ -1087,7 +1087,7 @@ nfs_vinvalbuf(struct vnode *vp, int flags, struct ucred *cred, error = vinvalbuf(vp, flags, cred, td, slpflag, 0); while (error) { if (intrflg && - nfs_sigintr(nmp, (struct nfsreq *)0, td->td_proc)) { + nfs_sigintr(nmp, (struct nfsreq *)0, td)) { np->n_flag &= ~NFLUSHINPROG; if (np->n_flag & NFLUSHWANT) { np->n_flag &= ~NFLUSHWANT; @@ -1200,7 +1200,7 @@ again: error = tsleep(&nmp->nm_bufq, slpflag | PRIBIO, "nfsaio", slptimeo); if (error) { - if (nfs_sigintr(nmp, NULL, td ? td->td_proc : NULL)) + if (nfs_sigintr(nmp, NULL, td)) return (EINTR); if (slpflag == PCATCH) { slpflag = 0; diff --git a/sys/nfsclient/nfs_socket.c b/sys/nfsclient/nfs_socket.c index be0063c..ef65b43 100644 --- a/sys/nfsclient/nfs_socket.c +++ b/sys/nfsclient/nfs_socket.c @@ -235,8 +235,7 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep) PSOCK, "nfscon", 2 * hz); if ((so->so_state & SS_ISCONNECTING) && so->so_error == 0 && rep && - (error = nfs_sigintr(nmp, rep, - (rep->r_td ? rep->r_td->td_proc : NULL))) != 0){ + (error = nfs_sigintr(nmp, rep, rep->r_td)) != 0) { so->so_state &= ~SS_ISCONNECTING; splx(s); goto bad; @@ -1075,8 +1074,7 @@ nfs_timer(void *arg) nmp = rep->r_nmp; if (rep->r_mrep || (rep->r_flags & R_SOFTTERM)) continue; - if (nfs_sigintr(nmp, rep, - (rep->r_td ? rep->r_td->td_proc : NULL))) { + if (nfs_sigintr(nmp, rep, rep->r_td)) { nfs_softterm(rep); continue; } @@ -1224,8 +1222,9 @@ nfs_softterm(struct nfsreq *rep) * This is used for NFSMNT_INT mounts. */ int -nfs_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct proc *p) +nfs_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct thread *td) { + struct proc *p; sigset_t tmpset; if (rep && (rep->r_flags & R_SOFTTERM)) @@ -1235,9 +1234,10 @@ nfs_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct proc *p) return (EINTR); if (!(nmp->nm_flag & NFSMNT_INT)) return (0); - if (p == NULL) + if (td == NULL) return (0); + p = td->td_proc; tmpset = p->p_siglist; SIGSETNAND(tmpset, p->p_sigmask); SIGSETNAND(tmpset, p->p_sigignore); @@ -1267,7 +1267,7 @@ nfs_sndlock(struct nfsreq *rep) } else td = (struct thread *)0; while (*statep & NFSSTA_SNDLOCK) { - if (nfs_sigintr(rep->r_nmp, rep, td ? td->td_proc : NULL)) + if (nfs_sigintr(rep->r_nmp, rep, td)) return (EINTR); *statep |= NFSSTA_WANTSND; (void) tsleep((caddr_t)statep, slpflag | (PZERO - 1), @@ -1309,8 +1309,7 @@ nfs_rcvlock(struct nfsreq *rep) else slpflag = 0; while (*statep & NFSSTA_RCVLOCK) { - if (nfs_sigintr(rep->r_nmp, rep, - (rep->r_td ? rep->r_td->td_proc : NULL))) + if (nfs_sigintr(rep->r_nmp, rep, rep->r_td)) return (EINTR); *statep |= NFSSTA_WANTRCV; (void) tsleep((caddr_t)statep, slpflag | (PZERO - 1), "nfsrcvlk", diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index d9bdcea..c1daf57 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -2776,7 +2776,7 @@ loop: panic("nfs_fsync: inconsistent lock"); if (error == ENOLCK) goto loop; - if (nfs_sigintr(nmp, (struct nfsreq *)0, td->td_proc)) { + if (nfs_sigintr(nmp, (struct nfsreq *)0, td)) { error = EINTR; goto done; } @@ -2812,7 +2812,7 @@ loop: error = tsleep((caddr_t)&vp->v_numoutput, slpflag | (PRIBIO + 1), "nfsfsync", slptimeo); if (error) { - if (nfs_sigintr(nmp, (struct nfsreq *)0, td->td_proc)) { + if (nfs_sigintr(nmp, (struct nfsreq *)0, td)) { error = EINTR; goto done; } -- cgit v1.1