NFS Jumbo commit part 1. Cosmetic and structural changes only. The aim

of this part of commits is to minimize unnecessary differences between
the other NFS's of similar origin.  Yes, there are gratuitous changes here
that the style folks won't like, but it makes the catch-up less difficult.
This commit is contained in:
Peter Wemm 1998-05-31 17:27:58 +00:00
parent 8422d3119c
commit e8cf20c8db
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=36503
29 changed files with 1852 additions and 1713 deletions

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
* $Id: nfs.h,v 1.35 1998/05/19 07:11:22 peter Exp $
* $Id: nfs.h,v 1.36 1998/05/24 14:41:47 peter Exp $
*/
#ifndef _NFS_NFS_H_
@ -293,14 +293,6 @@ struct nfsstats {
{ "nfsprivport", CTLTYPE_INT }, \
}
/*
* Network address hash list element
*/
union nethostaddr {
u_long had_inetaddr;
struct sockaddr *had_nam;
};
#ifdef KERNEL
#ifdef MALLOC_DECLARE
@ -399,6 +391,14 @@ extern TAILQ_HEAD(nfs_reqq, nfsreq) nfs_reqq;
#define NFSNOHASH(fhsum) \
(&nfsnodehashtbl[(fhsum) & nfsnodehash])
/*
* Network address hash list element
*/
union nethostaddr {
u_long had_inetaddr;
struct sockaddr *had_nam;
};
struct nfsuid {
TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */
LIST_ENTRY(nfsuid) nu_hash; /* Hash list */

View File

@ -33,8 +33,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
* $Id: nfs_subs.c,v 1.54 1998/05/19 07:11:24 peter Exp $
* @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95
* $Id: nfs_subs.c,v 1.55 1998/05/24 14:41:53 peter Exp $
*/
/*
@ -2129,4 +2129,45 @@ nfsrv_object_create(vp)
return (vfs_object_create(vp, curproc,
curproc ? curproc->p_ucred : NULL, 1));
}
/*
* Sort the group list in increasing numerical order.
* (Insertion sort by Chris Torek, who was grossed out by the bubble sort
* that used to be here.)
*/
void
nfsrvw_sort(list, num)
register gid_t *list;
register int num;
{
register int i, j;
gid_t v;
/* Insertion sort. */
for (i = 1; i < num; i++) {
v = list[i];
/* find correct slot for value v, moving others up */
for (j = i; --j >= 0 && v < list[j];)
list[j + 1] = list[j];
list[j + 1] = v;
}
}
/*
* copy credentials making sure that the result can be compared with bcmp().
*/
void
nfsrv_setcred(incred, outcred)
register struct ucred *incred, *outcred;
{
register int i;
bzero((caddr_t)outcred, sizeof (struct ucred));
outcred->cr_ref = 1;
outcred->cr_uid = incred->cr_uid;
outcred->cr_ngroups = incred->cr_ngroups;
for (i = 0; i < incred->cr_ngroups; i++)
outcred->cr_groups[i] = incred->cr_groups[i];
nfsrvw_sort(outcred->cr_groups, outcred->cr_ngroups);
}
#endif /* NFS_NOSERVER */

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfsm_subs.h 8.2 (Berkeley) 3/30/95
* $Id: nfsm_subs.h,v 1.15 1998/03/30 09:54:41 phk Exp $
* $Id: nfsm_subs.h,v 1.16 1998/05/16 15:11:24 bde Exp $
*/
@ -105,7 +105,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
if (t1 >= (s)) { \
(a) = (c)(dpos); \
dpos += (s); \
} else if (t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) { \
} else if ((t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) != 0){ \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
@ -122,8 +122,9 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
*(tl + ((t2>>2) - 2)) = 0; \
bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \
VTONFS(v)->n_fhsize); \
} else if (t2 = nfsm_strtmbuf(&mb, &bpos, \
(caddr_t)VTONFS(v)->n_fhp, VTONFS(v)->n_fhsize)) { \
} else if ((t2 = nfsm_strtmbuf(&mb, &bpos, \
(caddr_t)VTONFS(v)->n_fhp, \
VTONFS(v)->n_fhsize)) != 0) { \
error = t2; \
m_freem(mreq); \
goto nfsmout; \
@ -159,8 +160,8 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
(f) = 1; \
if (f) { \
nfsm_getfh(ttfhp, ttfhsize, (v3)); \
if (t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
&ttnp)) { \
if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
&ttnp)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
@ -193,7 +194,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
#define nfsm_loadattr(v, a) \
{ struct vnode *ttvp = (v); \
if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) { \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
@ -204,8 +205,8 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
{ struct vnode *ttvp = (v); \
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
if ((f) = fxdr_unsigned(int, *tl)) { \
if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
(struct vattr *)0)) { \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
(struct vattr *)0)) != 0) { \
error = t1; \
(f) = 0; \
m_freem(mrep); \
@ -275,14 +276,14 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
#define nfsm_mtouio(p,s) \
if ((s) > 0 && \
(t1 = nfsm_mbuftouio(&md,(p),(s),&dpos))) { \
(t1 = nfsm_mbuftouio(&md,(p),(s),&dpos)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
}
#define nfsm_uiotom(p,s) \
if (t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) { \
if ((t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) != 0) { \
error = t1; \
m_freem(mreq); \
goto nfsmout; \
@ -297,8 +298,8 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
#define nfsm_rndup(a) (((a)+3)&(~0x3))
#define nfsm_request(v, t, p, c) \
if (error = nfs_request((v), mreq, (t), (p), \
(c), &mrep, &md, &dpos)) { \
if ((error = nfs_request((v), mreq, (t), (p), \
(c), &mrep, &md, &dpos)) != 0) { \
if (error & NFSERR_RETERR) \
error &= ~NFSERR_RETERR; \
else \
@ -317,7 +318,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
*tl++ = txdr_unsigned(s); \
*(tl+((t2>>2)-2)) = 0; \
bcopy((caddr_t)(a), (caddr_t)tl, (s)); \
} else if (t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) { \
} else if ((t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) != 0) { \
error = t2; \
m_freem(mreq); \
goto nfsmout; \
@ -358,7 +359,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
{ t1 = mtod(md, caddr_t)+md->m_len-dpos; \
if (t1 >= (s)) { \
dpos += (s); \
} else if (t1 = nfs_adv(&md, &dpos, (s), t1)) { \
} else if ((t1 = nfs_adv(&md, &dpos, (s), t1)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_nqlease.c 8.9 (Berkeley) 5/20/95
* $Id: nfs_nqlease.c,v 1.34 1998/05/19 07:11:23 peter Exp $
* $Id: nfs_nqlease.c,v 1.35 1998/05/24 14:41:51 peter Exp $
*/
@ -199,8 +199,7 @@ nqsrv_getlease(vp, duration, flags, slp, procp, nam, cachablep, frev, cred)
tlp = vp->v_lease;
if ((flags & ND_CHECK) == 0)
nfsstats.srvnqnfs_getleases++;
if (tlp == (struct nqlease *)0) {
if (tlp == 0) {
/*
* Find the lease by searching the hash list.
*/
@ -224,7 +223,7 @@ nqsrv_getlease(vp, duration, flags, slp, procp, nam, cachablep, frev, cred)
}
} else
lp = tlp;
if (lp) {
if (lp != 0) {
if ((lp->lc_flag & LC_NONCACHABLE) ||
(lp->lc_morehosts == (struct nqm *)0 &&
nqsrv_cmpnam(slp, nam, &lp->lc_host)))
@ -820,7 +819,7 @@ nqnfsrv_vacated(nfsd, slp, procp, mrq)
tlp = lp;
break;
}
if (tlp) {
if (tlp != 0) {
lp = tlp;
len = 1;
i = 0;

View File

@ -33,8 +33,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfs_serv.c 8.3 (Berkeley) 1/12/94
* $Id: nfs_serv.c,v 1.61 1998/05/20 09:05:48 peter Exp $
* @(#)nfs_serv.c 8.8 (Berkeley) 7/31/95
* $Id: nfs_serv.c,v 1.62 1998/05/30 16:33:56 peter Exp $
*/
/*
@ -140,8 +140,9 @@ nfsrv3_access(nfsd, slp, procp, mrq)
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly,
(nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(NFSX_UNSIGNED);
nfsm_srvpostop_attr(1, (struct vattr *)0);
return (0);
@ -204,8 +205,9 @@ nfsrv_getattr(nfsd, slp, procp, mrq)
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(0);
return (0);
}
@ -296,8 +298,9 @@ nfsrv_setattr(nfsd, slp, procp, mrq)
/*
* Now that we have all the fields, lets do it.
*/
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly,
(nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(2 * NFSX_UNSIGNED);
nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap);
return (0);
@ -330,8 +333,8 @@ nfsrv_setattr(nfsd, slp, procp, mrq)
if (vp->v_type == VDIR) {
error = EISDIR;
goto out;
} else if (error = nfsrv_access(vp, VWRITE, cred, rdonly,
procp, 0))
} else if ((error = nfsrv_access(vp, VWRITE, cred, rdonly,
procp, 0)) != 0)
goto out;
}
error = VOP_SETATTR(vp, vap, cred, procp);
@ -537,8 +540,9 @@ nfsrv_readlink(nfsd, slp, procp, mrq)
uiop->uio_rw = UIO_READ;
uiop->uio_segflg = UIO_SYSSPACE;
uiop->uio_procp = (struct proc *)0;
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
m_freem(mp3);
nfsm_reply(2 * NFSX_UNSIGNED);
nfsm_srvpostop_attr(1, (struct vattr *)0);
@ -620,8 +624,9 @@ nfsrv_read(nfsd, slp, procp, mrq)
off = (off_t)fxdr_unsigned(u_long, *tl);
}
nfsm_srvstrsiz(reqlen, NFS_SRVMAXDATA(nfsd));
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(2 * NFSX_UNSIGNED);
nfsm_srvpostop_attr(1, (struct vattr *)0);
return (0);
@ -634,7 +639,7 @@ nfsrv_read(nfsd, slp, procp, mrq)
}
if (!error) {
nqsrv_getl(vp, ND_READ);
if (error = nfsrv_access(vp, VREAD, cred, rdonly, procp, 1))
if ((error = nfsrv_access(vp, VREAD, cred, rdonly, procp, 1)) != 0)
error = nfsrv_access(vp, VEXEC, cred, rdonly, procp, 1);
}
getret = VOP_GETATTR(vp, vap, cred, procp);
@ -834,8 +839,9 @@ nfsrv_write(nfsd, slp, procp, mrq)
nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap);
return (0);
}
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(2 * NFSX_UNSIGNED);
nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap);
return (0);
@ -1303,47 +1309,6 @@ nfsrvw_coalesce(owp, nfsd)
}
}
/*
* Sort the group list in increasing numerical order.
* (Insertion sort by Chris Torek, who was grossed out by the bubble sort
* that used to be here.)
*/
void
nfsrvw_sort(list, num)
register gid_t *list;
register int num;
{
register int i, j;
gid_t v;
/* Insertion sort. */
for (i = 1; i < num; i++) {
v = list[i];
/* find correct slot for value v, moving others up */
for (j = i; --j >= 0 && v < list[j];)
list[j + 1] = list[j];
list[j + 1] = v;
}
}
/*
* copy credentials making sure that the result can be compared with bcmp().
*/
void
nfsrv_setcred(incred, outcred)
register struct ucred *incred, *outcred;
{
register int i;
bzero((caddr_t)outcred, sizeof (struct ucred));
outcred->cr_ref = 1;
outcred->cr_uid = incred->cr_uid;
outcred->cr_ngroups = incred->cr_ngroups;
for (i = 0; i < incred->cr_ngroups; i++)
outcred->cr_groups[i] = incred->cr_groups[i];
nfsrvw_sort(outcred->cr_groups, outcred->cr_ngroups);
}
/*
* nfs create service
* now does a truncate to 0 length via. setattr if it already exists
@ -1445,6 +1410,8 @@ nfsrv_create(nfsd, slp, procp, mrq)
case VFIFO:
rdev = fxdr_unsigned(long, sp->sa_size);
break;
default:
break;
};
}
@ -1496,7 +1463,7 @@ nfsrv_create(nfsd, slp, procp, mrq)
nd.ni_cnd.cn_flags &= ~(LOCKPARENT | SAVESTART);
nd.ni_cnd.cn_proc = procp;
nd.ni_cnd.cn_cred = cred;
if (error = lookup(&nd)) {
if ((error = lookup(&nd)) != 0) {
zfree(namei_zone, nd.ni_cnd.cn_pnbuf);
nfsm_reply(0);
}
@ -1801,9 +1768,7 @@ nfsrv_remove(nfsd, slp, procp, mrq)
if (!error) {
nqsrv_getl(nd.ni_dvp, ND_WRITE);
nqsrv_getl(vp, ND_WRITE);
error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
} else {
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
}
@ -2065,8 +2030,9 @@ nfsrv_link(nfsd, slp, procp, mrq)
nfsm_srvmtofh(fhp);
nfsm_srvmtofh(dfhp);
nfsm_srvnamesiz(len);
if (error = nfsrv_fhtovp(fhp, FALSE, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, FALSE, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
nfsm_srvpostop_attr(getret, &at);
nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
@ -2577,8 +2543,9 @@ nfsrv_readdir(nfsd, slp, procp, mrq)
if (siz > xfer)
siz = xfer;
fullsiz = siz;
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(NFSX_UNSIGNED);
nfsm_srvpostop_attr(getret, &at);
return (0);
@ -2832,8 +2799,9 @@ nfsrv_readdirplus(nfsd, slp, procp, mrq)
if (siz > xfer)
siz = xfer;
fullsiz = siz;
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(NFSX_UNSIGNED);
nfsm_srvpostop_attr(getret, &at);
return (0);
@ -3128,8 +3096,9 @@ nfsrv_commit(nfsd, slp, procp, mrq)
fxdr_hyper(tl, &off);
tl += 2;
cnt = fxdr_unsigned(int, *tl);
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(2 * NFSX_UNSIGNED);
nfsm_srvwcc_data(for_ret, &bfor, aft_ret, &aft);
return (0);
@ -3188,8 +3157,9 @@ nfsrv_statfs(nfsd, slp, procp, mrq)
#endif
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(NFSX_UNSIGNED);
nfsm_srvpostop_attr(getret, &at);
return (0);
@ -3340,8 +3310,9 @@ nfsrv_pathconf(nfsd, slp, procp, mrq)
#endif
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(NFSX_UNSIGNED);
nfsm_srvpostop_attr(getret, &at);
return (0);
@ -3462,8 +3433,12 @@ nfsrv_access(vp, flags, cred, rdonly, p, override)
*/
if (rdonly || (vp->v_mount->mnt_flag & MNT_RDONLY)) {
switch (vp->v_type) {
case VREG: case VDIR: case VLNK:
case VREG:
case VDIR:
case VLNK:
return (EROFS);
default:
break;
}
}
/*
@ -3473,7 +3448,8 @@ nfsrv_access(vp, flags, cred, rdonly, p, override)
if (vp->v_flag & VTEXT)
return (ETXTBSY);
}
if (error = VOP_GETATTR(vp, &vattr, cred, p))
error = VOP_GETATTR(vp, &vattr, cred, p);
if (error)
return (error);
error = VOP_ACCESS(vp, flags, cred, p);
/*

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
* $Id: nfs_socket.c,v 1.31 1998/03/30 09:54:04 phk Exp $
* $Id: nfs_socket.c,v 1.32 1998/05/19 07:11:23 peter Exp $
*/
/*
@ -249,7 +249,7 @@ nfs_connect(nmp, rep)
"nfscon", 2 * hz);
if ((so->so_state & SS_ISCONNECTING) &&
so->so_error == 0 && rep &&
(error = nfs_sigintr(nmp, rep, rep->r_procp))) {
(error = nfs_sigintr(nmp, rep, rep->r_procp)) != 0){
so->so_state &= ~SS_ISCONNECTING;
splx(s);
goto bad;
@ -335,7 +335,7 @@ nfs_reconnect(rep)
int error;
nfs_disconnect(nmp);
while ((error = nfs_connect(nmp, rep))) {
while ((error = nfs_connect(nmp, rep)) != 0) {
if (error == EINTR || error == ERESTART)
return (EINTR);
(void) tsleep((caddr_t)&lbolt, PSOCK, "nfscon", 0);
@ -419,8 +419,7 @@ nfs_send(so, nam, top, rep)
flags, curproc /*XXX*/);
if (error) {
if (rep) {
log(LOG_INFO, "nfs send error %d for server %s\n",
error,
log(LOG_INFO, "nfs send error %d for server %s\n",error,
rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname);
/*
* Deal with errors for the client side.
@ -518,7 +517,7 @@ nfs_receive(rep, aname, mp)
error = nfs_send(so, rep->r_nmp->nm_nam, m, rep);
if (error) {
if (error == EINTR || error == ERESTART ||
(error = nfs_reconnect(rep))) {
(error = nfs_reconnect(rep)) != 0) {
nfs_sndunlock(&rep->r_nmp->nm_flag,
&rep->r_nmp->nm_state);
return (error);
@ -1641,6 +1640,270 @@ nfs_realign(m, hsiz)
}
#ifndef NFS_NOSERVER
/*
* Parse an RPC request
* - verify it
* - fill in the cred struct.
*/
int
nfs_getreq(nd, nfsd, has_header)
register struct nfsrv_descript *nd;
struct nfsd *nfsd;
int has_header;
{
register int len, i;
register u_long *tl;
register long t1;
struct uio uio;
struct iovec iov;
caddr_t dpos, cp2, cp;
u_long nfsvers, auth_type;
uid_t nickuid;
int error = 0, nqnfs = 0, ticklen;
struct mbuf *mrep, *md;
register struct nfsuid *nuidp;
struct timeval tvin, tvout;
#if 0 /* until encrypted keys are implemented */
NFSKERBKEYSCHED_T keys; /* stores key schedule */
#endif
mrep = nd->nd_mrep;
md = nd->nd_md;
dpos = nd->nd_dpos;
if (has_header) {
nfsm_dissect(tl, u_long *, 10 * NFSX_UNSIGNED);
nd->nd_retxid = fxdr_unsigned(u_long, *tl++);
if (*tl++ != rpc_call) {
m_freem(mrep);
return (EBADRPC);
}
} else
nfsm_dissect(tl, u_long *, 8 * NFSX_UNSIGNED);
nd->nd_repstat = 0;
nd->nd_flag = 0;
if (*tl++ != rpc_vers) {
nd->nd_repstat = ERPCMISMATCH;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if (*tl != nfs_prog) {
if (*tl == nqnfs_prog)
nqnfs++;
else {
nd->nd_repstat = EPROGUNAVAIL;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
}
tl++;
nfsvers = fxdr_unsigned(u_long, *tl++);
if (((nfsvers < NFS_VER2 || nfsvers > NFS_VER3) && !nqnfs) ||
(nfsvers != NQNFS_VER3 && nqnfs)) {
nd->nd_repstat = EPROGMISMATCH;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if (nqnfs)
nd->nd_flag = (ND_NFSV3 | ND_NQNFS);
else if (nfsvers == NFS_VER3)
nd->nd_flag = ND_NFSV3;
nd->nd_procnum = fxdr_unsigned(u_long, *tl++);
if (nd->nd_procnum == NFSPROC_NULL)
return (0);
if (nd->nd_procnum >= NFS_NPROCS ||
(!nqnfs && nd->nd_procnum >= NQNFSPROC_GETLEASE) ||
(!nd->nd_flag && nd->nd_procnum > NFSV2PROC_STATFS)) {
nd->nd_repstat = EPROCUNAVAIL;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if ((nd->nd_flag & ND_NFSV3) == 0)
nd->nd_procnum = nfsv3_procid[nd->nd_procnum];
auth_type = *tl++;
len = fxdr_unsigned(int, *tl++);
if (len < 0 || len > RPCAUTH_MAXSIZ) {
m_freem(mrep);
return (EBADRPC);
}
nd->nd_flag &= ~ND_KERBAUTH;
/*
* Handle auth_unix or auth_kerb.
*/
if (auth_type == rpc_auth_unix) {
len = fxdr_unsigned(int, *++tl);
if (len < 0 || len > NFS_MAXNAMLEN) {
m_freem(mrep);
return (EBADRPC);
}
nfsm_adv(nfsm_rndup(len));
nfsm_dissect(tl, u_long *, 3 * NFSX_UNSIGNED);
bzero((caddr_t)&nd->nd_cr, sizeof (struct ucred));
nd->nd_cr.cr_ref = 1;
nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++);
nd->nd_cr.cr_gid = fxdr_unsigned(gid_t, *tl++);
len = fxdr_unsigned(int, *tl);
if (len < 0 || len > RPCAUTH_UNIXGIDS) {
m_freem(mrep);
return (EBADRPC);
}
nfsm_dissect(tl, u_long *, (len + 2) * NFSX_UNSIGNED);
for (i = 1; i <= len; i++)
if (i < NGROUPS)
nd->nd_cr.cr_groups[i] = fxdr_unsigned(gid_t, *tl++);
else
tl++;
nd->nd_cr.cr_ngroups = (len >= NGROUPS) ? NGROUPS : (len + 1);
if (nd->nd_cr.cr_ngroups > 1)
nfsrvw_sort(nd->nd_cr.cr_groups, nd->nd_cr.cr_ngroups);
len = fxdr_unsigned(int, *++tl);
if (len < 0 || len > RPCAUTH_MAXSIZ) {
m_freem(mrep);
return (EBADRPC);
}
if (len > 0)
nfsm_adv(nfsm_rndup(len));
} else if (auth_type == rpc_auth_kerb) {
switch (fxdr_unsigned(int, *tl++)) {
case RPCAKN_FULLNAME:
ticklen = fxdr_unsigned(int, *tl);
*((u_long *)nfsd->nfsd_authstr) = *tl;
uio.uio_resid = nfsm_rndup(ticklen) + NFSX_UNSIGNED;
nfsd->nfsd_authlen = uio.uio_resid + NFSX_UNSIGNED;
if (uio.uio_resid > (len - 2 * NFSX_UNSIGNED)) {
m_freem(mrep);
return (EBADRPC);
}
uio.uio_offset = 0;
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
uio.uio_segflg = UIO_SYSSPACE;
iov.iov_base = (caddr_t)&nfsd->nfsd_authstr[4];
iov.iov_len = RPCAUTH_MAXSIZ - 4;
nfsm_mtouio(&uio, uio.uio_resid);
nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED);
if (*tl++ != rpc_auth_kerb ||
fxdr_unsigned(int, *tl) != 4 * NFSX_UNSIGNED) {
printf("Bad kerb verifier\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsm_dissect(cp, caddr_t, 4 * NFSX_UNSIGNED);
tl = (u_long *)cp;
if (fxdr_unsigned(int, *tl) != RPCAKN_FULLNAME) {
printf("Not fullname kerb verifier\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
cp += NFSX_UNSIGNED;
bcopy(cp, nfsd->nfsd_verfstr, 3 * NFSX_UNSIGNED);
nfsd->nfsd_verflen = 3 * NFSX_UNSIGNED;
nd->nd_flag |= ND_KERBFULL;
nfsd->nfsd_flag |= NFSD_NEEDAUTH;
break;
case RPCAKN_NICKNAME:
if (len != 2 * NFSX_UNSIGNED) {
printf("Kerb nickname short\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nickuid = fxdr_unsigned(uid_t, *tl);
nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED);
if (*tl++ != rpc_auth_kerb ||
fxdr_unsigned(int, *tl) != 3 * NFSX_UNSIGNED) {
printf("Kerb nick verifier bad\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsm_dissect(tl, u_long *, 3 * NFSX_UNSIGNED);
tvin.tv_sec = *tl++;
tvin.tv_usec = *tl;
for (nuidp = NUIDHASH(nfsd->nfsd_slp,nickuid)->lh_first;
nuidp != 0; nuidp = nuidp->nu_hash.le_next) {
if (nuidp->nu_cr.cr_uid == nickuid &&
(!nd->nd_nam2 ||
netaddr_match(NU_NETFAM(nuidp),
&nuidp->nu_haddr, nd->nd_nam2)))
break;
}
if (!nuidp) {
nd->nd_repstat =
(NFSERR_AUTHERR|AUTH_REJECTCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
/*
* Now, decrypt the timestamp using the session key
* and validate it.
*/
#ifdef NFSKERB
XXX
#endif
tvout.tv_sec = fxdr_unsigned(long, tvout.tv_sec);
tvout.tv_usec = fxdr_unsigned(long, tvout.tv_usec);
if (nuidp->nu_expire < time_second ||
nuidp->nu_timestamp.tv_sec > tvout.tv_sec ||
(nuidp->nu_timestamp.tv_sec == tvout.tv_sec &&
nuidp->nu_timestamp.tv_usec > tvout.tv_usec)) {
nuidp->nu_expire = 0;
nd->nd_repstat =
(NFSERR_AUTHERR|AUTH_REJECTVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsrv_setcred(&nuidp->nu_cr, &nd->nd_cr);
nd->nd_flag |= ND_KERBNICK;
};
} else {
nd->nd_repstat = (NFSERR_AUTHERR | AUTH_REJECTCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
/*
* For nqnfs, get piggybacked lease request.
*/
if (nqnfs && nd->nd_procnum != NQNFSPROC_EVICTED) {
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
nd->nd_flag |= fxdr_unsigned(int, *tl);
if (nd->nd_flag & ND_LEASE) {
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
nd->nd_duration = fxdr_unsigned(int, *tl);
} else
nd->nd_duration = NQ_MINLEASE;
} else
nd->nd_duration = NQ_MINLEASE;
nd->nd_md = md;
nd->nd_dpos = dpos;
return (0);
nfsmout:
return (error);
}
static int
nfs_msg(p, server, msg)
struct proc *p;
char *server, *msg;
{
tpr_t tpr;
if (p)
tpr = tprintf_open(p);
else
tpr = NULL;
tprintf(tpr, "nfs server %s: %s\n", server, msg);
tprintf_close(tpr);
return (0);
}
/*
* Socket upcall routine for the nfsd sockets.
* The caddr_t arg is a pointer to the "struct nfssvc_sock".
@ -1926,253 +2189,6 @@ nfsrv_dorec(slp, nfsd, ndp)
return (0);
}
/*
* Parse an RPC request
* - verify it
* - fill in the cred struct.
*/
int
nfs_getreq(nd, nfsd, has_header)
register struct nfsrv_descript *nd;
struct nfsd *nfsd;
int has_header;
{
register int len, i;
register u_long *tl;
register long t1;
struct uio uio;
struct iovec iov;
caddr_t dpos, cp2, cp;
u_long nfsvers, auth_type;
uid_t nickuid;
int error = 0, nqnfs = 0, ticklen;
struct mbuf *mrep, *md;
register struct nfsuid *nuidp;
struct timeval tvin, tvout;
#if 0 /* until encrypted keys are implemented */
NFSKERBKEYSCHED_T keys; /* stores key schedule */
#endif
mrep = nd->nd_mrep;
md = nd->nd_md;
dpos = nd->nd_dpos;
if (has_header) {
nfsm_dissect(tl, u_long *, 10 * NFSX_UNSIGNED);
nd->nd_retxid = fxdr_unsigned(u_long, *tl++);
if (*tl++ != rpc_call) {
m_freem(mrep);
return (EBADRPC);
}
} else
nfsm_dissect(tl, u_long *, 8 * NFSX_UNSIGNED);
nd->nd_repstat = 0;
nd->nd_flag = 0;
if (*tl++ != rpc_vers) {
nd->nd_repstat = ERPCMISMATCH;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if (*tl != nfs_prog) {
if (*tl == nqnfs_prog)
nqnfs++;
else {
nd->nd_repstat = EPROGUNAVAIL;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
}
tl++;
nfsvers = fxdr_unsigned(u_long, *tl++);
if (((nfsvers < NFS_VER2 || nfsvers > NFS_VER3) && !nqnfs) ||
(nfsvers != NQNFS_VER3 && nqnfs)) {
nd->nd_repstat = EPROGMISMATCH;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if (nqnfs)
nd->nd_flag = (ND_NFSV3 | ND_NQNFS);
else if (nfsvers == NFS_VER3)
nd->nd_flag = ND_NFSV3;
nd->nd_procnum = fxdr_unsigned(u_long, *tl++);
if (nd->nd_procnum == NFSPROC_NULL)
return (0);
if (nd->nd_procnum >= NFS_NPROCS ||
(!nqnfs && nd->nd_procnum >= NQNFSPROC_GETLEASE) ||
(!nd->nd_flag && nd->nd_procnum > NFSV2PROC_STATFS)) {
nd->nd_repstat = EPROCUNAVAIL;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if ((nd->nd_flag & ND_NFSV3) == 0)
nd->nd_procnum = nfsv3_procid[nd->nd_procnum];
auth_type = *tl++;
len = fxdr_unsigned(int, *tl++);
if (len < 0 || len > RPCAUTH_MAXSIZ) {
m_freem(mrep);
return (EBADRPC);
}
nd->nd_flag &= ~ND_KERBAUTH;
/*
* Handle auth_unix or auth_kerb.
*/
if (auth_type == rpc_auth_unix) {
len = fxdr_unsigned(int, *++tl);
if (len < 0 || len > NFS_MAXNAMLEN) {
m_freem(mrep);
return (EBADRPC);
}
nfsm_adv(nfsm_rndup(len));
nfsm_dissect(tl, u_long *, 3 * NFSX_UNSIGNED);
bzero((caddr_t)&nd->nd_cr, sizeof (struct ucred));
nd->nd_cr.cr_ref = 1;
nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++);
nd->nd_cr.cr_gid = fxdr_unsigned(gid_t, *tl++);
len = fxdr_unsigned(int, *tl);
if (len < 0 || len > RPCAUTH_UNIXGIDS) {
m_freem(mrep);
return (EBADRPC);
}
nfsm_dissect(tl, u_long *, (len + 2) * NFSX_UNSIGNED);
for (i = 1; i <= len; i++)
if (i < NGROUPS)
nd->nd_cr.cr_groups[i] = fxdr_unsigned(gid_t, *tl++);
else
tl++;
nd->nd_cr.cr_ngroups = (len >= NGROUPS) ? NGROUPS : (len + 1);
if (nd->nd_cr.cr_ngroups > 1)
nfsrvw_sort(nd->nd_cr.cr_groups, nd->nd_cr.cr_ngroups);
len = fxdr_unsigned(int, *++tl);
if (len < 0 || len > RPCAUTH_MAXSIZ) {
m_freem(mrep);
return (EBADRPC);
}
if (len > 0)
nfsm_adv(nfsm_rndup(len));
} else if (auth_type == rpc_auth_kerb) {
switch (fxdr_unsigned(int, *tl++)) {
case RPCAKN_FULLNAME:
ticklen = fxdr_unsigned(int, *tl);
*((u_long *)nfsd->nfsd_authstr) = *tl;
uio.uio_resid = nfsm_rndup(ticklen) + NFSX_UNSIGNED;
nfsd->nfsd_authlen = uio.uio_resid + NFSX_UNSIGNED;
if (uio.uio_resid > (len - 2 * NFSX_UNSIGNED)) {
m_freem(mrep);
return (EBADRPC);
}
uio.uio_offset = 0;
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
uio.uio_segflg = UIO_SYSSPACE;
iov.iov_base = (caddr_t)&nfsd->nfsd_authstr[4];
iov.iov_len = RPCAUTH_MAXSIZ - 4;
nfsm_mtouio(&uio, uio.uio_resid);
nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED);
if (*tl++ != rpc_auth_kerb ||
fxdr_unsigned(int, *tl) != 4 * NFSX_UNSIGNED) {
printf("Bad kerb verifier\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsm_dissect(cp, caddr_t, 4 * NFSX_UNSIGNED);
tl = (u_long *)cp;
if (fxdr_unsigned(int, *tl) != RPCAKN_FULLNAME) {
printf("Not fullname kerb verifier\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
cp += NFSX_UNSIGNED;
bcopy(cp, nfsd->nfsd_verfstr, 3 * NFSX_UNSIGNED);
nfsd->nfsd_verflen = 3 * NFSX_UNSIGNED;
nd->nd_flag |= ND_KERBFULL;
nfsd->nfsd_flag |= NFSD_NEEDAUTH;
break;
case RPCAKN_NICKNAME:
if (len != 2 * NFSX_UNSIGNED) {
printf("Kerb nickname short\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nickuid = fxdr_unsigned(uid_t, *tl);
nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED);
if (*tl++ != rpc_auth_kerb ||
fxdr_unsigned(int, *tl) != 3 * NFSX_UNSIGNED) {
printf("Kerb nick verifier bad\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsm_dissect(tl, u_long *, 3 * NFSX_UNSIGNED);
tvin.tv_sec = *tl++;
tvin.tv_usec = *tl;
for (nuidp = NUIDHASH(nfsd->nfsd_slp,nickuid)->lh_first;
nuidp != 0; nuidp = nuidp->nu_hash.le_next) {
if (nuidp->nu_cr.cr_uid == nickuid &&
(!nd->nd_nam2 ||
netaddr_match(NU_NETFAM(nuidp),
&nuidp->nu_haddr, nd->nd_nam2)))
break;
}
if (!nuidp) {
nd->nd_repstat =
(NFSERR_AUTHERR|AUTH_REJECTCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
/*
* Now, decrypt the timestamp using the session key
* and validate it.
*/
#ifdef NFSKERB
XXX
#endif
tvout.tv_sec = fxdr_unsigned(long, tvout.tv_sec);
tvout.tv_usec = fxdr_unsigned(long, tvout.tv_usec);
if (nuidp->nu_expire < time_second ||
nuidp->nu_timestamp.tv_sec > tvout.tv_sec ||
(nuidp->nu_timestamp.tv_sec == tvout.tv_sec &&
nuidp->nu_timestamp.tv_usec > tvout.tv_usec)) {
nuidp->nu_expire = 0;
nd->nd_repstat =
(NFSERR_AUTHERR|AUTH_REJECTVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsrv_setcred(&nuidp->nu_cr, &nd->nd_cr);
nd->nd_flag |= ND_KERBNICK;
};
} else {
nd->nd_repstat = (NFSERR_AUTHERR | AUTH_REJECTCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
/*
* For nqnfs, get piggybacked lease request.
*/
if (nqnfs && nd->nd_procnum != NQNFSPROC_EVICTED) {
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
nd->nd_flag |= fxdr_unsigned(int, *tl);
if (nd->nd_flag & ND_LEASE) {
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
nd->nd_duration = fxdr_unsigned(int, *tl);
} else
nd->nd_duration = NQ_MINLEASE;
} else
nd->nd_duration = NQ_MINLEASE;
nd->nd_md = md;
nd->nd_dpos = dpos;
return (0);
nfsmout:
return (error);
}
/*
* Search for a sleeping nfsd and wake it up.
* SIDE EFFECT: If none found, set NFSD_CHECKSLP flag, so that one of the
@ -2201,19 +2217,3 @@ nfsrv_wakenfsd(slp)
nfsd_head_flag |= NFSD_CHECKSLP;
}
#endif /* NFS_NOSERVER */
static int
nfs_msg(p, server, msg)
struct proc *p;
char *server, *msg;
{
tpr_t tpr;
if (p)
tpr = tprintf_open(p);
else
tpr = NULL;
tprintf(tpr, "nfs server %s: %s\n", server, msg);
tprintf_close(tpr);
return (0);
}

View File

@ -33,8 +33,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
* $Id: nfs_subs.c,v 1.54 1998/05/19 07:11:24 peter Exp $
* @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95
* $Id: nfs_subs.c,v 1.55 1998/05/24 14:41:53 peter Exp $
*/
/*
@ -2129,4 +2129,45 @@ nfsrv_object_create(vp)
return (vfs_object_create(vp, curproc,
curproc ? curproc->p_ucred : NULL, 1));
}
/*
* Sort the group list in increasing numerical order.
* (Insertion sort by Chris Torek, who was grossed out by the bubble sort
* that used to be here.)
*/
void
nfsrvw_sort(list, num)
register gid_t *list;
register int num;
{
register int i, j;
gid_t v;
/* Insertion sort. */
for (i = 1; i < num; i++) {
v = list[i];
/* find correct slot for value v, moving others up */
for (j = i; --j >= 0 && v < list[j];)
list[j + 1] = list[j];
list[j + 1] = v;
}
}
/*
* copy credentials making sure that the result can be compared with bcmp().
*/
void
nfsrv_setcred(incred, outcred)
register struct ucred *incred, *outcred;
{
register int i;
bzero((caddr_t)outcred, sizeof (struct ucred));
outcred->cr_ref = 1;
outcred->cr_uid = incred->cr_uid;
outcred->cr_ngroups = incred->cr_ngroups;
for (i = 0; i < incred->cr_ngroups; i++)
outcred->cr_groups[i] = incred->cr_groups[i];
nfsrvw_sort(outcred->cr_groups, outcred->cr_ngroups);
}
#endif /* NFS_NOSERVER */

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95
* $Id: nfs_syscalls.c,v 1.37 1998/03/30 09:54:17 phk Exp $
* $Id: nfs_syscalls.c,v 1.38 1998/05/19 07:11:25 peter Exp $
*/
#include <sys/param.h>
@ -252,8 +252,9 @@ nfssvc(p, uap)
error = copyin(uap->argp, (caddr_t)nsd, sizeof (*nsd));
if (error)
return (error);
if ((uap->flag & NFSSVC_AUTHIN) && ((nfsd = nsd->nsd_nfsd)) &&
(nfsd->nfsd_slp->ns_flag & SLP_VALID)) {
if ((uap->flag & NFSSVC_AUTHIN) &&
((nfsd = nsd->nsd_nfsd)) != NULL &&
(nfsd->nfsd_slp->ns_flag & SLP_VALID)) {
slp = nfsd->nfsd_slp;
/*
@ -465,11 +466,10 @@ nfssvc_nfsd(nsd, argp, p)
writes_todo = 0;
#endif
if (nfsd == (struct nfsd *)0) {
nfsd = (struct nfsd *)
nsd->nsd_nfsd = nfsd = (struct nfsd *)
malloc(sizeof (struct nfsd), M_NFSD, M_WAITOK);
bzero((caddr_t)nfsd, sizeof (struct nfsd));
s = splnet();
nsd->nsd_nfsd = nfsd;
nfsd->nfsd_procp = p;
TAILQ_INSERT_TAIL(&nfsd_head, nfsd, nfsd_chain);
nfs_numnfsd++;
@ -746,88 +746,6 @@ nfssvc_nfsd(nsd, argp, p)
nfsrv_init(TRUE); /* Reinitialize everything */
return (error);
}
#endif /* NFS_NOSERVER */
static int nfs_defect = 0;
SYSCTL_INT(_vfs_nfs, OID_AUTO, defect, CTLFLAG_RW, &nfs_defect, 0, "");
/*
* Asynchronous I/O daemons for client nfs.
* They do read-ahead and write-behind operations on the block I/O cache.
* Never returns unless it fails or gets killed.
*/
static int
nfssvc_iod(p)
struct proc *p;
{
register struct buf *bp;
register int i, myiod;
struct nfsmount *nmp;
int error = 0;
/*
* Assign my position or return error if too many already running
*/
myiod = -1;
for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
if (nfs_asyncdaemon[i] == 0) {
nfs_asyncdaemon[i]++;
myiod = i;
break;
}
if (myiod == -1)
return (EBUSY);
nfs_numasync++;
/*
* Just loop around doin our stuff until SIGKILL
*/
for (;;) {
while (((nmp = nfs_iodmount[myiod]) == NULL
|| nmp->nm_bufq.tqh_first == NULL)
&& error == 0) {
if (nmp)
nmp->nm_bufqiods--;
nfs_iodwant[myiod] = p;
nfs_iodmount[myiod] = NULL;
error = tsleep((caddr_t)&nfs_iodwant[myiod],
PWAIT | PCATCH, "nfsidl", 0);
}
if (error) {
nfs_asyncdaemon[myiod] = 0;
if (nmp) nmp->nm_bufqiods--;
nfs_iodwant[myiod] = NULL;
nfs_iodmount[myiod] = NULL;
nfs_numasync--;
return (error);
}
while ((bp = nmp->nm_bufq.tqh_first) != NULL) {
/* Take one off the front of the list */
TAILQ_REMOVE(&nmp->nm_bufq, bp, b_freelist);
nmp->nm_bufqlen--;
if (nmp->nm_bufqwant && nmp->nm_bufqlen < 2 * nfs_numasync) {
nmp->nm_bufqwant = FALSE;
wakeup(&nmp->nm_bufq);
}
if (bp->b_flags & B_READ)
(void) nfs_doio(bp, bp->b_rcred, (struct proc *)0);
else
(void) nfs_doio(bp, bp->b_wcred, (struct proc *)0);
/*
* If there are more than one iod on this mount, then defect
* so that the iods can be shared out fairly between the mounts
*/
if (nfs_defect && nmp->nm_bufqiods > 1) {
NFS_DPF(ASYNCIO,
("nfssvc_iod: iod %d defecting from mount %p\n",
myiod, nmp));
nfs_iodmount[myiod] = NULL;
nmp->nm_bufqiods--;
break;
}
}
}
}
/*
* Shut down a socket associated with an nfssvc_sock structure.
@ -885,6 +803,188 @@ nfsrv_zapsock(slp)
}
}
/*
* Derefence a server socket structure. If it has no more references and
* is no longer valid, you can throw it away.
*/
void
nfsrv_slpderef(slp)
register struct nfssvc_sock *slp;
{
if (--(slp->ns_sref) == 0 && (slp->ns_flag & SLP_VALID) == 0) {
TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
free((caddr_t)slp, M_NFSSVC);
}
}
/*
* Initialize the data structures for the server.
* Handshake with any new nfsds starting up to avoid any chance of
* corruption.
*/
void
nfsrv_init(terminating)
int terminating;
{
register struct nfssvc_sock *slp, *nslp;
if (nfssvc_sockhead_flag & SLP_INIT)
panic("nfsd init");
nfssvc_sockhead_flag |= SLP_INIT;
if (terminating) {
for (slp = nfssvc_sockhead.tqh_first; slp != 0; slp = nslp) {
nslp = slp->ns_chain.tqe_next;
if (slp->ns_flag & SLP_VALID)
nfsrv_zapsock(slp);
TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
free((caddr_t)slp, M_NFSSVC);
}
nfsrv_cleancache(); /* And clear out server cache */
} else
nfs_pub.np_valid = 0;
TAILQ_INIT(&nfssvc_sockhead);
nfssvc_sockhead_flag &= ~SLP_INIT;
if (nfssvc_sockhead_flag & SLP_WANTINIT) {
nfssvc_sockhead_flag &= ~SLP_WANTINIT;
wakeup((caddr_t)&nfssvc_sockhead);
}
TAILQ_INIT(&nfsd_head);
nfsd_head_flag &= ~NFSD_CHECKSLP;
nfs_udpsock = (struct nfssvc_sock *)
malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
bzero((caddr_t)nfs_udpsock, sizeof (struct nfssvc_sock));
STAILQ_INIT(&nfs_udpsock->ns_rec);
TAILQ_INIT(&nfs_udpsock->ns_uidlruhead);
TAILQ_INSERT_HEAD(&nfssvc_sockhead, nfs_udpsock, ns_chain);
nfs_cltpsock = (struct nfssvc_sock *)
malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
bzero((caddr_t)nfs_cltpsock, sizeof (struct nfssvc_sock));
STAILQ_INIT(&nfs_cltpsock->ns_rec);
TAILQ_INIT(&nfs_cltpsock->ns_uidlruhead);
TAILQ_INSERT_TAIL(&nfssvc_sockhead, nfs_cltpsock, ns_chain);
}
/*
* Add entries to the server monitor log.
*/
static void
nfsd_rt(sotype, nd, cacherep)
int sotype;
register struct nfsrv_descript *nd;
int cacherep;
{
register struct drt *rt;
rt = &nfsdrt.drt[nfsdrt.pos];
if (cacherep == RC_DOIT)
rt->flag = 0;
else if (cacherep == RC_REPLY)
rt->flag = DRT_CACHEREPLY;
else
rt->flag = DRT_CACHEDROP;
if (sotype == SOCK_STREAM)
rt->flag |= DRT_TCP;
if (nd->nd_flag & ND_NQNFS)
rt->flag |= DRT_NQNFS;
else if (nd->nd_flag & ND_NFSV3)
rt->flag |= DRT_NFSV3;
rt->proc = nd->nd_procnum;
if (nd->nd_nam->sa_family == AF_INET)
rt->ipadr = ((struct sockaddr_in *)nd->nd_nam)->sin_addr.s_addr;
else
rt->ipadr = INADDR_ANY;
rt->resptime = nfs_curusec() - (nd->nd_starttime.tv_sec * 1000000 + nd->nd_starttime.tv_usec);
getmicrotime(&rt->tstamp);
nfsdrt.pos = (nfsdrt.pos + 1) % NFSRTTLOGSIZ;
}
#endif /* NFS_NOSERVER */
static int nfs_defect = 0;
SYSCTL_INT(_vfs_nfs, OID_AUTO, defect, CTLFLAG_RW, &nfs_defect, 0, "");
/*
* Asynchronous I/O daemons for client nfs.
* They do read-ahead and write-behind operations on the block I/O cache.
* Never returns unless it fails or gets killed.
*/
static int
nfssvc_iod(p)
struct proc *p;
{
register struct buf *bp;
register int i, myiod;
struct nfsmount *nmp;
int error = 0;
/*
* Assign my position or return error if too many already running
*/
myiod = -1;
for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
if (nfs_asyncdaemon[i] == 0) {
nfs_asyncdaemon[i]++;
myiod = i;
break;
}
if (myiod == -1)
return (EBUSY);
nfs_numasync++;
/*
* Just loop around doin our stuff until SIGKILL
*/
for (;;) {
while (((nmp = nfs_iodmount[myiod]) == NULL
|| nmp->nm_bufq.tqh_first == NULL)
&& error == 0) {
if (nmp)
nmp->nm_bufqiods--;
nfs_iodwant[myiod] = p;
nfs_iodmount[myiod] = NULL;
error = tsleep((caddr_t)&nfs_iodwant[myiod],
PWAIT | PCATCH, "nfsidl", 0);
}
if (error) {
nfs_asyncdaemon[myiod] = 0;
if (nmp)
nmp->nm_bufqiods--;
nfs_iodwant[myiod] = NULL;
nfs_iodmount[myiod] = NULL;
nfs_numasync--;
return (error);
}
while ((bp = nmp->nm_bufq.tqh_first) != NULL) {
/* Take one off the front of the list */
TAILQ_REMOVE(&nmp->nm_bufq, bp, b_freelist);
nmp->nm_bufqlen--;
if (nmp->nm_bufqwant && nmp->nm_bufqlen < 2 * nfs_numasync) {
nmp->nm_bufqwant = FALSE;
wakeup(&nmp->nm_bufq);
}
if (bp->b_flags & B_READ)
(void) nfs_doio(bp, bp->b_rcred, (struct proc *)0);
else
(void) nfs_doio(bp, bp->b_wcred, (struct proc *)0);
/*
* If there are more than one iod on this mount, then defect
* so that the iods can be shared out fairly between the mounts
*/
if (nfs_defect && nmp->nm_bufqiods > 1) {
NFS_DPF(ASYNCIO,
("nfssvc_iod: iod %d defecting from mount %p\n",
myiod, nmp));
nfs_iodmount[myiod] = NULL;
nmp->nm_bufqiods--;
break;
}
}
}
}
/*
* Get an authorization string for the uid by having the mount_nfs sitting
* on this mount point porpous out of the kernel and do it.
@ -1088,105 +1188,3 @@ nfs_savenickauth(nmp, cred, len, key, mdp, dposp, mrep)
*dposp = dpos;
return (error);
}
#ifndef NFS_NOSERVER
/*
* Derefence a server socket structure. If it has no more references and
* is no longer valid, you can throw it away.
*/
void
nfsrv_slpderef(slp)
register struct nfssvc_sock *slp;
{
if (--(slp->ns_sref) == 0 && (slp->ns_flag & SLP_VALID) == 0) {
TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
free((caddr_t)slp, M_NFSSVC);
}
}
/*
* Initialize the data structures for the server.
* Handshake with any new nfsds starting up to avoid any chance of
* corruption.
*/
void
nfsrv_init(terminating)
int terminating;
{
register struct nfssvc_sock *slp, *nslp;
if (nfssvc_sockhead_flag & SLP_INIT)
panic("nfsd init");
nfssvc_sockhead_flag |= SLP_INIT;
if (terminating) {
for (slp = nfssvc_sockhead.tqh_first; slp != 0; slp = nslp) {
nslp = slp->ns_chain.tqe_next;
if (slp->ns_flag & SLP_VALID)
nfsrv_zapsock(slp);
TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
free((caddr_t)slp, M_NFSSVC);
}
nfsrv_cleancache(); /* And clear out server cache */
} else
nfs_pub.np_valid = 0;
TAILQ_INIT(&nfssvc_sockhead);
nfssvc_sockhead_flag &= ~SLP_INIT;
if (nfssvc_sockhead_flag & SLP_WANTINIT) {
nfssvc_sockhead_flag &= ~SLP_WANTINIT;
wakeup((caddr_t)&nfssvc_sockhead);
}
TAILQ_INIT(&nfsd_head);
nfsd_head_flag &= ~NFSD_CHECKSLP;
nfs_udpsock = (struct nfssvc_sock *)
malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
bzero((caddr_t)nfs_udpsock, sizeof (struct nfssvc_sock));
STAILQ_INIT(&nfs_udpsock->ns_rec);
TAILQ_INIT(&nfs_udpsock->ns_uidlruhead);
TAILQ_INSERT_HEAD(&nfssvc_sockhead, nfs_udpsock, ns_chain);
nfs_cltpsock = (struct nfssvc_sock *)
malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
bzero((caddr_t)nfs_cltpsock, sizeof (struct nfssvc_sock));
STAILQ_INIT(&nfs_cltpsock->ns_rec);
TAILQ_INIT(&nfs_cltpsock->ns_uidlruhead);
TAILQ_INSERT_TAIL(&nfssvc_sockhead, nfs_cltpsock, ns_chain);
}
/*
* Add entries to the server monitor log.
*/
static void
nfsd_rt(sotype, nd, cacherep)
int sotype;
register struct nfsrv_descript *nd;
int cacherep;
{
register struct drt *rt;
rt = &nfsdrt.drt[nfsdrt.pos];
if (cacherep == RC_DOIT)
rt->flag = 0;
else if (cacherep == RC_REPLY)
rt->flag = DRT_CACHEREPLY;
else
rt->flag = DRT_CACHEDROP;
if (sotype == SOCK_STREAM)
rt->flag |= DRT_TCP;
if (nd->nd_flag & ND_NQNFS)
rt->flag |= DRT_NQNFS;
else if (nd->nd_flag & ND_NFSV3)
rt->flag |= DRT_NFSV3;
rt->proc = nd->nd_procnum;
if (nd->nd_nam->sa_family == AF_INET)
rt->ipadr = ((struct sockaddr_in *)nd->nd_nam)->sin_addr.s_addr;
else
rt->ipadr = INADDR_ANY;
rt->resptime = nfs_curusec() - (nd->nd_starttime.tv_sec * 1000000 + nd->nd_starttime.tv_usec);
getmicrotime(&rt->tstamp);
nfsdrt.pos = (nfsdrt.pos + 1) % NFSRTTLOGSIZ;
}
#endif /* NFS_NOSERVER */

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_vfsops.c 8.12 (Berkeley) 5/20/95
* $Id: nfs_vfsops.c,v 1.63 1998/05/24 14:41:56 peter Exp $
* $Id: nfs_vfsops.c,v 1.64 1998/05/30 16:33:57 peter Exp $
*/
#include <sys/param.h>
@ -696,6 +696,7 @@ mountnfs(argp, mp, nam, pth, hst, vpp)
* unsuspecting binaries).
*/
mp->mnt_maxsymlinklen = 1;
if ((argp->flags & NFSMNT_NFSV3) == 0)
/*
* V2 can only handle 32 bit filesizes. For v3, nfs_fsinfo

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
* $Id: nfs_vnops.c,v 1.90 1998/05/30 16:33:57 peter Exp $
* $Id: nfs_vnops.c,v 1.91 1998/05/31 01:03:07 peter Exp $
*/
@ -275,8 +275,12 @@ nfs_access(ap)
*/
if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
switch (vp->v_type) {
case VREG: case VDIR: case VLNK:
case VREG:
case VDIR:
case VLNK:
return (EROFS);
default:
break;
}
}
/*
@ -296,17 +300,17 @@ nfs_access(ap)
mode = NFSV3ACCESS_READ;
else
mode = 0;
if (vp->v_type == VDIR) {
if (vp->v_type != VDIR) {
if (ap->a_mode & VWRITE)
mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND);
if (ap->a_mode & VEXEC)
mode |= NFSV3ACCESS_EXECUTE;
} else {
if (ap->a_mode & VWRITE)
mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND |
NFSV3ACCESS_DELETE);
if (ap->a_mode & VEXEC)
mode |= NFSV3ACCESS_LOOKUP;
} else {
if (ap->a_mode & VWRITE)
mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND);
if (ap->a_mode & VEXEC)
mode |= NFSV3ACCESS_EXECUTE;
}
*tl = txdr_unsigned(mode);
nfsm_request(vp, NFSPROC_ACCESS, ap->a_p, ap->a_cred);
@ -392,10 +396,10 @@ nfs_open(ap)
struct vattr vattr;
int error;
if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK)
{ printf("open eacces vtyp=%d\n",vp->v_type);
if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) {
printf("open eacces vtyp=%d\n",vp->v_type);
return (EACCES);
}
}
/*
* Get a valid lease. If cached data is stale, flush it.
*/
@ -545,8 +549,9 @@ nfs_getattr(ap)
nfsm_reqhead(vp, NFSPROC_GETATTR, NFSX_FH(v3));
nfsm_fhtom(vp, v3);
nfsm_request(vp, NFSPROC_GETATTR, ap->a_p, ap->a_cred);
if (!error)
if (!error) {
nfsm_loadattr(vp, ap->a_vap);
}
nfsm_reqdone;
return (error);
}
@ -756,14 +761,14 @@ nfs_lookup(ap)
struct componentname *a_cnp;
} */ *ap;
{
register struct componentname *cnp = ap->a_cnp;
register struct vnode *dvp = ap->a_dvp;
register struct vnode **vpp = ap->a_vpp;
register int flags = cnp->cn_flags;
register struct vnode *newvp;
register u_long *tl;
register caddr_t cp;
register long t1, t2;
struct componentname *cnp = ap->a_cnp;
struct vnode *dvp = ap->a_dvp;
struct vnode **vpp = ap->a_vpp;
int flags = cnp->cn_flags;
struct vnode *newvp;
u_long *tl;
caddr_t cp;
long t1, t2;
struct nfsmount *nmp;
caddr_t bpos, dpos, cp2;
struct mbuf *mreq, *mrep, *md, *mb, *mb2;
@ -858,7 +863,8 @@ nfs_lookup(ap)
m_freem(mrep);
return (EISDIR);
}
if (error = nfs_nget(dvp->v_mount, fhp, fhsize, &np)) {
error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
if (error) {
m_freem(mrep);
return (error);
}
@ -893,7 +899,8 @@ nfs_lookup(ap)
VREF(dvp);
newvp = dvp;
} else {
if (error = nfs_nget(dvp->v_mount, fhp, fhsize, &np)) {
error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
if (error) {
m_freem(mrep);
return (error);
}
@ -1146,8 +1153,7 @@ nfs_writerpc(vp, uiop, cred, iomode, must_commit)
else if (committed == NFSV3WRITE_DATASYNC &&
commit == NFSV3WRITE_UNSTABLE)
committed = commit;
if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0)
{
if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0){
bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf,
NFSX_V3WRITEVERF);
nmp->nm_state |= NFSSTA_HASWRITEVERF;
@ -2291,8 +2297,9 @@ nfs_readdirplusrpc(vp, uiop, cred)
newvp = vp;
np = dnp;
} else {
if (error = nfs_nget(vp->v_mount, fhp,
fhsize, &np))
error = nfs_nget(vp->v_mount, fhp,
fhsize, &np);
if (error)
doit = 0;
else
newvp = NFSTOV(np);
@ -2416,7 +2423,8 @@ nfs_sillyrename(dvp, vp, cnp)
goto bad;
}
}
if (error = nfs_renameit(dvp, cnp, sp))
error = nfs_renameit(dvp, cnp, sp);
if (error)
goto bad;
error = nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred,
cnp->cn_proc, &np);
@ -3069,8 +3077,12 @@ nfsspec_access(ap)
*/
if ((mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
switch (vp->v_type) {
case VREG: case VDIR: case VLNK:
case VREG:
case VDIR:
case VLNK:
return (EROFS);
default:
break;
}
}
/*

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfsm_subs.h 8.2 (Berkeley) 3/30/95
* $Id: nfsm_subs.h,v 1.15 1998/03/30 09:54:41 phk Exp $
* $Id: nfsm_subs.h,v 1.16 1998/05/16 15:11:24 bde Exp $
*/
@ -105,7 +105,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
if (t1 >= (s)) { \
(a) = (c)(dpos); \
dpos += (s); \
} else if (t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) { \
} else if ((t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) != 0){ \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
@ -122,8 +122,9 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
*(tl + ((t2>>2) - 2)) = 0; \
bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \
VTONFS(v)->n_fhsize); \
} else if (t2 = nfsm_strtmbuf(&mb, &bpos, \
(caddr_t)VTONFS(v)->n_fhp, VTONFS(v)->n_fhsize)) { \
} else if ((t2 = nfsm_strtmbuf(&mb, &bpos, \
(caddr_t)VTONFS(v)->n_fhp, \
VTONFS(v)->n_fhsize)) != 0) { \
error = t2; \
m_freem(mreq); \
goto nfsmout; \
@ -159,8 +160,8 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
(f) = 1; \
if (f) { \
nfsm_getfh(ttfhp, ttfhsize, (v3)); \
if (t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
&ttnp)) { \
if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
&ttnp)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
@ -193,7 +194,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
#define nfsm_loadattr(v, a) \
{ struct vnode *ttvp = (v); \
if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) { \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
@ -204,8 +205,8 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
{ struct vnode *ttvp = (v); \
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
if ((f) = fxdr_unsigned(int, *tl)) { \
if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
(struct vattr *)0)) { \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
(struct vattr *)0)) != 0) { \
error = t1; \
(f) = 0; \
m_freem(mrep); \
@ -275,14 +276,14 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
#define nfsm_mtouio(p,s) \
if ((s) > 0 && \
(t1 = nfsm_mbuftouio(&md,(p),(s),&dpos))) { \
(t1 = nfsm_mbuftouio(&md,(p),(s),&dpos)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
}
#define nfsm_uiotom(p,s) \
if (t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) { \
if ((t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) != 0) { \
error = t1; \
m_freem(mreq); \
goto nfsmout; \
@ -297,8 +298,8 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
#define nfsm_rndup(a) (((a)+3)&(~0x3))
#define nfsm_request(v, t, p, c) \
if (error = nfs_request((v), mreq, (t), (p), \
(c), &mrep, &md, &dpos)) { \
if ((error = nfs_request((v), mreq, (t), (p), \
(c), &mrep, &md, &dpos)) != 0) { \
if (error & NFSERR_RETERR) \
error &= ~NFSERR_RETERR; \
else \
@ -317,7 +318,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
*tl++ = txdr_unsigned(s); \
*(tl+((t2>>2)-2)) = 0; \
bcopy((caddr_t)(a), (caddr_t)tl, (s)); \
} else if (t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) { \
} else if ((t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) != 0) { \
error = t2; \
m_freem(mreq); \
goto nfsmout; \
@ -358,7 +359,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
{ t1 = mtod(md, caddr_t)+md->m_len-dpos; \
if (t1 >= (s)) { \
dpos += (s); \
} else if (t1 = nfs_adv(&md, &dpos, (s), t1)) { \
} else if ((t1 = nfs_adv(&md, &dpos, (s), t1)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \

View File

@ -33,8 +33,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfsproto.h 8.1 (Berkeley) 6/10/93
* $Id$
* @(#)nfsproto.h 8.2 (Berkeley) 3/30/95
* $Id: nfsproto.h,v 1.3 1997/02/22 09:42:50 peter Exp $
*/
#ifndef _NFS_NFSPROTO_H_

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
* $Id: nfs.h,v 1.35 1998/05/19 07:11:22 peter Exp $
* $Id: nfs.h,v 1.36 1998/05/24 14:41:47 peter Exp $
*/
#ifndef _NFS_NFS_H_
@ -293,14 +293,6 @@ struct nfsstats {
{ "nfsprivport", CTLTYPE_INT }, \
}
/*
* Network address hash list element
*/
union nethostaddr {
u_long had_inetaddr;
struct sockaddr *had_nam;
};
#ifdef KERNEL
#ifdef MALLOC_DECLARE
@ -399,6 +391,14 @@ extern TAILQ_HEAD(nfs_reqq, nfsreq) nfs_reqq;
#define NFSNOHASH(fhsum) \
(&nfsnodehashtbl[(fhsum) & nfsnodehash])
/*
* Network address hash list element
*/
union nethostaddr {
u_long had_inetaddr;
struct sockaddr *had_nam;
};
struct nfsuid {
TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */
LIST_ENTRY(nfsuid) nu_hash; /* Hash list */

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95
* $Id: nfs_syscalls.c,v 1.37 1998/03/30 09:54:17 phk Exp $
* $Id: nfs_syscalls.c,v 1.38 1998/05/19 07:11:25 peter Exp $
*/
#include <sys/param.h>
@ -252,8 +252,9 @@ nfssvc(p, uap)
error = copyin(uap->argp, (caddr_t)nsd, sizeof (*nsd));
if (error)
return (error);
if ((uap->flag & NFSSVC_AUTHIN) && ((nfsd = nsd->nsd_nfsd)) &&
(nfsd->nfsd_slp->ns_flag & SLP_VALID)) {
if ((uap->flag & NFSSVC_AUTHIN) &&
((nfsd = nsd->nsd_nfsd)) != NULL &&
(nfsd->nfsd_slp->ns_flag & SLP_VALID)) {
slp = nfsd->nfsd_slp;
/*
@ -465,11 +466,10 @@ nfssvc_nfsd(nsd, argp, p)
writes_todo = 0;
#endif
if (nfsd == (struct nfsd *)0) {
nfsd = (struct nfsd *)
nsd->nsd_nfsd = nfsd = (struct nfsd *)
malloc(sizeof (struct nfsd), M_NFSD, M_WAITOK);
bzero((caddr_t)nfsd, sizeof (struct nfsd));
s = splnet();
nsd->nsd_nfsd = nfsd;
nfsd->nfsd_procp = p;
TAILQ_INSERT_TAIL(&nfsd_head, nfsd, nfsd_chain);
nfs_numnfsd++;
@ -746,88 +746,6 @@ nfssvc_nfsd(nsd, argp, p)
nfsrv_init(TRUE); /* Reinitialize everything */
return (error);
}
#endif /* NFS_NOSERVER */
static int nfs_defect = 0;
SYSCTL_INT(_vfs_nfs, OID_AUTO, defect, CTLFLAG_RW, &nfs_defect, 0, "");
/*
* Asynchronous I/O daemons for client nfs.
* They do read-ahead and write-behind operations on the block I/O cache.
* Never returns unless it fails or gets killed.
*/
static int
nfssvc_iod(p)
struct proc *p;
{
register struct buf *bp;
register int i, myiod;
struct nfsmount *nmp;
int error = 0;
/*
* Assign my position or return error if too many already running
*/
myiod = -1;
for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
if (nfs_asyncdaemon[i] == 0) {
nfs_asyncdaemon[i]++;
myiod = i;
break;
}
if (myiod == -1)
return (EBUSY);
nfs_numasync++;
/*
* Just loop around doin our stuff until SIGKILL
*/
for (;;) {
while (((nmp = nfs_iodmount[myiod]) == NULL
|| nmp->nm_bufq.tqh_first == NULL)
&& error == 0) {
if (nmp)
nmp->nm_bufqiods--;
nfs_iodwant[myiod] = p;
nfs_iodmount[myiod] = NULL;
error = tsleep((caddr_t)&nfs_iodwant[myiod],
PWAIT | PCATCH, "nfsidl", 0);
}
if (error) {
nfs_asyncdaemon[myiod] = 0;
if (nmp) nmp->nm_bufqiods--;
nfs_iodwant[myiod] = NULL;
nfs_iodmount[myiod] = NULL;
nfs_numasync--;
return (error);
}
while ((bp = nmp->nm_bufq.tqh_first) != NULL) {
/* Take one off the front of the list */
TAILQ_REMOVE(&nmp->nm_bufq, bp, b_freelist);
nmp->nm_bufqlen--;
if (nmp->nm_bufqwant && nmp->nm_bufqlen < 2 * nfs_numasync) {
nmp->nm_bufqwant = FALSE;
wakeup(&nmp->nm_bufq);
}
if (bp->b_flags & B_READ)
(void) nfs_doio(bp, bp->b_rcred, (struct proc *)0);
else
(void) nfs_doio(bp, bp->b_wcred, (struct proc *)0);
/*
* If there are more than one iod on this mount, then defect
* so that the iods can be shared out fairly between the mounts
*/
if (nfs_defect && nmp->nm_bufqiods > 1) {
NFS_DPF(ASYNCIO,
("nfssvc_iod: iod %d defecting from mount %p\n",
myiod, nmp));
nfs_iodmount[myiod] = NULL;
nmp->nm_bufqiods--;
break;
}
}
}
}
/*
* Shut down a socket associated with an nfssvc_sock structure.
@ -885,6 +803,188 @@ nfsrv_zapsock(slp)
}
}
/*
* Derefence a server socket structure. If it has no more references and
* is no longer valid, you can throw it away.
*/
void
nfsrv_slpderef(slp)
register struct nfssvc_sock *slp;
{
if (--(slp->ns_sref) == 0 && (slp->ns_flag & SLP_VALID) == 0) {
TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
free((caddr_t)slp, M_NFSSVC);
}
}
/*
* Initialize the data structures for the server.
* Handshake with any new nfsds starting up to avoid any chance of
* corruption.
*/
void
nfsrv_init(terminating)
int terminating;
{
register struct nfssvc_sock *slp, *nslp;
if (nfssvc_sockhead_flag & SLP_INIT)
panic("nfsd init");
nfssvc_sockhead_flag |= SLP_INIT;
if (terminating) {
for (slp = nfssvc_sockhead.tqh_first; slp != 0; slp = nslp) {
nslp = slp->ns_chain.tqe_next;
if (slp->ns_flag & SLP_VALID)
nfsrv_zapsock(slp);
TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
free((caddr_t)slp, M_NFSSVC);
}
nfsrv_cleancache(); /* And clear out server cache */
} else
nfs_pub.np_valid = 0;
TAILQ_INIT(&nfssvc_sockhead);
nfssvc_sockhead_flag &= ~SLP_INIT;
if (nfssvc_sockhead_flag & SLP_WANTINIT) {
nfssvc_sockhead_flag &= ~SLP_WANTINIT;
wakeup((caddr_t)&nfssvc_sockhead);
}
TAILQ_INIT(&nfsd_head);
nfsd_head_flag &= ~NFSD_CHECKSLP;
nfs_udpsock = (struct nfssvc_sock *)
malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
bzero((caddr_t)nfs_udpsock, sizeof (struct nfssvc_sock));
STAILQ_INIT(&nfs_udpsock->ns_rec);
TAILQ_INIT(&nfs_udpsock->ns_uidlruhead);
TAILQ_INSERT_HEAD(&nfssvc_sockhead, nfs_udpsock, ns_chain);
nfs_cltpsock = (struct nfssvc_sock *)
malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
bzero((caddr_t)nfs_cltpsock, sizeof (struct nfssvc_sock));
STAILQ_INIT(&nfs_cltpsock->ns_rec);
TAILQ_INIT(&nfs_cltpsock->ns_uidlruhead);
TAILQ_INSERT_TAIL(&nfssvc_sockhead, nfs_cltpsock, ns_chain);
}
/*
* Add entries to the server monitor log.
*/
static void
nfsd_rt(sotype, nd, cacherep)
int sotype;
register struct nfsrv_descript *nd;
int cacherep;
{
register struct drt *rt;
rt = &nfsdrt.drt[nfsdrt.pos];
if (cacherep == RC_DOIT)
rt->flag = 0;
else if (cacherep == RC_REPLY)
rt->flag = DRT_CACHEREPLY;
else
rt->flag = DRT_CACHEDROP;
if (sotype == SOCK_STREAM)
rt->flag |= DRT_TCP;
if (nd->nd_flag & ND_NQNFS)
rt->flag |= DRT_NQNFS;
else if (nd->nd_flag & ND_NFSV3)
rt->flag |= DRT_NFSV3;
rt->proc = nd->nd_procnum;
if (nd->nd_nam->sa_family == AF_INET)
rt->ipadr = ((struct sockaddr_in *)nd->nd_nam)->sin_addr.s_addr;
else
rt->ipadr = INADDR_ANY;
rt->resptime = nfs_curusec() - (nd->nd_starttime.tv_sec * 1000000 + nd->nd_starttime.tv_usec);
getmicrotime(&rt->tstamp);
nfsdrt.pos = (nfsdrt.pos + 1) % NFSRTTLOGSIZ;
}
#endif /* NFS_NOSERVER */
static int nfs_defect = 0;
SYSCTL_INT(_vfs_nfs, OID_AUTO, defect, CTLFLAG_RW, &nfs_defect, 0, "");
/*
* Asynchronous I/O daemons for client nfs.
* They do read-ahead and write-behind operations on the block I/O cache.
* Never returns unless it fails or gets killed.
*/
static int
nfssvc_iod(p)
struct proc *p;
{
register struct buf *bp;
register int i, myiod;
struct nfsmount *nmp;
int error = 0;
/*
* Assign my position or return error if too many already running
*/
myiod = -1;
for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
if (nfs_asyncdaemon[i] == 0) {
nfs_asyncdaemon[i]++;
myiod = i;
break;
}
if (myiod == -1)
return (EBUSY);
nfs_numasync++;
/*
* Just loop around doin our stuff until SIGKILL
*/
for (;;) {
while (((nmp = nfs_iodmount[myiod]) == NULL
|| nmp->nm_bufq.tqh_first == NULL)
&& error == 0) {
if (nmp)
nmp->nm_bufqiods--;
nfs_iodwant[myiod] = p;
nfs_iodmount[myiod] = NULL;
error = tsleep((caddr_t)&nfs_iodwant[myiod],
PWAIT | PCATCH, "nfsidl", 0);
}
if (error) {
nfs_asyncdaemon[myiod] = 0;
if (nmp)
nmp->nm_bufqiods--;
nfs_iodwant[myiod] = NULL;
nfs_iodmount[myiod] = NULL;
nfs_numasync--;
return (error);
}
while ((bp = nmp->nm_bufq.tqh_first) != NULL) {
/* Take one off the front of the list */
TAILQ_REMOVE(&nmp->nm_bufq, bp, b_freelist);
nmp->nm_bufqlen--;
if (nmp->nm_bufqwant && nmp->nm_bufqlen < 2 * nfs_numasync) {
nmp->nm_bufqwant = FALSE;
wakeup(&nmp->nm_bufq);
}
if (bp->b_flags & B_READ)
(void) nfs_doio(bp, bp->b_rcred, (struct proc *)0);
else
(void) nfs_doio(bp, bp->b_wcred, (struct proc *)0);
/*
* If there are more than one iod on this mount, then defect
* so that the iods can be shared out fairly between the mounts
*/
if (nfs_defect && nmp->nm_bufqiods > 1) {
NFS_DPF(ASYNCIO,
("nfssvc_iod: iod %d defecting from mount %p\n",
myiod, nmp));
nfs_iodmount[myiod] = NULL;
nmp->nm_bufqiods--;
break;
}
}
}
}
/*
* Get an authorization string for the uid by having the mount_nfs sitting
* on this mount point porpous out of the kernel and do it.
@ -1088,105 +1188,3 @@ nfs_savenickauth(nmp, cred, len, key, mdp, dposp, mrep)
*dposp = dpos;
return (error);
}
#ifndef NFS_NOSERVER
/*
* Derefence a server socket structure. If it has no more references and
* is no longer valid, you can throw it away.
*/
void
nfsrv_slpderef(slp)
register struct nfssvc_sock *slp;
{
if (--(slp->ns_sref) == 0 && (slp->ns_flag & SLP_VALID) == 0) {
TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
free((caddr_t)slp, M_NFSSVC);
}
}
/*
* Initialize the data structures for the server.
* Handshake with any new nfsds starting up to avoid any chance of
* corruption.
*/
void
nfsrv_init(terminating)
int terminating;
{
register struct nfssvc_sock *slp, *nslp;
if (nfssvc_sockhead_flag & SLP_INIT)
panic("nfsd init");
nfssvc_sockhead_flag |= SLP_INIT;
if (terminating) {
for (slp = nfssvc_sockhead.tqh_first; slp != 0; slp = nslp) {
nslp = slp->ns_chain.tqe_next;
if (slp->ns_flag & SLP_VALID)
nfsrv_zapsock(slp);
TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
free((caddr_t)slp, M_NFSSVC);
}
nfsrv_cleancache(); /* And clear out server cache */
} else
nfs_pub.np_valid = 0;
TAILQ_INIT(&nfssvc_sockhead);
nfssvc_sockhead_flag &= ~SLP_INIT;
if (nfssvc_sockhead_flag & SLP_WANTINIT) {
nfssvc_sockhead_flag &= ~SLP_WANTINIT;
wakeup((caddr_t)&nfssvc_sockhead);
}
TAILQ_INIT(&nfsd_head);
nfsd_head_flag &= ~NFSD_CHECKSLP;
nfs_udpsock = (struct nfssvc_sock *)
malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
bzero((caddr_t)nfs_udpsock, sizeof (struct nfssvc_sock));
STAILQ_INIT(&nfs_udpsock->ns_rec);
TAILQ_INIT(&nfs_udpsock->ns_uidlruhead);
TAILQ_INSERT_HEAD(&nfssvc_sockhead, nfs_udpsock, ns_chain);
nfs_cltpsock = (struct nfssvc_sock *)
malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
bzero((caddr_t)nfs_cltpsock, sizeof (struct nfssvc_sock));
STAILQ_INIT(&nfs_cltpsock->ns_rec);
TAILQ_INIT(&nfs_cltpsock->ns_uidlruhead);
TAILQ_INSERT_TAIL(&nfssvc_sockhead, nfs_cltpsock, ns_chain);
}
/*
* Add entries to the server monitor log.
*/
static void
nfsd_rt(sotype, nd, cacherep)
int sotype;
register struct nfsrv_descript *nd;
int cacherep;
{
register struct drt *rt;
rt = &nfsdrt.drt[nfsdrt.pos];
if (cacherep == RC_DOIT)
rt->flag = 0;
else if (cacherep == RC_REPLY)
rt->flag = DRT_CACHEREPLY;
else
rt->flag = DRT_CACHEDROP;
if (sotype == SOCK_STREAM)
rt->flag |= DRT_TCP;
if (nd->nd_flag & ND_NQNFS)
rt->flag |= DRT_NQNFS;
else if (nd->nd_flag & ND_NFSV3)
rt->flag |= DRT_NFSV3;
rt->proc = nd->nd_procnum;
if (nd->nd_nam->sa_family == AF_INET)
rt->ipadr = ((struct sockaddr_in *)nd->nd_nam)->sin_addr.s_addr;
else
rt->ipadr = INADDR_ANY;
rt->resptime = nfs_curusec() - (nd->nd_starttime.tv_sec * 1000000 + nd->nd_starttime.tv_usec);
getmicrotime(&rt->tstamp);
nfsdrt.pos = (nfsdrt.pos + 1) % NFSRTTLOGSIZ;
}
#endif /* NFS_NOSERVER */

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
* $Id: nfs_socket.c,v 1.31 1998/03/30 09:54:04 phk Exp $
* $Id: nfs_socket.c,v 1.32 1998/05/19 07:11:23 peter Exp $
*/
/*
@ -249,7 +249,7 @@ nfs_connect(nmp, rep)
"nfscon", 2 * hz);
if ((so->so_state & SS_ISCONNECTING) &&
so->so_error == 0 && rep &&
(error = nfs_sigintr(nmp, rep, rep->r_procp))) {
(error = nfs_sigintr(nmp, rep, rep->r_procp)) != 0){
so->so_state &= ~SS_ISCONNECTING;
splx(s);
goto bad;
@ -335,7 +335,7 @@ nfs_reconnect(rep)
int error;
nfs_disconnect(nmp);
while ((error = nfs_connect(nmp, rep))) {
while ((error = nfs_connect(nmp, rep)) != 0) {
if (error == EINTR || error == ERESTART)
return (EINTR);
(void) tsleep((caddr_t)&lbolt, PSOCK, "nfscon", 0);
@ -419,8 +419,7 @@ nfs_send(so, nam, top, rep)
flags, curproc /*XXX*/);
if (error) {
if (rep) {
log(LOG_INFO, "nfs send error %d for server %s\n",
error,
log(LOG_INFO, "nfs send error %d for server %s\n",error,
rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname);
/*
* Deal with errors for the client side.
@ -518,7 +517,7 @@ nfs_receive(rep, aname, mp)
error = nfs_send(so, rep->r_nmp->nm_nam, m, rep);
if (error) {
if (error == EINTR || error == ERESTART ||
(error = nfs_reconnect(rep))) {
(error = nfs_reconnect(rep)) != 0) {
nfs_sndunlock(&rep->r_nmp->nm_flag,
&rep->r_nmp->nm_state);
return (error);
@ -1641,6 +1640,270 @@ nfs_realign(m, hsiz)
}
#ifndef NFS_NOSERVER
/*
* Parse an RPC request
* - verify it
* - fill in the cred struct.
*/
int
nfs_getreq(nd, nfsd, has_header)
register struct nfsrv_descript *nd;
struct nfsd *nfsd;
int has_header;
{
register int len, i;
register u_long *tl;
register long t1;
struct uio uio;
struct iovec iov;
caddr_t dpos, cp2, cp;
u_long nfsvers, auth_type;
uid_t nickuid;
int error = 0, nqnfs = 0, ticklen;
struct mbuf *mrep, *md;
register struct nfsuid *nuidp;
struct timeval tvin, tvout;
#if 0 /* until encrypted keys are implemented */
NFSKERBKEYSCHED_T keys; /* stores key schedule */
#endif
mrep = nd->nd_mrep;
md = nd->nd_md;
dpos = nd->nd_dpos;
if (has_header) {
nfsm_dissect(tl, u_long *, 10 * NFSX_UNSIGNED);
nd->nd_retxid = fxdr_unsigned(u_long, *tl++);
if (*tl++ != rpc_call) {
m_freem(mrep);
return (EBADRPC);
}
} else
nfsm_dissect(tl, u_long *, 8 * NFSX_UNSIGNED);
nd->nd_repstat = 0;
nd->nd_flag = 0;
if (*tl++ != rpc_vers) {
nd->nd_repstat = ERPCMISMATCH;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if (*tl != nfs_prog) {
if (*tl == nqnfs_prog)
nqnfs++;
else {
nd->nd_repstat = EPROGUNAVAIL;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
}
tl++;
nfsvers = fxdr_unsigned(u_long, *tl++);
if (((nfsvers < NFS_VER2 || nfsvers > NFS_VER3) && !nqnfs) ||
(nfsvers != NQNFS_VER3 && nqnfs)) {
nd->nd_repstat = EPROGMISMATCH;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if (nqnfs)
nd->nd_flag = (ND_NFSV3 | ND_NQNFS);
else if (nfsvers == NFS_VER3)
nd->nd_flag = ND_NFSV3;
nd->nd_procnum = fxdr_unsigned(u_long, *tl++);
if (nd->nd_procnum == NFSPROC_NULL)
return (0);
if (nd->nd_procnum >= NFS_NPROCS ||
(!nqnfs && nd->nd_procnum >= NQNFSPROC_GETLEASE) ||
(!nd->nd_flag && nd->nd_procnum > NFSV2PROC_STATFS)) {
nd->nd_repstat = EPROCUNAVAIL;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if ((nd->nd_flag & ND_NFSV3) == 0)
nd->nd_procnum = nfsv3_procid[nd->nd_procnum];
auth_type = *tl++;
len = fxdr_unsigned(int, *tl++);
if (len < 0 || len > RPCAUTH_MAXSIZ) {
m_freem(mrep);
return (EBADRPC);
}
nd->nd_flag &= ~ND_KERBAUTH;
/*
* Handle auth_unix or auth_kerb.
*/
if (auth_type == rpc_auth_unix) {
len = fxdr_unsigned(int, *++tl);
if (len < 0 || len > NFS_MAXNAMLEN) {
m_freem(mrep);
return (EBADRPC);
}
nfsm_adv(nfsm_rndup(len));
nfsm_dissect(tl, u_long *, 3 * NFSX_UNSIGNED);
bzero((caddr_t)&nd->nd_cr, sizeof (struct ucred));
nd->nd_cr.cr_ref = 1;
nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++);
nd->nd_cr.cr_gid = fxdr_unsigned(gid_t, *tl++);
len = fxdr_unsigned(int, *tl);
if (len < 0 || len > RPCAUTH_UNIXGIDS) {
m_freem(mrep);
return (EBADRPC);
}
nfsm_dissect(tl, u_long *, (len + 2) * NFSX_UNSIGNED);
for (i = 1; i <= len; i++)
if (i < NGROUPS)
nd->nd_cr.cr_groups[i] = fxdr_unsigned(gid_t, *tl++);
else
tl++;
nd->nd_cr.cr_ngroups = (len >= NGROUPS) ? NGROUPS : (len + 1);
if (nd->nd_cr.cr_ngroups > 1)
nfsrvw_sort(nd->nd_cr.cr_groups, nd->nd_cr.cr_ngroups);
len = fxdr_unsigned(int, *++tl);
if (len < 0 || len > RPCAUTH_MAXSIZ) {
m_freem(mrep);
return (EBADRPC);
}
if (len > 0)
nfsm_adv(nfsm_rndup(len));
} else if (auth_type == rpc_auth_kerb) {
switch (fxdr_unsigned(int, *tl++)) {
case RPCAKN_FULLNAME:
ticklen = fxdr_unsigned(int, *tl);
*((u_long *)nfsd->nfsd_authstr) = *tl;
uio.uio_resid = nfsm_rndup(ticklen) + NFSX_UNSIGNED;
nfsd->nfsd_authlen = uio.uio_resid + NFSX_UNSIGNED;
if (uio.uio_resid > (len - 2 * NFSX_UNSIGNED)) {
m_freem(mrep);
return (EBADRPC);
}
uio.uio_offset = 0;
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
uio.uio_segflg = UIO_SYSSPACE;
iov.iov_base = (caddr_t)&nfsd->nfsd_authstr[4];
iov.iov_len = RPCAUTH_MAXSIZ - 4;
nfsm_mtouio(&uio, uio.uio_resid);
nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED);
if (*tl++ != rpc_auth_kerb ||
fxdr_unsigned(int, *tl) != 4 * NFSX_UNSIGNED) {
printf("Bad kerb verifier\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsm_dissect(cp, caddr_t, 4 * NFSX_UNSIGNED);
tl = (u_long *)cp;
if (fxdr_unsigned(int, *tl) != RPCAKN_FULLNAME) {
printf("Not fullname kerb verifier\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
cp += NFSX_UNSIGNED;
bcopy(cp, nfsd->nfsd_verfstr, 3 * NFSX_UNSIGNED);
nfsd->nfsd_verflen = 3 * NFSX_UNSIGNED;
nd->nd_flag |= ND_KERBFULL;
nfsd->nfsd_flag |= NFSD_NEEDAUTH;
break;
case RPCAKN_NICKNAME:
if (len != 2 * NFSX_UNSIGNED) {
printf("Kerb nickname short\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nickuid = fxdr_unsigned(uid_t, *tl);
nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED);
if (*tl++ != rpc_auth_kerb ||
fxdr_unsigned(int, *tl) != 3 * NFSX_UNSIGNED) {
printf("Kerb nick verifier bad\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsm_dissect(tl, u_long *, 3 * NFSX_UNSIGNED);
tvin.tv_sec = *tl++;
tvin.tv_usec = *tl;
for (nuidp = NUIDHASH(nfsd->nfsd_slp,nickuid)->lh_first;
nuidp != 0; nuidp = nuidp->nu_hash.le_next) {
if (nuidp->nu_cr.cr_uid == nickuid &&
(!nd->nd_nam2 ||
netaddr_match(NU_NETFAM(nuidp),
&nuidp->nu_haddr, nd->nd_nam2)))
break;
}
if (!nuidp) {
nd->nd_repstat =
(NFSERR_AUTHERR|AUTH_REJECTCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
/*
* Now, decrypt the timestamp using the session key
* and validate it.
*/
#ifdef NFSKERB
XXX
#endif
tvout.tv_sec = fxdr_unsigned(long, tvout.tv_sec);
tvout.tv_usec = fxdr_unsigned(long, tvout.tv_usec);
if (nuidp->nu_expire < time_second ||
nuidp->nu_timestamp.tv_sec > tvout.tv_sec ||
(nuidp->nu_timestamp.tv_sec == tvout.tv_sec &&
nuidp->nu_timestamp.tv_usec > tvout.tv_usec)) {
nuidp->nu_expire = 0;
nd->nd_repstat =
(NFSERR_AUTHERR|AUTH_REJECTVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsrv_setcred(&nuidp->nu_cr, &nd->nd_cr);
nd->nd_flag |= ND_KERBNICK;
};
} else {
nd->nd_repstat = (NFSERR_AUTHERR | AUTH_REJECTCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
/*
* For nqnfs, get piggybacked lease request.
*/
if (nqnfs && nd->nd_procnum != NQNFSPROC_EVICTED) {
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
nd->nd_flag |= fxdr_unsigned(int, *tl);
if (nd->nd_flag & ND_LEASE) {
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
nd->nd_duration = fxdr_unsigned(int, *tl);
} else
nd->nd_duration = NQ_MINLEASE;
} else
nd->nd_duration = NQ_MINLEASE;
nd->nd_md = md;
nd->nd_dpos = dpos;
return (0);
nfsmout:
return (error);
}
static int
nfs_msg(p, server, msg)
struct proc *p;
char *server, *msg;
{
tpr_t tpr;
if (p)
tpr = tprintf_open(p);
else
tpr = NULL;
tprintf(tpr, "nfs server %s: %s\n", server, msg);
tprintf_close(tpr);
return (0);
}
/*
* Socket upcall routine for the nfsd sockets.
* The caddr_t arg is a pointer to the "struct nfssvc_sock".
@ -1926,253 +2189,6 @@ nfsrv_dorec(slp, nfsd, ndp)
return (0);
}
/*
* Parse an RPC request
* - verify it
* - fill in the cred struct.
*/
int
nfs_getreq(nd, nfsd, has_header)
register struct nfsrv_descript *nd;
struct nfsd *nfsd;
int has_header;
{
register int len, i;
register u_long *tl;
register long t1;
struct uio uio;
struct iovec iov;
caddr_t dpos, cp2, cp;
u_long nfsvers, auth_type;
uid_t nickuid;
int error = 0, nqnfs = 0, ticklen;
struct mbuf *mrep, *md;
register struct nfsuid *nuidp;
struct timeval tvin, tvout;
#if 0 /* until encrypted keys are implemented */
NFSKERBKEYSCHED_T keys; /* stores key schedule */
#endif
mrep = nd->nd_mrep;
md = nd->nd_md;
dpos = nd->nd_dpos;
if (has_header) {
nfsm_dissect(tl, u_long *, 10 * NFSX_UNSIGNED);
nd->nd_retxid = fxdr_unsigned(u_long, *tl++);
if (*tl++ != rpc_call) {
m_freem(mrep);
return (EBADRPC);
}
} else
nfsm_dissect(tl, u_long *, 8 * NFSX_UNSIGNED);
nd->nd_repstat = 0;
nd->nd_flag = 0;
if (*tl++ != rpc_vers) {
nd->nd_repstat = ERPCMISMATCH;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if (*tl != nfs_prog) {
if (*tl == nqnfs_prog)
nqnfs++;
else {
nd->nd_repstat = EPROGUNAVAIL;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
}
tl++;
nfsvers = fxdr_unsigned(u_long, *tl++);
if (((nfsvers < NFS_VER2 || nfsvers > NFS_VER3) && !nqnfs) ||
(nfsvers != NQNFS_VER3 && nqnfs)) {
nd->nd_repstat = EPROGMISMATCH;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if (nqnfs)
nd->nd_flag = (ND_NFSV3 | ND_NQNFS);
else if (nfsvers == NFS_VER3)
nd->nd_flag = ND_NFSV3;
nd->nd_procnum = fxdr_unsigned(u_long, *tl++);
if (nd->nd_procnum == NFSPROC_NULL)
return (0);
if (nd->nd_procnum >= NFS_NPROCS ||
(!nqnfs && nd->nd_procnum >= NQNFSPROC_GETLEASE) ||
(!nd->nd_flag && nd->nd_procnum > NFSV2PROC_STATFS)) {
nd->nd_repstat = EPROCUNAVAIL;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if ((nd->nd_flag & ND_NFSV3) == 0)
nd->nd_procnum = nfsv3_procid[nd->nd_procnum];
auth_type = *tl++;
len = fxdr_unsigned(int, *tl++);
if (len < 0 || len > RPCAUTH_MAXSIZ) {
m_freem(mrep);
return (EBADRPC);
}
nd->nd_flag &= ~ND_KERBAUTH;
/*
* Handle auth_unix or auth_kerb.
*/
if (auth_type == rpc_auth_unix) {
len = fxdr_unsigned(int, *++tl);
if (len < 0 || len > NFS_MAXNAMLEN) {
m_freem(mrep);
return (EBADRPC);
}
nfsm_adv(nfsm_rndup(len));
nfsm_dissect(tl, u_long *, 3 * NFSX_UNSIGNED);
bzero((caddr_t)&nd->nd_cr, sizeof (struct ucred));
nd->nd_cr.cr_ref = 1;
nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++);
nd->nd_cr.cr_gid = fxdr_unsigned(gid_t, *tl++);
len = fxdr_unsigned(int, *tl);
if (len < 0 || len > RPCAUTH_UNIXGIDS) {
m_freem(mrep);
return (EBADRPC);
}
nfsm_dissect(tl, u_long *, (len + 2) * NFSX_UNSIGNED);
for (i = 1; i <= len; i++)
if (i < NGROUPS)
nd->nd_cr.cr_groups[i] = fxdr_unsigned(gid_t, *tl++);
else
tl++;
nd->nd_cr.cr_ngroups = (len >= NGROUPS) ? NGROUPS : (len + 1);
if (nd->nd_cr.cr_ngroups > 1)
nfsrvw_sort(nd->nd_cr.cr_groups, nd->nd_cr.cr_ngroups);
len = fxdr_unsigned(int, *++tl);
if (len < 0 || len > RPCAUTH_MAXSIZ) {
m_freem(mrep);
return (EBADRPC);
}
if (len > 0)
nfsm_adv(nfsm_rndup(len));
} else if (auth_type == rpc_auth_kerb) {
switch (fxdr_unsigned(int, *tl++)) {
case RPCAKN_FULLNAME:
ticklen = fxdr_unsigned(int, *tl);
*((u_long *)nfsd->nfsd_authstr) = *tl;
uio.uio_resid = nfsm_rndup(ticklen) + NFSX_UNSIGNED;
nfsd->nfsd_authlen = uio.uio_resid + NFSX_UNSIGNED;
if (uio.uio_resid > (len - 2 * NFSX_UNSIGNED)) {
m_freem(mrep);
return (EBADRPC);
}
uio.uio_offset = 0;
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
uio.uio_segflg = UIO_SYSSPACE;
iov.iov_base = (caddr_t)&nfsd->nfsd_authstr[4];
iov.iov_len = RPCAUTH_MAXSIZ - 4;
nfsm_mtouio(&uio, uio.uio_resid);
nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED);
if (*tl++ != rpc_auth_kerb ||
fxdr_unsigned(int, *tl) != 4 * NFSX_UNSIGNED) {
printf("Bad kerb verifier\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsm_dissect(cp, caddr_t, 4 * NFSX_UNSIGNED);
tl = (u_long *)cp;
if (fxdr_unsigned(int, *tl) != RPCAKN_FULLNAME) {
printf("Not fullname kerb verifier\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
cp += NFSX_UNSIGNED;
bcopy(cp, nfsd->nfsd_verfstr, 3 * NFSX_UNSIGNED);
nfsd->nfsd_verflen = 3 * NFSX_UNSIGNED;
nd->nd_flag |= ND_KERBFULL;
nfsd->nfsd_flag |= NFSD_NEEDAUTH;
break;
case RPCAKN_NICKNAME:
if (len != 2 * NFSX_UNSIGNED) {
printf("Kerb nickname short\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nickuid = fxdr_unsigned(uid_t, *tl);
nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED);
if (*tl++ != rpc_auth_kerb ||
fxdr_unsigned(int, *tl) != 3 * NFSX_UNSIGNED) {
printf("Kerb nick verifier bad\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsm_dissect(tl, u_long *, 3 * NFSX_UNSIGNED);
tvin.tv_sec = *tl++;
tvin.tv_usec = *tl;
for (nuidp = NUIDHASH(nfsd->nfsd_slp,nickuid)->lh_first;
nuidp != 0; nuidp = nuidp->nu_hash.le_next) {
if (nuidp->nu_cr.cr_uid == nickuid &&
(!nd->nd_nam2 ||
netaddr_match(NU_NETFAM(nuidp),
&nuidp->nu_haddr, nd->nd_nam2)))
break;
}
if (!nuidp) {
nd->nd_repstat =
(NFSERR_AUTHERR|AUTH_REJECTCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
/*
* Now, decrypt the timestamp using the session key
* and validate it.
*/
#ifdef NFSKERB
XXX
#endif
tvout.tv_sec = fxdr_unsigned(long, tvout.tv_sec);
tvout.tv_usec = fxdr_unsigned(long, tvout.tv_usec);
if (nuidp->nu_expire < time_second ||
nuidp->nu_timestamp.tv_sec > tvout.tv_sec ||
(nuidp->nu_timestamp.tv_sec == tvout.tv_sec &&
nuidp->nu_timestamp.tv_usec > tvout.tv_usec)) {
nuidp->nu_expire = 0;
nd->nd_repstat =
(NFSERR_AUTHERR|AUTH_REJECTVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsrv_setcred(&nuidp->nu_cr, &nd->nd_cr);
nd->nd_flag |= ND_KERBNICK;
};
} else {
nd->nd_repstat = (NFSERR_AUTHERR | AUTH_REJECTCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
/*
* For nqnfs, get piggybacked lease request.
*/
if (nqnfs && nd->nd_procnum != NQNFSPROC_EVICTED) {
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
nd->nd_flag |= fxdr_unsigned(int, *tl);
if (nd->nd_flag & ND_LEASE) {
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
nd->nd_duration = fxdr_unsigned(int, *tl);
} else
nd->nd_duration = NQ_MINLEASE;
} else
nd->nd_duration = NQ_MINLEASE;
nd->nd_md = md;
nd->nd_dpos = dpos;
return (0);
nfsmout:
return (error);
}
/*
* Search for a sleeping nfsd and wake it up.
* SIDE EFFECT: If none found, set NFSD_CHECKSLP flag, so that one of the
@ -2201,19 +2217,3 @@ nfsrv_wakenfsd(slp)
nfsd_head_flag |= NFSD_CHECKSLP;
}
#endif /* NFS_NOSERVER */
static int
nfs_msg(p, server, msg)
struct proc *p;
char *server, *msg;
{
tpr_t tpr;
if (p)
tpr = tprintf_open(p);
else
tpr = NULL;
tprintf(tpr, "nfs server %s: %s\n", server, msg);
tprintf_close(tpr);
return (0);
}

View File

@ -33,8 +33,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
* $Id: nfs_subs.c,v 1.54 1998/05/19 07:11:24 peter Exp $
* @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95
* $Id: nfs_subs.c,v 1.55 1998/05/24 14:41:53 peter Exp $
*/
/*
@ -2129,4 +2129,45 @@ nfsrv_object_create(vp)
return (vfs_object_create(vp, curproc,
curproc ? curproc->p_ucred : NULL, 1));
}
/*
* Sort the group list in increasing numerical order.
* (Insertion sort by Chris Torek, who was grossed out by the bubble sort
* that used to be here.)
*/
void
nfsrvw_sort(list, num)
register gid_t *list;
register int num;
{
register int i, j;
gid_t v;
/* Insertion sort. */
for (i = 1; i < num; i++) {
v = list[i];
/* find correct slot for value v, moving others up */
for (j = i; --j >= 0 && v < list[j];)
list[j + 1] = list[j];
list[j + 1] = v;
}
}
/*
* copy credentials making sure that the result can be compared with bcmp().
*/
void
nfsrv_setcred(incred, outcred)
register struct ucred *incred, *outcred;
{
register int i;
bzero((caddr_t)outcred, sizeof (struct ucred));
outcred->cr_ref = 1;
outcred->cr_uid = incred->cr_uid;
outcred->cr_ngroups = incred->cr_ngroups;
for (i = 0; i < incred->cr_ngroups; i++)
outcred->cr_groups[i] = incred->cr_groups[i];
nfsrvw_sort(outcred->cr_groups, outcred->cr_ngroups);
}
#endif /* NFS_NOSERVER */

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_vfsops.c 8.12 (Berkeley) 5/20/95
* $Id: nfs_vfsops.c,v 1.63 1998/05/24 14:41:56 peter Exp $
* $Id: nfs_vfsops.c,v 1.64 1998/05/30 16:33:57 peter Exp $
*/
#include <sys/param.h>
@ -696,6 +696,7 @@ mountnfs(argp, mp, nam, pth, hst, vpp)
* unsuspecting binaries).
*/
mp->mnt_maxsymlinklen = 1;
if ((argp->flags & NFSMNT_NFSV3) == 0)
/*
* V2 can only handle 32 bit filesizes. For v3, nfs_fsinfo

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
* $Id: nfs_vnops.c,v 1.90 1998/05/30 16:33:57 peter Exp $
* $Id: nfs_vnops.c,v 1.91 1998/05/31 01:03:07 peter Exp $
*/
@ -275,8 +275,12 @@ nfs_access(ap)
*/
if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
switch (vp->v_type) {
case VREG: case VDIR: case VLNK:
case VREG:
case VDIR:
case VLNK:
return (EROFS);
default:
break;
}
}
/*
@ -296,17 +300,17 @@ nfs_access(ap)
mode = NFSV3ACCESS_READ;
else
mode = 0;
if (vp->v_type == VDIR) {
if (vp->v_type != VDIR) {
if (ap->a_mode & VWRITE)
mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND);
if (ap->a_mode & VEXEC)
mode |= NFSV3ACCESS_EXECUTE;
} else {
if (ap->a_mode & VWRITE)
mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND |
NFSV3ACCESS_DELETE);
if (ap->a_mode & VEXEC)
mode |= NFSV3ACCESS_LOOKUP;
} else {
if (ap->a_mode & VWRITE)
mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND);
if (ap->a_mode & VEXEC)
mode |= NFSV3ACCESS_EXECUTE;
}
*tl = txdr_unsigned(mode);
nfsm_request(vp, NFSPROC_ACCESS, ap->a_p, ap->a_cred);
@ -392,10 +396,10 @@ nfs_open(ap)
struct vattr vattr;
int error;
if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK)
{ printf("open eacces vtyp=%d\n",vp->v_type);
if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) {
printf("open eacces vtyp=%d\n",vp->v_type);
return (EACCES);
}
}
/*
* Get a valid lease. If cached data is stale, flush it.
*/
@ -545,8 +549,9 @@ nfs_getattr(ap)
nfsm_reqhead(vp, NFSPROC_GETATTR, NFSX_FH(v3));
nfsm_fhtom(vp, v3);
nfsm_request(vp, NFSPROC_GETATTR, ap->a_p, ap->a_cred);
if (!error)
if (!error) {
nfsm_loadattr(vp, ap->a_vap);
}
nfsm_reqdone;
return (error);
}
@ -756,14 +761,14 @@ nfs_lookup(ap)
struct componentname *a_cnp;
} */ *ap;
{
register struct componentname *cnp = ap->a_cnp;
register struct vnode *dvp = ap->a_dvp;
register struct vnode **vpp = ap->a_vpp;
register int flags = cnp->cn_flags;
register struct vnode *newvp;
register u_long *tl;
register caddr_t cp;
register long t1, t2;
struct componentname *cnp = ap->a_cnp;
struct vnode *dvp = ap->a_dvp;
struct vnode **vpp = ap->a_vpp;
int flags = cnp->cn_flags;
struct vnode *newvp;
u_long *tl;
caddr_t cp;
long t1, t2;
struct nfsmount *nmp;
caddr_t bpos, dpos, cp2;
struct mbuf *mreq, *mrep, *md, *mb, *mb2;
@ -858,7 +863,8 @@ nfs_lookup(ap)
m_freem(mrep);
return (EISDIR);
}
if (error = nfs_nget(dvp->v_mount, fhp, fhsize, &np)) {
error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
if (error) {
m_freem(mrep);
return (error);
}
@ -893,7 +899,8 @@ nfs_lookup(ap)
VREF(dvp);
newvp = dvp;
} else {
if (error = nfs_nget(dvp->v_mount, fhp, fhsize, &np)) {
error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
if (error) {
m_freem(mrep);
return (error);
}
@ -1146,8 +1153,7 @@ nfs_writerpc(vp, uiop, cred, iomode, must_commit)
else if (committed == NFSV3WRITE_DATASYNC &&
commit == NFSV3WRITE_UNSTABLE)
committed = commit;
if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0)
{
if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0){
bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf,
NFSX_V3WRITEVERF);
nmp->nm_state |= NFSSTA_HASWRITEVERF;
@ -2291,8 +2297,9 @@ nfs_readdirplusrpc(vp, uiop, cred)
newvp = vp;
np = dnp;
} else {
if (error = nfs_nget(vp->v_mount, fhp,
fhsize, &np))
error = nfs_nget(vp->v_mount, fhp,
fhsize, &np);
if (error)
doit = 0;
else
newvp = NFSTOV(np);
@ -2416,7 +2423,8 @@ nfs_sillyrename(dvp, vp, cnp)
goto bad;
}
}
if (error = nfs_renameit(dvp, cnp, sp))
error = nfs_renameit(dvp, cnp, sp);
if (error)
goto bad;
error = nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred,
cnp->cn_proc, &np);
@ -3069,8 +3077,12 @@ nfsspec_access(ap)
*/
if ((mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
switch (vp->v_type) {
case VREG: case VDIR: case VLNK:
case VREG:
case VDIR:
case VLNK:
return (EROFS);
default:
break;
}
}
/*

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
* $Id: nfs.h,v 1.35 1998/05/19 07:11:22 peter Exp $
* $Id: nfs.h,v 1.36 1998/05/24 14:41:47 peter Exp $
*/
#ifndef _NFS_NFS_H_
@ -293,14 +293,6 @@ struct nfsstats {
{ "nfsprivport", CTLTYPE_INT }, \
}
/*
* Network address hash list element
*/
union nethostaddr {
u_long had_inetaddr;
struct sockaddr *had_nam;
};
#ifdef KERNEL
#ifdef MALLOC_DECLARE
@ -399,6 +391,14 @@ extern TAILQ_HEAD(nfs_reqq, nfsreq) nfs_reqq;
#define NFSNOHASH(fhsum) \
(&nfsnodehashtbl[(fhsum) & nfsnodehash])
/*
* Network address hash list element
*/
union nethostaddr {
u_long had_inetaddr;
struct sockaddr *had_nam;
};
struct nfsuid {
TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */
LIST_ENTRY(nfsuid) nu_hash; /* Hash list */

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfsm_subs.h 8.2 (Berkeley) 3/30/95
* $Id: nfsm_subs.h,v 1.15 1998/03/30 09:54:41 phk Exp $
* $Id: nfsm_subs.h,v 1.16 1998/05/16 15:11:24 bde Exp $
*/
@ -105,7 +105,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
if (t1 >= (s)) { \
(a) = (c)(dpos); \
dpos += (s); \
} else if (t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) { \
} else if ((t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) != 0){ \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
@ -122,8 +122,9 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
*(tl + ((t2>>2) - 2)) = 0; \
bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \
VTONFS(v)->n_fhsize); \
} else if (t2 = nfsm_strtmbuf(&mb, &bpos, \
(caddr_t)VTONFS(v)->n_fhp, VTONFS(v)->n_fhsize)) { \
} else if ((t2 = nfsm_strtmbuf(&mb, &bpos, \
(caddr_t)VTONFS(v)->n_fhp, \
VTONFS(v)->n_fhsize)) != 0) { \
error = t2; \
m_freem(mreq); \
goto nfsmout; \
@ -159,8 +160,8 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
(f) = 1; \
if (f) { \
nfsm_getfh(ttfhp, ttfhsize, (v3)); \
if (t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
&ttnp)) { \
if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
&ttnp)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
@ -193,7 +194,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
#define nfsm_loadattr(v, a) \
{ struct vnode *ttvp = (v); \
if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) { \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
@ -204,8 +205,8 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
{ struct vnode *ttvp = (v); \
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
if ((f) = fxdr_unsigned(int, *tl)) { \
if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
(struct vattr *)0)) { \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
(struct vattr *)0)) != 0) { \
error = t1; \
(f) = 0; \
m_freem(mrep); \
@ -275,14 +276,14 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
#define nfsm_mtouio(p,s) \
if ((s) > 0 && \
(t1 = nfsm_mbuftouio(&md,(p),(s),&dpos))) { \
(t1 = nfsm_mbuftouio(&md,(p),(s),&dpos)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
}
#define nfsm_uiotom(p,s) \
if (t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) { \
if ((t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) != 0) { \
error = t1; \
m_freem(mreq); \
goto nfsmout; \
@ -297,8 +298,8 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
#define nfsm_rndup(a) (((a)+3)&(~0x3))
#define nfsm_request(v, t, p, c) \
if (error = nfs_request((v), mreq, (t), (p), \
(c), &mrep, &md, &dpos)) { \
if ((error = nfs_request((v), mreq, (t), (p), \
(c), &mrep, &md, &dpos)) != 0) { \
if (error & NFSERR_RETERR) \
error &= ~NFSERR_RETERR; \
else \
@ -317,7 +318,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
*tl++ = txdr_unsigned(s); \
*(tl+((t2>>2)-2)) = 0; \
bcopy((caddr_t)(a), (caddr_t)tl, (s)); \
} else if (t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) { \
} else if ((t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) != 0) { \
error = t2; \
m_freem(mreq); \
goto nfsmout; \
@ -358,7 +359,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
{ t1 = mtod(md, caddr_t)+md->m_len-dpos; \
if (t1 >= (s)) { \
dpos += (s); \
} else if (t1 = nfs_adv(&md, &dpos, (s), t1)) { \
} else if ((t1 = nfs_adv(&md, &dpos, (s), t1)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
* $Id: nfs.h,v 1.35 1998/05/19 07:11:22 peter Exp $
* $Id: nfs.h,v 1.36 1998/05/24 14:41:47 peter Exp $
*/
#ifndef _NFS_NFS_H_
@ -293,14 +293,6 @@ struct nfsstats {
{ "nfsprivport", CTLTYPE_INT }, \
}
/*
* Network address hash list element
*/
union nethostaddr {
u_long had_inetaddr;
struct sockaddr *had_nam;
};
#ifdef KERNEL
#ifdef MALLOC_DECLARE
@ -399,6 +391,14 @@ extern TAILQ_HEAD(nfs_reqq, nfsreq) nfs_reqq;
#define NFSNOHASH(fhsum) \
(&nfsnodehashtbl[(fhsum) & nfsnodehash])
/*
* Network address hash list element
*/
union nethostaddr {
u_long had_inetaddr;
struct sockaddr *had_nam;
};
struct nfsuid {
TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */
LIST_ENTRY(nfsuid) nu_hash; /* Hash list */

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
* $Id: nfs.h,v 1.35 1998/05/19 07:11:22 peter Exp $
* $Id: nfs.h,v 1.36 1998/05/24 14:41:47 peter Exp $
*/
#ifndef _NFS_NFS_H_
@ -293,14 +293,6 @@ struct nfsstats {
{ "nfsprivport", CTLTYPE_INT }, \
}
/*
* Network address hash list element
*/
union nethostaddr {
u_long had_inetaddr;
struct sockaddr *had_nam;
};
#ifdef KERNEL
#ifdef MALLOC_DECLARE
@ -399,6 +391,14 @@ extern TAILQ_HEAD(nfs_reqq, nfsreq) nfs_reqq;
#define NFSNOHASH(fhsum) \
(&nfsnodehashtbl[(fhsum) & nfsnodehash])
/*
* Network address hash list element
*/
union nethostaddr {
u_long had_inetaddr;
struct sockaddr *had_nam;
};
struct nfsuid {
TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */
LIST_ENTRY(nfsuid) nu_hash; /* Hash list */

View File

@ -33,8 +33,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfs_serv.c 8.3 (Berkeley) 1/12/94
* $Id: nfs_serv.c,v 1.61 1998/05/20 09:05:48 peter Exp $
* @(#)nfs_serv.c 8.8 (Berkeley) 7/31/95
* $Id: nfs_serv.c,v 1.62 1998/05/30 16:33:56 peter Exp $
*/
/*
@ -140,8 +140,9 @@ nfsrv3_access(nfsd, slp, procp, mrq)
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly,
(nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(NFSX_UNSIGNED);
nfsm_srvpostop_attr(1, (struct vattr *)0);
return (0);
@ -204,8 +205,9 @@ nfsrv_getattr(nfsd, slp, procp, mrq)
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(0);
return (0);
}
@ -296,8 +298,9 @@ nfsrv_setattr(nfsd, slp, procp, mrq)
/*
* Now that we have all the fields, lets do it.
*/
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly,
(nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(2 * NFSX_UNSIGNED);
nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap);
return (0);
@ -330,8 +333,8 @@ nfsrv_setattr(nfsd, slp, procp, mrq)
if (vp->v_type == VDIR) {
error = EISDIR;
goto out;
} else if (error = nfsrv_access(vp, VWRITE, cred, rdonly,
procp, 0))
} else if ((error = nfsrv_access(vp, VWRITE, cred, rdonly,
procp, 0)) != 0)
goto out;
}
error = VOP_SETATTR(vp, vap, cred, procp);
@ -537,8 +540,9 @@ nfsrv_readlink(nfsd, slp, procp, mrq)
uiop->uio_rw = UIO_READ;
uiop->uio_segflg = UIO_SYSSPACE;
uiop->uio_procp = (struct proc *)0;
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
m_freem(mp3);
nfsm_reply(2 * NFSX_UNSIGNED);
nfsm_srvpostop_attr(1, (struct vattr *)0);
@ -620,8 +624,9 @@ nfsrv_read(nfsd, slp, procp, mrq)
off = (off_t)fxdr_unsigned(u_long, *tl);
}
nfsm_srvstrsiz(reqlen, NFS_SRVMAXDATA(nfsd));
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(2 * NFSX_UNSIGNED);
nfsm_srvpostop_attr(1, (struct vattr *)0);
return (0);
@ -634,7 +639,7 @@ nfsrv_read(nfsd, slp, procp, mrq)
}
if (!error) {
nqsrv_getl(vp, ND_READ);
if (error = nfsrv_access(vp, VREAD, cred, rdonly, procp, 1))
if ((error = nfsrv_access(vp, VREAD, cred, rdonly, procp, 1)) != 0)
error = nfsrv_access(vp, VEXEC, cred, rdonly, procp, 1);
}
getret = VOP_GETATTR(vp, vap, cred, procp);
@ -834,8 +839,9 @@ nfsrv_write(nfsd, slp, procp, mrq)
nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap);
return (0);
}
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(2 * NFSX_UNSIGNED);
nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap);
return (0);
@ -1303,47 +1309,6 @@ nfsrvw_coalesce(owp, nfsd)
}
}
/*
* Sort the group list in increasing numerical order.
* (Insertion sort by Chris Torek, who was grossed out by the bubble sort
* that used to be here.)
*/
void
nfsrvw_sort(list, num)
register gid_t *list;
register int num;
{
register int i, j;
gid_t v;
/* Insertion sort. */
for (i = 1; i < num; i++) {
v = list[i];
/* find correct slot for value v, moving others up */
for (j = i; --j >= 0 && v < list[j];)
list[j + 1] = list[j];
list[j + 1] = v;
}
}
/*
* copy credentials making sure that the result can be compared with bcmp().
*/
void
nfsrv_setcred(incred, outcred)
register struct ucred *incred, *outcred;
{
register int i;
bzero((caddr_t)outcred, sizeof (struct ucred));
outcred->cr_ref = 1;
outcred->cr_uid = incred->cr_uid;
outcred->cr_ngroups = incred->cr_ngroups;
for (i = 0; i < incred->cr_ngroups; i++)
outcred->cr_groups[i] = incred->cr_groups[i];
nfsrvw_sort(outcred->cr_groups, outcred->cr_ngroups);
}
/*
* nfs create service
* now does a truncate to 0 length via. setattr if it already exists
@ -1445,6 +1410,8 @@ nfsrv_create(nfsd, slp, procp, mrq)
case VFIFO:
rdev = fxdr_unsigned(long, sp->sa_size);
break;
default:
break;
};
}
@ -1496,7 +1463,7 @@ nfsrv_create(nfsd, slp, procp, mrq)
nd.ni_cnd.cn_flags &= ~(LOCKPARENT | SAVESTART);
nd.ni_cnd.cn_proc = procp;
nd.ni_cnd.cn_cred = cred;
if (error = lookup(&nd)) {
if ((error = lookup(&nd)) != 0) {
zfree(namei_zone, nd.ni_cnd.cn_pnbuf);
nfsm_reply(0);
}
@ -1801,9 +1768,7 @@ nfsrv_remove(nfsd, slp, procp, mrq)
if (!error) {
nqsrv_getl(nd.ni_dvp, ND_WRITE);
nqsrv_getl(vp, ND_WRITE);
error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
} else {
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
}
@ -2065,8 +2030,9 @@ nfsrv_link(nfsd, slp, procp, mrq)
nfsm_srvmtofh(fhp);
nfsm_srvmtofh(dfhp);
nfsm_srvnamesiz(len);
if (error = nfsrv_fhtovp(fhp, FALSE, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, FALSE, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
nfsm_srvpostop_attr(getret, &at);
nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
@ -2577,8 +2543,9 @@ nfsrv_readdir(nfsd, slp, procp, mrq)
if (siz > xfer)
siz = xfer;
fullsiz = siz;
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(NFSX_UNSIGNED);
nfsm_srvpostop_attr(getret, &at);
return (0);
@ -2832,8 +2799,9 @@ nfsrv_readdirplus(nfsd, slp, procp, mrq)
if (siz > xfer)
siz = xfer;
fullsiz = siz;
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(NFSX_UNSIGNED);
nfsm_srvpostop_attr(getret, &at);
return (0);
@ -3128,8 +3096,9 @@ nfsrv_commit(nfsd, slp, procp, mrq)
fxdr_hyper(tl, &off);
tl += 2;
cnt = fxdr_unsigned(int, *tl);
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(2 * NFSX_UNSIGNED);
nfsm_srvwcc_data(for_ret, &bfor, aft_ret, &aft);
return (0);
@ -3188,8 +3157,9 @@ nfsrv_statfs(nfsd, slp, procp, mrq)
#endif
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(NFSX_UNSIGNED);
nfsm_srvpostop_attr(getret, &at);
return (0);
@ -3340,8 +3310,9 @@ nfsrv_pathconf(nfsd, slp, procp, mrq)
#endif
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) {
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE);
if (error) {
nfsm_reply(NFSX_UNSIGNED);
nfsm_srvpostop_attr(getret, &at);
return (0);
@ -3462,8 +3433,12 @@ nfsrv_access(vp, flags, cred, rdonly, p, override)
*/
if (rdonly || (vp->v_mount->mnt_flag & MNT_RDONLY)) {
switch (vp->v_type) {
case VREG: case VDIR: case VLNK:
case VREG:
case VDIR:
case VLNK:
return (EROFS);
default:
break;
}
}
/*
@ -3473,7 +3448,8 @@ nfsrv_access(vp, flags, cred, rdonly, p, override)
if (vp->v_flag & VTEXT)
return (ETXTBSY);
}
if (error = VOP_GETATTR(vp, &vattr, cred, p))
error = VOP_GETATTR(vp, &vattr, cred, p);
if (error)
return (error);
error = VOP_ACCESS(vp, flags, cred, p);
/*

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
* $Id: nfs_socket.c,v 1.31 1998/03/30 09:54:04 phk Exp $
* $Id: nfs_socket.c,v 1.32 1998/05/19 07:11:23 peter Exp $
*/
/*
@ -249,7 +249,7 @@ nfs_connect(nmp, rep)
"nfscon", 2 * hz);
if ((so->so_state & SS_ISCONNECTING) &&
so->so_error == 0 && rep &&
(error = nfs_sigintr(nmp, rep, rep->r_procp))) {
(error = nfs_sigintr(nmp, rep, rep->r_procp)) != 0){
so->so_state &= ~SS_ISCONNECTING;
splx(s);
goto bad;
@ -335,7 +335,7 @@ nfs_reconnect(rep)
int error;
nfs_disconnect(nmp);
while ((error = nfs_connect(nmp, rep))) {
while ((error = nfs_connect(nmp, rep)) != 0) {
if (error == EINTR || error == ERESTART)
return (EINTR);
(void) tsleep((caddr_t)&lbolt, PSOCK, "nfscon", 0);
@ -419,8 +419,7 @@ nfs_send(so, nam, top, rep)
flags, curproc /*XXX*/);
if (error) {
if (rep) {
log(LOG_INFO, "nfs send error %d for server %s\n",
error,
log(LOG_INFO, "nfs send error %d for server %s\n",error,
rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname);
/*
* Deal with errors for the client side.
@ -518,7 +517,7 @@ nfs_receive(rep, aname, mp)
error = nfs_send(so, rep->r_nmp->nm_nam, m, rep);
if (error) {
if (error == EINTR || error == ERESTART ||
(error = nfs_reconnect(rep))) {
(error = nfs_reconnect(rep)) != 0) {
nfs_sndunlock(&rep->r_nmp->nm_flag,
&rep->r_nmp->nm_state);
return (error);
@ -1641,6 +1640,270 @@ nfs_realign(m, hsiz)
}
#ifndef NFS_NOSERVER
/*
* Parse an RPC request
* - verify it
* - fill in the cred struct.
*/
int
nfs_getreq(nd, nfsd, has_header)
register struct nfsrv_descript *nd;
struct nfsd *nfsd;
int has_header;
{
register int len, i;
register u_long *tl;
register long t1;
struct uio uio;
struct iovec iov;
caddr_t dpos, cp2, cp;
u_long nfsvers, auth_type;
uid_t nickuid;
int error = 0, nqnfs = 0, ticklen;
struct mbuf *mrep, *md;
register struct nfsuid *nuidp;
struct timeval tvin, tvout;
#if 0 /* until encrypted keys are implemented */
NFSKERBKEYSCHED_T keys; /* stores key schedule */
#endif
mrep = nd->nd_mrep;
md = nd->nd_md;
dpos = nd->nd_dpos;
if (has_header) {
nfsm_dissect(tl, u_long *, 10 * NFSX_UNSIGNED);
nd->nd_retxid = fxdr_unsigned(u_long, *tl++);
if (*tl++ != rpc_call) {
m_freem(mrep);
return (EBADRPC);
}
} else
nfsm_dissect(tl, u_long *, 8 * NFSX_UNSIGNED);
nd->nd_repstat = 0;
nd->nd_flag = 0;
if (*tl++ != rpc_vers) {
nd->nd_repstat = ERPCMISMATCH;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if (*tl != nfs_prog) {
if (*tl == nqnfs_prog)
nqnfs++;
else {
nd->nd_repstat = EPROGUNAVAIL;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
}
tl++;
nfsvers = fxdr_unsigned(u_long, *tl++);
if (((nfsvers < NFS_VER2 || nfsvers > NFS_VER3) && !nqnfs) ||
(nfsvers != NQNFS_VER3 && nqnfs)) {
nd->nd_repstat = EPROGMISMATCH;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if (nqnfs)
nd->nd_flag = (ND_NFSV3 | ND_NQNFS);
else if (nfsvers == NFS_VER3)
nd->nd_flag = ND_NFSV3;
nd->nd_procnum = fxdr_unsigned(u_long, *tl++);
if (nd->nd_procnum == NFSPROC_NULL)
return (0);
if (nd->nd_procnum >= NFS_NPROCS ||
(!nqnfs && nd->nd_procnum >= NQNFSPROC_GETLEASE) ||
(!nd->nd_flag && nd->nd_procnum > NFSV2PROC_STATFS)) {
nd->nd_repstat = EPROCUNAVAIL;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if ((nd->nd_flag & ND_NFSV3) == 0)
nd->nd_procnum = nfsv3_procid[nd->nd_procnum];
auth_type = *tl++;
len = fxdr_unsigned(int, *tl++);
if (len < 0 || len > RPCAUTH_MAXSIZ) {
m_freem(mrep);
return (EBADRPC);
}
nd->nd_flag &= ~ND_KERBAUTH;
/*
* Handle auth_unix or auth_kerb.
*/
if (auth_type == rpc_auth_unix) {
len = fxdr_unsigned(int, *++tl);
if (len < 0 || len > NFS_MAXNAMLEN) {
m_freem(mrep);
return (EBADRPC);
}
nfsm_adv(nfsm_rndup(len));
nfsm_dissect(tl, u_long *, 3 * NFSX_UNSIGNED);
bzero((caddr_t)&nd->nd_cr, sizeof (struct ucred));
nd->nd_cr.cr_ref = 1;
nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++);
nd->nd_cr.cr_gid = fxdr_unsigned(gid_t, *tl++);
len = fxdr_unsigned(int, *tl);
if (len < 0 || len > RPCAUTH_UNIXGIDS) {
m_freem(mrep);
return (EBADRPC);
}
nfsm_dissect(tl, u_long *, (len + 2) * NFSX_UNSIGNED);
for (i = 1; i <= len; i++)
if (i < NGROUPS)
nd->nd_cr.cr_groups[i] = fxdr_unsigned(gid_t, *tl++);
else
tl++;
nd->nd_cr.cr_ngroups = (len >= NGROUPS) ? NGROUPS : (len + 1);
if (nd->nd_cr.cr_ngroups > 1)
nfsrvw_sort(nd->nd_cr.cr_groups, nd->nd_cr.cr_ngroups);
len = fxdr_unsigned(int, *++tl);
if (len < 0 || len > RPCAUTH_MAXSIZ) {
m_freem(mrep);
return (EBADRPC);
}
if (len > 0)
nfsm_adv(nfsm_rndup(len));
} else if (auth_type == rpc_auth_kerb) {
switch (fxdr_unsigned(int, *tl++)) {
case RPCAKN_FULLNAME:
ticklen = fxdr_unsigned(int, *tl);
*((u_long *)nfsd->nfsd_authstr) = *tl;
uio.uio_resid = nfsm_rndup(ticklen) + NFSX_UNSIGNED;
nfsd->nfsd_authlen = uio.uio_resid + NFSX_UNSIGNED;
if (uio.uio_resid > (len - 2 * NFSX_UNSIGNED)) {
m_freem(mrep);
return (EBADRPC);
}
uio.uio_offset = 0;
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
uio.uio_segflg = UIO_SYSSPACE;
iov.iov_base = (caddr_t)&nfsd->nfsd_authstr[4];
iov.iov_len = RPCAUTH_MAXSIZ - 4;
nfsm_mtouio(&uio, uio.uio_resid);
nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED);
if (*tl++ != rpc_auth_kerb ||
fxdr_unsigned(int, *tl) != 4 * NFSX_UNSIGNED) {
printf("Bad kerb verifier\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsm_dissect(cp, caddr_t, 4 * NFSX_UNSIGNED);
tl = (u_long *)cp;
if (fxdr_unsigned(int, *tl) != RPCAKN_FULLNAME) {
printf("Not fullname kerb verifier\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
cp += NFSX_UNSIGNED;
bcopy(cp, nfsd->nfsd_verfstr, 3 * NFSX_UNSIGNED);
nfsd->nfsd_verflen = 3 * NFSX_UNSIGNED;
nd->nd_flag |= ND_KERBFULL;
nfsd->nfsd_flag |= NFSD_NEEDAUTH;
break;
case RPCAKN_NICKNAME:
if (len != 2 * NFSX_UNSIGNED) {
printf("Kerb nickname short\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nickuid = fxdr_unsigned(uid_t, *tl);
nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED);
if (*tl++ != rpc_auth_kerb ||
fxdr_unsigned(int, *tl) != 3 * NFSX_UNSIGNED) {
printf("Kerb nick verifier bad\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsm_dissect(tl, u_long *, 3 * NFSX_UNSIGNED);
tvin.tv_sec = *tl++;
tvin.tv_usec = *tl;
for (nuidp = NUIDHASH(nfsd->nfsd_slp,nickuid)->lh_first;
nuidp != 0; nuidp = nuidp->nu_hash.le_next) {
if (nuidp->nu_cr.cr_uid == nickuid &&
(!nd->nd_nam2 ||
netaddr_match(NU_NETFAM(nuidp),
&nuidp->nu_haddr, nd->nd_nam2)))
break;
}
if (!nuidp) {
nd->nd_repstat =
(NFSERR_AUTHERR|AUTH_REJECTCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
/*
* Now, decrypt the timestamp using the session key
* and validate it.
*/
#ifdef NFSKERB
XXX
#endif
tvout.tv_sec = fxdr_unsigned(long, tvout.tv_sec);
tvout.tv_usec = fxdr_unsigned(long, tvout.tv_usec);
if (nuidp->nu_expire < time_second ||
nuidp->nu_timestamp.tv_sec > tvout.tv_sec ||
(nuidp->nu_timestamp.tv_sec == tvout.tv_sec &&
nuidp->nu_timestamp.tv_usec > tvout.tv_usec)) {
nuidp->nu_expire = 0;
nd->nd_repstat =
(NFSERR_AUTHERR|AUTH_REJECTVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsrv_setcred(&nuidp->nu_cr, &nd->nd_cr);
nd->nd_flag |= ND_KERBNICK;
};
} else {
nd->nd_repstat = (NFSERR_AUTHERR | AUTH_REJECTCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
/*
* For nqnfs, get piggybacked lease request.
*/
if (nqnfs && nd->nd_procnum != NQNFSPROC_EVICTED) {
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
nd->nd_flag |= fxdr_unsigned(int, *tl);
if (nd->nd_flag & ND_LEASE) {
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
nd->nd_duration = fxdr_unsigned(int, *tl);
} else
nd->nd_duration = NQ_MINLEASE;
} else
nd->nd_duration = NQ_MINLEASE;
nd->nd_md = md;
nd->nd_dpos = dpos;
return (0);
nfsmout:
return (error);
}
static int
nfs_msg(p, server, msg)
struct proc *p;
char *server, *msg;
{
tpr_t tpr;
if (p)
tpr = tprintf_open(p);
else
tpr = NULL;
tprintf(tpr, "nfs server %s: %s\n", server, msg);
tprintf_close(tpr);
return (0);
}
/*
* Socket upcall routine for the nfsd sockets.
* The caddr_t arg is a pointer to the "struct nfssvc_sock".
@ -1926,253 +2189,6 @@ nfsrv_dorec(slp, nfsd, ndp)
return (0);
}
/*
* Parse an RPC request
* - verify it
* - fill in the cred struct.
*/
int
nfs_getreq(nd, nfsd, has_header)
register struct nfsrv_descript *nd;
struct nfsd *nfsd;
int has_header;
{
register int len, i;
register u_long *tl;
register long t1;
struct uio uio;
struct iovec iov;
caddr_t dpos, cp2, cp;
u_long nfsvers, auth_type;
uid_t nickuid;
int error = 0, nqnfs = 0, ticklen;
struct mbuf *mrep, *md;
register struct nfsuid *nuidp;
struct timeval tvin, tvout;
#if 0 /* until encrypted keys are implemented */
NFSKERBKEYSCHED_T keys; /* stores key schedule */
#endif
mrep = nd->nd_mrep;
md = nd->nd_md;
dpos = nd->nd_dpos;
if (has_header) {
nfsm_dissect(tl, u_long *, 10 * NFSX_UNSIGNED);
nd->nd_retxid = fxdr_unsigned(u_long, *tl++);
if (*tl++ != rpc_call) {
m_freem(mrep);
return (EBADRPC);
}
} else
nfsm_dissect(tl, u_long *, 8 * NFSX_UNSIGNED);
nd->nd_repstat = 0;
nd->nd_flag = 0;
if (*tl++ != rpc_vers) {
nd->nd_repstat = ERPCMISMATCH;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if (*tl != nfs_prog) {
if (*tl == nqnfs_prog)
nqnfs++;
else {
nd->nd_repstat = EPROGUNAVAIL;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
}
tl++;
nfsvers = fxdr_unsigned(u_long, *tl++);
if (((nfsvers < NFS_VER2 || nfsvers > NFS_VER3) && !nqnfs) ||
(nfsvers != NQNFS_VER3 && nqnfs)) {
nd->nd_repstat = EPROGMISMATCH;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if (nqnfs)
nd->nd_flag = (ND_NFSV3 | ND_NQNFS);
else if (nfsvers == NFS_VER3)
nd->nd_flag = ND_NFSV3;
nd->nd_procnum = fxdr_unsigned(u_long, *tl++);
if (nd->nd_procnum == NFSPROC_NULL)
return (0);
if (nd->nd_procnum >= NFS_NPROCS ||
(!nqnfs && nd->nd_procnum >= NQNFSPROC_GETLEASE) ||
(!nd->nd_flag && nd->nd_procnum > NFSV2PROC_STATFS)) {
nd->nd_repstat = EPROCUNAVAIL;
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
if ((nd->nd_flag & ND_NFSV3) == 0)
nd->nd_procnum = nfsv3_procid[nd->nd_procnum];
auth_type = *tl++;
len = fxdr_unsigned(int, *tl++);
if (len < 0 || len > RPCAUTH_MAXSIZ) {
m_freem(mrep);
return (EBADRPC);
}
nd->nd_flag &= ~ND_KERBAUTH;
/*
* Handle auth_unix or auth_kerb.
*/
if (auth_type == rpc_auth_unix) {
len = fxdr_unsigned(int, *++tl);
if (len < 0 || len > NFS_MAXNAMLEN) {
m_freem(mrep);
return (EBADRPC);
}
nfsm_adv(nfsm_rndup(len));
nfsm_dissect(tl, u_long *, 3 * NFSX_UNSIGNED);
bzero((caddr_t)&nd->nd_cr, sizeof (struct ucred));
nd->nd_cr.cr_ref = 1;
nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++);
nd->nd_cr.cr_gid = fxdr_unsigned(gid_t, *tl++);
len = fxdr_unsigned(int, *tl);
if (len < 0 || len > RPCAUTH_UNIXGIDS) {
m_freem(mrep);
return (EBADRPC);
}
nfsm_dissect(tl, u_long *, (len + 2) * NFSX_UNSIGNED);
for (i = 1; i <= len; i++)
if (i < NGROUPS)
nd->nd_cr.cr_groups[i] = fxdr_unsigned(gid_t, *tl++);
else
tl++;
nd->nd_cr.cr_ngroups = (len >= NGROUPS) ? NGROUPS : (len + 1);
if (nd->nd_cr.cr_ngroups > 1)
nfsrvw_sort(nd->nd_cr.cr_groups, nd->nd_cr.cr_ngroups);
len = fxdr_unsigned(int, *++tl);
if (len < 0 || len > RPCAUTH_MAXSIZ) {
m_freem(mrep);
return (EBADRPC);
}
if (len > 0)
nfsm_adv(nfsm_rndup(len));
} else if (auth_type == rpc_auth_kerb) {
switch (fxdr_unsigned(int, *tl++)) {
case RPCAKN_FULLNAME:
ticklen = fxdr_unsigned(int, *tl);
*((u_long *)nfsd->nfsd_authstr) = *tl;
uio.uio_resid = nfsm_rndup(ticklen) + NFSX_UNSIGNED;
nfsd->nfsd_authlen = uio.uio_resid + NFSX_UNSIGNED;
if (uio.uio_resid > (len - 2 * NFSX_UNSIGNED)) {
m_freem(mrep);
return (EBADRPC);
}
uio.uio_offset = 0;
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
uio.uio_segflg = UIO_SYSSPACE;
iov.iov_base = (caddr_t)&nfsd->nfsd_authstr[4];
iov.iov_len = RPCAUTH_MAXSIZ - 4;
nfsm_mtouio(&uio, uio.uio_resid);
nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED);
if (*tl++ != rpc_auth_kerb ||
fxdr_unsigned(int, *tl) != 4 * NFSX_UNSIGNED) {
printf("Bad kerb verifier\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsm_dissect(cp, caddr_t, 4 * NFSX_UNSIGNED);
tl = (u_long *)cp;
if (fxdr_unsigned(int, *tl) != RPCAKN_FULLNAME) {
printf("Not fullname kerb verifier\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
cp += NFSX_UNSIGNED;
bcopy(cp, nfsd->nfsd_verfstr, 3 * NFSX_UNSIGNED);
nfsd->nfsd_verflen = 3 * NFSX_UNSIGNED;
nd->nd_flag |= ND_KERBFULL;
nfsd->nfsd_flag |= NFSD_NEEDAUTH;
break;
case RPCAKN_NICKNAME:
if (len != 2 * NFSX_UNSIGNED) {
printf("Kerb nickname short\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nickuid = fxdr_unsigned(uid_t, *tl);
nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED);
if (*tl++ != rpc_auth_kerb ||
fxdr_unsigned(int, *tl) != 3 * NFSX_UNSIGNED) {
printf("Kerb nick verifier bad\n");
nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsm_dissect(tl, u_long *, 3 * NFSX_UNSIGNED);
tvin.tv_sec = *tl++;
tvin.tv_usec = *tl;
for (nuidp = NUIDHASH(nfsd->nfsd_slp,nickuid)->lh_first;
nuidp != 0; nuidp = nuidp->nu_hash.le_next) {
if (nuidp->nu_cr.cr_uid == nickuid &&
(!nd->nd_nam2 ||
netaddr_match(NU_NETFAM(nuidp),
&nuidp->nu_haddr, nd->nd_nam2)))
break;
}
if (!nuidp) {
nd->nd_repstat =
(NFSERR_AUTHERR|AUTH_REJECTCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
/*
* Now, decrypt the timestamp using the session key
* and validate it.
*/
#ifdef NFSKERB
XXX
#endif
tvout.tv_sec = fxdr_unsigned(long, tvout.tv_sec);
tvout.tv_usec = fxdr_unsigned(long, tvout.tv_usec);
if (nuidp->nu_expire < time_second ||
nuidp->nu_timestamp.tv_sec > tvout.tv_sec ||
(nuidp->nu_timestamp.tv_sec == tvout.tv_sec &&
nuidp->nu_timestamp.tv_usec > tvout.tv_usec)) {
nuidp->nu_expire = 0;
nd->nd_repstat =
(NFSERR_AUTHERR|AUTH_REJECTVERF);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
nfsrv_setcred(&nuidp->nu_cr, &nd->nd_cr);
nd->nd_flag |= ND_KERBNICK;
};
} else {
nd->nd_repstat = (NFSERR_AUTHERR | AUTH_REJECTCRED);
nd->nd_procnum = NFSPROC_NOOP;
return (0);
}
/*
* For nqnfs, get piggybacked lease request.
*/
if (nqnfs && nd->nd_procnum != NQNFSPROC_EVICTED) {
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
nd->nd_flag |= fxdr_unsigned(int, *tl);
if (nd->nd_flag & ND_LEASE) {
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
nd->nd_duration = fxdr_unsigned(int, *tl);
} else
nd->nd_duration = NQ_MINLEASE;
} else
nd->nd_duration = NQ_MINLEASE;
nd->nd_md = md;
nd->nd_dpos = dpos;
return (0);
nfsmout:
return (error);
}
/*
* Search for a sleeping nfsd and wake it up.
* SIDE EFFECT: If none found, set NFSD_CHECKSLP flag, so that one of the
@ -2201,19 +2217,3 @@ nfsrv_wakenfsd(slp)
nfsd_head_flag |= NFSD_CHECKSLP;
}
#endif /* NFS_NOSERVER */
static int
nfs_msg(p, server, msg)
struct proc *p;
char *server, *msg;
{
tpr_t tpr;
if (p)
tpr = tprintf_open(p);
else
tpr = NULL;
tprintf(tpr, "nfs server %s: %s\n", server, msg);
tprintf_close(tpr);
return (0);
}

View File

@ -33,8 +33,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
* $Id: nfs_subs.c,v 1.54 1998/05/19 07:11:24 peter Exp $
* @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95
* $Id: nfs_subs.c,v 1.55 1998/05/24 14:41:53 peter Exp $
*/
/*
@ -2129,4 +2129,45 @@ nfsrv_object_create(vp)
return (vfs_object_create(vp, curproc,
curproc ? curproc->p_ucred : NULL, 1));
}
/*
* Sort the group list in increasing numerical order.
* (Insertion sort by Chris Torek, who was grossed out by the bubble sort
* that used to be here.)
*/
void
nfsrvw_sort(list, num)
register gid_t *list;
register int num;
{
register int i, j;
gid_t v;
/* Insertion sort. */
for (i = 1; i < num; i++) {
v = list[i];
/* find correct slot for value v, moving others up */
for (j = i; --j >= 0 && v < list[j];)
list[j + 1] = list[j];
list[j + 1] = v;
}
}
/*
* copy credentials making sure that the result can be compared with bcmp().
*/
void
nfsrv_setcred(incred, outcred)
register struct ucred *incred, *outcred;
{
register int i;
bzero((caddr_t)outcred, sizeof (struct ucred));
outcred->cr_ref = 1;
outcred->cr_uid = incred->cr_uid;
outcred->cr_ngroups = incred->cr_ngroups;
for (i = 0; i < incred->cr_ngroups; i++)
outcred->cr_groups[i] = incred->cr_groups[i];
nfsrvw_sort(outcred->cr_groups, outcred->cr_ngroups);
}
#endif /* NFS_NOSERVER */

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95
* $Id: nfs_syscalls.c,v 1.37 1998/03/30 09:54:17 phk Exp $
* $Id: nfs_syscalls.c,v 1.38 1998/05/19 07:11:25 peter Exp $
*/
#include <sys/param.h>
@ -252,8 +252,9 @@ nfssvc(p, uap)
error = copyin(uap->argp, (caddr_t)nsd, sizeof (*nsd));
if (error)
return (error);
if ((uap->flag & NFSSVC_AUTHIN) && ((nfsd = nsd->nsd_nfsd)) &&
(nfsd->nfsd_slp->ns_flag & SLP_VALID)) {
if ((uap->flag & NFSSVC_AUTHIN) &&
((nfsd = nsd->nsd_nfsd)) != NULL &&
(nfsd->nfsd_slp->ns_flag & SLP_VALID)) {
slp = nfsd->nfsd_slp;
/*
@ -465,11 +466,10 @@ nfssvc_nfsd(nsd, argp, p)
writes_todo = 0;
#endif
if (nfsd == (struct nfsd *)0) {
nfsd = (struct nfsd *)
nsd->nsd_nfsd = nfsd = (struct nfsd *)
malloc(sizeof (struct nfsd), M_NFSD, M_WAITOK);
bzero((caddr_t)nfsd, sizeof (struct nfsd));
s = splnet();
nsd->nsd_nfsd = nfsd;
nfsd->nfsd_procp = p;
TAILQ_INSERT_TAIL(&nfsd_head, nfsd, nfsd_chain);
nfs_numnfsd++;
@ -746,88 +746,6 @@ nfssvc_nfsd(nsd, argp, p)
nfsrv_init(TRUE); /* Reinitialize everything */
return (error);
}
#endif /* NFS_NOSERVER */
static int nfs_defect = 0;
SYSCTL_INT(_vfs_nfs, OID_AUTO, defect, CTLFLAG_RW, &nfs_defect, 0, "");
/*
* Asynchronous I/O daemons for client nfs.
* They do read-ahead and write-behind operations on the block I/O cache.
* Never returns unless it fails or gets killed.
*/
static int
nfssvc_iod(p)
struct proc *p;
{
register struct buf *bp;
register int i, myiod;
struct nfsmount *nmp;
int error = 0;
/*
* Assign my position or return error if too many already running
*/
myiod = -1;
for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
if (nfs_asyncdaemon[i] == 0) {
nfs_asyncdaemon[i]++;
myiod = i;
break;
}
if (myiod == -1)
return (EBUSY);
nfs_numasync++;
/*
* Just loop around doin our stuff until SIGKILL
*/
for (;;) {
while (((nmp = nfs_iodmount[myiod]) == NULL
|| nmp->nm_bufq.tqh_first == NULL)
&& error == 0) {
if (nmp)
nmp->nm_bufqiods--;
nfs_iodwant[myiod] = p;
nfs_iodmount[myiod] = NULL;
error = tsleep((caddr_t)&nfs_iodwant[myiod],
PWAIT | PCATCH, "nfsidl", 0);
}
if (error) {
nfs_asyncdaemon[myiod] = 0;
if (nmp) nmp->nm_bufqiods--;
nfs_iodwant[myiod] = NULL;
nfs_iodmount[myiod] = NULL;
nfs_numasync--;
return (error);
}
while ((bp = nmp->nm_bufq.tqh_first) != NULL) {
/* Take one off the front of the list */
TAILQ_REMOVE(&nmp->nm_bufq, bp, b_freelist);
nmp->nm_bufqlen--;
if (nmp->nm_bufqwant && nmp->nm_bufqlen < 2 * nfs_numasync) {
nmp->nm_bufqwant = FALSE;
wakeup(&nmp->nm_bufq);
}
if (bp->b_flags & B_READ)
(void) nfs_doio(bp, bp->b_rcred, (struct proc *)0);
else
(void) nfs_doio(bp, bp->b_wcred, (struct proc *)0);
/*
* If there are more than one iod on this mount, then defect
* so that the iods can be shared out fairly between the mounts
*/
if (nfs_defect && nmp->nm_bufqiods > 1) {
NFS_DPF(ASYNCIO,
("nfssvc_iod: iod %d defecting from mount %p\n",
myiod, nmp));
nfs_iodmount[myiod] = NULL;
nmp->nm_bufqiods--;
break;
}
}
}
}
/*
* Shut down a socket associated with an nfssvc_sock structure.
@ -885,6 +803,188 @@ nfsrv_zapsock(slp)
}
}
/*
* Derefence a server socket structure. If it has no more references and
* is no longer valid, you can throw it away.
*/
void
nfsrv_slpderef(slp)
register struct nfssvc_sock *slp;
{
if (--(slp->ns_sref) == 0 && (slp->ns_flag & SLP_VALID) == 0) {
TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
free((caddr_t)slp, M_NFSSVC);
}
}
/*
* Initialize the data structures for the server.
* Handshake with any new nfsds starting up to avoid any chance of
* corruption.
*/
void
nfsrv_init(terminating)
int terminating;
{
register struct nfssvc_sock *slp, *nslp;
if (nfssvc_sockhead_flag & SLP_INIT)
panic("nfsd init");
nfssvc_sockhead_flag |= SLP_INIT;
if (terminating) {
for (slp = nfssvc_sockhead.tqh_first; slp != 0; slp = nslp) {
nslp = slp->ns_chain.tqe_next;
if (slp->ns_flag & SLP_VALID)
nfsrv_zapsock(slp);
TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
free((caddr_t)slp, M_NFSSVC);
}
nfsrv_cleancache(); /* And clear out server cache */
} else
nfs_pub.np_valid = 0;
TAILQ_INIT(&nfssvc_sockhead);
nfssvc_sockhead_flag &= ~SLP_INIT;
if (nfssvc_sockhead_flag & SLP_WANTINIT) {
nfssvc_sockhead_flag &= ~SLP_WANTINIT;
wakeup((caddr_t)&nfssvc_sockhead);
}
TAILQ_INIT(&nfsd_head);
nfsd_head_flag &= ~NFSD_CHECKSLP;
nfs_udpsock = (struct nfssvc_sock *)
malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
bzero((caddr_t)nfs_udpsock, sizeof (struct nfssvc_sock));
STAILQ_INIT(&nfs_udpsock->ns_rec);
TAILQ_INIT(&nfs_udpsock->ns_uidlruhead);
TAILQ_INSERT_HEAD(&nfssvc_sockhead, nfs_udpsock, ns_chain);
nfs_cltpsock = (struct nfssvc_sock *)
malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
bzero((caddr_t)nfs_cltpsock, sizeof (struct nfssvc_sock));
STAILQ_INIT(&nfs_cltpsock->ns_rec);
TAILQ_INIT(&nfs_cltpsock->ns_uidlruhead);
TAILQ_INSERT_TAIL(&nfssvc_sockhead, nfs_cltpsock, ns_chain);
}
/*
* Add entries to the server monitor log.
*/
static void
nfsd_rt(sotype, nd, cacherep)
int sotype;
register struct nfsrv_descript *nd;
int cacherep;
{
register struct drt *rt;
rt = &nfsdrt.drt[nfsdrt.pos];
if (cacherep == RC_DOIT)
rt->flag = 0;
else if (cacherep == RC_REPLY)
rt->flag = DRT_CACHEREPLY;
else
rt->flag = DRT_CACHEDROP;
if (sotype == SOCK_STREAM)
rt->flag |= DRT_TCP;
if (nd->nd_flag & ND_NQNFS)
rt->flag |= DRT_NQNFS;
else if (nd->nd_flag & ND_NFSV3)
rt->flag |= DRT_NFSV3;
rt->proc = nd->nd_procnum;
if (nd->nd_nam->sa_family == AF_INET)
rt->ipadr = ((struct sockaddr_in *)nd->nd_nam)->sin_addr.s_addr;
else
rt->ipadr = INADDR_ANY;
rt->resptime = nfs_curusec() - (nd->nd_starttime.tv_sec * 1000000 + nd->nd_starttime.tv_usec);
getmicrotime(&rt->tstamp);
nfsdrt.pos = (nfsdrt.pos + 1) % NFSRTTLOGSIZ;
}
#endif /* NFS_NOSERVER */
static int nfs_defect = 0;
SYSCTL_INT(_vfs_nfs, OID_AUTO, defect, CTLFLAG_RW, &nfs_defect, 0, "");
/*
* Asynchronous I/O daemons for client nfs.
* They do read-ahead and write-behind operations on the block I/O cache.
* Never returns unless it fails or gets killed.
*/
static int
nfssvc_iod(p)
struct proc *p;
{
register struct buf *bp;
register int i, myiod;
struct nfsmount *nmp;
int error = 0;
/*
* Assign my position or return error if too many already running
*/
myiod = -1;
for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
if (nfs_asyncdaemon[i] == 0) {
nfs_asyncdaemon[i]++;
myiod = i;
break;
}
if (myiod == -1)
return (EBUSY);
nfs_numasync++;
/*
* Just loop around doin our stuff until SIGKILL
*/
for (;;) {
while (((nmp = nfs_iodmount[myiod]) == NULL
|| nmp->nm_bufq.tqh_first == NULL)
&& error == 0) {
if (nmp)
nmp->nm_bufqiods--;
nfs_iodwant[myiod] = p;
nfs_iodmount[myiod] = NULL;
error = tsleep((caddr_t)&nfs_iodwant[myiod],
PWAIT | PCATCH, "nfsidl", 0);
}
if (error) {
nfs_asyncdaemon[myiod] = 0;
if (nmp)
nmp->nm_bufqiods--;
nfs_iodwant[myiod] = NULL;
nfs_iodmount[myiod] = NULL;
nfs_numasync--;
return (error);
}
while ((bp = nmp->nm_bufq.tqh_first) != NULL) {
/* Take one off the front of the list */
TAILQ_REMOVE(&nmp->nm_bufq, bp, b_freelist);
nmp->nm_bufqlen--;
if (nmp->nm_bufqwant && nmp->nm_bufqlen < 2 * nfs_numasync) {
nmp->nm_bufqwant = FALSE;
wakeup(&nmp->nm_bufq);
}
if (bp->b_flags & B_READ)
(void) nfs_doio(bp, bp->b_rcred, (struct proc *)0);
else
(void) nfs_doio(bp, bp->b_wcred, (struct proc *)0);
/*
* If there are more than one iod on this mount, then defect
* so that the iods can be shared out fairly between the mounts
*/
if (nfs_defect && nmp->nm_bufqiods > 1) {
NFS_DPF(ASYNCIO,
("nfssvc_iod: iod %d defecting from mount %p\n",
myiod, nmp));
nfs_iodmount[myiod] = NULL;
nmp->nm_bufqiods--;
break;
}
}
}
}
/*
* Get an authorization string for the uid by having the mount_nfs sitting
* on this mount point porpous out of the kernel and do it.
@ -1088,105 +1188,3 @@ nfs_savenickauth(nmp, cred, len, key, mdp, dposp, mrep)
*dposp = dpos;
return (error);
}
#ifndef NFS_NOSERVER
/*
* Derefence a server socket structure. If it has no more references and
* is no longer valid, you can throw it away.
*/
void
nfsrv_slpderef(slp)
register struct nfssvc_sock *slp;
{
if (--(slp->ns_sref) == 0 && (slp->ns_flag & SLP_VALID) == 0) {
TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
free((caddr_t)slp, M_NFSSVC);
}
}
/*
* Initialize the data structures for the server.
* Handshake with any new nfsds starting up to avoid any chance of
* corruption.
*/
void
nfsrv_init(terminating)
int terminating;
{
register struct nfssvc_sock *slp, *nslp;
if (nfssvc_sockhead_flag & SLP_INIT)
panic("nfsd init");
nfssvc_sockhead_flag |= SLP_INIT;
if (terminating) {
for (slp = nfssvc_sockhead.tqh_first; slp != 0; slp = nslp) {
nslp = slp->ns_chain.tqe_next;
if (slp->ns_flag & SLP_VALID)
nfsrv_zapsock(slp);
TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
free((caddr_t)slp, M_NFSSVC);
}
nfsrv_cleancache(); /* And clear out server cache */
} else
nfs_pub.np_valid = 0;
TAILQ_INIT(&nfssvc_sockhead);
nfssvc_sockhead_flag &= ~SLP_INIT;
if (nfssvc_sockhead_flag & SLP_WANTINIT) {
nfssvc_sockhead_flag &= ~SLP_WANTINIT;
wakeup((caddr_t)&nfssvc_sockhead);
}
TAILQ_INIT(&nfsd_head);
nfsd_head_flag &= ~NFSD_CHECKSLP;
nfs_udpsock = (struct nfssvc_sock *)
malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
bzero((caddr_t)nfs_udpsock, sizeof (struct nfssvc_sock));
STAILQ_INIT(&nfs_udpsock->ns_rec);
TAILQ_INIT(&nfs_udpsock->ns_uidlruhead);
TAILQ_INSERT_HEAD(&nfssvc_sockhead, nfs_udpsock, ns_chain);
nfs_cltpsock = (struct nfssvc_sock *)
malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
bzero((caddr_t)nfs_cltpsock, sizeof (struct nfssvc_sock));
STAILQ_INIT(&nfs_cltpsock->ns_rec);
TAILQ_INIT(&nfs_cltpsock->ns_uidlruhead);
TAILQ_INSERT_TAIL(&nfssvc_sockhead, nfs_cltpsock, ns_chain);
}
/*
* Add entries to the server monitor log.
*/
static void
nfsd_rt(sotype, nd, cacherep)
int sotype;
register struct nfsrv_descript *nd;
int cacherep;
{
register struct drt *rt;
rt = &nfsdrt.drt[nfsdrt.pos];
if (cacherep == RC_DOIT)
rt->flag = 0;
else if (cacherep == RC_REPLY)
rt->flag = DRT_CACHEREPLY;
else
rt->flag = DRT_CACHEDROP;
if (sotype == SOCK_STREAM)
rt->flag |= DRT_TCP;
if (nd->nd_flag & ND_NQNFS)
rt->flag |= DRT_NQNFS;
else if (nd->nd_flag & ND_NFSV3)
rt->flag |= DRT_NFSV3;
rt->proc = nd->nd_procnum;
if (nd->nd_nam->sa_family == AF_INET)
rt->ipadr = ((struct sockaddr_in *)nd->nd_nam)->sin_addr.s_addr;
else
rt->ipadr = INADDR_ANY;
rt->resptime = nfs_curusec() - (nd->nd_starttime.tv_sec * 1000000 + nd->nd_starttime.tv_usec);
getmicrotime(&rt->tstamp);
nfsdrt.pos = (nfsdrt.pos + 1) % NFSRTTLOGSIZ;
}
#endif /* NFS_NOSERVER */

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfsm_subs.h 8.2 (Berkeley) 3/30/95
* $Id: nfsm_subs.h,v 1.15 1998/03/30 09:54:41 phk Exp $
* $Id: nfsm_subs.h,v 1.16 1998/05/16 15:11:24 bde Exp $
*/
@ -105,7 +105,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
if (t1 >= (s)) { \
(a) = (c)(dpos); \
dpos += (s); \
} else if (t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) { \
} else if ((t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) != 0){ \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
@ -122,8 +122,9 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
*(tl + ((t2>>2) - 2)) = 0; \
bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \
VTONFS(v)->n_fhsize); \
} else if (t2 = nfsm_strtmbuf(&mb, &bpos, \
(caddr_t)VTONFS(v)->n_fhp, VTONFS(v)->n_fhsize)) { \
} else if ((t2 = nfsm_strtmbuf(&mb, &bpos, \
(caddr_t)VTONFS(v)->n_fhp, \
VTONFS(v)->n_fhsize)) != 0) { \
error = t2; \
m_freem(mreq); \
goto nfsmout; \
@ -159,8 +160,8 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
(f) = 1; \
if (f) { \
nfsm_getfh(ttfhp, ttfhsize, (v3)); \
if (t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
&ttnp)) { \
if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
&ttnp)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
@ -193,7 +194,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
#define nfsm_loadattr(v, a) \
{ struct vnode *ttvp = (v); \
if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) { \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
@ -204,8 +205,8 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
{ struct vnode *ttvp = (v); \
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
if ((f) = fxdr_unsigned(int, *tl)) { \
if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
(struct vattr *)0)) { \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
(struct vattr *)0)) != 0) { \
error = t1; \
(f) = 0; \
m_freem(mrep); \
@ -275,14 +276,14 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
#define nfsm_mtouio(p,s) \
if ((s) > 0 && \
(t1 = nfsm_mbuftouio(&md,(p),(s),&dpos))) { \
(t1 = nfsm_mbuftouio(&md,(p),(s),&dpos)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
}
#define nfsm_uiotom(p,s) \
if (t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) { \
if ((t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) != 0) { \
error = t1; \
m_freem(mreq); \
goto nfsmout; \
@ -297,8 +298,8 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
#define nfsm_rndup(a) (((a)+3)&(~0x3))
#define nfsm_request(v, t, p, c) \
if (error = nfs_request((v), mreq, (t), (p), \
(c), &mrep, &md, &dpos)) { \
if ((error = nfs_request((v), mreq, (t), (p), \
(c), &mrep, &md, &dpos)) != 0) { \
if (error & NFSERR_RETERR) \
error &= ~NFSERR_RETERR; \
else \
@ -317,7 +318,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
*tl++ = txdr_unsigned(s); \
*(tl+((t2>>2)-2)) = 0; \
bcopy((caddr_t)(a), (caddr_t)tl, (s)); \
} else if (t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) { \
} else if ((t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) != 0) { \
error = t2; \
m_freem(mreq); \
goto nfsmout; \
@ -358,7 +359,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
{ t1 = mtod(md, caddr_t)+md->m_len-dpos; \
if (t1 >= (s)) { \
dpos += (s); \
} else if (t1 = nfs_adv(&md, &dpos, (s), t1)) { \
} else if ((t1 = nfs_adv(&md, &dpos, (s), t1)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \

View File

@ -33,8 +33,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfsproto.h 8.1 (Berkeley) 6/10/93
* $Id$
* @(#)nfsproto.h 8.2 (Berkeley) 3/30/95
* $Id: nfsproto.h,v 1.3 1997/02/22 09:42:50 peter Exp $
*/
#ifndef _NFS_NFSPROTO_H_

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
* $Id: nfs.h,v 1.35 1998/05/19 07:11:22 peter Exp $
* $Id: nfs.h,v 1.36 1998/05/24 14:41:47 peter Exp $
*/
#ifndef _NFS_NFS_H_
@ -293,14 +293,6 @@ struct nfsstats {
{ "nfsprivport", CTLTYPE_INT }, \
}
/*
* Network address hash list element
*/
union nethostaddr {
u_long had_inetaddr;
struct sockaddr *had_nam;
};
#ifdef KERNEL
#ifdef MALLOC_DECLARE
@ -399,6 +391,14 @@ extern TAILQ_HEAD(nfs_reqq, nfsreq) nfs_reqq;
#define NFSNOHASH(fhsum) \
(&nfsnodehashtbl[(fhsum) & nfsnodehash])
/*
* Network address hash list element
*/
union nethostaddr {
u_long had_inetaddr;
struct sockaddr *had_nam;
};
struct nfsuid {
TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */
LIST_ENTRY(nfsuid) nu_hash; /* Hash list */