nfsd and lockd use F_SETLK cmd with the FL_SLEEP flag set to request asynchronous processing of blocking locks. Currently nfs4 use locks_lock_inode_wait() function which is blocked for such requests. To handle them correctly FL_SLEEP flag should be temporarily reset before executing the locks_lock_inode_wait() function. Additionally block flag is forced to set, to translate blocking lock to remote nfs server, expecting it supports async processing of the blocking locks too. https://bugzilla.kernel.org/show_bug.cgi?id=215383 Signed-off-by: Vasily Averin <vvs@xxxxxxxxxxxxx> --- fs/nfs/nfs4proc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index ee3bc79f6ca3..9b1380c4223c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -7094,7 +7094,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f recovery_type == NFS_LOCK_NEW ? GFP_KERNEL : GFP_NOFS); if (data == NULL) return -ENOMEM; - if (IS_SETLKW(cmd)) + if (IS_SETLKW(cmd) || (fl->fl_flags & FL_SLEEP)) data->arg.block = 1; nfs4_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1, recovery_type > NFS_LOCK_NEW); @@ -7200,6 +7200,9 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock int status; request->fl_flags |= FL_ACCESS; + if (((fl_flags & FL_SLEEP_POSIX) == FL_SLEEP_POSIX) && IS_SETLK(cmd)) + request->fl_flags &= ~FL_SLEEP; + status = locks_lock_inode_wait(state->inode, request); if (status < 0) goto out; -- 2.25.1