1 // SPDX-License-Identifier: GPL-2.0
3 * linux/fs/lockd/xdr4.c
5 * XDR support for lockd and the lock client.
7 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
8 * Copyright (C) 1999, Trond Myklebust <trond.myklebust@fys.uio.no>
11 #include <linux/types.h>
12 #include <linux/sched.h>
13 #include <linux/nfs.h>
15 #include <linux/sunrpc/xdr.h>
16 #include <linux/sunrpc/clnt.h>
17 #include <linux/sunrpc/svc.h>
18 #include <linux/sunrpc/stats.h>
19 #include <linux/lockd/lockd.h>
21 #define NLMDBG_FACILITY NLMDBG_XDR
24 s64_to_loff_t(__s64 offset
)
26 return (loff_t
)offset
;
31 loff_t_to_s64(loff_t offset
)
34 if (offset
> NLM4_OFFSET_MAX
)
35 res
= NLM4_OFFSET_MAX
;
36 else if (offset
< -NLM4_OFFSET_MAX
)
37 res
= -NLM4_OFFSET_MAX
;
44 * XDR functions for basic NLM types
47 nlm4_decode_cookie(__be32
*p
, struct nlm_cookie
*c
)
56 memset(c
->data
, 0, 4); /* hockeypux brain damage */
58 else if(len
<=NLM_MAXCOOKIELEN
)
61 memcpy(c
->data
, p
, len
);
66 dprintk("lockd: bad cookie size %d (only cookies under "
67 "%d bytes are supported.)\n",
68 len
, NLM_MAXCOOKIELEN
);
75 nlm4_encode_cookie(__be32
*p
, struct nlm_cookie
*c
)
78 memcpy(p
, c
->data
, c
->len
);
79 p
+=XDR_QUADLEN(c
->len
);
84 nlm4_decode_fh(__be32
*p
, struct nfs_fh
*f
)
86 memset(f
->data
, 0, sizeof(f
->data
));
87 f
->size
= ntohl(*p
++);
88 if (f
->size
> NFS_MAXFHSIZE
) {
89 dprintk("lockd: bad fhandle size %d (should be <=%d)\n",
90 f
->size
, NFS_MAXFHSIZE
);
93 memcpy(f
->data
, p
, f
->size
);
94 return p
+ XDR_QUADLEN(f
->size
);
98 * Encode and decode owner handle
101 nlm4_decode_oh(__be32
*p
, struct xdr_netobj
*oh
)
103 return xdr_decode_netobj(p
, oh
);
107 nlm4_decode_lock(__be32
*p
, struct nlm_lock
*lock
)
109 struct file_lock
*fl
= &lock
->fl
;
113 if (!(p
= xdr_decode_string_inplace(p
, &lock
->caller
,
114 &lock
->len
, NLM_MAXSTRLEN
))
115 || !(p
= nlm4_decode_fh(p
, &lock
->fh
))
116 || !(p
= nlm4_decode_oh(p
, &lock
->oh
)))
118 lock
->svid
= ntohl(*p
++);
121 fl
->fl_owner
= current
->files
;
122 fl
->fl_pid
= (pid_t
)lock
->svid
;
123 fl
->fl_flags
= FL_POSIX
;
124 fl
->fl_type
= F_RDLCK
; /* as good as anything else */
125 p
= xdr_decode_hyper(p
, &start
);
126 p
= xdr_decode_hyper(p
, &len
);
127 end
= start
+ len
- 1;
129 fl
->fl_start
= s64_to_loff_t(start
);
131 if (len
== 0 || end
< 0)
132 fl
->fl_end
= OFFSET_MAX
;
134 fl
->fl_end
= s64_to_loff_t(end
);
139 * Encode result of a TEST/TEST_MSG call
142 nlm4_encode_testres(__be32
*p
, struct nlm_res
*resp
)
146 dprintk("xdr: before encode_testres (p %p resp %p)\n", p
, resp
);
147 if (!(p
= nlm4_encode_cookie(p
, &resp
->cookie
)))
151 if (resp
->status
== nlm_lck_denied
) {
152 struct file_lock
*fl
= &resp
->lock
.fl
;
154 *p
++ = (fl
->fl_type
== F_RDLCK
)? xdr_zero
: xdr_one
;
155 *p
++ = htonl(resp
->lock
.svid
);
157 /* Encode owner handle. */
158 if (!(p
= xdr_encode_netobj(p
, &resp
->lock
.oh
)))
161 start
= loff_t_to_s64(fl
->fl_start
);
162 if (fl
->fl_end
== OFFSET_MAX
)
165 len
= loff_t_to_s64(fl
->fl_end
- fl
->fl_start
+ 1);
167 p
= xdr_encode_hyper(p
, start
);
168 p
= xdr_encode_hyper(p
, len
);
169 dprintk("xdr: encode_testres (status %u pid %d type %d start %Ld end %Ld)\n",
170 resp
->status
, (int)resp
->lock
.svid
, fl
->fl_type
,
171 (long long)fl
->fl_start
, (long long)fl
->fl_end
);
174 dprintk("xdr: after encode_testres (p %p resp %p)\n", p
, resp
);
180 * First, the server side XDR functions
183 nlm4svc_decode_testargs(struct svc_rqst
*rqstp
, __be32
*p
)
185 struct nlm_args
*argp
= rqstp
->rq_argp
;
188 if (!(p
= nlm4_decode_cookie(p
, &argp
->cookie
)))
191 exclusive
= ntohl(*p
++);
192 if (!(p
= nlm4_decode_lock(p
, &argp
->lock
)))
195 argp
->lock
.fl
.fl_type
= F_WRLCK
;
197 return xdr_argsize_check(rqstp
, p
);
201 nlm4svc_encode_testres(struct svc_rqst
*rqstp
, __be32
*p
)
203 struct nlm_res
*resp
= rqstp
->rq_resp
;
205 if (!(p
= nlm4_encode_testres(p
, resp
)))
207 return xdr_ressize_check(rqstp
, p
);
211 nlm4svc_decode_lockargs(struct svc_rqst
*rqstp
, __be32
*p
)
213 struct nlm_args
*argp
= rqstp
->rq_argp
;
216 if (!(p
= nlm4_decode_cookie(p
, &argp
->cookie
)))
218 argp
->block
= ntohl(*p
++);
219 exclusive
= ntohl(*p
++);
220 if (!(p
= nlm4_decode_lock(p
, &argp
->lock
)))
223 argp
->lock
.fl
.fl_type
= F_WRLCK
;
224 argp
->reclaim
= ntohl(*p
++);
225 argp
->state
= ntohl(*p
++);
226 argp
->monitor
= 1; /* monitor client by default */
228 return xdr_argsize_check(rqstp
, p
);
232 nlm4svc_decode_cancargs(struct svc_rqst
*rqstp
, __be32
*p
)
234 struct nlm_args
*argp
= rqstp
->rq_argp
;
237 if (!(p
= nlm4_decode_cookie(p
, &argp
->cookie
)))
239 argp
->block
= ntohl(*p
++);
240 exclusive
= ntohl(*p
++);
241 if (!(p
= nlm4_decode_lock(p
, &argp
->lock
)))
244 argp
->lock
.fl
.fl_type
= F_WRLCK
;
245 return xdr_argsize_check(rqstp
, p
);
249 nlm4svc_decode_unlockargs(struct svc_rqst
*rqstp
, __be32
*p
)
251 struct nlm_args
*argp
= rqstp
->rq_argp
;
253 if (!(p
= nlm4_decode_cookie(p
, &argp
->cookie
))
254 || !(p
= nlm4_decode_lock(p
, &argp
->lock
)))
256 argp
->lock
.fl
.fl_type
= F_UNLCK
;
257 return xdr_argsize_check(rqstp
, p
);
261 nlm4svc_decode_shareargs(struct svc_rqst
*rqstp
, __be32
*p
)
263 struct nlm_args
*argp
= rqstp
->rq_argp
;
264 struct nlm_lock
*lock
= &argp
->lock
;
266 memset(lock
, 0, sizeof(*lock
));
267 locks_init_lock(&lock
->fl
);
268 lock
->svid
= ~(u32
) 0;
269 lock
->fl
.fl_pid
= (pid_t
)lock
->svid
;
271 if (!(p
= nlm4_decode_cookie(p
, &argp
->cookie
))
272 || !(p
= xdr_decode_string_inplace(p
, &lock
->caller
,
273 &lock
->len
, NLM_MAXSTRLEN
))
274 || !(p
= nlm4_decode_fh(p
, &lock
->fh
))
275 || !(p
= nlm4_decode_oh(p
, &lock
->oh
)))
277 argp
->fsm_mode
= ntohl(*p
++);
278 argp
->fsm_access
= ntohl(*p
++);
279 return xdr_argsize_check(rqstp
, p
);
283 nlm4svc_encode_shareres(struct svc_rqst
*rqstp
, __be32
*p
)
285 struct nlm_res
*resp
= rqstp
->rq_resp
;
287 if (!(p
= nlm4_encode_cookie(p
, &resp
->cookie
)))
290 *p
++ = xdr_zero
; /* sequence argument */
291 return xdr_ressize_check(rqstp
, p
);
295 nlm4svc_encode_res(struct svc_rqst
*rqstp
, __be32
*p
)
297 struct nlm_res
*resp
= rqstp
->rq_resp
;
299 if (!(p
= nlm4_encode_cookie(p
, &resp
->cookie
)))
302 return xdr_ressize_check(rqstp
, p
);
306 nlm4svc_decode_notify(struct svc_rqst
*rqstp
, __be32
*p
)
308 struct nlm_args
*argp
= rqstp
->rq_argp
;
309 struct nlm_lock
*lock
= &argp
->lock
;
311 if (!(p
= xdr_decode_string_inplace(p
, &lock
->caller
,
312 &lock
->len
, NLM_MAXSTRLEN
)))
314 argp
->state
= ntohl(*p
++);
315 return xdr_argsize_check(rqstp
, p
);
319 nlm4svc_decode_reboot(struct svc_rqst
*rqstp
, __be32
*p
)
321 struct nlm_reboot
*argp
= rqstp
->rq_argp
;
323 if (!(p
= xdr_decode_string_inplace(p
, &argp
->mon
, &argp
->len
, SM_MAXSTRLEN
)))
325 argp
->state
= ntohl(*p
++);
326 memcpy(&argp
->priv
.data
, p
, sizeof(argp
->priv
.data
));
327 p
+= XDR_QUADLEN(SM_PRIV_SIZE
);
328 return xdr_argsize_check(rqstp
, p
);
332 nlm4svc_decode_res(struct svc_rqst
*rqstp
, __be32
*p
)
334 struct nlm_res
*resp
= rqstp
->rq_argp
;
336 if (!(p
= nlm4_decode_cookie(p
, &resp
->cookie
)))
339 return xdr_argsize_check(rqstp
, p
);
343 nlm4svc_decode_void(struct svc_rqst
*rqstp
, __be32
*p
)
345 return xdr_argsize_check(rqstp
, p
);
349 nlm4svc_encode_void(struct svc_rqst
*rqstp
, __be32
*p
)
351 return xdr_ressize_check(rqstp
, p
);