All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/6] RELEASE_LOCKOWNER discussion, cont...
@ 2022-05-24 18:56 Chuck Lever
  2022-05-24 18:56 ` [PATCH v2 1/6] fs/locks.c: Count held file locks Chuck Lever
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Chuck Lever @ 2022-05-24 18:56 UTC (permalink / raw)
  To: linux-nfs

Check-point for discussion.

For completeness, here is the whole series of patches (including
experimental and temporary patches) that I'm considering for
addressing the RELEASE_LOCKOWNER "sleep while spin locked" splat.
It's not finished by any means.

Getting the new boolean arguments right is not straightforward. This
series does not work properly, for example, when LOCK returns
NFS4ERR_DENIED -- it leaves the lo_lockcnt bumped. I still fear this
approach would be brittle in the long run; I'm leaning towards the
so_count-based approach instead, as that is simple and nicely
contained within NFSD itself.

Thanks for taking a look.

---

Chuck Lever (6):
      fs/locks.c: Count held file locks
      NFSD: Fix possible sleep during nfsd4_release_lockowner()
      blargh
      NFSD: Modernize nfsd4_release_lockowner()
      NFSD: Add documenting comment for nfsd4_release_lockowner()
      NFSD: nfsd_file_put() can sleep


 fs/lockd/svclock.c  |  4 +--
 fs/locks.c          | 20 +++++++-----
 fs/nfsd/filecache.c |  2 ++
 fs/nfsd/nfs4state.c | 80 +++++++++++++++++++++++++--------------------
 fs/nfsd/state.h     |  1 +
 include/linux/fs.h  | 12 ++-----
 6 files changed, 65 insertions(+), 54 deletions(-)

--
Chuck Lever


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/6] fs/locks.c: Count held file locks
  2022-05-24 18:56 [PATCH v2 0/6] RELEASE_LOCKOWNER discussion, cont Chuck Lever
@ 2022-05-24 18:56 ` Chuck Lever
  2022-05-24 18:57 ` [PATCH v2 2/6] NFSD: Fix possible sleep during nfsd4_release_lockowner() Chuck Lever
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Chuck Lever @ 2022-05-24 18:56 UTC (permalink / raw)
  To: linux-nfs

To properly handle an NFSv4.0 RELEASE_LOCKOWNER operation, NFSD needs
to know whether there are locks associated with a lockowner. The
current mechanism for making this assessment is heavyweight, to say
the least.

Instead, NFSD could count the number of locks based on the number of
calls to ->lm_get_owner() and ->lm_put_owner(). The number of
->lm_get_owner() and ->lm_put_owner() calls should always be 100%
balanced once all the locks belonging to a specific lock owner are
removed.

However, NFSD would have to sort out two cases:

+ When fs/locks adds or removes a lock record, and
+ When fs/locks copies a conflicting lock

The latter case should never adjust the "locks held" count. Add a
boolean argument to both APIs so that NFSD knows exactly when to
bump and decrement the lockowner's new "locks held" counter.

Suggested-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/lockd/svclock.c  |    4 ++--
 fs/locks.c          |   15 ++++++++-------
 fs/nfsd/nfs4state.c |   12 +++++++++---
 fs/nfsd/state.h     |    1 +
 include/linux/fs.h  |   12 +++---------
 5 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index cb3658ab9b7a..020eef930bf1 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -790,12 +790,12 @@ nlmsvc_notify_blocked(struct file_lock *fl)
 	printk(KERN_WARNING "lockd: notification for unknown block!\n");
 }
 
-static fl_owner_t nlmsvc_get_owner(fl_owner_t owner)
+static fl_owner_t nlmsvc_get_owner(fl_owner_t owner, bool lock)
 {
 	return nlmsvc_get_lockowner(owner);
 }
 
-static void nlmsvc_put_owner(fl_owner_t owner)
+static void nlmsvc_put_owner(fl_owner_t owner, bool unlock)
 {
 	nlmsvc_put_lockowner(owner);
 }
diff --git a/fs/locks.c b/fs/locks.c
index ca28e0e50e56..bfeb6c3de03f 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -292,7 +292,8 @@ void locks_release_private(struct file_lock *fl)
 
 	if (fl->fl_lmops) {
 		if (fl->fl_lmops->lm_put_owner) {
-			fl->fl_lmops->lm_put_owner(fl->fl_owner);
+			fl->fl_lmops->lm_put_owner(fl->fl_owner,
+						   fl->fl_type == F_UNLCK);
 			fl->fl_owner = NULL;
 		}
 		fl->fl_lmops = NULL;
@@ -358,7 +359,8 @@ EXPORT_SYMBOL(locks_init_lock);
 /*
  * Initialize a new lock from an existing file_lock structure.
  */
-void locks_copy_conflock(struct file_lock *new, struct file_lock *fl)
+static void locks_copy_conflock(struct file_lock *new, struct file_lock *fl,
+				bool lock)
 {
 	new->fl_owner = fl->fl_owner;
 	new->fl_pid = fl->fl_pid;
@@ -372,17 +374,16 @@ void locks_copy_conflock(struct file_lock *new, struct file_lock *fl)
 
 	if (fl->fl_lmops) {
 		if (fl->fl_lmops->lm_get_owner)
-			fl->fl_lmops->lm_get_owner(fl->fl_owner);
+			fl->fl_lmops->lm_get_owner(fl->fl_owner, lock);
 	}
 }
-EXPORT_SYMBOL(locks_copy_conflock);
 
 void locks_copy_lock(struct file_lock *new, struct file_lock *fl)
 {
 	/* "new" must be a freshly-initialized lock */
 	WARN_ON_ONCE(new->fl_ops);
 
-	locks_copy_conflock(new, fl);
+	locks_copy_conflock(new, fl, true);
 
 	new->fl_file = fl->fl_file;
 	new->fl_ops = fl->fl_ops;
@@ -926,7 +927,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
 			module_put(owner);
 			goto retry;
 		}
-		locks_copy_conflock(fl, cfl);
+		locks_copy_conflock(fl, cfl, false);
 		goto out;
 	}
 	fl->fl_type = F_UNLCK;
@@ -1145,7 +1146,7 @@ static int posix_lock_inode(struct inode *inode, struct file_lock *request,
 				goto retry;
 			}
 			if (conflock)
-				locks_copy_conflock(conflock, fl);
+				locks_copy_conflock(conflock, fl, true);
 			error = -EAGAIN;
 			if (!(request->fl_flags & FL_SLEEP))
 				goto out;
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index a280256cbb03..d2d9748eaca6 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -6735,21 +6735,26 @@ nfs4_transform_lock_offset(struct file_lock *lock)
 }
 
 static fl_owner_t
-nfsd4_lm_get_owner(fl_owner_t owner)
+nfsd4_lm_get_owner(fl_owner_t owner, bool lock)
 {
 	struct nfs4_lockowner *lo = (struct nfs4_lockowner *)owner;
 
 	nfs4_get_stateowner(&lo->lo_owner);
+	if (lock)
+		atomic_inc(&lo->lo_lockcnt);
 	return owner;
 }
 
 static void
-nfsd4_lm_put_owner(fl_owner_t owner)
+nfsd4_lm_put_owner(fl_owner_t owner, bool unlock)
 {
 	struct nfs4_lockowner *lo = (struct nfs4_lockowner *)owner;
 
-	if (lo)
+	if (lo) {
+		if (unlock)
+			atomic_dec(&lo->lo_lockcnt);
 		nfs4_put_stateowner(&lo->lo_owner);
+	}
 }
 
 /* return pointer to struct nfs4_client if client is expirable */
@@ -6903,6 +6908,7 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp,
 		return NULL;
 	INIT_LIST_HEAD(&lo->lo_blocked);
 	INIT_LIST_HEAD(&lo->lo_owner.so_stateids);
+	atomic_set(&lo->lo_lockcnt, 0);
 	lo->lo_owner.so_is_open_owner = 0;
 	lo->lo_owner.so_seqid = lock->lk_new_lock_seqid;
 	lo->lo_owner.so_ops = &lockowner_ops;
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index f3d6313914ed..762dff43cf70 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -505,6 +505,7 @@ struct nfs4_openowner {
 struct nfs4_lockowner {
 	struct nfs4_stateowner	lo_owner;	/* must be first element */
 	struct list_head	lo_blocked;	/* blocked file_locks */
+	atomic_t		lo_lockcnt;	/* count of locks held */
 };
 
 static inline struct nfs4_openowner * openowner(struct nfs4_stateowner *so)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b848355b5e6c..841cd62d3eb1 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1030,8 +1030,8 @@ struct file_lock_operations {
 
 struct lock_manager_operations {
 	void *lm_mod_owner;
-	fl_owner_t (*lm_get_owner)(fl_owner_t);
-	void (*lm_put_owner)(fl_owner_t);
+	fl_owner_t (*lm_get_owner)(fl_owner_t owner, bool lock);
+	void (*lm_put_owner)(fl_owner_t owner, bool unlock);
 	void (*lm_notify)(struct file_lock *);	/* unblock callback */
 	int (*lm_grant)(struct file_lock *, int);
 	bool (*lm_break)(struct file_lock *);
@@ -1153,10 +1153,9 @@ void locks_free_lock(struct file_lock *fl);
 extern void locks_init_lock(struct file_lock *);
 extern struct file_lock * locks_alloc_lock(void);
 extern void locks_copy_lock(struct file_lock *, struct file_lock *);
-extern void locks_copy_conflock(struct file_lock *, struct file_lock *);
 extern void locks_remove_posix(struct file *, fl_owner_t);
 extern void locks_remove_file(struct file *);
-extern void locks_release_private(struct file_lock *);
+extern void locks_release_private(struct file_lock *fl);
 extern void posix_test_lock(struct file *, struct file_lock *);
 extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock *);
 extern int locks_delete_block(struct file_lock *);
@@ -1225,11 +1224,6 @@ static inline void locks_init_lock(struct file_lock *fl)
 	return;
 }
 
-static inline void locks_copy_conflock(struct file_lock *new, struct file_lock *fl)
-{
-	return;
-}
-
 static inline void locks_copy_lock(struct file_lock *new, struct file_lock *fl)
 {
 	return;



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/6] NFSD: Fix possible sleep during nfsd4_release_lockowner()
  2022-05-24 18:56 [PATCH v2 0/6] RELEASE_LOCKOWNER discussion, cont Chuck Lever
  2022-05-24 18:56 ` [PATCH v2 1/6] fs/locks.c: Count held file locks Chuck Lever
@ 2022-05-24 18:57 ` Chuck Lever
  2022-05-24 18:57 ` [PATCH v2 3/6] blargh Chuck Lever
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Chuck Lever @ 2022-05-24 18:57 UTC (permalink / raw)
  To: linux-nfs

nfsd4_release_lockowner() holds clp->cl_lock when it calls
check_for_locks(). However, check_for_locks() calls nfsd_file_get()
/ nfsd_file_put() to access the backing inode's flc_posix list, and
nfsd_file_put() can sleep if the inode was recently removed.

Instead, use the recently introduced counter field in struct
nfs4_lockowner that keeps track of how many locks are associated
with that lock owner.

Reported-by: Dai Ngo <dai.ngo@oracle.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: stable@vger.kernel.org
---
 fs/nfsd/nfs4state.c |   11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index d2d9748eaca6..7cedb0da888d 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -7563,16 +7563,11 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
 		if (sop->so_is_open_owner || !same_owner_str(sop, owner))
 			continue;
 
-		/* see if there are still any locks associated with it */
 		lo = lockowner(sop);
-		list_for_each_entry(stp, &sop->so_stateids, st_perstateowner) {
-			if (check_for_locks(stp->st_stid.sc_file, lo)) {
-				status = nfserr_locks_held;
-				spin_unlock(&clp->cl_lock);
-				return status;
-			}
+		if (atomic_read(&lo->lo_lockcnt) != 0) {
+			spin_unlock(&clp->cl_lock);
+			return nfserr_locks_held;
 		}
-
 		nfs4_get_stateowner(sop);
 		break;
 	}



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 3/6] blargh
  2022-05-24 18:56 [PATCH v2 0/6] RELEASE_LOCKOWNER discussion, cont Chuck Lever
  2022-05-24 18:56 ` [PATCH v2 1/6] fs/locks.c: Count held file locks Chuck Lever
  2022-05-24 18:57 ` [PATCH v2 2/6] NFSD: Fix possible sleep during nfsd4_release_lockowner() Chuck Lever
@ 2022-05-24 18:57 ` Chuck Lever
  2022-05-24 18:57 ` [PATCH v2 4/6] NFSD: Modernize nfsd4_release_lockowner() Chuck Lever
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Chuck Lever @ 2022-05-24 18:57 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/locks.c          |    5 ++++-
 fs/nfsd/nfs4state.c |   10 ++++++++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/fs/locks.c b/fs/locks.c
index bfeb6c3de03f..80cc410f72b2 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -292,6 +292,7 @@ void locks_release_private(struct file_lock *fl)
 
 	if (fl->fl_lmops) {
 		if (fl->fl_lmops->lm_put_owner) {
+			trace_printk("lo=%p type=%d\n", fl->fl_owner, fl->fl_type);
 			fl->fl_lmops->lm_put_owner(fl->fl_owner,
 						   fl->fl_type == F_UNLCK);
 			fl->fl_owner = NULL;
@@ -373,8 +374,10 @@ static void locks_copy_conflock(struct file_lock *new, struct file_lock *fl,
 	new->fl_ops = NULL;
 
 	if (fl->fl_lmops) {
-		if (fl->fl_lmops->lm_get_owner)
+		if (fl->fl_lmops->lm_get_owner) {
+			trace_printk("lo=%p type=%d\n", fl->fl_owner, fl->fl_type);
 			fl->fl_lmops->lm_get_owner(fl->fl_owner, lock);
+		}
 	}
 }
 
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 7cedb0da888d..dd8749e96c9f 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -6742,6 +6742,10 @@ nfsd4_lm_get_owner(fl_owner_t owner, bool lock)
 	nfs4_get_stateowner(&lo->lo_owner);
 	if (lock)
 		atomic_inc(&lo->lo_lockcnt);
+	trace_printk("lo=%p lock=%s lockcnt=%d so_count=%d\n",
+		lo, lock ? "true" : "false",
+		atomic_read(&lo->lo_lockcnt),
+		atomic_read(&lo->lo_owner.so_count));
 	return owner;
 }
 
@@ -6751,6 +6755,10 @@ nfsd4_lm_put_owner(fl_owner_t owner, bool unlock)
 	struct nfs4_lockowner *lo = (struct nfs4_lockowner *)owner;
 
 	if (lo) {
+		trace_printk("lo=%p unlock=%s lockcnt=%d so_count=%d\n",
+			lo, unlock ? "true" : "false",
+			atomic_read(&lo->lo_lockcnt),
+			atomic_read(&lo->lo_owner.so_count));
 		if (unlock)
 			atomic_dec(&lo->lo_lockcnt);
 		nfs4_put_stateowner(&lo->lo_owner);
@@ -7564,6 +7572,8 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
 			continue;
 
 		lo = lockowner(sop);
+		trace_printk("lo=%p lockcnt=%d so_count=%d\n",
+			lo, atomic_read(&lo->lo_lockcnt), atomic_read(&sop->so_count));
 		if (atomic_read(&lo->lo_lockcnt) != 0) {
 			spin_unlock(&clp->cl_lock);
 			return nfserr_locks_held;



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 4/6] NFSD: Modernize nfsd4_release_lockowner()
  2022-05-24 18:56 [PATCH v2 0/6] RELEASE_LOCKOWNER discussion, cont Chuck Lever
                   ` (2 preceding siblings ...)
  2022-05-24 18:57 ` [PATCH v2 3/6] blargh Chuck Lever
@ 2022-05-24 18:57 ` Chuck Lever
  2022-05-24 18:57 ` [PATCH v2 5/6] NFSD: Add documenting comment for nfsd4_release_lockowner() Chuck Lever
  2022-05-24 18:57 ` [PATCH v2 6/6] NFSD: nfsd_file_put() can sleep Chuck Lever
  5 siblings, 0 replies; 7+ messages in thread
From: Chuck Lever @ 2022-05-24 18:57 UTC (permalink / raw)
  To: linux-nfs

Refactor: Use existing helper infrastructure that other lock
operations use. This removes several automatic variables, so
re-organize the declarations for readability.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4state.c |   39 +++++++++++++--------------------------
 1 file changed, 13 insertions(+), 26 deletions(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index dd8749e96c9f..b8e17125fdf1 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -7544,16 +7544,13 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
 			union nfsd4_op_u *u)
 {
 	struct nfsd4_release_lockowner *rlockowner = &u->release_lockowner;
+	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
 	clientid_t *clid = &rlockowner->rl_clientid;
-	struct nfs4_stateowner *sop;
-	struct nfs4_lockowner *lo = NULL;
 	struct nfs4_ol_stateid *stp;
-	struct xdr_netobj *owner = &rlockowner->rl_owner;
-	unsigned int hashval = ownerstr_hashval(owner);
-	__be32 status;
-	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
+	struct nfs4_lockowner *lo;
 	struct nfs4_client *clp;
-	LIST_HEAD (reaplist);
+	LIST_HEAD(reaplist);
+	__be32 status;
 
 	dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
 		clid->cl_boot, clid->cl_id);
@@ -7561,31 +7558,21 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
 	status = set_client(clid, cstate, nn);
 	if (status)
 		return status;
-
 	clp = cstate->clp;
-	/* Find the matching lock stateowner */
-	spin_lock(&clp->cl_lock);
-	list_for_each_entry(sop, &clp->cl_ownerstr_hashtbl[hashval],
-			    so_strhash) {
 
-		if (sop->so_is_open_owner || !same_owner_str(sop, owner))
-			continue;
-
-		lo = lockowner(sop);
-		trace_printk("lo=%p lockcnt=%d so_count=%d\n",
-			lo, atomic_read(&lo->lo_lockcnt), atomic_read(&sop->so_count));
-		if (atomic_read(&lo->lo_lockcnt) != 0) {
-			spin_unlock(&clp->cl_lock);
-			return nfserr_locks_held;
-		}
-		nfs4_get_stateowner(sop);
-		break;
-	}
+	spin_lock(&clp->cl_lock);
+	lo = find_lockowner_str_locked(clp, &rlockowner->rl_owner);
 	if (!lo) {
 		spin_unlock(&clp->cl_lock);
 		return status;
 	}
-
+	trace_printk("lo=%p lockcnt=%d so_count=%d\n",
+		lo, atomic_read(&lo->lo_lockcnt), atomic_read(&lo->lo_owner.so_count));
+	if (atomic_read(&lo->lo_lockcnt) != 0) {
+		spin_unlock(&clp->cl_lock);
+		nfs4_put_stateowner(&lo->lo_owner);
+		return nfserr_locks_held;
+	}
 	unhash_lockowner_locked(lo);
 	while (!list_empty(&lo->lo_owner.so_stateids)) {
 		stp = list_first_entry(&lo->lo_owner.so_stateids,



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 5/6] NFSD: Add documenting comment for nfsd4_release_lockowner()
  2022-05-24 18:56 [PATCH v2 0/6] RELEASE_LOCKOWNER discussion, cont Chuck Lever
                   ` (3 preceding siblings ...)
  2022-05-24 18:57 ` [PATCH v2 4/6] NFSD: Modernize nfsd4_release_lockowner() Chuck Lever
@ 2022-05-24 18:57 ` Chuck Lever
  2022-05-24 18:57 ` [PATCH v2 6/6] NFSD: nfsd_file_put() can sleep Chuck Lever
  5 siblings, 0 replies; 7+ messages in thread
From: Chuck Lever @ 2022-05-24 18:57 UTC (permalink / raw)
  To: linux-nfs

And return fixed nfserr values that match what is documented in the
new comment / API contract.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4state.c |   18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index b8e17125fdf1..578a44495d0f 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -7538,6 +7538,18 @@ check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner)
 	return status;
 }
 
+/**
+ * nfsd4_release_lockowner - process NFSv4.0 RELEASE_LOCKOWNER operations
+ * @rqstp: RPC transaction
+ * @cstate: NFSv4 COMPOUND state
+ * @u: RELEASE_LOCKOWNER arguments
+ *
+ * Return values:
+ *   %nfs_ok: lockowner released or not found
+ *   %nfserr_locks_held: lockowner still in use
+ *   %nfserr_stale_clientid: clientid no longer active
+ *   %nfserr_expired: clientid not recognized
+ */
 __be32
 nfsd4_release_lockowner(struct svc_rqst *rqstp,
 			struct nfsd4_compound_state *cstate,
@@ -7564,7 +7576,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
 	lo = find_lockowner_str_locked(clp, &rlockowner->rl_owner);
 	if (!lo) {
 		spin_unlock(&clp->cl_lock);
-		return status;
+		return nfs_ok;
 	}
 	trace_printk("lo=%p lockcnt=%d so_count=%d\n",
 		lo, atomic_read(&lo->lo_lockcnt), atomic_read(&lo->lo_owner.so_count));
@@ -7582,11 +7594,11 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
 		put_ol_stateid_locked(stp, &reaplist);
 	}
 	spin_unlock(&clp->cl_lock);
+
 	free_ol_stateid_reaplist(&reaplist);
 	remove_blocked_locks(lo);
 	nfs4_put_stateowner(&lo->lo_owner);
-
-	return status;
+	return nfs_ok;
 }
 
 static inline struct nfs4_client_reclaim *



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 6/6] NFSD: nfsd_file_put() can sleep
  2022-05-24 18:56 [PATCH v2 0/6] RELEASE_LOCKOWNER discussion, cont Chuck Lever
                   ` (4 preceding siblings ...)
  2022-05-24 18:57 ` [PATCH v2 5/6] NFSD: Add documenting comment for nfsd4_release_lockowner() Chuck Lever
@ 2022-05-24 18:57 ` Chuck Lever
  5 siblings, 0 replies; 7+ messages in thread
From: Chuck Lever @ 2022-05-24 18:57 UTC (permalink / raw)
  To: linux-nfs

Now that there are no more callers of nfsd_file_put() that might
hold a spin lock, ensure the lockdep infrastructure can catch
newly introduced calls to nfsd_file_put() made while a spinlock
is held.

Link: https://lore.kernel.org/linux-nfs/ece7fd1d-5fb3-5155-54ba-347cfc19bd9a@oracle.com/T/#mf1855552570cf9a9c80d1e49d91438cd9085aada
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
---
 fs/nfsd/filecache.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c
index a7e3a443a2cb..d32fcd8ad457 100644
--- a/fs/nfsd/filecache.c
+++ b/fs/nfsd/filecache.c
@@ -302,6 +302,8 @@ nfsd_file_put_noref(struct nfsd_file *nf)
 void
 nfsd_file_put(struct nfsd_file *nf)
 {
+	might_sleep();
+
 	set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags);
 	if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags) == 0) {
 		nfsd_file_flush(nf);



^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-05-24 18:57 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-24 18:56 [PATCH v2 0/6] RELEASE_LOCKOWNER discussion, cont Chuck Lever
2022-05-24 18:56 ` [PATCH v2 1/6] fs/locks.c: Count held file locks Chuck Lever
2022-05-24 18:57 ` [PATCH v2 2/6] NFSD: Fix possible sleep during nfsd4_release_lockowner() Chuck Lever
2022-05-24 18:57 ` [PATCH v2 3/6] blargh Chuck Lever
2022-05-24 18:57 ` [PATCH v2 4/6] NFSD: Modernize nfsd4_release_lockowner() Chuck Lever
2022-05-24 18:57 ` [PATCH v2 5/6] NFSD: Add documenting comment for nfsd4_release_lockowner() Chuck Lever
2022-05-24 18:57 ` [PATCH v2 6/6] NFSD: nfsd_file_put() can sleep Chuck Lever

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.