Pushdown Giant for nfs syscalls (nfssvc())

This commit is contained in:
Matthew Dillon 2001-08-31 22:39:36 +00:00
parent 2afac34da3
commit 4e174404a3
3 changed files with 69 additions and 36 deletions

View File

@ -136,6 +136,9 @@ struct nfssvc_args {
caddr_t argp; caddr_t argp;
}; };
#endif #endif
/*
* MPSAFE
*/
int int
nfssvc(p, uap) nfssvc(p, uap)
struct proc *p; struct proc *p;
@ -155,18 +158,22 @@ nfssvc(p, uap)
#endif /* NFS_NOSERVER */ #endif /* NFS_NOSERVER */
int error; int error;
mtx_lock(&Giant);
if ((uap->flag & NFSSVC_LOCKDANS) != 0) { if ((uap->flag & NFSSVC_LOCKDANS) != 0) {
struct lockd_ans la; struct lockd_ans la;
error = copyin(uap->argp, &la, sizeof(la)); error = copyin(uap->argp, &la, sizeof(la));
return (error != 0 ? error : nfslockdans(p, &la)); if (error == 0)
error = nfslockdans(p, &la);
goto done2;
} }
/* /*
* Must be super user * Must be super user
*/ */
error = suser(p); error = suser(p);
if(error) if (error)
return (error); goto done2;
while (nfssvc_sockhead_flag & SLP_INIT) { while (nfssvc_sockhead_flag & SLP_INIT) {
nfssvc_sockhead_flag |= SLP_WANTINIT; nfssvc_sockhead_flag |= SLP_WANTINIT;
(void) tsleep((caddr_t)&nfssvc_sockhead, PSOCK, "nfsd init", 0); (void) tsleep((caddr_t)&nfssvc_sockhead, PSOCK, "nfsd init", 0);
@ -180,32 +187,34 @@ nfssvc(p, uap)
else if (uap->flag & NFSSVC_MNTD) { else if (uap->flag & NFSSVC_MNTD) {
error = copyin(uap->argp, (caddr_t)&ncd, sizeof (ncd)); error = copyin(uap->argp, (caddr_t)&ncd, sizeof (ncd));
if (error) if (error)
return (error); goto done2;
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
ncd.ncd_dirp, p); ncd.ncd_dirp, p);
error = namei(&nd); error = namei(&nd);
if (error) if (error)
return (error); goto done2;
NDFREE(&nd, NDF_ONLY_PNBUF); NDFREE(&nd, NDF_ONLY_PNBUF);
if ((nd.ni_vp->v_flag & VROOT) == 0) if ((nd.ni_vp->v_flag & VROOT) == 0)
error = EINVAL; error = EINVAL;
nmp = VFSTONFS(nd.ni_vp->v_mount); nmp = VFSTONFS(nd.ni_vp->v_mount);
vput(nd.ni_vp); vput(nd.ni_vp);
if (error) if (error)
return (error); goto done2;
if ((nmp->nm_state & NFSSTA_MNTD) && if ((nmp->nm_state & NFSSTA_MNTD) &&
(uap->flag & NFSSVC_GOTAUTH) == 0) (uap->flag & NFSSVC_GOTAUTH) == 0) {
return (0); error = 0;
goto done2;
}
nmp->nm_state |= NFSSTA_MNTD; nmp->nm_state |= NFSSTA_MNTD;
error = nqnfs_clientd(nmp, p->p_ucred, &ncd, uap->flag, error = nqnfs_clientd(nmp, p->p_ucred, &ncd, uap->flag,
uap->argp, p); uap->argp, p);
} else if (uap->flag & NFSSVC_ADDSOCK) { } else if (uap->flag & NFSSVC_ADDSOCK) {
error = copyin(uap->argp, (caddr_t)&nfsdarg, sizeof(nfsdarg)); error = copyin(uap->argp, (caddr_t)&nfsdarg, sizeof(nfsdarg));
if (error) if (error)
return (error); goto done2;
error = holdsock(p->p_fd, nfsdarg.sock, &fp); error = holdsock(p->p_fd, nfsdarg.sock, &fp);
if (error) if (error)
return (error); goto done2;
/* /*
* Get the client address for connected sockets. * Get the client address for connected sockets.
*/ */
@ -216,7 +225,7 @@ nfssvc(p, uap)
nfsdarg.namelen); nfsdarg.namelen);
if (error) { if (error) {
fdrop(fp, p); fdrop(fp, p);
return (error); goto done2;
} }
} }
error = nfssvc_addsock(fp, nam, p); error = nfssvc_addsock(fp, nam, p);
@ -224,7 +233,7 @@ nfssvc(p, uap)
} else { } else {
error = copyin(uap->argp, (caddr_t)nsd, sizeof (*nsd)); error = copyin(uap->argp, (caddr_t)nsd, sizeof (*nsd));
if (error) if (error)
return (error); goto done2;
if ((uap->flag & NFSSVC_AUTHIN) && if ((uap->flag & NFSSVC_AUTHIN) &&
((nfsd = nsd->nsd_nfsd)) != NULL && ((nfsd = nsd->nsd_nfsd)) != NULL &&
(nfsd->nfsd_slp->ns_flag & SLP_VALID)) { (nfsd->nfsd_slp->ns_flag & SLP_VALID)) {
@ -323,6 +332,8 @@ nfssvc(p, uap)
#endif /* NFS_NOSERVER */ #endif /* NFS_NOSERVER */
if (error == EINTR || error == ERESTART) if (error == EINTR || error == ERESTART)
error = 0; error = 0;
done2:
mtx_unlock(&Giant);
return (error); return (error);
} }

View File

@ -136,6 +136,9 @@ struct nfssvc_args {
caddr_t argp; caddr_t argp;
}; };
#endif #endif
/*
* MPSAFE
*/
int int
nfssvc(p, uap) nfssvc(p, uap)
struct proc *p; struct proc *p;
@ -155,18 +158,22 @@ nfssvc(p, uap)
#endif /* NFS_NOSERVER */ #endif /* NFS_NOSERVER */
int error; int error;
mtx_lock(&Giant);
if ((uap->flag & NFSSVC_LOCKDANS) != 0) { if ((uap->flag & NFSSVC_LOCKDANS) != 0) {
struct lockd_ans la; struct lockd_ans la;
error = copyin(uap->argp, &la, sizeof(la)); error = copyin(uap->argp, &la, sizeof(la));
return (error != 0 ? error : nfslockdans(p, &la)); if (error == 0)
error = nfslockdans(p, &la);
goto done2;
} }
/* /*
* Must be super user * Must be super user
*/ */
error = suser(p); error = suser(p);
if(error) if (error)
return (error); goto done2;
while (nfssvc_sockhead_flag & SLP_INIT) { while (nfssvc_sockhead_flag & SLP_INIT) {
nfssvc_sockhead_flag |= SLP_WANTINIT; nfssvc_sockhead_flag |= SLP_WANTINIT;
(void) tsleep((caddr_t)&nfssvc_sockhead, PSOCK, "nfsd init", 0); (void) tsleep((caddr_t)&nfssvc_sockhead, PSOCK, "nfsd init", 0);
@ -180,32 +187,34 @@ nfssvc(p, uap)
else if (uap->flag & NFSSVC_MNTD) { else if (uap->flag & NFSSVC_MNTD) {
error = copyin(uap->argp, (caddr_t)&ncd, sizeof (ncd)); error = copyin(uap->argp, (caddr_t)&ncd, sizeof (ncd));
if (error) if (error)
return (error); goto done2;
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
ncd.ncd_dirp, p); ncd.ncd_dirp, p);
error = namei(&nd); error = namei(&nd);
if (error) if (error)
return (error); goto done2;
NDFREE(&nd, NDF_ONLY_PNBUF); NDFREE(&nd, NDF_ONLY_PNBUF);
if ((nd.ni_vp->v_flag & VROOT) == 0) if ((nd.ni_vp->v_flag & VROOT) == 0)
error = EINVAL; error = EINVAL;
nmp = VFSTONFS(nd.ni_vp->v_mount); nmp = VFSTONFS(nd.ni_vp->v_mount);
vput(nd.ni_vp); vput(nd.ni_vp);
if (error) if (error)
return (error); goto done2;
if ((nmp->nm_state & NFSSTA_MNTD) && if ((nmp->nm_state & NFSSTA_MNTD) &&
(uap->flag & NFSSVC_GOTAUTH) == 0) (uap->flag & NFSSVC_GOTAUTH) == 0) {
return (0); error = 0;
goto done2;
}
nmp->nm_state |= NFSSTA_MNTD; nmp->nm_state |= NFSSTA_MNTD;
error = nqnfs_clientd(nmp, p->p_ucred, &ncd, uap->flag, error = nqnfs_clientd(nmp, p->p_ucred, &ncd, uap->flag,
uap->argp, p); uap->argp, p);
} else if (uap->flag & NFSSVC_ADDSOCK) { } else if (uap->flag & NFSSVC_ADDSOCK) {
error = copyin(uap->argp, (caddr_t)&nfsdarg, sizeof(nfsdarg)); error = copyin(uap->argp, (caddr_t)&nfsdarg, sizeof(nfsdarg));
if (error) if (error)
return (error); goto done2;
error = holdsock(p->p_fd, nfsdarg.sock, &fp); error = holdsock(p->p_fd, nfsdarg.sock, &fp);
if (error) if (error)
return (error); goto done2;
/* /*
* Get the client address for connected sockets. * Get the client address for connected sockets.
*/ */
@ -216,7 +225,7 @@ nfssvc(p, uap)
nfsdarg.namelen); nfsdarg.namelen);
if (error) { if (error) {
fdrop(fp, p); fdrop(fp, p);
return (error); goto done2;
} }
} }
error = nfssvc_addsock(fp, nam, p); error = nfssvc_addsock(fp, nam, p);
@ -224,7 +233,7 @@ nfssvc(p, uap)
} else { } else {
error = copyin(uap->argp, (caddr_t)nsd, sizeof (*nsd)); error = copyin(uap->argp, (caddr_t)nsd, sizeof (*nsd));
if (error) if (error)
return (error); goto done2;
if ((uap->flag & NFSSVC_AUTHIN) && if ((uap->flag & NFSSVC_AUTHIN) &&
((nfsd = nsd->nsd_nfsd)) != NULL && ((nfsd = nsd->nsd_nfsd)) != NULL &&
(nfsd->nfsd_slp->ns_flag & SLP_VALID)) { (nfsd->nfsd_slp->ns_flag & SLP_VALID)) {
@ -323,6 +332,8 @@ nfssvc(p, uap)
#endif /* NFS_NOSERVER */ #endif /* NFS_NOSERVER */
if (error == EINTR || error == ERESTART) if (error == EINTR || error == ERESTART)
error = 0; error = 0;
done2:
mtx_unlock(&Giant);
return (error); return (error);
} }

View File

@ -136,6 +136,9 @@ struct nfssvc_args {
caddr_t argp; caddr_t argp;
}; };
#endif #endif
/*
* MPSAFE
*/
int int
nfssvc(p, uap) nfssvc(p, uap)
struct proc *p; struct proc *p;
@ -155,18 +158,22 @@ nfssvc(p, uap)
#endif /* NFS_NOSERVER */ #endif /* NFS_NOSERVER */
int error; int error;
mtx_lock(&Giant);
if ((uap->flag & NFSSVC_LOCKDANS) != 0) { if ((uap->flag & NFSSVC_LOCKDANS) != 0) {
struct lockd_ans la; struct lockd_ans la;
error = copyin(uap->argp, &la, sizeof(la)); error = copyin(uap->argp, &la, sizeof(la));
return (error != 0 ? error : nfslockdans(p, &la)); if (error == 0)
error = nfslockdans(p, &la);
goto done2;
} }
/* /*
* Must be super user * Must be super user
*/ */
error = suser(p); error = suser(p);
if(error) if (error)
return (error); goto done2;
while (nfssvc_sockhead_flag & SLP_INIT) { while (nfssvc_sockhead_flag & SLP_INIT) {
nfssvc_sockhead_flag |= SLP_WANTINIT; nfssvc_sockhead_flag |= SLP_WANTINIT;
(void) tsleep((caddr_t)&nfssvc_sockhead, PSOCK, "nfsd init", 0); (void) tsleep((caddr_t)&nfssvc_sockhead, PSOCK, "nfsd init", 0);
@ -180,32 +187,34 @@ nfssvc(p, uap)
else if (uap->flag & NFSSVC_MNTD) { else if (uap->flag & NFSSVC_MNTD) {
error = copyin(uap->argp, (caddr_t)&ncd, sizeof (ncd)); error = copyin(uap->argp, (caddr_t)&ncd, sizeof (ncd));
if (error) if (error)
return (error); goto done2;
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
ncd.ncd_dirp, p); ncd.ncd_dirp, p);
error = namei(&nd); error = namei(&nd);
if (error) if (error)
return (error); goto done2;
NDFREE(&nd, NDF_ONLY_PNBUF); NDFREE(&nd, NDF_ONLY_PNBUF);
if ((nd.ni_vp->v_flag & VROOT) == 0) if ((nd.ni_vp->v_flag & VROOT) == 0)
error = EINVAL; error = EINVAL;
nmp = VFSTONFS(nd.ni_vp->v_mount); nmp = VFSTONFS(nd.ni_vp->v_mount);
vput(nd.ni_vp); vput(nd.ni_vp);
if (error) if (error)
return (error); goto done2;
if ((nmp->nm_state & NFSSTA_MNTD) && if ((nmp->nm_state & NFSSTA_MNTD) &&
(uap->flag & NFSSVC_GOTAUTH) == 0) (uap->flag & NFSSVC_GOTAUTH) == 0) {
return (0); error = 0;
goto done2;
}
nmp->nm_state |= NFSSTA_MNTD; nmp->nm_state |= NFSSTA_MNTD;
error = nqnfs_clientd(nmp, p->p_ucred, &ncd, uap->flag, error = nqnfs_clientd(nmp, p->p_ucred, &ncd, uap->flag,
uap->argp, p); uap->argp, p);
} else if (uap->flag & NFSSVC_ADDSOCK) { } else if (uap->flag & NFSSVC_ADDSOCK) {
error = copyin(uap->argp, (caddr_t)&nfsdarg, sizeof(nfsdarg)); error = copyin(uap->argp, (caddr_t)&nfsdarg, sizeof(nfsdarg));
if (error) if (error)
return (error); goto done2;
error = holdsock(p->p_fd, nfsdarg.sock, &fp); error = holdsock(p->p_fd, nfsdarg.sock, &fp);
if (error) if (error)
return (error); goto done2;
/* /*
* Get the client address for connected sockets. * Get the client address for connected sockets.
*/ */
@ -216,7 +225,7 @@ nfssvc(p, uap)
nfsdarg.namelen); nfsdarg.namelen);
if (error) { if (error) {
fdrop(fp, p); fdrop(fp, p);
return (error); goto done2;
} }
} }
error = nfssvc_addsock(fp, nam, p); error = nfssvc_addsock(fp, nam, p);
@ -224,7 +233,7 @@ nfssvc(p, uap)
} else { } else {
error = copyin(uap->argp, (caddr_t)nsd, sizeof (*nsd)); error = copyin(uap->argp, (caddr_t)nsd, sizeof (*nsd));
if (error) if (error)
return (error); goto done2;
if ((uap->flag & NFSSVC_AUTHIN) && if ((uap->flag & NFSSVC_AUTHIN) &&
((nfsd = nsd->nsd_nfsd)) != NULL && ((nfsd = nsd->nsd_nfsd)) != NULL &&
(nfsd->nfsd_slp->ns_flag & SLP_VALID)) { (nfsd->nfsd_slp->ns_flag & SLP_VALID)) {
@ -323,6 +332,8 @@ nfssvc(p, uap)
#endif /* NFS_NOSERVER */ #endif /* NFS_NOSERVER */
if (error == EINTR || error == ERESTART) if (error == EINTR || error == ERESTART)
error = 0; error = 0;
done2:
mtx_unlock(&Giant);
return (error); return (error);
} }