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; + } + } + 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