Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/nfsserver/nfs_nfsdstate.c
Show First 20 Lines • Show All 234 Lines • ▼ Show 20 Lines | |||||
static struct nfsdevice *nfsrv_findmirroredds(struct nfsmount *nmp); | static struct nfsdevice *nfsrv_findmirroredds(struct nfsmount *nmp); | ||||
/* | /* | ||||
* Scan the client list for a match and either return the current one, | * Scan the client list for a match and either return the current one, | ||||
* create a new entry or return an error. | * create a new entry or return an error. | ||||
* If returning a non-error, the clp structure must either be linked into | * If returning a non-error, the clp structure must either be linked into | ||||
* the client list or free'd. | * the client list or free'd. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp, | nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp, | ||||
nfsquad_t *clientidp, nfsquad_t *confirmp, NFSPROC_T *p) | nfsquad_t *clientidp, nfsquad_t *confirmp, NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsclient *clp = NULL, *new_clp = *new_clpp; | struct nfsclient *clp = NULL, *new_clp = *new_clpp; | ||||
int i, error = 0, ret; | int i, error = 0, ret; | ||||
struct nfsstate *stp, *tstp; | struct nfsstate *stp, *tstp; | ||||
#ifdef INET | #ifdef INET | ||||
struct sockaddr_in *sin, *rin; | struct sockaddr_in *sin, *rin; | ||||
▲ Show 20 Lines • Show All 324 Lines • ▼ Show 20 Lines | |||||
out: | out: | ||||
NFSEXITCODE2(error, nd); | NFSEXITCODE2(error, nd); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Check to see if the client id exists and optionally confirm it. | * Check to see if the client id exists and optionally confirm it. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_getclient(nfsquad_t clientid, int opflags, struct nfsclient **clpp, | nfsrv_getclient(nfsquad_t clientid, int opflags, struct nfsclient **clpp, | ||||
struct nfsdsession *nsep, nfsquad_t confirm, uint32_t cbprogram, | struct nfsdsession *nsep, nfsquad_t confirm, uint32_t cbprogram, | ||||
struct nfsrv_descript *nd, NFSPROC_T *p) | struct nfsrv_descript *nd, NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsclient *clp; | struct nfsclient *clp; | ||||
struct nfsstate *stp; | struct nfsstate *stp; | ||||
int i; | int i; | ||||
struct nfsclienthashhead *hp; | struct nfsclienthashhead *hp; | ||||
▲ Show 20 Lines • Show All 266 Lines • ▼ Show 20 Lines | out: | ||||
NFSEXITCODE2(error, nd); | NFSEXITCODE2(error, nd); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Called from the new nfssvc syscall to admin revoke a clientid. | * Called from the new nfssvc syscall to admin revoke a clientid. | ||||
* Returns 0 for success, error otherwise. | * Returns 0 for success, error otherwise. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_adminrevoke(struct nfsd_clid *revokep, NFSPROC_T *p) | nfsrv_adminrevoke(struct nfsd_clid *revokep, NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsclient *clp = NULL; | struct nfsclient *clp = NULL; | ||||
int i, error = 0; | int i, error = 0; | ||||
int gotit, igotlock; | int gotit, igotlock; | ||||
/* | /* | ||||
* First, lock out the nfsd so that state won't change while the | * First, lock out the nfsd so that state won't change while the | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | out: | ||||
NFSEXITCODE(error); | NFSEXITCODE(error); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Dump out stats for all clients. Called from nfssvc(2), that is used | * Dump out stats for all clients. Called from nfssvc(2), that is used | ||||
* nfsstatsv1. | * nfsstatsv1. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsrv_dumpclients(struct nfsd_dumpclients *dumpp, int maxcnt) | nfsrv_dumpclients(struct nfsd_dumpclients *dumpp, int maxcnt) | ||||
{ | { | ||||
struct nfsclient *clp; | struct nfsclient *clp; | ||||
int i = 0, cnt = 0; | int i = 0, cnt = 0; | ||||
/* | /* | ||||
* First, get a reference on the nfsv4rootfs_lock so that an | * First, get a reference on the nfsv4rootfs_lock so that an | ||||
* exclusive lock cannot be acquired while dumping the clients. | * exclusive lock cannot be acquired while dumping the clients. | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | #endif | ||||
LIST_FOREACH(stp, &clp->lc_olddeleg, ls_list) { | LIST_FOREACH(stp, &clp->lc_olddeleg, ls_list) { | ||||
dumpp->ndcl_nolddelegs++; | dumpp->ndcl_nolddelegs++; | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Dump out lock stats for a file. | * Dump out lock stats for a file. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsrv_dumplocks(vnode_t vp, struct nfsd_dumplocks *ldumpp, int maxcnt, | nfsrv_dumplocks(vnode_t vp, struct nfsd_dumplocks *ldumpp, int maxcnt, | ||||
NFSPROC_T *p) | NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsstate *stp; | struct nfsstate *stp; | ||||
struct nfslock *lop; | struct nfslock *lop; | ||||
int cnt = 0; | int cnt = 0; | ||||
struct nfslockfile *lfp; | struct nfslockfile *lfp; | ||||
sa_family_t af; | sa_family_t af; | ||||
▲ Show 20 Lines • Show All 156 Lines • ▼ Show 20 Lines | |||||
* Server timer routine. It can scan any linked list, so long | * Server timer routine. It can scan any linked list, so long | ||||
* as it holds the spin/mutex lock and there is no exclusive lock on | * as it holds the spin/mutex lock and there is no exclusive lock on | ||||
* nfsv4rootfs_lock. | * nfsv4rootfs_lock. | ||||
* (For OpenBSD, a kthread is ok. For FreeBSD, I think it is ok | * (For OpenBSD, a kthread is ok. For FreeBSD, I think it is ok | ||||
* to do this from a callout, since the spin locks work. For | * to do this from a callout, since the spin locks work. For | ||||
* Darwin, I'm not sure what will work correctly yet.) | * Darwin, I'm not sure what will work correctly yet.) | ||||
* Should be called once per second. | * Should be called once per second. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsrv_servertimer(void) | nfsrv_servertimer(void) | ||||
{ | { | ||||
struct nfsclient *clp, *nclp; | struct nfsclient *clp, *nclp; | ||||
struct nfsstate *stp, *nstp; | struct nfsstate *stp, *nstp; | ||||
int got_ref, i; | int got_ref, i; | ||||
/* | /* | ||||
* Make sure nfsboottime is set. This is used by V3 as well | * Make sure nfsboottime is set. This is used by V3 as well | ||||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* The following set of functions free up the various data structures. | * The following set of functions free up the various data structures. | ||||
*/ | */ | ||||
/* | /* | ||||
* Clear out all open/lock state related to this nfsclient. | * Clear out all open/lock state related to this nfsclient. | ||||
* Caller must hold an exclusive lock on nfsv4rootfs_lock, so that | * Caller must hold an exclusive lock on nfsv4rootfs_lock, so that | ||||
* there are no other active nfsd threads. | * there are no other active nfsd threads. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsrv_cleanclient(struct nfsclient *clp, NFSPROC_T *p) | nfsrv_cleanclient(struct nfsclient *clp, NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsstate *stp, *nstp; | struct nfsstate *stp, *nstp; | ||||
struct nfsdsession *sep, *nsep; | struct nfsdsession *sep, *nsep; | ||||
LIST_FOREACH_SAFE(stp, &clp->lc_open, ls_list, nstp) | LIST_FOREACH_SAFE(stp, &clp->lc_open, ls_list, nstp) | ||||
nfsrv_freeopenowner(stp, 1, p); | nfsrv_freeopenowner(stp, 1, p); | ||||
if ((clp->lc_flags & LCL_ADMINREVOKED) == 0) | if ((clp->lc_flags & LCL_ADMINREVOKED) == 0) | ||||
LIST_FOREACH_SAFE(sep, &clp->lc_session, sess_list, nsep) | LIST_FOREACH_SAFE(sep, &clp->lc_session, sess_list, nsep) | ||||
(void)nfsrv_freesession(sep, NULL); | (void)nfsrv_freesession(sep, NULL); | ||||
} | } | ||||
/* | /* | ||||
* Free a client that has been cleaned. It should also already have been | * Free a client that has been cleaned. It should also already have been | ||||
* removed from the lists. | * removed from the lists. | ||||
* (Just to be safe w.r.t. newnfs_disconnect(), call this function when | * (Just to be safe w.r.t. newnfs_disconnect(), call this function when | ||||
* softclock interrupts are enabled.) | * softclock interrupts are enabled.) | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsrv_zapclient(struct nfsclient *clp, NFSPROC_T *p) | nfsrv_zapclient(struct nfsclient *clp, NFSPROC_T *p) | ||||
{ | { | ||||
#ifdef notyet | #ifdef notyet | ||||
if ((clp->lc_flags & (LCL_GSS | LCL_CALLBACKSON)) == | if ((clp->lc_flags & (LCL_GSS | LCL_CALLBACKSON)) == | ||||
(LCL_GSS | LCL_CALLBACKSON) && | (LCL_GSS | LCL_CALLBACKSON) && | ||||
(clp->lc_hand.nfsh_flag & NFSG_COMPLETE) && | (clp->lc_hand.nfsh_flag & NFSG_COMPLETE) && | ||||
clp->lc_handlelen > 0) { | clp->lc_handlelen > 0) { | ||||
Show All 15 Lines | #endif | ||||
NFSUNLOCKSTATE(); | NFSUNLOCKSTATE(); | ||||
} | } | ||||
/* | /* | ||||
* Free a list of delegation state structures. | * Free a list of delegation state structures. | ||||
* (This function will also free all nfslockfile structures that no | * (This function will also free all nfslockfile structures that no | ||||
* longer have associated state.) | * longer have associated state.) | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsrv_freedeleglist(struct nfsstatehead *sthp) | nfsrv_freedeleglist(struct nfsstatehead *sthp) | ||||
{ | { | ||||
struct nfsstate *stp, *nstp; | struct nfsstate *stp, *nstp; | ||||
LIST_FOREACH_SAFE(stp, sthp, ls_list, nstp) { | LIST_FOREACH_SAFE(stp, sthp, ls_list, nstp) { | ||||
nfsrv_freedeleg(stp); | nfsrv_freedeleg(stp); | ||||
} | } | ||||
LIST_INIT(sthp); | LIST_INIT(sthp); | ||||
▲ Show 20 Lines • Show All 267 Lines • ▼ Show 20 Lines | |||||
* that one isn't to be created and an NFSERR_xxx for other errors. | * that one isn't to be created and an NFSERR_xxx for other errors. | ||||
* The structures new_stp and new_lop are passed in as pointers that should | * The structures new_stp and new_lop are passed in as pointers that should | ||||
* be set to NULL if the structure is used and shouldn't be free'd. | * be set to NULL if the structure is used and shouldn't be free'd. | ||||
* For the NFSLCK_TEST and NFSLCK_CHECK cases, the structures are | * For the NFSLCK_TEST and NFSLCK_CHECK cases, the structures are | ||||
* never used and can safely be allocated on the stack. For all other | * never used and can safely be allocated on the stack. For all other | ||||
* cases, *new_stpp and *new_lopp should be malloc'd before the call, | * cases, *new_stpp and *new_lopp should be malloc'd before the call, | ||||
* in case they are used. | * in case they are used. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp, | nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp, | ||||
struct nfslock **new_lopp, struct nfslockconflict *cfp, | struct nfslock **new_lopp, struct nfslockconflict *cfp, | ||||
nfsquad_t clientid, nfsv4stateid_t *stateidp, | nfsquad_t clientid, nfsv4stateid_t *stateidp, | ||||
__unused struct nfsexstuff *exp, | __unused struct nfsexstuff *exp, | ||||
struct nfsrv_descript *nd, NFSPROC_T *p) | struct nfsrv_descript *nd, NFSPROC_T *p) | ||||
{ | { | ||||
struct nfslock *lop; | struct nfslock *lop; | ||||
struct nfsstate *new_stp = *new_stpp; | struct nfsstate *new_stp = *new_stpp; | ||||
▲ Show 20 Lines • Show All 706 Lines • ▼ Show 20 Lines | out: | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Check for state errors for Open. | * Check for state errors for Open. | ||||
* repstat is passed back out as an error if more critical errors | * repstat is passed back out as an error if more critical errors | ||||
* are not detected. | * are not detected. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_opencheck(nfsquad_t clientid, nfsv4stateid_t *stateidp, | nfsrv_opencheck(nfsquad_t clientid, nfsv4stateid_t *stateidp, | ||||
struct nfsstate *new_stp, vnode_t vp, struct nfsrv_descript *nd, | struct nfsstate *new_stp, vnode_t vp, struct nfsrv_descript *nd, | ||||
NFSPROC_T *p, int repstat) | NFSPROC_T *p, int repstat) | ||||
{ | { | ||||
struct nfsstate *stp, *nstp; | struct nfsstate *stp, *nstp; | ||||
struct nfsclient *clp; | struct nfsclient *clp; | ||||
struct nfsstate *ownerstp; | struct nfsstate *ownerstp; | ||||
struct nfslockfile *lfp, *new_lfp; | struct nfslockfile *lfp, *new_lfp; | ||||
▲ Show 20 Lines • Show All 234 Lines • ▼ Show 20 Lines | |||||
out: | out: | ||||
NFSEXITCODE2(error, nd); | NFSEXITCODE2(error, nd); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Open control function to create/update open state for an open. | * Open control function to create/update open state for an open. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_openctrl(struct nfsrv_descript *nd, vnode_t vp, | nfsrv_openctrl(struct nfsrv_descript *nd, vnode_t vp, | ||||
struct nfsstate **new_stpp, nfsquad_t clientid, nfsv4stateid_t *stateidp, | struct nfsstate **new_stpp, nfsquad_t clientid, nfsv4stateid_t *stateidp, | ||||
nfsv4stateid_t *delegstateidp, u_int32_t *rflagsp, struct nfsexstuff *exp, | nfsv4stateid_t *delegstateidp, u_int32_t *rflagsp, struct nfsexstuff *exp, | ||||
NFSPROC_T *p, u_quad_t filerev) | NFSPROC_T *p, u_quad_t filerev) | ||||
{ | { | ||||
struct nfsstate *new_stp = *new_stpp; | struct nfsstate *new_stp = *new_stpp; | ||||
struct nfsstate *stp, *nstp; | struct nfsstate *stp, *nstp; | ||||
struct nfsstate *openstp = NULL, *new_open, *ownerstp, *new_deleg; | struct nfsstate *openstp = NULL, *new_open, *ownerstp, *new_deleg; | ||||
▲ Show 20 Lines • Show All 749 Lines • ▼ Show 20 Lines | out: | ||||
free(clidp, M_TEMP); | free(clidp, M_TEMP); | ||||
NFSEXITCODE2(error, nd); | NFSEXITCODE2(error, nd); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Open update. Does the confirm, downgrade and close. | * Open update. Does the confirm, downgrade and close. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid, | nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid, | ||||
nfsv4stateid_t *stateidp, struct nfsrv_descript *nd, NFSPROC_T *p, | nfsv4stateid_t *stateidp, struct nfsrv_descript *nd, NFSPROC_T *p, | ||||
int *retwriteaccessp) | int *retwriteaccessp) | ||||
{ | { | ||||
struct nfsstate *stp; | struct nfsstate *stp; | ||||
struct nfsclient *clp; | struct nfsclient *clp; | ||||
struct nfslockfile *lfp; | struct nfslockfile *lfp; | ||||
u_int32_t bits; | u_int32_t bits; | ||||
▲ Show 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | out: | ||||
free(clidp, M_TEMP); | free(clidp, M_TEMP); | ||||
NFSEXITCODE2(error, nd); | NFSEXITCODE2(error, nd); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Delegation update. Does the purge and return. | * Delegation update. Does the purge and return. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_delegupdate(struct nfsrv_descript *nd, nfsquad_t clientid, | nfsrv_delegupdate(struct nfsrv_descript *nd, nfsquad_t clientid, | ||||
nfsv4stateid_t *stateidp, vnode_t vp, int op, struct ucred *cred, | nfsv4stateid_t *stateidp, vnode_t vp, int op, struct ucred *cred, | ||||
NFSPROC_T *p, int *retwriteaccessp) | NFSPROC_T *p, int *retwriteaccessp) | ||||
{ | { | ||||
struct nfsstate *stp; | struct nfsstate *stp; | ||||
struct nfsclient *clp; | struct nfsclient *clp; | ||||
int error = 0; | int error = 0; | ||||
fhandle_t fh; | fhandle_t fh; | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | |||||
out: | out: | ||||
NFSEXITCODE(error); | NFSEXITCODE(error); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Release lock owner. | * Release lock owner. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_releaselckown(struct nfsstate *new_stp, nfsquad_t clientid, | nfsrv_releaselckown(struct nfsstate *new_stp, nfsquad_t clientid, | ||||
NFSPROC_T *p) | NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsstate *stp, *nstp, *openstp, *ownstp; | struct nfsstate *stp, *nstp, *openstp, *ownstp; | ||||
struct nfsclient *clp; | struct nfsclient *clp; | ||||
int error = 0; | int error = 0; | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 369 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Get the client ip address for callbacks. If the strings can't be parsed, | * Get the client ip address for callbacks. If the strings can't be parsed, | ||||
* just set lc_program to 0 to indicate no callbacks are possible. | * just set lc_program to 0 to indicate no callbacks are possible. | ||||
* (For cases where the address can't be parsed or is 0.0.0.0.0.0, set | * (For cases where the address can't be parsed or is 0.0.0.0.0.0, set | ||||
* the address to the client's transport address. This won't be used | * the address to the client's transport address. This won't be used | ||||
* for callbacks, but can be printed out by nfsstats for info.) | * for callbacks, but can be printed out by nfsstats for info.) | ||||
* Return error if the xdr can't be parsed, 0 otherwise. | * Return error if the xdr can't be parsed, 0 otherwise. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_getclientipaddr(struct nfsrv_descript *nd, struct nfsclient *clp) | nfsrv_getclientipaddr(struct nfsrv_descript *nd, struct nfsclient *clp) | ||||
{ | { | ||||
u_int32_t *tl; | u_int32_t *tl; | ||||
u_char *cp, *cp2; | u_char *cp, *cp2; | ||||
int i, j, maxalen = 0, minalen = 0; | int i, j, maxalen = 0, minalen = 0; | ||||
sa_family_t af; | sa_family_t af; | ||||
#ifdef INET | #ifdef INET | ||||
struct sockaddr_in *rin = NULL, *sin; | struct sockaddr_in *rin = NULL, *sin; | ||||
▲ Show 20 Lines • Show All 738 Lines • ▼ Show 20 Lines | |||||
* If, for some reason, the file can't be read, the grace period is | * If, for some reason, the file can't be read, the grace period is | ||||
* immediately terminated and all reclaims get NFSERR_NOGRACE. | * immediately terminated and all reclaims get NFSERR_NOGRACE. | ||||
*/ | */ | ||||
/* | /* | ||||
* Read in the stable storage file. Called by nfssvc() before the nfsd | * Read in the stable storage file. Called by nfssvc() before the nfsd | ||||
* processes start servicing requests. | * processes start servicing requests. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsrv_setupstable(NFSPROC_T *p) | nfsrv_setupstable(NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsrv_stablefirst *sf = &nfsrv_stablefirst; | struct nfsrv_stablefirst *sf = &nfsrv_stablefirst; | ||||
struct nfsrv_stable *sp, *nsp; | struct nfsrv_stable *sp, *nsp; | ||||
struct nfst_rec *tsp; | struct nfst_rec *tsp; | ||||
int error, i, tryagain; | int error, i, tryagain; | ||||
off_t off = 0; | off_t off = 0; | ||||
ssize_t aresid, len; | ssize_t aresid, len; | ||||
▲ Show 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | nfsrv_setupstable(NFSPROC_T *p) | ||||
sf->nsf_flags = NFSNSF_OK; | sf->nsf_flags = NFSNSF_OK; | ||||
sf->nsf_eograce = NFSD_MONOSEC + sf->nsf_lease + | sf->nsf_eograce = NFSD_MONOSEC + sf->nsf_lease + | ||||
NFSRV_LEASEDELTA; | NFSRV_LEASEDELTA; | ||||
} | } | ||||
/* | /* | ||||
* Update the stable storage file, now that the grace period is over. | * Update the stable storage file, now that the grace period is over. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsrv_updatestable(NFSPROC_T *p) | nfsrv_updatestable(NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsrv_stablefirst *sf = &nfsrv_stablefirst; | struct nfsrv_stablefirst *sf = &nfsrv_stablefirst; | ||||
struct nfsrv_stable *sp, *nsp; | struct nfsrv_stable *sp, *nsp; | ||||
int i; | int i; | ||||
struct nfsvattr nva; | struct nfsvattr nva; | ||||
vnode_t vp; | vnode_t vp; | ||||
#if defined(__FreeBSD_version) && (__FreeBSD_version >= 500000) | #if defined(__FreeBSD_version) && (__FreeBSD_version >= 500000) | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | LIST_FOREACH_SAFE(sp, &sf->nsf_head, nst_list, nsp) { | ||||
free(sp, M_TEMP); | free(sp, M_TEMP); | ||||
} | } | ||||
nfsrv_backupstable(); | nfsrv_backupstable(); | ||||
} | } | ||||
/* | /* | ||||
* Append a record to the stable storage file. | * Append a record to the stable storage file. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsrv_writestable(u_char *client, int len, int flag, NFSPROC_T *p) | nfsrv_writestable(u_char *client, int len, int flag, NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsrv_stablefirst *sf = &nfsrv_stablefirst; | struct nfsrv_stablefirst *sf = &nfsrv_stablefirst; | ||||
struct nfst_rec *sp; | struct nfst_rec *sp; | ||||
int error; | int error; | ||||
if (!(sf->nsf_flags & NFSNSF_OK) || sf->nsf_fp == NULL) | if (!(sf->nsf_flags & NFSNSF_OK) || sf->nsf_fp == NULL) | ||||
return; | return; | ||||
▲ Show 20 Lines • Show All 351 Lines • ▼ Show 20 Lines | out: | ||||
NFSEXITCODE(error); | NFSEXITCODE(error); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Check for a remove allowed, if remove is set to 1 and get rid of | * Check for a remove allowed, if remove is set to 1 and get rid of | ||||
* delegations. | * delegations. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_checkremove(vnode_t vp, int remove, struct nfsrv_descript *nd, | nfsrv_checkremove(vnode_t vp, int remove, struct nfsrv_descript *nd, | ||||
nfsquad_t clientid, NFSPROC_T *p) | nfsquad_t clientid, NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsclient *clp; | struct nfsclient *clp; | ||||
struct nfsstate *stp; | struct nfsstate *stp; | ||||
struct nfslockfile *lfp; | struct nfslockfile *lfp; | ||||
int error, haslock = 0; | int error, haslock = 0; | ||||
fhandle_t nfh; | fhandle_t nfh; | ||||
▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | |||||
* Since the functions can only be called with an unlocked vnode, this | * Since the functions can only be called with an unlocked vnode, this | ||||
* can't be done at this time. | * can't be done at this time. | ||||
* VOP_ADVLOCK() - When a client holds a delegation, it can issue byte range | * VOP_ADVLOCK() - When a client holds a delegation, it can issue byte range | ||||
* locks locally in the client, which are not visible to the server. To | * locks locally in the client, which are not visible to the server. To | ||||
* deal with this, issuing of delegations for a vnode must be disabled | * deal with this, issuing of delegations for a vnode must be disabled | ||||
* and all delegations for the vnode recalled. This is done via the | * and all delegations for the vnode recalled. This is done via the | ||||
* second function, using the VV_DISABLEDELEG vflag on the vnode. | * second function, using the VV_DISABLEDELEG vflag on the vnode. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsd_recalldelegation(vnode_t vp, NFSPROC_T *p) | nfsd_recalldelegation(vnode_t vp, NFSPROC_T *p) | ||||
{ | { | ||||
time_t starttime; | time_t starttime; | ||||
int error; | int error; | ||||
/* | /* | ||||
* First, check to see if the server is currently running and it has | * First, check to see if the server is currently running and it has | ||||
* been called for a regular file when issuing delegations. | * been called for a regular file when issuing delegations. | ||||
Show All 30 Lines | if (error == NFSERR_DELAY) { | ||||
(void) nfs_catnap(PZERO, 0, "nfsremove"); | (void) nfs_catnap(PZERO, 0, "nfsremove"); | ||||
} | } | ||||
} while (error == NFSERR_DELAY); | } while (error == NFSERR_DELAY); | ||||
NFSLOCKV4ROOTMUTEX(); | NFSLOCKV4ROOTMUTEX(); | ||||
nfsv4_relref(&nfsv4rootfs_lock); | nfsv4_relref(&nfsv4rootfs_lock); | ||||
NFSUNLOCKV4ROOTMUTEX(); | NFSUNLOCKV4ROOTMUTEX(); | ||||
} | } | ||||
APPLESTATIC void | void | ||||
nfsd_disabledelegation(vnode_t vp, NFSPROC_T *p) | nfsd_disabledelegation(vnode_t vp, NFSPROC_T *p) | ||||
{ | { | ||||
#ifdef VV_DISABLEDELEG | #ifdef VV_DISABLEDELEG | ||||
/* | /* | ||||
* First, flag issuance of delegations disabled. | * First, flag issuance of delegations disabled. | ||||
*/ | */ | ||||
atomic_set_long(&vp->v_vflag, VV_DISABLEDELEG); | atomic_set_long(&vp->v_vflag, VV_DISABLEDELEG); | ||||
Show All 13 Lines | |||||
* allowed by the delegation. However, Setattr Ops that aren't changing | * allowed by the delegation. However, Setattr Ops that aren't changing | ||||
* the size get a stateid of all 0s, so you can't tell if it is a delegation | * the size get a stateid of all 0s, so you can't tell if it is a delegation | ||||
* for the same client or a different one, so I decided to only get rid | * for the same client or a different one, so I decided to only get rid | ||||
* of delegations for other clients when the size is being changed.) | * of delegations for other clients when the size is being changed.) | ||||
* In general, a Setattr can disable NFS I/O Ops that are outstanding, such | * In general, a Setattr can disable NFS I/O Ops that are outstanding, such | ||||
* as Write backs, even if there is no delegation, so it really isn't any | * as Write backs, even if there is no delegation, so it really isn't any | ||||
* different?) | * different?) | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_checksetattr(vnode_t vp, struct nfsrv_descript *nd, | nfsrv_checksetattr(vnode_t vp, struct nfsrv_descript *nd, | ||||
nfsv4stateid_t *stateidp, struct nfsvattr *nvap, nfsattrbit_t *attrbitp, | nfsv4stateid_t *stateidp, struct nfsvattr *nvap, nfsattrbit_t *attrbitp, | ||||
struct nfsexstuff *exp, NFSPROC_T *p) | struct nfsexstuff *exp, NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsstate st, *stp = &st; | struct nfsstate st, *stp = &st; | ||||
struct nfslock lo, *lop = &lo; | struct nfslock lo, *lop = &lo; | ||||
int error = 0; | int error = 0; | ||||
nfsquad_t clientid; | nfsquad_t clientid; | ||||
Show All 30 Lines | |||||
} | } | ||||
/* | /* | ||||
* Check for a write delegation and do a CBGETATTR if there is one, updating | * Check for a write delegation and do a CBGETATTR if there is one, updating | ||||
* the attributes, as required. | * the attributes, as required. | ||||
* Should I return an error if I can't get the attributes? (For now, I'll | * Should I return an error if I can't get the attributes? (For now, I'll | ||||
* just return ok. | * just return ok. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_checkgetattr(struct nfsrv_descript *nd, vnode_t vp, | nfsrv_checkgetattr(struct nfsrv_descript *nd, vnode_t vp, | ||||
struct nfsvattr *nvap, nfsattrbit_t *attrbitp, NFSPROC_T *p) | struct nfsvattr *nvap, nfsattrbit_t *attrbitp, NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsstate *stp; | struct nfsstate *stp; | ||||
struct nfslockfile *lfp; | struct nfslockfile *lfp; | ||||
struct nfsclient *clp; | struct nfsclient *clp; | ||||
struct nfsvattr nva; | struct nfsvattr nva; | ||||
fhandle_t nfh; | fhandle_t nfh; | ||||
▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | out: | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* This function looks for openowners that haven't had any opens for | * This function looks for openowners that haven't had any opens for | ||||
* a while and throws them away. Called by an nfsd when NFSNSF_NOOPENS | * a while and throws them away. Called by an nfsd when NFSNSF_NOOPENS | ||||
* is set. | * is set. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsrv_throwawayopens(NFSPROC_T *p) | nfsrv_throwawayopens(NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsclient *clp, *nclp; | struct nfsclient *clp, *nclp; | ||||
struct nfsstate *stp, *nstp; | struct nfsstate *stp, *nstp; | ||||
int i; | int i; | ||||
NFSLOCKSTATE(); | NFSLOCKSTATE(); | ||||
nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NOOPENS; | nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NOOPENS; | ||||
▲ Show 20 Lines • Show All 874 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Free up all backchannel xprts. This needs to be done when the nfsd threads | * Free up all backchannel xprts. This needs to be done when the nfsd threads | ||||
* exit, since those transports will all be going away. | * exit, since those transports will all be going away. | ||||
* This is only called after all the nfsd threads are done performing RPCs, | * This is only called after all the nfsd threads are done performing RPCs, | ||||
* so locking shouldn't be an issue. | * so locking shouldn't be an issue. | ||||
*/ | */ | ||||
APPLESTATIC void | void | ||||
nfsrv_freeallbackchannel_xprts(void) | nfsrv_freeallbackchannel_xprts(void) | ||||
{ | { | ||||
struct nfsdsession *sep; | struct nfsdsession *sep; | ||||
struct nfsclient *clp; | struct nfsclient *clp; | ||||
SVCXPRT *xprt; | SVCXPRT *xprt; | ||||
int i; | int i; | ||||
for (i = 0; i < nfsrv_clienthashsize; i++) { | for (i = 0; i < nfsrv_clienthashsize; i++) { | ||||
▲ Show 20 Lines • Show All 1,123 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Similar to nfsrv_deldsnmp(), except that the DS is indicated by deviceid. | * Similar to nfsrv_deldsnmp(), except that the DS is indicated by deviceid. | ||||
* This function also calls nfsrv_killrpcs() to unblock RPCs on the mount | * This function also calls nfsrv_killrpcs() to unblock RPCs on the mount | ||||
* point. | * point. | ||||
* Also, returns an error instead of the nfsdevice found. | * Also, returns an error instead of the nfsdevice found. | ||||
*/ | */ | ||||
APPLESTATIC int | int | ||||
nfsrv_delds(char *devid, NFSPROC_T *p) | nfsrv_delds(char *devid, NFSPROC_T *p) | ||||
{ | { | ||||
struct nfsdevice *ds, *fndds; | struct nfsdevice *ds, *fndds; | ||||
struct nfsmount *nmp; | struct nfsmount *nmp; | ||||
int fndmirror; | int fndmirror; | ||||
NFSD_DEBUG(4, "delds\n"); | NFSD_DEBUG(4, "delds\n"); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 237 Lines • ▼ Show 20 Lines | |||||
* - A Write Delegation | * - A Write Delegation | ||||
* or | * or | ||||
* - An Open with Write_access. | * - An Open with Write_access. | ||||
* Return 1 if this is the case and 0 otherwise. | * Return 1 if this is the case and 0 otherwise. | ||||
* This function is used by nfsrv_proxyds() to decide if doing a Proxy | * This function is used by nfsrv_proxyds() to decide if doing a Proxy | ||||
* Getattr RPC to the Data Server (DS) is necessary. | * Getattr RPC to the Data Server (DS) is necessary. | ||||
*/ | */ | ||||
#define NFSCLIDVECSIZE 6 | #define NFSCLIDVECSIZE 6 | ||||
APPLESTATIC int | int | ||||
nfsrv_checkdsattr(vnode_t vp, NFSPROC_T *p) | nfsrv_checkdsattr(vnode_t vp, NFSPROC_T *p) | ||||
{ | { | ||||
fhandle_t fh, *tfhp; | fhandle_t fh, *tfhp; | ||||
struct nfsstate *stp; | struct nfsstate *stp; | ||||
struct nfslayout *lyp; | struct nfslayout *lyp; | ||||
struct nfslayouthash *lhyp; | struct nfslayouthash *lhyp; | ||||
struct nfslockhashhead *hp; | struct nfslockhashhead *hp; | ||||
struct nfslockfile *lfp; | struct nfslockfile *lfp; | ||||
▲ Show 20 Lines • Show All 691 Lines • Show Last 20 Lines |