2 * linux/fs/lockd/xdr4.c
4 * XDR support for lockd and the lock client.
6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7 * Copyright (C) 1999, Trond Myklebust <trond.myklebust@fys.uio.no>
10 #include <linux/types.h>
11 #include <linux/sched.h>
12 #include <linux/nfs.h>
14 #include <linux/sunrpc/xdr.h>
15 #include <linux/sunrpc/clnt.h>
16 #include <linux/sunrpc/svc.h>
17 #include <linux/sunrpc/stats.h>
18 #include <linux/lockd/lockd.h>
20 #define NLMDBG_FACILITY NLMDBG_XDR
23 s64_to_loff_t(__s64 offset
)
25 return (loff_t
)offset
;
30 loff_t_to_s64(loff_t offset
)
33 if (offset
> NLM4_OFFSET_MAX
)
34 res
= NLM4_OFFSET_MAX
;
35 else if (offset
< -NLM4_OFFSET_MAX
)
36 res
= -NLM4_OFFSET_MAX
;
43 * XDR functions for basic NLM types
46 nlm4_decode_cookie(__be32
*p
, struct nlm_cookie
*c
)
55 memset(c
->data
, 0, 4); /* hockeypux brain damage */
57 else if(len
<=NLM_MAXCOOKIELEN
)
60 memcpy(c
->data
, p
, len
);
65 dprintk("lockd: bad cookie size %d (only cookies under "
66 "%d bytes are supported.)\n",
67 len
, NLM_MAXCOOKIELEN
);
74 nlm4_encode_cookie(__be32
*p
, struct nlm_cookie
*c
)
77 memcpy(p
, c
->data
, c
->len
);
78 p
+=XDR_QUADLEN(c
->len
);
83 nlm4_decode_fh(__be32
*p
, struct nfs_fh
*f
)
85 memset(f
->data
, 0, sizeof(f
->data
));
86 f
->size
= ntohl(*p
++);
87 if (f
->size
> NFS_MAXFHSIZE
) {
88 dprintk("lockd: bad fhandle size %d (should be <=%d)\n",
89 f
->size
, NFS_MAXFHSIZE
);
92 memcpy(f
->data
, p
, f
->size
);
93 return p
+ XDR_QUADLEN(f
->size
);
97 * Encode and decode owner handle
100 nlm4_decode_oh(__be32
*p
, struct xdr_netobj
*oh
)
102 return xdr_decode_netobj(p
, oh
);
106 nlm4_decode_lock(__be32
*p
, struct nlm_lock
*lock
)
108 struct file_lock
*fl
= &lock
->fl
;
112 if (!(p
= xdr_decode_string_inplace(p
, &lock
->caller
,
113 &lock
->len
, NLM_MAXSTRLEN
))
114 || !(p
= nlm4_decode_fh(p
, &lock
->fh
))
115 || !(p
= nlm4_decode_oh(p
, &lock
->oh
)))
117 lock
->svid
= ntohl(*p
++);
120 fl
->fl_owner
= current
->files
;
121 fl
->fl_pid
= (pid_t
)lock
->svid
;
122 fl
->fl_flags
= FL_POSIX
;
123 fl
->fl_type
= F_RDLCK
; /* as good as anything else */
124 p
= xdr_decode_hyper(p
, &start
);
125 p
= xdr_decode_hyper(p
, &len
);
126 end
= start
+ len
- 1;
128 fl
->fl_start
= s64_to_loff_t(start
);
130 if (len
== 0 || end
< 0)
131 fl
->fl_end
= OFFSET_MAX
;
133 fl
->fl_end
= s64_to_loff_t(end
);
138 * Encode result of a TEST/TEST_MSG call
141 nlm4_encode_testres(__be32
*p
, struct nlm_res
*resp
)
145 dprintk("xdr: before encode_testres (p %p resp %p)\n", p
, resp
);
146 if (!(p
= nlm4_encode_cookie(p
, &resp
->cookie
)))
150 if (resp
->status
== nlm_lck_denied
) {
151 struct file_lock
*fl
= &resp
->lock
.fl
;
153 *p
++ = (fl
->fl_type
== F_RDLCK
)? xdr_zero
: xdr_one
;
154 *p
++ = htonl(resp
->lock
.svid
);
156 /* Encode owner handle. */
157 if (!(p
= xdr_encode_netobj(p
, &resp
->lock
.oh
)))
160 start
= loff_t_to_s64(fl
->fl_start
);
161 if (fl
->fl_end
== OFFSET_MAX
)
164 len
= loff_t_to_s64(fl
->fl_end
- fl
->fl_start
+ 1);
166 p
= xdr_encode_hyper(p
, start
);
167 p
= xdr_encode_hyper(p
, len
);
168 dprintk("xdr: encode_testres (status %u pid %d type %d start %Ld end %Ld)\n",
169 resp
->status
, (int)resp
->lock
.svid
, fl
->fl_type
,
170 (long long)fl
->fl_start
, (long long)fl
->fl_end
);
173 dprintk("xdr: after encode_testres (p %p resp %p)\n", p
, resp
);
179 * First, the server side XDR functions
182 nlm4svc_decode_testargs(struct svc_rqst
*rqstp
, __be32
*p
, nlm_args
*argp
)
186 if (!(p
= nlm4_decode_cookie(p
, &argp
->cookie
)))
189 exclusive
= ntohl(*p
++);
190 if (!(p
= nlm4_decode_lock(p
, &argp
->lock
)))
193 argp
->lock
.fl
.fl_type
= F_WRLCK
;
195 return xdr_argsize_check(rqstp
, p
);
199 nlm4svc_encode_testres(struct svc_rqst
*rqstp
, __be32
*p
, struct nlm_res
*resp
)
201 if (!(p
= nlm4_encode_testres(p
, resp
)))
203 return xdr_ressize_check(rqstp
, p
);
207 nlm4svc_decode_lockargs(struct svc_rqst
*rqstp
, __be32
*p
, nlm_args
*argp
)
211 if (!(p
= nlm4_decode_cookie(p
, &argp
->cookie
)))
213 argp
->block
= ntohl(*p
++);
214 exclusive
= ntohl(*p
++);
215 if (!(p
= nlm4_decode_lock(p
, &argp
->lock
)))
218 argp
->lock
.fl
.fl_type
= F_WRLCK
;
219 argp
->reclaim
= ntohl(*p
++);
220 argp
->state
= ntohl(*p
++);
221 argp
->monitor
= 1; /* monitor client by default */
223 return xdr_argsize_check(rqstp
, p
);
227 nlm4svc_decode_cancargs(struct svc_rqst
*rqstp
, __be32
*p
, nlm_args
*argp
)
231 if (!(p
= nlm4_decode_cookie(p
, &argp
->cookie
)))
233 argp
->block
= ntohl(*p
++);
234 exclusive
= ntohl(*p
++);
235 if (!(p
= nlm4_decode_lock(p
, &argp
->lock
)))
238 argp
->lock
.fl
.fl_type
= F_WRLCK
;
239 return xdr_argsize_check(rqstp
, p
);
243 nlm4svc_decode_unlockargs(struct svc_rqst
*rqstp
, __be32
*p
, nlm_args
*argp
)
245 if (!(p
= nlm4_decode_cookie(p
, &argp
->cookie
))
246 || !(p
= nlm4_decode_lock(p
, &argp
->lock
)))
248 argp
->lock
.fl
.fl_type
= F_UNLCK
;
249 return xdr_argsize_check(rqstp
, p
);
253 nlm4svc_decode_shareargs(struct svc_rqst
*rqstp
, __be32
*p
, nlm_args
*argp
)
255 struct nlm_lock
*lock
= &argp
->lock
;
257 memset(lock
, 0, sizeof(*lock
));
258 locks_init_lock(&lock
->fl
);
259 lock
->svid
= ~(u32
) 0;
260 lock
->fl
.fl_pid
= (pid_t
)lock
->svid
;
262 if (!(p
= nlm4_decode_cookie(p
, &argp
->cookie
))
263 || !(p
= xdr_decode_string_inplace(p
, &lock
->caller
,
264 &lock
->len
, NLM_MAXSTRLEN
))
265 || !(p
= nlm4_decode_fh(p
, &lock
->fh
))
266 || !(p
= nlm4_decode_oh(p
, &lock
->oh
)))
268 argp
->fsm_mode
= ntohl(*p
++);
269 argp
->fsm_access
= ntohl(*p
++);
270 return xdr_argsize_check(rqstp
, p
);
274 nlm4svc_encode_shareres(struct svc_rqst
*rqstp
, __be32
*p
, struct nlm_res
*resp
)
276 if (!(p
= nlm4_encode_cookie(p
, &resp
->cookie
)))
279 *p
++ = xdr_zero
; /* sequence argument */
280 return xdr_ressize_check(rqstp
, p
);
284 nlm4svc_encode_res(struct svc_rqst
*rqstp
, __be32
*p
, struct nlm_res
*resp
)
286 if (!(p
= nlm4_encode_cookie(p
, &resp
->cookie
)))
289 return xdr_ressize_check(rqstp
, p
);
293 nlm4svc_decode_notify(struct svc_rqst
*rqstp
, __be32
*p
, struct nlm_args
*argp
)
295 struct nlm_lock
*lock
= &argp
->lock
;
297 if (!(p
= xdr_decode_string_inplace(p
, &lock
->caller
,
298 &lock
->len
, NLM_MAXSTRLEN
)))
300 argp
->state
= ntohl(*p
++);
301 return xdr_argsize_check(rqstp
, p
);
305 nlm4svc_decode_reboot(struct svc_rqst
*rqstp
, __be32
*p
, struct nlm_reboot
*argp
)
307 if (!(p
= xdr_decode_string_inplace(p
, &argp
->mon
, &argp
->len
, SM_MAXSTRLEN
)))
309 argp
->state
= ntohl(*p
++);
310 memcpy(&argp
->priv
.data
, p
, sizeof(argp
->priv
.data
));
311 p
+= XDR_QUADLEN(SM_PRIV_SIZE
);
312 return xdr_argsize_check(rqstp
, p
);
316 nlm4svc_decode_res(struct svc_rqst
*rqstp
, __be32
*p
, struct nlm_res
*resp
)
318 if (!(p
= nlm4_decode_cookie(p
, &resp
->cookie
)))
321 return xdr_argsize_check(rqstp
, p
);
325 nlm4svc_decode_void(struct svc_rqst
*rqstp
, __be32
*p
, void *dummy
)
327 return xdr_argsize_check(rqstp
, p
);
331 nlm4svc_encode_void(struct svc_rqst
*rqstp
, __be32
*p
, void *dummy
)
333 return xdr_ressize_check(rqstp
, p
);