Unverified Commit 7e64c5bc authored by Benjamin Coddington's avatar Benjamin Coddington Committed by Christian Brauner
Browse files

NLM/NFSD: Fix lock notifications for async-capable filesystems



Instead of checking just the exportfs flag, use the new
locks_can_async_lock() helper which allows NLM and NFSD to once again
support lock notifications for all filesystems which use posix_lock_file().

Signed-off-by: default avatarBenjamin Coddington <bcodding@redhat.com>
Link: https://lore.kernel.org/r/865c40da44af67939e8eb560d17a26c9c50f23e0.1726083391.git.bcodding@redhat.com


Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent 2253ab99
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@
#include <linux/sunrpc/svc_xprt.h>
#include <linux/lockd/nlm.h>
#include <linux/lockd/lockd.h>
#include <linux/exportfs.h>

#define NLMDBG_FACILITY		NLMDBG_SVCLOCK

@@ -481,7 +480,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
	    struct nlm_host *host, struct nlm_lock *lock, int wait,
	    struct nlm_cookie *cookie, int reclaim)
{
	struct inode		*inode = nlmsvc_file_inode(file);
	struct inode		*inode __maybe_unused = nlmsvc_file_inode(file);
	struct nlm_block	*block = NULL;
	int			error;
	int			mode;
@@ -496,7 +495,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
				(long long)lock->fl.fl_end,
				wait);

	if (!exportfs_lock_op_is_async(inode->i_sb->s_export_op)) {
	if (!locks_can_async_lock(nlmsvc_file_file(file)->f_op)) {
		async_block = wait;
		wait = 0;
	}
@@ -550,7 +549,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
	 * requests on the underlaying ->lock() implementation but
	 * only one nlm_block to being granted by lm_grant().
	 */
	if (exportfs_lock_op_is_async(inode->i_sb->s_export_op) &&
	if (locks_can_async_lock(nlmsvc_file_file(file)->f_op) &&
	    !list_empty(&block->b_list)) {
		spin_unlock(&nlm_blocked_lock);
		ret = nlm_lck_blocked;
+4 −15
Original line number Diff line number Diff line
@@ -7953,9 +7953,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	fp = lock_stp->st_stid.sc_file;
	switch (lock->lk_type) {
		case NFS4_READW_LT:
			if (nfsd4_has_session(cstate) ||
			    exportfs_lock_op_is_async(sb->s_export_op))
				flags |= FL_SLEEP;
			fallthrough;
		case NFS4_READ_LT:
			spin_lock(&fp->fi_lock);
@@ -7966,9 +7963,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
			type = F_RDLCK;
			break;
		case NFS4_WRITEW_LT:
			if (nfsd4_has_session(cstate) ||
			    exportfs_lock_op_is_async(sb->s_export_op))
				flags |= FL_SLEEP;
			fallthrough;
		case NFS4_WRITE_LT:
			spin_lock(&fp->fi_lock);
@@ -7988,15 +7982,10 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		goto out;
	}

	/*
	 * Most filesystems with their own ->lock operations will block
	 * the nfsd thread waiting to acquire the lock.  That leads to
	 * deadlocks (we don't want every nfsd thread tied up waiting
	 * for file locks), so don't attempt blocking lock notifications
	 * on those filesystems:
	 */
	if (!exportfs_lock_op_is_async(sb->s_export_op))
		flags &= ~FL_SLEEP;
	if (lock->lk_type & (NFS4_READW_LT | NFS4_WRITEW_LT) &&
		nfsd4_has_session(cstate) &&
		locks_can_async_lock(nf->nf_file->f_op))
			flags |= FL_SLEEP;

	nbl = find_or_allocate_block(lock_sop, &fp->fi_fhandle, nn);
	if (!nbl) {