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 09802fd2a8 ("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>
This commit is contained in:
NeilBrown 2025-11-22 12:00:37 +11:00 committed by Chuck Lever
parent 4329010ad9
commit 96f04d24fc
2 changed files with 14 additions and 7 deletions

View 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;
}

View 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);