Changeset View
Changeset View
Standalone View
Standalone View
head/sys/fs/nfsclient/nfs_clstate.c
Show First 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
#ifndef APPLEKEXT | #ifndef APPLEKEXT | ||||
#include <fs/nfs/nfsport.h> | #include <fs/nfs/nfsport.h> | ||||
/* | /* | ||||
* Global variables | * Global variables | ||||
*/ | */ | ||||
extern struct nfsstats newnfsstats; | extern struct nfsstatsv1 nfsstatsv1; | ||||
extern struct nfsreqhead nfsd_reqq; | extern struct nfsreqhead nfsd_reqq; | ||||
extern u_int32_t newnfs_false, newnfs_true; | extern u_int32_t newnfs_false, newnfs_true; | ||||
extern int nfscl_debuglevel; | extern int nfscl_debuglevel; | ||||
NFSREQSPINLOCK; | NFSREQSPINLOCK; | ||||
NFSCLSTATEMUTEX; | NFSCLSTATEMUTEX; | ||||
int nfscl_inited = 0; | int nfscl_inited = 0; | ||||
struct nfsclhead nfsclhead; /* Head of clientid list */ | struct nfsclhead nfsclhead; /* Head of clientid list */ | ||||
int nfscl_deleghighwater = NFSCLDELEGHIGHWATER; | int nfscl_deleghighwater = NFSCLDELEGHIGHWATER; | ||||
▲ Show 20 Lines • Show All 242 Lines • ▼ Show 20 Lines | nfscl_newopen(struct nfsclclient *clp, struct nfscldeleg *dp, | ||||
if (owp == NULL && nowp != NULL) { | if (owp == NULL && nowp != NULL) { | ||||
NFSBCOPY(own, nowp->nfsow_owner, NFSV4CL_LOCKNAMELEN); | NFSBCOPY(own, nowp->nfsow_owner, NFSV4CL_LOCKNAMELEN); | ||||
LIST_INIT(&nowp->nfsow_open); | LIST_INIT(&nowp->nfsow_open); | ||||
nowp->nfsow_clp = clp; | nowp->nfsow_clp = clp; | ||||
nowp->nfsow_seqid = 0; | nowp->nfsow_seqid = 0; | ||||
nowp->nfsow_defunct = 0; | nowp->nfsow_defunct = 0; | ||||
nfscl_lockinit(&nowp->nfsow_rwlock); | nfscl_lockinit(&nowp->nfsow_rwlock); | ||||
if (dp != NULL) { | if (dp != NULL) { | ||||
newnfsstats.cllocalopenowners++; | nfsstatsv1.cllocalopenowners++; | ||||
LIST_INSERT_HEAD(&dp->nfsdl_owner, nowp, nfsow_list); | LIST_INSERT_HEAD(&dp->nfsdl_owner, nowp, nfsow_list); | ||||
} else { | } else { | ||||
newnfsstats.clopenowners++; | nfsstatsv1.clopenowners++; | ||||
LIST_INSERT_HEAD(&clp->nfsc_owner, nowp, nfsow_list); | LIST_INSERT_HEAD(&clp->nfsc_owner, nowp, nfsow_list); | ||||
} | } | ||||
owp = *owpp = nowp; | owp = *owpp = nowp; | ||||
*nowpp = NULL; | *nowpp = NULL; | ||||
if (newonep != NULL) | if (newonep != NULL) | ||||
*newonep = 1; | *newonep = 1; | ||||
} | } | ||||
Show All 17 Lines | if (op == NULL && nop != NULL) { | ||||
nop->nfso_stateid.other[0] = 0; | nop->nfso_stateid.other[0] = 0; | ||||
nop->nfso_stateid.other[1] = 0; | nop->nfso_stateid.other[1] = 0; | ||||
nop->nfso_stateid.other[2] = 0; | nop->nfso_stateid.other[2] = 0; | ||||
if (dp != NULL) { | if (dp != NULL) { | ||||
TAILQ_REMOVE(&clp->nfsc_deleg, dp, nfsdl_list); | TAILQ_REMOVE(&clp->nfsc_deleg, dp, nfsdl_list); | ||||
TAILQ_INSERT_HEAD(&clp->nfsc_deleg, dp, | TAILQ_INSERT_HEAD(&clp->nfsc_deleg, dp, | ||||
nfsdl_list); | nfsdl_list); | ||||
dp->nfsdl_timestamp = NFSD_MONOSEC + 120; | dp->nfsdl_timestamp = NFSD_MONOSEC + 120; | ||||
newnfsstats.cllocalopens++; | nfsstatsv1.cllocalopens++; | ||||
} else { | } else { | ||||
newnfsstats.clopens++; | nfsstatsv1.clopens++; | ||||
} | } | ||||
LIST_INSERT_HEAD(&owp->nfsow_open, nop, nfso_list); | LIST_INSERT_HEAD(&owp->nfsow_open, nop, nfso_list); | ||||
*opp = nop; | *opp = nop; | ||||
*nopp = NULL; | *nopp = NULL; | ||||
if (newonep != NULL) | if (newonep != NULL) | ||||
*newonep = 1; | *newonep = 1; | ||||
} else { | } else { | ||||
*opp = op; | *opp = op; | ||||
Show All 31 Lines | if (dp == NULL) { | ||||
NFSUNLOCKCLSTATE(); | NFSUNLOCKCLSTATE(); | ||||
return (NFSERR_BADSTATEID); | return (NFSERR_BADSTATEID); | ||||
} | } | ||||
*dpp = NULL; | *dpp = NULL; | ||||
TAILQ_INSERT_HEAD(&clp->nfsc_deleg, dp, nfsdl_list); | TAILQ_INSERT_HEAD(&clp->nfsc_deleg, dp, nfsdl_list); | ||||
LIST_INSERT_HEAD(NFSCLDELEGHASH(clp, nfhp, fhlen), dp, | LIST_INSERT_HEAD(NFSCLDELEGHASH(clp, nfhp, fhlen), dp, | ||||
nfsdl_hash); | nfsdl_hash); | ||||
dp->nfsdl_timestamp = NFSD_MONOSEC + 120; | dp->nfsdl_timestamp = NFSD_MONOSEC + 120; | ||||
newnfsstats.cldelegates++; | nfsstatsv1.cldelegates++; | ||||
nfscl_delegcnt++; | nfscl_delegcnt++; | ||||
} else { | } else { | ||||
/* | /* | ||||
* Delegation already exists, what do we do if a new one?? | * Delegation already exists, what do we do if a new one?? | ||||
*/ | */ | ||||
if (dp != NULL) { | if (dp != NULL) { | ||||
printf("Deleg already exists!\n"); | printf("Deleg already exists!\n"); | ||||
FREE((caddr_t)dp, M_NFSCLDELEG); | FREE((caddr_t)dp, M_NFSCLDELEG); | ||||
▲ Show 20 Lines • Show All 624 Lines • ▼ Show 20 Lines | else | ||||
NFSV4CL_LOCKNAMELEN); | NFSV4CL_LOCKNAMELEN); | ||||
nlp->nfsl_seqid = 0; | nlp->nfsl_seqid = 0; | ||||
nlp->nfsl_lockflags = flags; | nlp->nfsl_lockflags = flags; | ||||
nlp->nfsl_inprog = NULL; | nlp->nfsl_inprog = NULL; | ||||
nfscl_lockinit(&nlp->nfsl_rwlock); | nfscl_lockinit(&nlp->nfsl_rwlock); | ||||
LIST_INIT(&nlp->nfsl_lock); | LIST_INIT(&nlp->nfsl_lock); | ||||
if (donelocally) { | if (donelocally) { | ||||
nlp->nfsl_open = NULL; | nlp->nfsl_open = NULL; | ||||
newnfsstats.cllocallockowners++; | nfsstatsv1.cllocallockowners++; | ||||
} else { | } else { | ||||
nlp->nfsl_open = op; | nlp->nfsl_open = op; | ||||
newnfsstats.cllockowners++; | nfsstatsv1.cllockowners++; | ||||
} | } | ||||
LIST_INSERT_HEAD(lhp, nlp, nfsl_list); | LIST_INSERT_HEAD(lhp, nlp, nfsl_list); | ||||
lp = nlp; | lp = nlp; | ||||
nlp = NULL; | nlp = NULL; | ||||
*newonep = 1; | *newonep = 1; | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 311 Lines • ▼ Show 20 Lines | |||||
APPLESTATIC void | APPLESTATIC void | ||||
nfscl_freeopen(struct nfsclopen *op, int local) | nfscl_freeopen(struct nfsclopen *op, int local) | ||||
{ | { | ||||
LIST_REMOVE(op, nfso_list); | LIST_REMOVE(op, nfso_list); | ||||
nfscl_freealllocks(&op->nfso_lock, local); | nfscl_freealllocks(&op->nfso_lock, local); | ||||
FREE((caddr_t)op, M_NFSCLOPEN); | FREE((caddr_t)op, M_NFSCLOPEN); | ||||
if (local) | if (local) | ||||
newnfsstats.cllocalopens--; | nfsstatsv1.cllocalopens--; | ||||
else | else | ||||
newnfsstats.clopens--; | nfsstatsv1.clopens--; | ||||
} | } | ||||
/* | /* | ||||
* Free up all lock owners and associated locks. | * Free up all lock owners and associated locks. | ||||
*/ | */ | ||||
static void | static void | ||||
nfscl_freealllocks(struct nfscllockownerhead *lhp, int local) | nfscl_freealllocks(struct nfscllockownerhead *lhp, int local) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
static void | static void | ||||
nfscl_freeopenowner(struct nfsclowner *owp, int local) | nfscl_freeopenowner(struct nfsclowner *owp, int local) | ||||
{ | { | ||||
LIST_REMOVE(owp, nfsow_list); | LIST_REMOVE(owp, nfsow_list); | ||||
FREE((caddr_t)owp, M_NFSCLOWNER); | FREE((caddr_t)owp, M_NFSCLOWNER); | ||||
if (local) | if (local) | ||||
newnfsstats.cllocalopenowners--; | nfsstatsv1.cllocalopenowners--; | ||||
else | else | ||||
newnfsstats.clopenowners--; | nfsstatsv1.clopenowners--; | ||||
} | } | ||||
/* | /* | ||||
* Free up a byte range lock owner structure. | * Free up a byte range lock owner structure. | ||||
*/ | */ | ||||
APPLESTATIC void | APPLESTATIC void | ||||
nfscl_freelockowner(struct nfscllockowner *lp, int local) | nfscl_freelockowner(struct nfscllockowner *lp, int local) | ||||
{ | { | ||||
struct nfscllock *lop, *nlop; | struct nfscllock *lop, *nlop; | ||||
LIST_REMOVE(lp, nfsl_list); | LIST_REMOVE(lp, nfsl_list); | ||||
LIST_FOREACH_SAFE(lop, &lp->nfsl_lock, nfslo_list, nlop) { | LIST_FOREACH_SAFE(lop, &lp->nfsl_lock, nfslo_list, nlop) { | ||||
nfscl_freelock(lop, local); | nfscl_freelock(lop, local); | ||||
} | } | ||||
FREE((caddr_t)lp, M_NFSCLLOCKOWNER); | FREE((caddr_t)lp, M_NFSCLLOCKOWNER); | ||||
if (local) | if (local) | ||||
newnfsstats.cllocallockowners--; | nfsstatsv1.cllocallockowners--; | ||||
else | else | ||||
newnfsstats.cllockowners--; | nfsstatsv1.cllockowners--; | ||||
} | } | ||||
/* | /* | ||||
* Free up a byte range lock structure. | * Free up a byte range lock structure. | ||||
*/ | */ | ||||
APPLESTATIC void | APPLESTATIC void | ||||
nfscl_freelock(struct nfscllock *lop, int local) | nfscl_freelock(struct nfscllock *lop, int local) | ||||
{ | { | ||||
LIST_REMOVE(lop, nfslo_list); | LIST_REMOVE(lop, nfslo_list); | ||||
FREE((caddr_t)lop, M_NFSCLLOCK); | FREE((caddr_t)lop, M_NFSCLLOCK); | ||||
if (local) | if (local) | ||||
newnfsstats.cllocallocks--; | nfsstatsv1.cllocallocks--; | ||||
else | else | ||||
newnfsstats.cllocks--; | nfsstatsv1.cllocks--; | ||||
} | } | ||||
/* | /* | ||||
* Clean out the state related to a delegation. | * Clean out the state related to a delegation. | ||||
*/ | */ | ||||
static void | static void | ||||
nfscl_cleandeleg(struct nfscldeleg *dp) | nfscl_cleandeleg(struct nfscldeleg *dp) | ||||
{ | { | ||||
Show All 17 Lines | |||||
*/ | */ | ||||
static void | static void | ||||
nfscl_freedeleg(struct nfscldeleghead *hdp, struct nfscldeleg *dp) | nfscl_freedeleg(struct nfscldeleghead *hdp, struct nfscldeleg *dp) | ||||
{ | { | ||||
TAILQ_REMOVE(hdp, dp, nfsdl_list); | TAILQ_REMOVE(hdp, dp, nfsdl_list); | ||||
LIST_REMOVE(dp, nfsdl_hash); | LIST_REMOVE(dp, nfsdl_hash); | ||||
FREE((caddr_t)dp, M_NFSCLDELEG); | FREE((caddr_t)dp, M_NFSCLDELEG); | ||||
newnfsstats.cldelegates--; | nfsstatsv1.cldelegates--; | ||||
nfscl_delegcnt--; | nfscl_delegcnt--; | ||||
} | } | ||||
/* | /* | ||||
* Free up all state related to this client structure. | * Free up all state related to this client structure. | ||||
*/ | */ | ||||
static void | static void | ||||
nfscl_cleanclient(struct nfsclclient *clp) | nfscl_cleanclient(struct nfsclclient *clp) | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | if (op != NULL) { | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if (top == NULL) { | if (top == NULL) { | ||||
/* Just add the open to the owner list */ | /* Just add the open to the owner list */ | ||||
LIST_REMOVE(op, nfso_list); | LIST_REMOVE(op, nfso_list); | ||||
op->nfso_own = towp; | op->nfso_own = towp; | ||||
LIST_INSERT_HEAD(&towp->nfsow_open, op, nfso_list); | LIST_INSERT_HEAD(&towp->nfsow_open, op, nfso_list); | ||||
newnfsstats.cllocalopens--; | nfsstatsv1.cllocalopens--; | ||||
newnfsstats.clopens++; | nfsstatsv1.clopens++; | ||||
} | } | ||||
} else { | } else { | ||||
/* Just add the openowner to the client list */ | /* Just add the openowner to the client list */ | ||||
LIST_REMOVE(owp, nfsow_list); | LIST_REMOVE(owp, nfsow_list); | ||||
owp->nfsow_clp = clp; | owp->nfsow_clp = clp; | ||||
LIST_INSERT_HEAD(&clp->nfsc_owner, owp, nfsow_list); | LIST_INSERT_HEAD(&clp->nfsc_owner, owp, nfsow_list); | ||||
newnfsstats.cllocalopenowners--; | nfsstatsv1.cllocalopenowners--; | ||||
newnfsstats.clopenowners++; | nfsstatsv1.clopenowners++; | ||||
newnfsstats.cllocalopens--; | nfsstatsv1.cllocalopens--; | ||||
newnfsstats.clopens++; | nfsstatsv1.clopens++; | ||||
} | } | ||||
} | } | ||||
owp = nowp; | owp = nowp; | ||||
} | } | ||||
if (!printed && !LIST_EMPTY(&dp->nfsdl_lock)) { | if (!printed && !LIST_EMPTY(&dp->nfsdl_lock)) { | ||||
printed = 1; | printed = 1; | ||||
printf("nfsv4 expired locks lost\n"); | printf("nfsv4 expired locks lost\n"); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 633 Lines • ▼ Show 20 Lines | nfscl_insertlock(struct nfscllockowner *lp, struct nfscllock *new_lop, | ||||
struct nfscllock *insert_lop, int local) | struct nfscllock *insert_lop, int local) | ||||
{ | { | ||||
if ((struct nfscllockowner *)insert_lop == lp) | if ((struct nfscllockowner *)insert_lop == lp) | ||||
LIST_INSERT_HEAD(&lp->nfsl_lock, new_lop, nfslo_list); | LIST_INSERT_HEAD(&lp->nfsl_lock, new_lop, nfslo_list); | ||||
else | else | ||||
LIST_INSERT_AFTER(insert_lop, new_lop, nfslo_list); | LIST_INSERT_AFTER(insert_lop, new_lop, nfslo_list); | ||||
if (local) | if (local) | ||||
newnfsstats.cllocallocks++; | nfsstatsv1.cllocallocks++; | ||||
else | else | ||||
newnfsstats.cllocks++; | nfsstatsv1.cllocks++; | ||||
} | } | ||||
/* | /* | ||||
* This function updates the locking for a lock owner and given file. It | * This function updates the locking for a lock owner and given file. It | ||||
* maintains a list of lock ranges ordered on increasing file offset that | * maintains a list of lock ranges ordered on increasing file offset that | ||||
* are NFSCLLOCK_READ or NFSCLLOCK_WRITE and non-overlapping (aka POSIX style). | * are NFSCLLOCK_READ or NFSCLLOCK_WRITE and non-overlapping (aka POSIX style). | ||||
* It always adds new_lop to the list and sometimes uses the one pointed | * It always adds new_lop to the list and sometimes uses the one pointed | ||||
* at by other_lopp. | * at by other_lopp. | ||||
▲ Show 20 Lines • Show All 270 Lines • ▼ Show 20 Lines | while (dp != NULL) { | ||||
NULL, cred, p, 1); | NULL, cred, p, 1); | ||||
if (!ret) { | if (!ret) { | ||||
nfscl_cleandeleg(dp); | nfscl_cleandeleg(dp); | ||||
TAILQ_REMOVE(&clp->nfsc_deleg, dp, | TAILQ_REMOVE(&clp->nfsc_deleg, dp, | ||||
nfsdl_list); | nfsdl_list); | ||||
LIST_REMOVE(dp, nfsdl_hash); | LIST_REMOVE(dp, nfsdl_hash); | ||||
TAILQ_INSERT_HEAD(&dh, dp, nfsdl_list); | TAILQ_INSERT_HEAD(&dh, dp, nfsdl_list); | ||||
nfscl_delegcnt--; | nfscl_delegcnt--; | ||||
newnfsstats.cldelegates--; | nfsstatsv1.cldelegates--; | ||||
} | } | ||||
NFSLOCKCLSTATE(); | NFSLOCKCLSTATE(); | ||||
} | } | ||||
dp = ndp; | dp = ndp; | ||||
} | } | ||||
/* | /* | ||||
* Clear out old delegations, if we are above the high water | * Clear out old delegations, if we are above the high water | ||||
Show All 24 Lines | while (nfscl_delegcnt > nfscl_deleghighwater && dp != NULL) { | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (clearok) { | if (clearok) { | ||||
TAILQ_REMOVE(&clp->nfsc_deleg, dp, nfsdl_list); | TAILQ_REMOVE(&clp->nfsc_deleg, dp, nfsdl_list); | ||||
LIST_REMOVE(dp, nfsdl_hash); | LIST_REMOVE(dp, nfsdl_hash); | ||||
TAILQ_INSERT_HEAD(&dh, dp, nfsdl_list); | TAILQ_INSERT_HEAD(&dh, dp, nfsdl_list); | ||||
nfscl_delegcnt--; | nfscl_delegcnt--; | ||||
newnfsstats.cldelegates--; | nfsstatsv1.cldelegates--; | ||||
} | } | ||||
} | } | ||||
dp = ndp; | dp = ndp; | ||||
} | } | ||||
if (igotlock) | if (igotlock) | ||||
nfsv4_unlock(&clp->nfsc_lock, 0); | nfsv4_unlock(&clp->nfsc_lock, 0); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 586 Lines • ▼ Show 20 Lines | if (op < NFSV4OP_CBGETATTR || | ||||
(op > NFSV4OP_CBNOTIFYDEVID && | (op > NFSV4OP_CBNOTIFYDEVID && | ||||
minorvers == NFSV41_MINORVERSION)) { | minorvers == NFSV41_MINORVERSION)) { | ||||
nd->nd_repstat = NFSERR_OPILLEGAL; | nd->nd_repstat = NFSERR_OPILLEGAL; | ||||
*repp = nfscl_errmap(nd, minorvers); | *repp = nfscl_errmap(nd, minorvers); | ||||
retops++; | retops++; | ||||
break; | break; | ||||
} | } | ||||
nd->nd_procnum = op; | nd->nd_procnum = op; | ||||
if (op < NFSV4OP_CBNOPS) | if (op < NFSV41_CBNOPS) | ||||
newnfsstats.cbrpccnt[nd->nd_procnum]++; | nfsstatsv1.cbrpccnt[nd->nd_procnum]++; | ||||
switch (op) { | switch (op) { | ||||
case NFSV4OP_CBGETATTR: | case NFSV4OP_CBGETATTR: | ||||
NFSCL_DEBUG(4, "cbgetattr\n"); | NFSCL_DEBUG(4, "cbgetattr\n"); | ||||
mp = NULL; | mp = NULL; | ||||
vp = NULL; | vp = NULL; | ||||
error = nfsm_getfh(nd, &nfhp); | error = nfsm_getfh(nd, &nfhp); | ||||
if (!error) | if (!error) | ||||
error = nfsrv_getattrbits(nd, &attrbits, | error = nfsrv_getattrbits(nd, &attrbits, | ||||
▲ Show 20 Lines • Show All 1,994 Lines • Show Last 20 Lines |