version 1.199, 2008/02/13 09:51:37 |
version 1.199.6.4, 2008/09/28 10:41:00 |
Line 94 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 94 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <sys/mbuf.h> |
#include <sys/mbuf.h> |
#include <sys/socket.h> |
#include <sys/socket.h> |
#include <sys/stat.h> |
#include <sys/stat.h> |
#include <sys/malloc.h> |
|
#include <sys/filedesc.h> |
#include <sys/filedesc.h> |
#include <sys/time.h> |
#include <sys/time.h> |
#include <sys/dirent.h> |
#include <sys/dirent.h> |
Line 564 static const short * const nfsrv_v3errma |
|
Line 563 static const short * const nfsrv_v3errma |
|
nfsv3err_commit, |
nfsv3err_commit, |
}; |
}; |
|
|
|
extern struct vfs_hooks nfs_export_hooks; |
extern struct nfsrtt nfsrtt; |
extern struct nfsrtt nfsrtt; |
extern struct nfsnodehashhead *nfsnodehashtbl; |
extern struct nfsnodehashhead *nfsnodehashtbl; |
extern u_long nfsnodehash; |
extern u_long nfsnodehash; |
Line 948 nfsm_disct(mdp, dposp, siz, left, cp2) |
|
Line 948 nfsm_disct(mdp, dposp, siz, left, cp2) |
|
return (0); |
return (0); |
} |
} |
} |
} |
if (m1->m_flags & M_EXT) { |
if ((m1->m_flags & M_EXT) != 0) { |
if (havebuf) { |
if (havebuf && M_TRAILINGSPACE(havebuf) >= siz && |
/* If the first mbuf with data has external data |
nfsm_aligned(mtod(havebuf, char *) + havebuf->m_len)) { |
* and there is a previous empty mbuf use it |
/* |
* to move the data into. |
* If the first mbuf with data has external data |
|
* and there is a previous mbuf with some trailing |
|
* space, use it to move the data into. |
*/ |
*/ |
m2 = m1; |
m2 = m1; |
*mdp = m1 = havebuf; |
*mdp = m1 = havebuf; |
if (m1->m_flags & M_EXT) { |
*cp2 = mtod(m1, char *) + m1->m_len; |
MEXTREMOVE(m1); |
} else if (havebuf) { |
} |
|
} else { |
|
/* |
/* |
* If the first mbuf has a external data |
* If the first mbuf has a external data |
* and there is no previous empty mbuf |
* and there is no previous empty mbuf |
Line 967 nfsm_disct(mdp, dposp, siz, left, cp2) |
|
Line 967 nfsm_disct(mdp, dposp, siz, left, cp2) |
|
* data to the new mbuf. Also make the first |
* data to the new mbuf. Also make the first |
* mbuf look empty. |
* mbuf look empty. |
*/ |
*/ |
m2 = m_get(M_WAIT, MT_DATA); |
m2 = m1; |
m2->m_ext = m1->m_ext; |
*mdp = m1 = m_get(M_WAIT, MT_DATA); |
|
MCLAIM(m1, m2->m_owner); |
|
if ((m2->m_flags & M_PKTHDR) != 0) { |
|
/* XXX MOVE */ |
|
M_COPY_PKTHDR(m1, m2); |
|
m_tag_delete_chain(m2, NULL); |
|
m2->m_flags &= ~M_PKTHDR; |
|
} |
|
if (havebuf) { |
|
havebuf->m_next = m1; |
|
} |
|
m1->m_next = m2; |
|
MRESETDATA(m1); |
|
m1->m_len = 0; |
m2->m_data = src; |
m2->m_data = src; |
m2->m_len = left; |
m2->m_len = left; |
MCLADDREFERENCE(m1, m2); |
*cp2 = mtod(m1, char *); |
MEXTREMOVE(m1); |
} else { |
m2->m_next = m1->m_next; |
struct mbuf **nextp = &m1->m_next; |
m1->m_next = m2; |
|
|
m1->m_len -= left; |
|
do { |
|
m2 = m_get(M_WAIT, MT_DATA); |
|
MCLAIM(m2, m1->m_owner); |
|
if (left >= MINCLSIZE) { |
|
MCLGET(m2, M_WAIT); |
|
} |
|
m2->m_next = *nextp; |
|
*nextp = m2; |
|
nextp = &m2->m_next; |
|
len = (m2->m_flags & M_EXT) != 0 ? |
|
MCLBYTES : MLEN; |
|
if (len > left) { |
|
len = left; |
|
} |
|
memcpy(mtod(m2, char *), src, len); |
|
m2->m_len = len; |
|
src += len; |
|
left -= len; |
|
} while (left > 0); |
|
*mdp = m1 = m1->m_next; |
|
m2 = m1->m_next; |
|
*cp2 = mtod(m1, char *); |
} |
} |
m1->m_len = 0; |
|
if (m1->m_flags & M_PKTHDR) |
|
dst = m1->m_pktdat; |
|
else |
|
dst = m1->m_dat; |
|
m1->m_data = dst; |
|
} else { |
} else { |
/* |
/* |
* If the first mbuf has no external data |
* If the first mbuf has no external data |
* move the data to the front of the mbuf. |
* move the data to the front of the mbuf. |
*/ |
*/ |
if (m1->m_flags & M_PKTHDR) |
MRESETDATA(m1); |
dst = m1->m_pktdat; |
dst = mtod(m1, char *); |
else |
if (dst != src) { |
dst = m1->m_dat; |
|
m1->m_data = dst; |
|
if (dst != src) |
|
memmove(dst, src, left); |
memmove(dst, src, left); |
dst += left; |
} |
m1->m_len = left; |
m1->m_len = left; |
m2 = m1->m_next; |
m2 = m1->m_next; |
|
*cp2 = m1->m_data; |
} |
} |
*cp2 = m1->m_data; |
*dposp = *cp2 + siz; |
*dposp = mtod(m1, char *) + siz; |
|
/* |
/* |
* Loop through mbufs pulling data up into first mbuf until |
* Loop through mbufs pulling data up into first mbuf until |
* the first mbuf is full or there is no more data to |
* the first mbuf is full or there is no more data to |
* pullup. |
* pullup. |
*/ |
*/ |
|
dst = mtod(m1, char *) + m1->m_len; |
while ((len = M_TRAILINGSPACE(m1)) != 0 && m2) { |
while ((len = M_TRAILINGSPACE(m1)) != 0 && m2) { |
if ((len = min(len, m2->m_len)) != 0) |
if ((len = min(len, m2->m_len)) != 0) { |
memcpy(dst, m2->m_data, len); |
memcpy(dst, mtod(m2, char *), len); |
|
} |
m1->m_len += len; |
m1->m_len += len; |
dst += len; |
dst += len; |
m2->m_data += len; |
m2->m_data += len; |
Line 1174 nfs_initdircache(vp) |
|
Line 1203 nfs_initdircache(vp) |
|
struct nfsnode *np = VTONFS(vp); |
struct nfsnode *np = VTONFS(vp); |
struct nfsdirhashhead *dircache; |
struct nfsdirhashhead *dircache; |
|
|
dircache = hashinit(NFS_DIRHASHSIZ, HASH_LIST, M_NFSDIROFF, |
dircache = hashinit(NFS_DIRHASHSIZ, HASH_LIST, true, |
M_WAITOK, &nfsdirhashmask); |
&nfsdirhashmask); |
|
|
NFSDC_LOCK(np); |
NFSDC_LOCK(np); |
if (np->n_dircache == NULL) { |
if (np->n_dircache == NULL) { |
Line 1186 nfs_initdircache(vp) |
|
Line 1215 nfs_initdircache(vp) |
|
} |
} |
NFSDC_UNLOCK(np); |
NFSDC_UNLOCK(np); |
if (dircache) |
if (dircache) |
hashdone(dircache, M_NFSDIROFF); |
hashdone(dircache, HASH_LIST, nfsdirhashmask); |
} |
} |
|
|
void |
void |
Line 1511 nfs_init0(void) |
|
Line 1540 nfs_init0(void) |
|
if (nfs_ticks < 1) |
if (nfs_ticks < 1) |
nfs_ticks = 1; |
nfs_ticks = 1; |
#ifdef NFSSERVER |
#ifdef NFSSERVER |
|
vfs_hooks_attach(&nfs_export_hooks); |
nfsrv_init(0); /* Init server data structures */ |
nfsrv_init(0); /* Init server data structures */ |
nfsrv_initcache(); /* Init the server request cache */ |
nfsrv_initcache(); /* Init the server request cache */ |
{ |
{ |
Line 1694 nfs_loadattrcache(vpp, fp, vaper, flags) |
|
Line 1724 nfs_loadattrcache(vpp, fp, vaper, flags) |
|
vap->va_rdev = (dev_t)rdev; |
vap->va_rdev = (dev_t)rdev; |
vap->va_mtime = mtime; |
vap->va_mtime = mtime; |
vap->va_ctime = ctime; |
vap->va_ctime = ctime; |
|
vap->va_birthtime.tv_sec = VNOVAL; |
|
vap->va_birthtime.tv_nsec = VNOVAL; |
vap->va_fsid = vp->v_mount->mnt_stat.f_fsidx.__fsid_val[0]; |
vap->va_fsid = vp->v_mount->mnt_stat.f_fsidx.__fsid_val[0]; |
switch (vtyp) { |
switch (vtyp) { |
case VDIR: |
case VDIR: |
Line 2512 nfsrv_fhtovp(nfsrvfh_t *nsfh, int lockfl |
|
Line 2544 nfsrv_fhtovp(nfsrvfh_t *nsfh, int lockfl |
|
} else if (kerbflag) { |
} else if (kerbflag) { |
vput(*vpp); |
vput(*vpp); |
return (NFSERR_AUTHERR | AUTH_TOOWEAK); |
return (NFSERR_AUTHERR | AUTH_TOOWEAK); |
} else if (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, |
} else if (kauth_cred_geteuid(cred) == 0 || /* NFS maproot, see below */ |
NULL) == 0 || (exflags & MNT_EXPORTANON)) { |
(exflags & MNT_EXPORTANON)) { |
|
/* |
|
* This is used by the NFS maproot option. While we can change |
|
* the secmodel on our own host, we can't change it on the |
|
* clients. As means of least surprise, we're doing the |
|
* traditional thing here. |
|
* Should look into adding a "mapprivileged" or similar where |
|
* the users can be explicitly specified... |
|
* [elad, yamt 2008-03-05] |
|
*/ |
kauth_cred_clone(credanon, cred); |
kauth_cred_clone(credanon, cred); |
} |
} |
if (exflags & MNT_EXRDONLY) |
if (exflags & MNT_EXRDONLY) |
Line 2631 nfs_clearcommit(mp) |
|
Line 2672 nfs_clearcommit(mp) |
|
np->n_commitflags &= |
np->n_commitflags &= |
~(NFS_COMMIT_PUSH_VALID | NFS_COMMIT_PUSHED_VALID); |
~(NFS_COMMIT_PUSH_VALID | NFS_COMMIT_PUSHED_VALID); |
mutex_enter(&vp->v_uobj.vmobjlock); |
mutex_enter(&vp->v_uobj.vmobjlock); |
TAILQ_FOREACH(pg, &vp->v_uobj.memq, listq) { |
TAILQ_FOREACH(pg, &vp->v_uobj.memq, listq.queue) { |
pg->flags &= ~PG_NEEDCOMMIT; |
pg->flags &= ~PG_NEEDCOMMIT; |
} |
} |
mutex_exit(&vp->v_uobj.vmobjlock); |
mutex_exit(&vp->v_uobj.vmobjlock); |