On 3/15/22 10:20 AM, J. Bruce Fields wrote:
On Tue, Mar 15, 2022 at 09:26:46AM -0700, 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.
No, the next line does it because we set the EXPIRED bit.
ok, as mentioned below this code will be changed to use an u8
for the courtesy client state and only either CLIENT_EXPIRED or
CLIENT_COURTESY is set but not both so it might be slightly
different in v17.
-Dai
--b.
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.
-Dai
--b.
+ 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