nfscl: Restructure nfscl_freeopen() slightly

This patch factors the unlinking of the nfsclopen structure out of
nfscl_freeopen() into a separate function called nfscl_unlinkopen().
It also adds a new argument to nfscl_freeopen() to conditionally do
the unlink.  Since this new argument is always passed in as "true"
at this time, no semantics change should occur.

This is being done to prepare the code for a future patch that fixes
the case where an NFSv4.1/4.2 server replies NFSERR_DELAY to a Close
operation.

MFC after:	2 week
This commit is contained in:
Rick Macklem 2021-10-14 17:28:01 -07:00
parent a72ee35564
commit 6495766acf
3 changed files with 28 additions and 16 deletions

View File

@ -595,7 +595,7 @@ int nfscl_checkwritelocked(vnode_t, struct flock *,
void nfscl_lockrelease(struct nfscllockowner *, int, int);
void nfscl_fillclid(u_int64_t, char *, u_int8_t *, u_int16_t);
void nfscl_filllockowner(void *, u_int8_t *, int);
void nfscl_freeopen(struct nfsclopen *, int);
void nfscl_freeopen(struct nfsclopen *, int, bool);
void nfscl_umount(struct nfsmount *, NFSPROC_T *);
void nfscl_renewthread(struct nfsclclient *, NFSPROC_T *);
void nfscl_initiate_recovery(struct nfsclclient *);

View File

@ -850,7 +850,7 @@ nfsrpc_doclose(struct nfsmount *nmp, struct nfsclopen *op, NFSPROC_T *p)
LIST_FOREACH_SAFE(lp, &op->nfso_lock, nfsl_list, nlp)
nfscl_freelockowner(lp, 0);
nfscl_freeopen(op, 0);
nfscl_freeopen(op, 0, true);
NFSUNLOCKCLSTATE();
NFSFREECRED(tcred);
}

View File

@ -107,6 +107,7 @@ static bool nfscl_checkown(struct nfsclowner *, struct nfsclopen *, uint8_t *,
uint8_t *, struct nfscllockowner **, struct nfsclopen **,
struct nfsclopen **);
static void nfscl_clrelease(struct nfsclclient *);
static void nfscl_unlinkopen(struct nfsclopen *);
static void nfscl_cleanclient(struct nfsclclient *);
static void nfscl_expireclient(struct nfsclclient *, struct nfsmount *,
struct ucred *, NFSPROC_T *);
@ -846,7 +847,7 @@ nfscl_openrelease(struct nfsmount *nmp, struct nfsclopen *op, int error,
nfscl_lockunlock(&owp->nfsow_rwlock);
clp = owp->nfsow_clp;
if (error && candelete && op->nfso_opencnt == 0)
nfscl_freeopen(op, 0);
nfscl_freeopen(op, 0, true);
nfscl_clrelease(clp);
NFSUNLOCKCLSTATE();
}
@ -1540,15 +1541,26 @@ nfscl_lockrelease(struct nfscllockowner *lp, int error, int candelete)
}
/*
* Free up an open structure and any associated byte range lock structures.
* Unlink the open structure.
*/
void
nfscl_freeopen(struct nfsclopen *op, int local)
static void
nfscl_unlinkopen(struct nfsclopen *op)
{
LIST_REMOVE(op, nfso_list);
if (op->nfso_hash.le_prev != NULL)
LIST_REMOVE(op, nfso_hash);
}
/*
* Free up an open structure and any associated byte range lock structures.
*/
void
nfscl_freeopen(struct nfsclopen *op, int local, bool unlink)
{
if (unlink)
nfscl_unlinkopen(op);
nfscl_freealllocks(&op->nfso_lock, local);
free(op, M_NFSCLOPEN);
if (local)
@ -1619,7 +1631,7 @@ nfscl_expireopen(struct nfsclclient *clp, struct nfsclopen *op,
* If a byte range lock or Share deny or couldn't re-open, free it.
*/
if (mustdelete)
nfscl_freeopen(op, 0);
nfscl_freeopen(op, 0, true);
return (mustdelete);
}
@ -1686,7 +1698,7 @@ nfscl_cleandeleg(struct nfscldeleg *dp)
if (op != NULL) {
if (LIST_NEXT(op, nfso_list) != NULL)
panic("nfscleandel");
nfscl_freeopen(op, 1);
nfscl_freeopen(op, 1, true);
}
nfscl_freeopenowner(owp, 1);
}
@ -1728,7 +1740,7 @@ nfscl_cleanclient(struct nfsclclient *clp)
/* Now, all the OpenOwners, etc. */
LIST_FOREACH_SAFE(owp, &clp->nfsc_owner, nfsow_list, nowp) {
LIST_FOREACH_SAFE(op, &owp->nfsow_open, nfso_list, nop) {
nfscl_freeopen(op, 0);
nfscl_freeopen(op, 0, true);
}
nfscl_freeopenowner(owp, 0);
}
@ -2267,7 +2279,7 @@ nfscl_recover(struct nfsclclient *clp, bool *retokp, struct ucred *cred,
}
}
if (error != 0 && error != NFSERR_BADSESSION)
nfscl_freeopen(op, 0);
nfscl_freeopen(op, 0, true);
op = nop;
}
owp = nowp;
@ -3341,7 +3353,7 @@ nfscl_doclose(vnode_t vp, struct nfsclclient **clpp, NFSPROC_T *p)
if (op != NULL) {
KASSERT((op->nfso_opencnt == 0),
("nfscl: bad open cnt on deleg"));
nfscl_freeopen(op, 1);
nfscl_freeopen(op, 1, true);
}
nfscl_freeopenowner(owp, 1);
}
@ -4187,7 +4199,7 @@ nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *nmp,
ret == NFSERR_BADSESSION)
return (ret);
if (ret) {
nfscl_freeopen(lop, 1);
nfscl_freeopen(lop, 1, true);
if (!error)
error = ret;
}
@ -4216,7 +4228,7 @@ nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *nmp,
ret == NFSERR_BADSESSION)
return (ret);
if (ret) {
nfscl_freeopen(lop, 1);
nfscl_freeopen(lop, 1, true);
if (!error)
error = ret;
}
@ -4268,7 +4280,7 @@ nfscl_moveopen(vnode_t vp, struct nfsclclient *clp, struct nfsmount *nmp,
op->nfso_fhlen == lop->nfso_fhlen &&
!NFSBCMP(op->nfso_fh, lop->nfso_fh, op->nfso_fhlen)) {
op->nfso_opencnt += lop->nfso_opencnt;
nfscl_freeopen(lop, 1);
nfscl_freeopen(lop, 1, true);
return (0);
}
}
@ -4287,11 +4299,11 @@ nfscl_moveopen(vnode_t vp, struct nfsclclient *clp, struct nfsmount *nmp,
NFS4NODENAME(np->n_v4), np->n_v4->n4_namelen, &ndp, 0, 0, cred, p);
if (error) {
if (newone)
nfscl_freeopen(op, 0);
nfscl_freeopen(op, 0, true);
} else {
op->nfso_mode |= lop->nfso_mode;
op->nfso_opencnt += lop->nfso_opencnt;
nfscl_freeopen(lop, 1);
nfscl_freeopen(lop, 1, true);
}
if (nop != NULL)
free(nop, M_NFSCLOPEN);