Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/nfs/nfs_commonsubs.c
Show First 20 Lines • Show All 308 Lines • ▼ Show 20 Lines | static int nfs_bigrequest[NFSV42_NPROCS] = { | ||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 | 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 | ||||
}; | }; | ||||
/* | /* | ||||
* Start building a request. Mostly just put the first file handle in | * Start building a request. Mostly just put the first file handle in | ||||
* place. | * place. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp, | nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp, | ||||
u_int8_t *nfhp, int fhlen, u_int32_t **opcntpp, struct nfsclsession *sep, | u_int8_t *nfhp, int fhlen, u_int32_t **opcntpp, struct nfsclsession *sep, | ||||
int vers, int minorvers) | int vers, int minorvers) | ||||
{ | { | ||||
struct mbuf *mb; | struct mbuf *mb; | ||||
u_int32_t *tl; | u_int32_t *tl; | ||||
int opcnt; | int opcnt; | ||||
nfsattrbit_t attrbits; | nfsattrbit_t attrbits; | ||||
▲ Show 20 Lines • Show All 122 Lines • ▼ Show 20 Lines | nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp, | ||||
} | } | ||||
if (procnum < NFSV42_NPROCS) | if (procnum < NFSV42_NPROCS) | ||||
NFSINCRGLOBAL(nfsstatsv1.rpccnt[procnum]); | NFSINCRGLOBAL(nfsstatsv1.rpccnt[procnum]); | ||||
} | } | ||||
/* | /* | ||||
* Put a state Id in the mbuf list. | * Put a state Id in the mbuf list. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsm_stateidtom(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp, int flag) | nfsm_stateidtom(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp, int flag) | ||||
{ | { | ||||
nfsv4stateid_t *st; | nfsv4stateid_t *st; | ||||
NFSM_BUILD(st, nfsv4stateid_t *, NFSX_STATEID); | NFSM_BUILD(st, nfsv4stateid_t *, NFSX_STATEID); | ||||
if (flag == NFSSTATEID_PUTALLZERO) { | if (flag == NFSSTATEID_PUTALLZERO) { | ||||
st->seqid = 0; | st->seqid = 0; | ||||
st->other[0] = 0; | st->other[0] = 0; | ||||
▲ Show 20 Lines • Show All 219 Lines • ▼ Show 20 Lines | |||||
#endif /* !APPLE */ | #endif /* !APPLE */ | ||||
/* | /* | ||||
* Help break down an mbuf chain by setting the first siz bytes contiguous | * Help break down an mbuf chain by setting the first siz bytes contiguous | ||||
* pointed to by returned val. | * pointed to by returned val. | ||||
* This is used by the macro NFSM_DISSECT for tough | * This is used by the macro NFSM_DISSECT for tough | ||||
* cases. | * cases. | ||||
*/ | */ | ||||
APPLESTATIC void * | void * | ||||
nfsm_dissct(struct nfsrv_descript *nd, int siz, int how) | nfsm_dissct(struct nfsrv_descript *nd, int siz, int how) | ||||
{ | { | ||||
struct mbuf *mp2; | struct mbuf *mp2; | ||||
int siz2, xfer; | int siz2, xfer; | ||||
caddr_t p; | caddr_t p; | ||||
int left; | int left; | ||||
caddr_t retp; | caddr_t retp; | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Advance the position in the mbuf chain. | * Advance the position in the mbuf chain. | ||||
* If offs == 0, this is a no-op, but it is simpler to just return from | * If offs == 0, this is a no-op, but it is simpler to just return from | ||||
* here than check for offs > 0 for all calls to nfsm_advance. | * here than check for offs > 0 for all calls to nfsm_advance. | ||||
* If left == -1, it should be calculated here. | * If left == -1, it should be calculated here. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsm_advance(struct nfsrv_descript *nd, int offs, int left) | nfsm_advance(struct nfsrv_descript *nd, int offs, int left) | ||||
{ | { | ||||
int error = 0; | int error = 0; | ||||
if (offs == 0) | if (offs == 0) | ||||
goto out; | goto out; | ||||
/* | /* | ||||
* A negative offs might indicate a corrupted mbuf chain and, | * A negative offs might indicate a corrupted mbuf chain and, | ||||
Show All 31 Lines | out: | ||||
NFSEXITCODE(error); | NFSEXITCODE(error); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Copy a string into mbuf(s). | * Copy a string into mbuf(s). | ||||
* Return the number of bytes output, including XDR overheads. | * Return the number of bytes output, including XDR overheads. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsm_strtom(struct nfsrv_descript *nd, const char *cp, int siz) | nfsm_strtom(struct nfsrv_descript *nd, const char *cp, int siz) | ||||
{ | { | ||||
struct mbuf *m2; | struct mbuf *m2; | ||||
int xfer, left; | int xfer, left; | ||||
struct mbuf *m1; | struct mbuf *m1; | ||||
int rem, bytesize; | int rem, bytesize; | ||||
u_int32_t *tl; | u_int32_t *tl; | ||||
char *cp2; | char *cp2; | ||||
Show All 40 Lines | nfsm_strtom(struct nfsrv_descript *nd, const char *cp, int siz) | ||||
nd->nd_mb = m2; | nd->nd_mb = m2; | ||||
nd->nd_bpos = mtod(m2, caddr_t) + m2->m_len; | nd->nd_bpos = mtod(m2, caddr_t) + m2->m_len; | ||||
return (bytesize); | return (bytesize); | ||||
} | } | ||||
/* | /* | ||||
* Called once to initialize data structures... | * Called once to initialize data structures... | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
newnfs_init(void) | newnfs_init(void) | ||||
{ | { | ||||
static int nfs_inited = 0; | static int nfs_inited = 0; | ||||
if (nfs_inited) | if (nfs_inited) | ||||
return; | return; | ||||
nfs_inited = 1; | nfs_inited = 1; | ||||
Show All 13 Lines | |||||
} | } | ||||
/* | /* | ||||
* Put a file handle in an mbuf list. | * Put a file handle in an mbuf list. | ||||
* If the size argument == 0, just use the default size. | * If the size argument == 0, just use the default size. | ||||
* set_true == 1 if there should be an newnfs_true prepended on the file handle. | * set_true == 1 if there should be an newnfs_true prepended on the file handle. | ||||
* Return the number of bytes output, including XDR overhead. | * Return the number of bytes output, including XDR overhead. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsm_fhtom(struct nfsrv_descript *nd, u_int8_t *fhp, int size, int set_true) | nfsm_fhtom(struct nfsrv_descript *nd, u_int8_t *fhp, int size, int set_true) | ||||
{ | { | ||||
u_int32_t *tl; | u_int32_t *tl; | ||||
u_int8_t *cp; | u_int8_t *cp; | ||||
int fullsiz, rem, bytesize = 0; | int fullsiz, rem, bytesize = 0; | ||||
if (size == 0) | if (size == 0) | ||||
size = NFSX_MYFH; | size = NFSX_MYFH; | ||||
Show All 26 Lines | |||||
/* | /* | ||||
* This function compares two net addresses by family and returns TRUE | * This function compares two net addresses by family and returns TRUE | ||||
* if they are the same host. | * if they are the same host. | ||||
* If there is any doubt, return FALSE. | * If there is any doubt, return FALSE. | ||||
* The AF_INET family is handled as a special case so that address mbufs | * The AF_INET family is handled as a special case so that address mbufs | ||||
* don't need to be saved to store "struct in_addr", which is only 4 bytes. | * don't need to be saved to store "struct in_addr", which is only 4 bytes. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsaddr_match(int family, union nethostaddr *haddr, NFSSOCKADDR_T nam) | nfsaddr_match(int family, union nethostaddr *haddr, NFSSOCKADDR_T nam) | ||||
{ | { | ||||
#ifdef INET | #ifdef INET | ||||
struct sockaddr_in *inetaddr; | struct sockaddr_in *inetaddr; | ||||
#endif | #endif | ||||
switch (family) { | switch (family) { | ||||
#ifdef INET | #ifdef INET | ||||
Show All 20 Lines | |||||
#endif | #endif | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Similar to the above, but takes to NFSSOCKADDR_T args. | * Similar to the above, but takes to NFSSOCKADDR_T args. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsaddr2_match(NFSSOCKADDR_T nam1, NFSSOCKADDR_T nam2) | nfsaddr2_match(NFSSOCKADDR_T nam1, NFSSOCKADDR_T nam2) | ||||
{ | { | ||||
struct sockaddr_in *addr1, *addr2; | struct sockaddr_in *addr1, *addr2; | ||||
struct sockaddr *inaddr; | struct sockaddr *inaddr; | ||||
inaddr = NFSSOCKADDR(nam1, struct sockaddr *); | inaddr = NFSSOCKADDR(nam1, struct sockaddr *); | ||||
switch (inaddr->sa_family) { | switch (inaddr->sa_family) { | ||||
case AF_INET: | case AF_INET: | ||||
Show All 20 Lines | |||||
#endif | #endif | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Trim trailing data off the mbuf list being built. | * Trim trailing data off the mbuf list being built. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
newnfs_trimtrailing(nd, mb, bpos) | newnfs_trimtrailing(nd, mb, bpos) | ||||
struct nfsrv_descript *nd; | struct nfsrv_descript *nd; | ||||
struct mbuf *mb; | struct mbuf *mb; | ||||
caddr_t bpos; | caddr_t bpos; | ||||
{ | { | ||||
if (mb->m_next) { | if (mb->m_next) { | ||||
m_freem(mb->m_next); | m_freem(mb->m_next); | ||||
mb->m_next = NULL; | mb->m_next = NULL; | ||||
} | } | ||||
mb->m_len = bpos - mtod(mb, caddr_t); | mb->m_len = bpos - mtod(mb, caddr_t); | ||||
nd->nd_mb = mb; | nd->nd_mb = mb; | ||||
nd->nd_bpos = bpos; | nd->nd_bpos = bpos; | ||||
} | } | ||||
/* | /* | ||||
* Dissect a file handle on the client. | * Dissect a file handle on the client. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsm_getfh(struct nfsrv_descript *nd, struct nfsfh **nfhpp) | nfsm_getfh(struct nfsrv_descript *nd, struct nfsfh **nfhpp) | ||||
{ | { | ||||
u_int32_t *tl; | u_int32_t *tl; | ||||
struct nfsfh *nfhp; | struct nfsfh *nfhp; | ||||
int error, len; | int error, len; | ||||
*nfhpp = NULL; | *nfhpp = NULL; | ||||
if (nd->nd_flag & (ND_NFSV3 | ND_NFSV4)) { | if (nd->nd_flag & (ND_NFSV3 | ND_NFSV4)) { | ||||
Show All 18 Lines | nfsmout: | ||||
NFSEXITCODE2(error, nd); | NFSEXITCODE2(error, nd); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Break down the nfsv4 acl. | * Break down the nfsv4 acl. | ||||
* If the aclp == NULL or won't fit in an acl, just discard the acl info. | * If the aclp == NULL or won't fit in an acl, just discard the acl info. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_dissectacl(struct nfsrv_descript *nd, NFSACL_T *aclp, int *aclerrp, | nfsrv_dissectacl(struct nfsrv_descript *nd, NFSACL_T *aclp, int *aclerrp, | ||||
int *aclsizep, __unused NFSPROC_T *p) | int *aclsizep, __unused NFSPROC_T *p) | ||||
{ | { | ||||
u_int32_t *tl; | u_int32_t *tl; | ||||
int i, aclsize; | int i, aclsize; | ||||
int acecnt, error = 0, aceerr = 0, acesize; | int acecnt, error = 0, aceerr = 0, acesize; | ||||
*aclerrp = 0; | *aclerrp = 0; | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | nfsmout: | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Get attribute bits from an mbuf list. | * Get attribute bits from an mbuf list. | ||||
* Returns EBADRPC for a parsing error, 0 otherwise. | * Returns EBADRPC for a parsing error, 0 otherwise. | ||||
* If the clearinvalid flag is set, clear the bits not supported. | * If the clearinvalid flag is set, clear the bits not supported. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_getattrbits(struct nfsrv_descript *nd, nfsattrbit_t *attrbitp, int *cntp, | nfsrv_getattrbits(struct nfsrv_descript *nd, nfsattrbit_t *attrbitp, int *cntp, | ||||
int *retnotsupp) | int *retnotsupp) | ||||
{ | { | ||||
u_int32_t *tl; | u_int32_t *tl; | ||||
int cnt, i, outcnt; | int cnt, i, outcnt; | ||||
int error = 0; | int error = 0; | ||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); | NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); | ||||
Show All 29 Lines | |||||
* If the compare flag is true, test for any attribute changes, | * If the compare flag is true, test for any attribute changes, | ||||
* otherwise return the attribute values. | * otherwise return the attribute values. | ||||
* These attributes cover fields in "struct vattr", "struct statfs", | * These attributes cover fields in "struct vattr", "struct statfs", | ||||
* "struct nfsfsinfo", the file handle and the lease duration. | * "struct nfsfsinfo", the file handle and the lease duration. | ||||
* The value of retcmpp is set to 1 if all attributes are the same, | * The value of retcmpp is set to 1 if all attributes are the same, | ||||
* and 0 otherwise. | * and 0 otherwise. | ||||
* Returns EBADRPC if it can't be parsed, 0 otherwise. | * Returns EBADRPC if it can't be parsed, 0 otherwise. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, | nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, | ||||
struct nfsvattr *nap, struct nfsfh **nfhpp, fhandle_t *fhp, int fhsize, | struct nfsvattr *nap, struct nfsfh **nfhpp, fhandle_t *fhp, int fhsize, | ||||
struct nfsv3_pathconf *pc, struct statfs *sbp, struct nfsstatfs *sfp, | struct nfsv3_pathconf *pc, struct statfs *sbp, struct nfsstatfs *sfp, | ||||
struct nfsfsinfo *fsp, NFSACL_T *aclp, int compare, int *retcmpp, | struct nfsfsinfo *fsp, NFSACL_T *aclp, int compare, int *retcmpp, | ||||
u_int32_t *leasep, u_int32_t *rderrp, NFSPROC_T *p, struct ucred *cred) | u_int32_t *leasep, u_int32_t *rderrp, NFSPROC_T *p, struct ucred *cred) | ||||
{ | { | ||||
u_int32_t *tl; | u_int32_t *tl; | ||||
int i = 0, j, k, l = 0, m, bitpos, attrsum = 0; | int i = 0, j, k, l = 0, m, bitpos, attrsum = 0; | ||||
▲ Show 20 Lines • Show All 1,027 Lines • ▼ Show 20 Lines | |||||
* loop until the function returns 1 to indicate the lock was acquired.) | * loop until the function returns 1 to indicate the lock was acquired.) | ||||
* Any usecnt must be decremented by calling nfsv4_relref() before | * Any usecnt must be decremented by calling nfsv4_relref() before | ||||
* calling nfsv4_lock(). It was done this way, so nfsv4_lock() could | * calling nfsv4_lock(). It was done this way, so nfsv4_lock() could | ||||
* be called in a loop. | * be called in a loop. | ||||
* The isleptp argument is set to indicate if the call slept, iff not NULL | * The isleptp argument is set to indicate if the call slept, iff not NULL | ||||
* and the mp argument indicates to check for a forced dismount, iff not | * and the mp argument indicates to check for a forced dismount, iff not | ||||
* NULL. | * NULL. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsv4_lock(struct nfsv4lock *lp, int iwantlock, int *isleptp, | nfsv4_lock(struct nfsv4lock *lp, int iwantlock, int *isleptp, | ||||
void *mutex, struct mount *mp) | void *mutex, struct mount *mp) | ||||
{ | { | ||||
if (isleptp) | if (isleptp) | ||||
*isleptp = 0; | *isleptp = 0; | ||||
/* | /* | ||||
* If a lock is wanted, loop around until the lock is acquired by | * If a lock is wanted, loop around until the lock is acquired by | ||||
Show All 30 Lines | nfsv4_lock(struct nfsv4lock *lp, int iwantlock, int *isleptp, | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Release the lock acquired by nfsv4_lock(). | * Release the lock acquired by nfsv4_lock(). | ||||
* The second argument is set to 1 to indicate the nfslock_usecnt should be | * The second argument is set to 1 to indicate the nfslock_usecnt should be | ||||
* incremented, as well. | * incremented, as well. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsv4_unlock(struct nfsv4lock *lp, int incref) | nfsv4_unlock(struct nfsv4lock *lp, int incref) | ||||
{ | { | ||||
lp->nfslock_lock &= ~NFSV4LOCK_LOCK; | lp->nfslock_lock &= ~NFSV4LOCK_LOCK; | ||||
if (incref) | if (incref) | ||||
lp->nfslock_usecnt++; | lp->nfslock_usecnt++; | ||||
nfsv4_wanted(lp); | nfsv4_wanted(lp); | ||||
} | } | ||||
/* | /* | ||||
* Release a reference cnt. | * Release a reference cnt. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsv4_relref(struct nfsv4lock *lp) | nfsv4_relref(struct nfsv4lock *lp) | ||||
{ | { | ||||
if (lp->nfslock_usecnt <= 0) | if (lp->nfslock_usecnt <= 0) | ||||
panic("nfsv4root ref cnt"); | panic("nfsv4root ref cnt"); | ||||
lp->nfslock_usecnt--; | lp->nfslock_usecnt--; | ||||
if (lp->nfslock_usecnt == 0) | if (lp->nfslock_usecnt == 0) | ||||
nfsv4_wanted(lp); | nfsv4_wanted(lp); | ||||
} | } | ||||
/* | /* | ||||
* Get a reference cnt. | * Get a reference cnt. | ||||
* This function will wait for any exclusive lock to be released, but will | * This function will wait for any exclusive lock to be released, but will | ||||
* not wait for threads that want the exclusive lock. If priority needs | * not wait for threads that want the exclusive lock. If priority needs | ||||
* to be given to threads that need the exclusive lock, a call to nfsv4_lock() | * to be given to threads that need the exclusive lock, a call to nfsv4_lock() | ||||
* with the 2nd argument == 0 should be done before calling nfsv4_getref(). | * with the 2nd argument == 0 should be done before calling nfsv4_getref(). | ||||
* If the mp argument is not NULL, check for NFSCL_FORCEDISM() being set and | * If the mp argument is not NULL, check for NFSCL_FORCEDISM() being set and | ||||
* return without getting a refcnt for that case. | * return without getting a refcnt for that case. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsv4_getref(struct nfsv4lock *lp, int *isleptp, void *mutex, | nfsv4_getref(struct nfsv4lock *lp, int *isleptp, void *mutex, | ||||
struct mount *mp) | struct mount *mp) | ||||
{ | { | ||||
if (isleptp) | if (isleptp) | ||||
*isleptp = 0; | *isleptp = 0; | ||||
/* | /* | ||||
Show All 13 Lines | nfsv4_getref(struct nfsv4lock *lp, int *isleptp, void *mutex, | ||||
lp->nfslock_usecnt++; | lp->nfslock_usecnt++; | ||||
} | } | ||||
/* | /* | ||||
* Get a reference as above, but return failure instead of sleeping if | * Get a reference as above, but return failure instead of sleeping if | ||||
* an exclusive lock is held. | * an exclusive lock is held. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsv4_getref_nonblock(struct nfsv4lock *lp) | nfsv4_getref_nonblock(struct nfsv4lock *lp) | ||||
{ | { | ||||
if ((lp->nfslock_lock & NFSV4LOCK_LOCK) != 0) | if ((lp->nfslock_lock & NFSV4LOCK_LOCK) != 0) | ||||
return (0); | return (0); | ||||
lp->nfslock_usecnt++; | lp->nfslock_usecnt++; | ||||
return (1); | return (1); | ||||
} | } | ||||
/* | /* | ||||
* Test for a lock. Return 1 if locked, 0 otherwise. | * Test for a lock. Return 1 if locked, 0 otherwise. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsv4_testlock(struct nfsv4lock *lp) | nfsv4_testlock(struct nfsv4lock *lp) | ||||
{ | { | ||||
if ((lp->nfslock_lock & NFSV4LOCK_LOCK) == 0 && | if ((lp->nfslock_lock & NFSV4LOCK_LOCK) == 0 && | ||||
lp->nfslock_usecnt == 0) | lp->nfslock_usecnt == 0) | ||||
return (0); | return (0); | ||||
return (1); | return (1); | ||||
} | } | ||||
Show All 11 Lines | nfsv4_wanted(struct nfsv4lock *lp) | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Copy a string from an mbuf list into a character array. | * Copy a string from an mbuf list into a character array. | ||||
* Return EBADRPC if there is an mbuf error, | * Return EBADRPC if there is an mbuf error, | ||||
* 0 otherwise. | * 0 otherwise. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_mtostr(struct nfsrv_descript *nd, char *str, int siz) | nfsrv_mtostr(struct nfsrv_descript *nd, char *str, int siz) | ||||
{ | { | ||||
char *cp; | char *cp; | ||||
int xfer, len; | int xfer, len; | ||||
struct mbuf *mp; | struct mbuf *mp; | ||||
int rem, error = 0; | int rem, error = 0; | ||||
mp = nd->nd_md; | mp = nd->nd_md; | ||||
Show All 34 Lines | |||||
out: | out: | ||||
NFSEXITCODE2(error, nd); | NFSEXITCODE2(error, nd); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Fill in the attributes as marked by the bitmap (V4). | * Fill in the attributes as marked by the bitmap (V4). | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, | nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, | ||||
NFSACL_T *saclp, struct vattr *vap, fhandle_t *fhp, int rderror, | NFSACL_T *saclp, struct vattr *vap, fhandle_t *fhp, int rderror, | ||||
nfsattrbit_t *attrbitp, struct ucred *cred, NFSPROC_T *p, int isdgram, | nfsattrbit_t *attrbitp, struct ucred *cred, NFSPROC_T *p, int isdgram, | ||||
int reterr, int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno, | int reterr, int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno, | ||||
struct statfs *pnfssf) | struct statfs *pnfssf) | ||||
{ | { | ||||
int bitpos, retnum = 0; | int bitpos, retnum = 0; | ||||
u_int32_t *tl; | u_int32_t *tl; | ||||
▲ Show 20 Lines • Show All 563 Lines • ▼ Show 20 Lines | #endif /* QUOTA */ | ||||
*retnump = txdr_unsigned(retnum); | *retnump = txdr_unsigned(retnum); | ||||
return (retnum + prefixnum); | return (retnum + prefixnum); | ||||
} | } | ||||
/* | /* | ||||
* Put the attribute bits onto an mbuf list. | * Put the attribute bits onto an mbuf list. | ||||
* Return the number of bytes of output generated. | * Return the number of bytes of output generated. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_putattrbit(struct nfsrv_descript *nd, nfsattrbit_t *attrbitp) | nfsrv_putattrbit(struct nfsrv_descript *nd, nfsattrbit_t *attrbitp) | ||||
{ | { | ||||
u_int32_t *tl; | u_int32_t *tl; | ||||
int cnt, i, bytesize; | int cnt, i, bytesize; | ||||
for (cnt = NFSATTRBIT_MAXWORDS; cnt > 0; cnt--) | for (cnt = NFSATTRBIT_MAXWORDS; cnt > 0; cnt--) | ||||
if (attrbitp->bits[cnt - 1]) | if (attrbitp->bits[cnt - 1]) | ||||
break; | break; | ||||
bytesize = (cnt + 1) * NFSX_UNSIGNED; | bytesize = (cnt + 1) * NFSX_UNSIGNED; | ||||
NFSM_BUILD(tl, u_int32_t *, bytesize); | NFSM_BUILD(tl, u_int32_t *, bytesize); | ||||
*tl++ = txdr_unsigned(cnt); | *tl++ = txdr_unsigned(cnt); | ||||
for (i = 0; i < cnt; i++) | for (i = 0; i < cnt; i++) | ||||
*tl++ = txdr_unsigned(attrbitp->bits[i]); | *tl++ = txdr_unsigned(attrbitp->bits[i]); | ||||
return (bytesize); | return (bytesize); | ||||
} | } | ||||
/* | /* | ||||
* Convert a uid to a string. | * Convert a uid to a string. | ||||
* If the lookup fails, just output the digits. | * If the lookup fails, just output the digits. | ||||
* uid - the user id | * uid - the user id | ||||
* cpp - points to a buffer of size NFSV4_SMALLSTR | * cpp - points to a buffer of size NFSV4_SMALLSTR | ||||
* (malloc a larger one, as required) | * (malloc a larger one, as required) | ||||
* retlenp - pointer to length to be returned | * retlenp - pointer to length to be returned | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsv4_uidtostr(uid_t uid, u_char **cpp, int *retlenp) | nfsv4_uidtostr(uid_t uid, u_char **cpp, int *retlenp) | ||||
{ | { | ||||
int i; | int i; | ||||
struct nfsusrgrp *usrp; | struct nfsusrgrp *usrp; | ||||
u_char *cp = *cpp; | u_char *cp = *cpp; | ||||
uid_t tmp; | uid_t tmp; | ||||
int cnt, hasampersand, len = NFSV4_SMALLSTR, ret; | int cnt, hasampersand, len = NFSV4_SMALLSTR, ret; | ||||
struct nfsrv_lughash *hp; | struct nfsrv_lughash *hp; | ||||
▲ Show 20 Lines • Show All 140 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Convert a string to a uid. | * Convert a string to a uid. | ||||
* If no conversion is possible return NFSERR_BADOWNER, otherwise | * If no conversion is possible return NFSERR_BADOWNER, otherwise | ||||
* return 0. | * return 0. | ||||
* If this is called from a client side mount using AUTH_SYS and the | * If this is called from a client side mount using AUTH_SYS and the | ||||
* string is made up entirely of digits, just convert the string to | * string is made up entirely of digits, just convert the string to | ||||
* a number. | * a number. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsv4_strtouid(struct nfsrv_descript *nd, u_char *str, int len, uid_t *uidp) | nfsv4_strtouid(struct nfsrv_descript *nd, u_char *str, int len, uid_t *uidp) | ||||
{ | { | ||||
int i; | int i; | ||||
char *cp, *endstr, *str0; | char *cp, *endstr, *str0; | ||||
struct nfsusrgrp *usrp; | struct nfsusrgrp *usrp; | ||||
int cnt, ret; | int cnt, ret; | ||||
int error = 0; | int error = 0; | ||||
uid_t tuid; | uid_t tuid; | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Convert a gid to a string. | * Convert a gid to a string. | ||||
* gid - the group id | * gid - the group id | ||||
* cpp - points to a buffer of size NFSV4_SMALLSTR | * cpp - points to a buffer of size NFSV4_SMALLSTR | ||||
* (malloc a larger one, as required) | * (malloc a larger one, as required) | ||||
* retlenp - pointer to length to be returned | * retlenp - pointer to length to be returned | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsv4_gidtostr(gid_t gid, u_char **cpp, int *retlenp) | nfsv4_gidtostr(gid_t gid, u_char **cpp, int *retlenp) | ||||
{ | { | ||||
int i; | int i; | ||||
struct nfsusrgrp *usrp; | struct nfsusrgrp *usrp; | ||||
u_char *cp = *cpp; | u_char *cp = *cpp; | ||||
gid_t tmp; | gid_t tmp; | ||||
int cnt, hasampersand, len = NFSV4_SMALLSTR, ret; | int cnt, hasampersand, len = NFSV4_SMALLSTR, ret; | ||||
struct nfsrv_lughash *hp; | struct nfsrv_lughash *hp; | ||||
▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Convert a string to a gid. | * Convert a string to a gid. | ||||
* If no conversion is possible return NFSERR_BADOWNER, otherwise | * If no conversion is possible return NFSERR_BADOWNER, otherwise | ||||
* return 0. | * return 0. | ||||
* If this is called from a client side mount using AUTH_SYS and the | * If this is called from a client side mount using AUTH_SYS and the | ||||
* string is made up entirely of digits, just convert the string to | * string is made up entirely of digits, just convert the string to | ||||
* a number. | * a number. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsv4_strtogid(struct nfsrv_descript *nd, u_char *str, int len, gid_t *gidp) | nfsv4_strtogid(struct nfsrv_descript *nd, u_char *str, int len, gid_t *gidp) | ||||
{ | { | ||||
int i; | int i; | ||||
char *cp, *endstr, *str0; | char *cp, *endstr, *str0; | ||||
struct nfsusrgrp *usrp; | struct nfsusrgrp *usrp; | ||||
int cnt, ret; | int cnt, ret; | ||||
int error = 0; | int error = 0; | ||||
gid_t tgid; | gid_t tgid; | ||||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | if (fndlower) | ||||
return (0); | return (0); | ||||
else | else | ||||
return (1); | return (1); | ||||
} | } | ||||
/* | /* | ||||
* Set the port for the nfsuserd. | * Set the port for the nfsuserd. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_nfsuserdport(struct nfsuserd_args *nargs, NFSPROC_T *p) | nfsrv_nfsuserdport(struct nfsuserd_args *nargs, NFSPROC_T *p) | ||||
{ | { | ||||
struct nfssockreq *rp; | struct nfssockreq *rp; | ||||
#ifdef INET | #ifdef INET | ||||
struct sockaddr_in *ad; | struct sockaddr_in *ad; | ||||
#endif | #endif | ||||
#ifdef INET6 | #ifdef INET6 | ||||
struct sockaddr_in6 *ad6; | struct sockaddr_in6 *ad6; | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | |||||
out: | out: | ||||
NFSEXITCODE(error); | NFSEXITCODE(error); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Delete the nfsuserd port. | * Delete the nfsuserd port. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsrv_nfsuserddelport(void) | nfsrv_nfsuserddelport(void) | ||||
{ | { | ||||
NFSLOCKNAMEID(); | NFSLOCKNAMEID(); | ||||
if (nfsrv_nfsuserd != RUNNING) { | if (nfsrv_nfsuserd != RUNNING) { | ||||
NFSUNLOCKNAMEID(); | NFSUNLOCKNAMEID(); | ||||
return; | return; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | out: | ||||
NFSEXITCODE(error); | NFSEXITCODE(error); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* This function is called from the nfssvc(2) system call, to update the | * This function is called from the nfssvc(2) system call, to update the | ||||
* kernel user/group name list(s) for the V4 owner and ownergroup attributes. | * kernel user/group name list(s) for the V4 owner and ownergroup attributes. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfssvc_idname(struct nfsd_idargs *nidp) | nfssvc_idname(struct nfsd_idargs *nidp) | ||||
{ | { | ||||
struct nfsusrgrp *nusrp, *usrp, *newusrp; | struct nfsusrgrp *nusrp, *usrp, *newusrp; | ||||
struct nfsrv_lughash *hp_name, *hp_idnum, *thp; | struct nfsrv_lughash *hp_name, *hp_idnum, *thp; | ||||
int i, group_locked, groupname_locked, user_locked, username_locked; | int i, group_locked, groupname_locked, user_locked, username_locked; | ||||
int error = 0; | int error = 0; | ||||
u_char *cp; | u_char *cp; | ||||
gid_t *grps; | gid_t *grps; | ||||
▲ Show 20 Lines • Show All 376 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Free up all the allocations related to the name<-->id cache. | * Free up all the allocations related to the name<-->id cache. | ||||
* This function should only be called when the nfsuserd daemon isn't | * This function should only be called when the nfsuserd daemon isn't | ||||
* running, since it doesn't do any locking. | * running, since it doesn't do any locking. | ||||
* This function is meant to be used when the nfscommon module is unloaded. | * This function is meant to be used when the nfscommon module is unloaded. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsrv_cleanusergroup(void) | nfsrv_cleanusergroup(void) | ||||
{ | { | ||||
struct nfsrv_lughash *hp, *hp2; | struct nfsrv_lughash *hp, *hp2; | ||||
struct nfsusrgrp *nusrp, *usrp; | struct nfsusrgrp *nusrp, *usrp; | ||||
int i; | int i; | ||||
if (nfsuserhash == NULL) | if (nfsuserhash == NULL) | ||||
return; | return; | ||||
Show All 30 Lines | nfsrv_cleanusergroup(void) | ||||
free(nfsgroupnamehash, M_NFSUSERGROUP); | free(nfsgroupnamehash, M_NFSUSERGROUP); | ||||
free(nfsrv_dnsname, M_NFSSTRING); | free(nfsrv_dnsname, M_NFSSTRING); | ||||
} | } | ||||
/* | /* | ||||
* This function scans a byte string and checks for UTF-8 compliance. | * This function scans a byte string and checks for UTF-8 compliance. | ||||
* It returns 0 if it conforms and NFSERR_INVAL if not. | * It returns 0 if it conforms and NFSERR_INVAL if not. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_checkutf8(u_int8_t *cp, int len) | nfsrv_checkutf8(u_int8_t *cp, int len) | ||||
{ | { | ||||
u_int32_t val = 0x0; | u_int32_t val = 0x0; | ||||
int cnt = 0, gotd = 0, shift = 0; | int cnt = 0, gotd = 0, shift = 0; | ||||
u_int8_t byte; | u_int8_t byte; | ||||
static int utf8_shift[5] = { 7, 11, 16, 21, 26 }; | static int utf8_shift[5] = { 7, 11, 16, 21, 26 }; | ||||
int error = 0; | int error = 0; | ||||
▲ Show 20 Lines • Show All 236 Lines • ▼ Show 20 Lines | nfsrv_refstrbigenough(int siz, u_char **cpp, u_char **cpp2, int *slenp) | ||||
*cpp = cp; | *cpp = cp; | ||||
*cpp2 = cp + i; | *cpp2 = cp + i; | ||||
*slenp = siz + 1024; | *slenp = siz + 1024; | ||||
} | } | ||||
/* | /* | ||||
* Initialize the reply header data structures. | * Initialize the reply header data structures. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsrvd_rephead(struct nfsrv_descript *nd) | nfsrvd_rephead(struct nfsrv_descript *nd) | ||||
{ | { | ||||
struct mbuf *mreq; | struct mbuf *mreq; | ||||
/* | /* | ||||
* If this is a big reply, use a cluster. | * If this is a big reply, use a cluster. | ||||
*/ | */ | ||||
if ((nd->nd_flag & ND_GSSINITREPLY) == 0 && | if ((nd->nd_flag & ND_GSSINITREPLY) == 0 && | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | newnfs_sndunlock(int *flagp) | ||||
*flagp &= ~NFSR_SNDLOCK; | *flagp &= ~NFSR_SNDLOCK; | ||||
if (*flagp & NFSR_WANTSND) { | if (*flagp & NFSR_WANTSND) { | ||||
*flagp &= ~NFSR_WANTSND; | *flagp &= ~NFSR_WANTSND; | ||||
wakeup((caddr_t)flagp); | wakeup((caddr_t)flagp); | ||||
} | } | ||||
NFSUNLOCKSOCK(); | NFSUNLOCKSOCK(); | ||||
} | } | ||||
APPLESTATIC int | int | ||||
nfsv4_getipaddr(struct nfsrv_descript *nd, struct sockaddr_in *sin, | nfsv4_getipaddr(struct nfsrv_descript *nd, struct sockaddr_in *sin, | ||||
struct sockaddr_in6 *sin6, sa_family_t *saf, int *isudp) | struct sockaddr_in6 *sin6, sa_family_t *saf, int *isudp) | ||||
{ | { | ||||
struct in_addr saddr; | struct in_addr saddr; | ||||
uint32_t portnum, *tl; | uint32_t portnum, *tl; | ||||
int i, j, k; | int i, j, k; | ||||
sa_family_t af = AF_UNSPEC; | sa_family_t af = AF_UNSPEC; | ||||
char addr[64], protocol[5], *cp; | char addr[64], protocol[5], *cp; | ||||
▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | if (repstat == NFSERR_REPLYFROMCACHE) { | ||||
slots[slotid].nfssl_reply = *rep; | slots[slotid].nfssl_reply = *rep; | ||||
} | } | ||||
slots[slotid].nfssl_inprog = 0; | slots[slotid].nfssl_inprog = 0; | ||||
} | } | ||||
/* | /* | ||||
* Generate the xdr for an NFSv4.1 Sequence Operation. | * Generate the xdr for an NFSv4.1 Sequence Operation. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsv4_setsequence(struct nfsmount *nmp, struct nfsrv_descript *nd, | nfsv4_setsequence(struct nfsmount *nmp, struct nfsrv_descript *nd, | ||||
struct nfsclsession *sep, int dont_replycache) | struct nfsclsession *sep, int dont_replycache) | ||||
{ | { | ||||
uint32_t *tl, slotseq = 0; | uint32_t *tl, slotseq = 0; | ||||
int error, maxslot, slotpos; | int error, maxslot, slotpos; | ||||
uint8_t sessionid[NFSX_V4SESSIONID]; | uint8_t sessionid[NFSX_V4SESSIONID]; | ||||
error = nfsv4_sequencelookup(nmp, sep, &slotpos, &maxslot, &slotseq, | error = nfsv4_sequencelookup(nmp, sep, &slotpos, &maxslot, &slotseq, | ||||
▲ Show 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | nfsv4_sequencelookup(struct nfsmount *nmp, struct nfsclsession *sep, | ||||
*slotposp = slotpos; | *slotposp = slotpos; | ||||
*maxslotp = maxslot; | *maxslotp = maxslot; | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Free a session slot. | * Free a session slot. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsv4_freeslot(struct nfsclsession *sep, int slot) | nfsv4_freeslot(struct nfsclsession *sep, int slot) | ||||
{ | { | ||||
uint64_t bitval; | uint64_t bitval; | ||||
bitval = 1; | bitval = 1; | ||||
if (slot > 0) | if (slot > 0) | ||||
bitval <<= slot; | bitval <<= slot; | ||||
mtx_lock(&sep->nfsess_mtx); | mtx_lock(&sep->nfsess_mtx); | ||||
Show All 31 Lines |