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, resp->status = nlmsvc_lock(rqstp, file, host, &argp->lock,
argp->block, &argp->cookie, argp->block, &argp->cookie,
argp->reclaim); argp->reclaim);
if (resp->status == nlm__int__drop_reply) switch (resp->status) {
case nlm__int__drop_reply:
rc = rpc_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)); dprintk("lockd: LOCK status %d\n", ntohl(resp->status));
}
nlmsvc_release_lockowner(&argp->lock); nlmsvc_release_lockowner(&argp->lock);
nlmsvc_release_host(host); nlmsvc_release_host(host);

View File

@ -33,12 +33,6 @@
#define NLMDBG_FACILITY NLMDBG_SVCLOCK #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_release_block(struct nlm_block *block);
static void nlmsvc_insert_block(struct nlm_block *block, unsigned long); static void nlmsvc_insert_block(struct nlm_block *block, unsigned long);
static void nlmsvc_remove_block(struct nlm_block *block); 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; goto out;
case -EDEADLK: case -EDEADLK:
nlmsvc_remove_block(block); nlmsvc_remove_block(block);
ret = nlm_deadlock; ret = nlm__int__deadlock;
goto out; goto out;
default: /* includes ENOLCK */ default: /* includes ENOLCK */
nlmsvc_remove_block(block); 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_lck_denied_grace_period:
case nlm__int__drop_reply: case nlm__int__drop_reply:
break; break;
case nlm4_deadlock: case nlm__int__deadlock:
status = nlm_lck_denied; status = nlm_lck_denied;
break; break;
default: default:
@ -39,6 +39,8 @@ static inline __be32 cast_status(__be32 status)
#else #else
static inline __be32 cast_status(__be32 status) static inline __be32 cast_status(__be32 status)
{ {
if (status == nlm__int__deadlock)
status = nlm_lck_denied;
return status; return status;
} }
#endif #endif

View File

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