> On Mar 15, 2022, at 12:26 PM, Dai Ngo <dai.ngo@xxxxxxxxxx> wrote: > > > On 3/15/22 8:02 AM, J. Bruce Fields wrote: >> On Fri, Mar 11, 2022 at 06:13:27PM -0800, Dai Ngo wrote: >>> Add callout function nfsd4_lm_lock_expired for lm_lock_expired. >>> If lock request has conflict with courtesy client then expire the >>> courtesy client and return no conflict to caller. >>> >>> Signed-off-by: Dai Ngo <dai.ngo@xxxxxxxxxx> >>> --- >>> fs/nfsd/nfs4state.c | 37 +++++++++++++++++++++++++++++++++++++ >>> 1 file changed, 37 insertions(+) >>> >>> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c >>> index a65d59510681..583ac807e98d 100644 >>> --- a/fs/nfsd/nfs4state.c >>> +++ b/fs/nfsd/nfs4state.c >>> @@ -6578,10 +6578,47 @@ nfsd4_lm_notify(struct file_lock *fl) >>> } >>> } >>> +/** >>> + * nfsd4_lm_lock_expired - check if lock conflict can be resolved. >>> + * >>> + * @fl: pointer to file_lock with a potential conflict >>> + * Return values: >>> + * %false: real conflict, lock conflict can not be resolved. >>> + * %true: no conflict, lock conflict was resolved. >>> + * >>> + * Note that this function is called while the flc_lock is held. >>> + */ >>> +static bool >>> +nfsd4_lm_lock_expired(struct file_lock *fl) >>> +{ >>> + struct nfs4_lockowner *lo; >>> + struct nfs4_client *clp; >>> + bool rc = false; >>> + >>> + if (!fl) >>> + return false; >>> + lo = (struct nfs4_lockowner *)fl->fl_owner; >>> + clp = lo->lo_owner.so_client; >>> + >>> + /* need to sync with courtesy client trying to reconnect */ >>> + spin_lock(&clp->cl_cs_lock); >>> + if (test_bit(NFSD4_CLIENT_EXPIRED, &clp->cl_flags)) >>> + rc = true; >>> + else { >>> + if (test_bit(NFSD4_CLIENT_COURTESY, &clp->cl_flags)) { >>> + set_bit(NFSD4_CLIENT_EXPIRED, &clp->cl_flags); >>> + rc = true; >>> + } >>> + } >> I'd prefer: >> >> if (test_bit(NFSD4_CLIENT_COURTESY, &clp->cl_flags)) >> set_bit(NFSD4_CLIENT_EXPIRED, &clp->cl_flags); > > we also need to set rc to true here. > >> if (test_bit(NFSD4_CLIENT_EXPIRED, &clp->cl_flags)) >> rc = true; > > With v16 we need to check for NFSD4_CLIENT_EXPIRED first then > NFSD4_CLIENT_COURTESY because both flags can be set. In the > next patch version, we will clear NFSD4_CLIENT_COURTESY when > setting NFSD4_CLIENT_EXPIRED so the order of check does not > matter. > >> >> Same result, but more compact and straightforward, I think. > > Chuck wants to replace the bits used for courtesy client in > cl_flags with a separate u8 field so it does not have to use > bit operation to set/test. Code audit suggested there are really only four unique combinations of the bit flags that are used. Plus, taking a spin_lock and using bitops seems like overkill. The rules for transitioning between the courtesy states are straightforward, but need to be done in a critical section. So I suggested storing the courtesy state in a lock-protected unsigned int instead of using bit flags. If we hate it, we can go back to bit flags. >>> + spin_unlock(&clp->cl_cs_lock); >>> + return rc; >>> +} >>> + >>> static const struct lock_manager_operations nfsd_posix_mng_ops = { >>> .lm_notify = nfsd4_lm_notify, >>> .lm_get_owner = nfsd4_lm_get_owner, >>> .lm_put_owner = nfsd4_lm_put_owner, >>> + .lm_lock_expired = nfsd4_lm_lock_expired, >>> }; >>> static inline void >>> -- >>> 2.9.5 -- Chuck Lever