]>
git.ipfire.org Git - people/ms/linux.git/blob - fs/lockd/xdr4.c
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>
24 loff_t_to_s64(loff_t offset
)
27 if (offset
> NLM4_OFFSET_MAX
)
28 res
= NLM4_OFFSET_MAX
;
29 else if (offset
< -NLM4_OFFSET_MAX
)
30 res
= -NLM4_OFFSET_MAX
;
37 * NLM file handles are defined by specification to be a variable-length
38 * XDR opaque no longer than 1024 bytes. However, this implementation
39 * limits their length to the size of an NFSv3 file handle.
42 svcxdr_decode_fhandle(struct xdr_stream
*xdr
, struct nfs_fh
*fh
)
47 if (xdr_stream_decode_u32(xdr
, &len
) < 0)
49 if (len
> NFS_MAXFHSIZE
)
52 p
= xdr_inline_decode(xdr
, len
);
56 memcpy(fh
->data
, p
, len
);
57 memset(fh
->data
+ len
, 0, sizeof(fh
->data
) - len
);
63 svcxdr_decode_lock(struct xdr_stream
*xdr
, struct nlm_lock
*lock
)
65 struct file_lock
*fl
= &lock
->fl
;
67 if (!svcxdr_decode_string(xdr
, &lock
->caller
, &lock
->len
))
69 if (!svcxdr_decode_fhandle(xdr
, &lock
->fh
))
71 if (!svcxdr_decode_owner(xdr
, &lock
->oh
))
73 if (xdr_stream_decode_u32(xdr
, &lock
->svid
) < 0)
75 if (xdr_stream_decode_u64(xdr
, &lock
->lock_start
) < 0)
77 if (xdr_stream_decode_u64(xdr
, &lock
->lock_len
) < 0)
81 fl
->fl_flags
= FL_POSIX
;
82 fl
->fl_type
= F_RDLCK
;
88 svcxdr_encode_holder(struct xdr_stream
*xdr
, const struct nlm_lock
*lock
)
90 const struct file_lock
*fl
= &lock
->fl
;
94 if (xdr_stream_encode_bool(xdr
, fl
->fl_type
!= F_RDLCK
) < 0)
96 if (xdr_stream_encode_u32(xdr
, lock
->svid
) < 0)
98 if (!svcxdr_encode_owner(xdr
, &lock
->oh
))
100 start
= loff_t_to_s64(fl
->fl_start
);
101 if (fl
->fl_end
== OFFSET_MAX
)
104 len
= loff_t_to_s64(fl
->fl_end
- fl
->fl_start
+ 1);
105 if (xdr_stream_encode_u64(xdr
, start
) < 0)
107 if (xdr_stream_encode_u64(xdr
, len
) < 0)
114 svcxdr_encode_testrply(struct xdr_stream
*xdr
, const struct nlm_res
*resp
)
116 if (!svcxdr_encode_stats(xdr
, resp
->status
))
118 switch (resp
->status
) {
120 if (!svcxdr_encode_holder(xdr
, &resp
->lock
))
129 * Decode Call arguments
133 nlm4svc_decode_void(struct svc_rqst
*rqstp
, struct xdr_stream
*xdr
)
139 nlm4svc_decode_testargs(struct svc_rqst
*rqstp
, struct xdr_stream
*xdr
)
141 struct nlm_args
*argp
= rqstp
->rq_argp
;
144 if (!svcxdr_decode_cookie(xdr
, &argp
->cookie
))
146 if (xdr_stream_decode_bool(xdr
, &exclusive
) < 0)
148 if (!svcxdr_decode_lock(xdr
, &argp
->lock
))
151 argp
->lock
.fl
.fl_type
= F_WRLCK
;
157 nlm4svc_decode_lockargs(struct svc_rqst
*rqstp
, struct xdr_stream
*xdr
)
159 struct nlm_args
*argp
= rqstp
->rq_argp
;
162 if (!svcxdr_decode_cookie(xdr
, &argp
->cookie
))
164 if (xdr_stream_decode_bool(xdr
, &argp
->block
) < 0)
166 if (xdr_stream_decode_bool(xdr
, &exclusive
) < 0)
168 if (!svcxdr_decode_lock(xdr
, &argp
->lock
))
171 argp
->lock
.fl
.fl_type
= F_WRLCK
;
172 if (xdr_stream_decode_bool(xdr
, &argp
->reclaim
) < 0)
174 if (xdr_stream_decode_u32(xdr
, &argp
->state
) < 0)
176 argp
->monitor
= 1; /* monitor client by default */
182 nlm4svc_decode_cancargs(struct svc_rqst
*rqstp
, struct xdr_stream
*xdr
)
184 struct nlm_args
*argp
= rqstp
->rq_argp
;
187 if (!svcxdr_decode_cookie(xdr
, &argp
->cookie
))
189 if (xdr_stream_decode_bool(xdr
, &argp
->block
) < 0)
191 if (xdr_stream_decode_bool(xdr
, &exclusive
) < 0)
193 if (!svcxdr_decode_lock(xdr
, &argp
->lock
))
196 argp
->lock
.fl
.fl_type
= F_WRLCK
;
202 nlm4svc_decode_unlockargs(struct svc_rqst
*rqstp
, struct xdr_stream
*xdr
)
204 struct nlm_args
*argp
= rqstp
->rq_argp
;
206 if (!svcxdr_decode_cookie(xdr
, &argp
->cookie
))
208 if (!svcxdr_decode_lock(xdr
, &argp
->lock
))
210 argp
->lock
.fl
.fl_type
= F_UNLCK
;
216 nlm4svc_decode_res(struct svc_rqst
*rqstp
, struct xdr_stream
*xdr
)
218 struct nlm_res
*resp
= rqstp
->rq_argp
;
220 if (!svcxdr_decode_cookie(xdr
, &resp
->cookie
))
222 if (!svcxdr_decode_stats(xdr
, &resp
->status
))
229 nlm4svc_decode_reboot(struct svc_rqst
*rqstp
, struct xdr_stream
*xdr
)
231 struct nlm_reboot
*argp
= rqstp
->rq_argp
;
235 if (xdr_stream_decode_u32(xdr
, &len
) < 0)
237 if (len
> SM_MAXSTRLEN
)
239 p
= xdr_inline_decode(xdr
, len
);
243 argp
->mon
= (char *)p
;
244 if (xdr_stream_decode_u32(xdr
, &argp
->state
) < 0)
246 p
= xdr_inline_decode(xdr
, SM_PRIV_SIZE
);
249 memcpy(&argp
->priv
.data
, p
, sizeof(argp
->priv
.data
));
255 nlm4svc_decode_shareargs(struct svc_rqst
*rqstp
, struct xdr_stream
*xdr
)
257 struct nlm_args
*argp
= rqstp
->rq_argp
;
258 struct nlm_lock
*lock
= &argp
->lock
;
260 memset(lock
, 0, sizeof(*lock
));
261 locks_init_lock(&lock
->fl
);
262 lock
->svid
= ~(u32
)0;
264 if (!svcxdr_decode_cookie(xdr
, &argp
->cookie
))
266 if (!svcxdr_decode_string(xdr
, &lock
->caller
, &lock
->len
))
268 if (!svcxdr_decode_fhandle(xdr
, &lock
->fh
))
270 if (!svcxdr_decode_owner(xdr
, &lock
->oh
))
272 /* XXX: Range checks are missing in the original code */
273 if (xdr_stream_decode_u32(xdr
, &argp
->fsm_mode
) < 0)
275 if (xdr_stream_decode_u32(xdr
, &argp
->fsm_access
) < 0)
282 nlm4svc_decode_notify(struct svc_rqst
*rqstp
, struct xdr_stream
*xdr
)
284 struct nlm_args
*argp
= rqstp
->rq_argp
;
285 struct nlm_lock
*lock
= &argp
->lock
;
287 if (!svcxdr_decode_string(xdr
, &lock
->caller
, &lock
->len
))
289 if (xdr_stream_decode_u32(xdr
, &argp
->state
) < 0)
297 * Encode Reply results
301 nlm4svc_encode_void(struct svc_rqst
*rqstp
, struct xdr_stream
*xdr
)
307 nlm4svc_encode_testres(struct svc_rqst
*rqstp
, struct xdr_stream
*xdr
)
309 struct nlm_res
*resp
= rqstp
->rq_resp
;
311 return svcxdr_encode_cookie(xdr
, &resp
->cookie
) &&
312 svcxdr_encode_testrply(xdr
, resp
);
316 nlm4svc_encode_res(struct svc_rqst
*rqstp
, struct xdr_stream
*xdr
)
318 struct nlm_res
*resp
= rqstp
->rq_resp
;
320 return svcxdr_encode_cookie(xdr
, &resp
->cookie
) &&
321 svcxdr_encode_stats(xdr
, resp
->status
);
325 nlm4svc_encode_shareres(struct svc_rqst
*rqstp
, struct xdr_stream
*xdr
)
327 struct nlm_res
*resp
= rqstp
->rq_resp
;
329 if (!svcxdr_encode_cookie(xdr
, &resp
->cookie
))
331 if (!svcxdr_encode_stats(xdr
, resp
->status
))
334 if (xdr_stream_encode_u32(xdr
, 0) < 0)