]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
locks: ensure vfs_test_lock() never returns FILE_LOCK_DEFERRED
authorNeilBrown <neil@brown.name>
Sat, 22 Nov 2025 01:00:37 +0000 (12:00 +1100)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 26 Jan 2026 15:10:58 +0000 (10:10 -0500)
FILE_LOCK_DEFERRED can be returned when creating or removing a lock, but
not when testing for a lock.  This support was explicitly removed in
Commit 09802fd2a8ca ("lockd: rip out deferred lock handling from testlock codepath")

However the test in nlmsvc_testlock() suggests that it *can* be returned,
only nlm cannot handle it.

To aid clarity, remove the test and instead put a similar test and
warning in vfs_test_lock().  If the impossible happens, convert
FILE_LOCK_DEFERRED to -EIO.

Signed-off-by: NeilBrown <neil@brown.name>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/lockd/svclock.c
fs/locks.c

index 6bce19fd024c5013ec1cbe03fd23b523dcc28e43..712df1e025d8f1540ff342c7e1eb993425092e59 100644 (file)
@@ -641,10 +641,6 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
        conflock->fl.c.flc_owner = lock->fl.c.flc_owner;
        error = vfs_test_lock(file->f_file[mode], &conflock->fl);
        if (error) {
-               /* We can't currently deal with deferred test requests */
-               if (error == FILE_LOCK_DEFERRED)
-                       WARN_ON_ONCE(1);
-
                ret = nlm_lck_denied_nolocks;
                goto out;
        }
index 7ea949d7ff451546c948855a63210abb38a04133..46f229f740c88b2d580c65613c250297269f0d55 100644 (file)
@@ -2253,12 +2253,23 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
  */
 int vfs_test_lock(struct file *filp, struct file_lock *fl)
 {
+       int error = 0;
+
        WARN_ON_ONCE(fl->fl_ops || fl->fl_lmops);
        WARN_ON_ONCE(filp != fl->c.flc_file);
        if (filp->f_op->lock)
-               return filp->f_op->lock(filp, F_GETLK, fl);
-       posix_test_lock(filp, fl);
-       return 0;
+               error = filp->f_op->lock(filp, F_GETLK, fl);
+       else
+               posix_test_lock(filp, fl);
+
+       /*
+        * We don't expect FILE_LOCK_DEFERRED and callers cannot
+        * handle it.
+        */
+       if (WARN_ON_ONCE(error == FILE_LOCK_DEFERRED))
+               error = -EIO;
+
+       return error;
 }
 EXPORT_SYMBOL_GPL(vfs_test_lock);