From: NeilBrown Date: Sat, 22 Nov 2025 01:00:37 +0000 (+1100) Subject: locks: ensure vfs_test_lock() never returns FILE_LOCK_DEFERRED X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=96f04d24fc961a600cc9d2c4b740acf273cfcd1e;p=thirdparty%2Fkernel%2Flinux.git locks: ensure vfs_test_lock() never returns FILE_LOCK_DEFERRED 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 Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever --- diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index 6bce19fd024c5..712df1e025d8f 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -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; } diff --git a/fs/locks.c b/fs/locks.c index 7ea949d7ff451..46f229f740c88 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -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);