@@ -4727,6 +4727,24 @@ static bool nfsd_breaker_owns_lease(struct file_lock *fl)
struct svc_rqst *rqst;
struct nfs4_client *clp;
+ clp = dl->dl_stid.sc_client;
+ /*
+ * need to sync with courtesy client trying to reconnect using
+ * the cl_cs_lock, nn->client_lock can not be used since this
+ * function is called with the fl_lck held.
+ */
+ spin_lock(&clp->cl_cs_lock);
+ if (test_bit(NFSD4_CLIENT_EXPIRED, &clp->cl_flags)) {
+ spin_unlock(&clp->cl_cs_lock);
+ return true;
+ }
+ if (test_bit(NFSD4_CLIENT_COURTESY, &clp->cl_flags)) {
+ set_bit(NFSD4_CLIENT_EXPIRED, &clp->cl_flags);
+ spin_unlock(&clp->cl_cs_lock);
+ return true;
+ }
+ spin_unlock(&clp->cl_cs_lock);
+
if (!i_am_nfsd())
return false;
rqst = kthread_data(current);
Update nfsd_breaker_owns_lease() to handle delegation conflict with courtesy clients. If conflict was caused courtesy client then discard the courtesy client by setting CLIENT_EXPIRED and return conflict resolved. Client with CLIENT_EXPIRED is expired by the laundromat. Signed-off-by: Dai Ngo <dai.ngo@oracle.com> --- fs/nfsd/nfs4state.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)