lockd: Introduce nlm__int__deadlock

The use of CONFIG_LOCKD_V4 in combination with a later cast_status()
in the NLMv3 code is difficult to reason about. Instead, replace the
use of nlm_deadlock with an implementation-defined status value that
version-specific code translates appropriately.

The new approach establishes a translation boundary: generic lockd
code returns nlm__int__deadlock when posix_lock_file() yields
-EDEADLK. Version-specific handlers (svc4proc.c for NLMv4,
svcproc.c for NLMv3) translate this internal status to the
appropriate wire protocol value. NLMv4 maps to nlm4_deadlock;
NLMv3 maps to nlm_lck_denied (since NLMv3 lacks a deadlock-specific
status code).

Later this modification will also remove the need to include NLMv4
headers in NLMv3 and generic code.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
Chuck Lever
2026-01-28 10:19:24 -05:00
parent 153b9e0253
commit 9e0d0c6194
4 changed files with 13 additions and 10 deletions

View File

@@ -148,10 +148,16 @@ __nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_res *resp)
resp->status = nlmsvc_lock(rqstp, file, host, &argp->lock,
argp->block, &argp->cookie,
argp->reclaim);
if (resp->status == nlm__int__drop_reply)
switch (resp->status) {
case nlm__int__drop_reply:
rc = rpc_drop_reply;
else
break;
case nlm__int__deadlock:
resp->status = nlm4_deadlock;
fallthrough;
default:
dprintk("lockd: LOCK status %d\n", ntohl(resp->status));
}
nlmsvc_release_lockowner(&argp->lock);
nlmsvc_release_host(host);

View File

@@ -33,12 +33,6 @@
#define NLMDBG_FACILITY NLMDBG_SVCLOCK
#ifdef CONFIG_LOCKD_V4
#define nlm_deadlock nlm4_deadlock
#else
#define nlm_deadlock nlm_lck_denied
#endif
static void nlmsvc_release_block(struct nlm_block *block);
static void nlmsvc_insert_block(struct nlm_block *block, unsigned long);
static void nlmsvc_remove_block(struct nlm_block *block);
@@ -589,7 +583,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
goto out;
case -EDEADLK:
nlmsvc_remove_block(block);
ret = nlm_deadlock;
ret = nlm__int__deadlock;
goto out;
default: /* includes ENOLCK */
nlmsvc_remove_block(block);

View File

@@ -27,7 +27,7 @@ static inline __be32 cast_status(__be32 status)
case nlm_lck_denied_grace_period:
case nlm__int__drop_reply:
break;
case nlm4_deadlock:
case nlm__int__deadlock:
status = nlm_lck_denied;
break;
default:
@@ -39,6 +39,8 @@ static inline __be32 cast_status(__be32 status)
#else
static inline __be32 cast_status(__be32 status)
{
if (status == nlm__int__deadlock)
status = nlm_lck_denied;
return status;
}
#endif

View File

@@ -43,6 +43,7 @@
* Version handlers translate these to appropriate wire values.
*/
#define nlm__int__drop_reply cpu_to_be32(30000)
#define nlm__int__deadlock cpu_to_be32(30001)
/*
* Lockd host handle (used both by the client and server personality).