summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2026-01-28 18:19:24 +0300
committerChuck Lever <chuck.lever@oracle.com>2026-03-30 04:25:09 +0300
commit9e0d0c61940796893e0c2200cdc7be0684218238 (patch)
tree6e200736bdc212d76c875f37abff0c15dfd3d69b
parent153b9e025308417d167332c93e1bcc11174178de (diff)
downloadlinux-9e0d0c61940796893e0c2200cdc7be0684218238.tar.xz
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>
-rw-r--r--fs/lockd/svc4proc.c10
-rw-r--r--fs/lockd/svclock.c8
-rw-r--r--fs/lockd/svcproc.c4
-rw-r--r--include/linux/lockd/lockd.h1
4 files changed, 13 insertions, 10 deletions
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index 9c756d07223a..55b6dcc56db1 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -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);
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index d86b02153c7c..5edf00751a1e 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -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);
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 2a2e48a9bd12..27ed71935e45 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -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
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index fdefec39553f..793691912137 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -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).