4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
24 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
28 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
29 * Use is subject to license terms.
32 #include <sys/salib.h>
33 #include <rpc/types.h>
36 #include <rpcsvc/nfs4_prot.h>
39 #define dprintf if (boothowto & RB_DEBUG) printf
42 * XDR routines for NFSv4 ops.
45 xdr_b_utf8string(XDR
*xdrs
, utf8string
*objp
)
47 return (xdr_bytes(xdrs
, (char **)&objp
->utf8string_val
,
48 (uint_t
*)&objp
->utf8string_len
, NFS4_MAX_UTF8STRING
));
52 xdr_nfs_bfh4(XDR
*xdrs
, struct nfs_bfh4
*objp
)
54 char *data
= (char *)&objp
->data
;
55 return (xdr_bytes(xdrs
, (char **)&data
, (uint_t
*)&objp
->len
,
60 xdr_b_putfh4_args(XDR
*xdrs
, putfh4arg_t
*objp
)
62 if (!xdr_u_int(xdrs
, (uint_t
*)&objp
->pf_opnum
))
64 return (xdr_nfs_bfh4(xdrs
, (struct nfs_bfh4
*)&objp
->pf_filehandle
));
68 * Common xdr routines for compound. Let the specific op routines handle
69 * op specific portions of the compound.
72 xdr_b_compound_args(XDR
*xdrs
, b_compound_t
*objp
)
74 if (!xdr_b_utf8string(xdrs
, &objp
->ca_tag
)) {
77 if (!xdr_u_int(xdrs
, &objp
->ca_minorversion
))
79 if (!xdr_u_int(xdrs
, &objp
->ca_argarray_len
))
81 if (objp
->ca_isputrootfh
)
82 return (xdr_u_int(xdrs
, &objp
->ca_opputfh
.pf_opnum
));
83 return (xdr_b_putfh4_args(xdrs
, &objp
->ca_opputfh
));
87 xdr_b_compound_res(XDR
*xdrs
, b_compound_t
*objp
)
89 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->cr_status
))
91 if (!xdr_b_utf8string(xdrs
, &objp
->cr_tag
))
93 if (!xdr_u_int(xdrs
, &objp
->cr_resarray_len
))
95 if (!xdr_u_int(xdrs
, &objp
->cr_opputfh
))
97 return (xdr_enum(xdrs
, (enum_t
*)&objp
->cr_putfh_status
));
101 xdr_b_bitmap4(XDR
*xdrs
, b_bitmap4_t
*objp
)
103 char *arp
= (char *)&objp
->b_bitmap_val
;
104 return (xdr_array(xdrs
, (char **)&arp
,
105 (uint_t
*)&objp
->b_bitmap_len
, ~0,
106 sizeof (uint_t
), (xdrproc_t
)xdr_u_int
));
110 xdr_b_stateid4(XDR
*xdrs
, stateid4
*objp
)
112 if (!xdr_u_int(xdrs
, (uint_t
*)&objp
->seqid
))
114 return (xdr_opaque(xdrs
, objp
->other
, NFS4_OTHER_SIZE
));
118 xdr_getattr4_args(XDR
*xdrs
, getattr4arg_t
*objp
)
120 if (!xdr_b_compound_args(xdrs
, (b_compound_t
*)&objp
->ga_arg
))
122 if (!xdr_u_int(xdrs
, (uint_t
*)&objp
->ga_opgetattr
))
124 return (xdr_b_bitmap4(xdrs
, (b_bitmap4_t
*)&objp
->ga_attr_req
));
128 xdr_b_getattr_res_common(XDR
*xdrs
, getattrres_cmn_t
*objp
)
130 if (!xdr_u_int(xdrs
, (uint_t
*)&objp
->gc_opgetattr
))
132 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->gc_attr_status
))
136 * If the getattr suceeded, proceed and begin to decode the attributes.
138 if (objp
->gc_attr_status
== NFS4_OK
) {
139 char attrvals
[sizeof (b_fattr4_t
)];
142 if (!xdr_b_bitmap4(xdrs
, (b_bitmap4_t
*)&objp
->gc_retattr
))
145 bzero(&attrvals
, sizeof (attrvals
));
146 if (!xdr_bytes(xdrs
, (char **)&ap
,
147 (uint_t
*)&objp
->gc_attrlist_len
, sizeof (b_fattr4_t
)))
150 printf("xdr_b_getattr_res_common: attrlist_len = %d\n",
151 objp
->gc_attrlist_len
);
154 * Go through the bitmap and see if the server
157 if (objp
->gc_attrlist_len
> 0) {
159 b_fattr4_t
*fattrp
= &objp
->gc_attrs
;
160 attr4_bitmap1_t bitmap1
;
161 attr4_bitmap2_t bitmap2
;
165 printf("dumping contents of attr buffer\n");
166 for (i
= 0; i
< objp
->gc_attrlist_len
; i
++) {
167 printf("[%d] = 0x%x\n", i
, ap
[i
]);
170 bitmap1
.word
= objp
->gc_retattr
.b_bitmap_val
[0];
171 bitmap2
.word
= objp
->gc_retattr
.b_bitmap_val
[1];
174 printf("xdr_b_getattr_res_common: bitmap1 = %d "
176 bitmap1
.word
, bitmap2
.word
);
178 xdrmem_create(&mxdrs
, ap
, objp
->gc_attrlist_len
,
182 * Start with the first bitmap
184 if (bitmap1
.word
> 0) {
185 if (bitmap1
.bm_supported_attrs
) {
186 if (!xdr_b_bitmap4(&mxdrs
,
187 (b_bitmap4_t
*)&fattrp
->
192 if (bitmap1
.bm_fattr4_type
) {
193 if (!xdr_enum(&mxdrs
,
194 (enum_t
*)&fattrp
->b_fattr4_type
)) {
198 if (bitmap1
.bm_fattr4_size
) {
199 if (!xdr_u_longlong_t(&mxdrs
,
200 (u_longlong_t
*)&fattrp
->
205 if (bitmap1
.bm_fattr4_fsid
) {
206 if (!xdr_u_longlong_t(&mxdrs
,
207 (u_longlong_t
*)&fattrp
->
208 b_fattr4_fsid
.major
))
211 if (!xdr_u_longlong_t(&mxdrs
,
212 (u_longlong_t
*)&fattrp
->
213 b_fattr4_fsid
.minor
))
216 if (bitmap1
.bm_fattr4_filehandle
) {
217 if (!xdr_nfs_bfh4(&mxdrs
,
218 (struct nfs_bfh4
*)&fattrp
->
219 b_fattr4_filehandle
))
222 if (bitmap1
.bm_fattr4_fileid
) {
223 if (!xdr_u_longlong_t(&mxdrs
,
224 (u_longlong_t
*)&fattrp
->
231 * Now the second bitmap
233 if (bitmap2
.word
> 0) {
234 if (bitmap2
.bm_fattr4_mode
) {
235 if (!xdr_u_int(&mxdrs
, (uint_t
*)&objp
->
236 gc_attrs
.b_fattr4_mode
))
240 if (bitmap2
.bm_fattr4_time_access
) {
241 if (!xdr_longlong_t(&mxdrs
,
242 (longlong_t
*)&objp
->gc_attrs
.
243 b_fattr4_time_access
.seconds
))
245 if (!xdr_u_int(&mxdrs
,
246 (uint_t
*)&objp
->gc_attrs
.
247 b_fattr4_time_access
.nseconds
))
251 if (bitmap2
.bm_fattr4_time_metadata
) {
252 if (!xdr_longlong_t(&mxdrs
,
253 (longlong_t
*)&objp
->gc_attrs
.
254 b_fattr4_time_metadata
.seconds
))
256 if (!xdr_u_int(&mxdrs
,
257 (uint_t
*)&objp
->gc_attrs
.
258 b_fattr4_time_metadata
.nseconds
))
262 if (bitmap2
.bm_fattr4_time_modify
) {
263 if (!xdr_longlong_t(&mxdrs
,
264 (longlong_t
*)&objp
->gc_attrs
.
265 b_fattr4_time_modify
.seconds
))
267 if (!xdr_u_int(&mxdrs
,
268 (uint_t
*)&objp
->gc_attrs
.
269 b_fattr4_time_modify
.nseconds
))
279 xdr_getattr4_res(XDR
*xdrs
, getattr4res_t
*objp
)
281 if (!xdr_b_compound_res(xdrs
, (b_compound_t
*)&objp
->gr_res
))
283 return (xdr_b_getattr_res_common(xdrs
,
284 (getattrres_cmn_t
*)&objp
->gr_cmn
));
288 xdr_lookup4_args(XDR
*xdrs
, lookup4arg_t
*objp
)
290 if (!xdr_b_compound_args(xdrs
, (b_compound_t
*)&objp
->la_arg
))
292 if (!xdr_u_int(xdrs
, (uint_t
*)&objp
->la_oplookup
))
294 if (!xdr_b_utf8string(xdrs
, (utf8string
*)&objp
->la_pathname
))
296 if (!xdr_u_int(xdrs
, (uint_t
*)&objp
->la_opgetattr
))
298 return (xdr_b_bitmap4(xdrs
, (b_bitmap4_t
*)&objp
->la_attr_req
));
302 xdr_lookup4_res(XDR
*xdrs
, lookup4res_t
*objp
)
304 if (!xdr_b_compound_res(xdrs
, (b_compound_t
*)&objp
->lr_res
))
306 if (!xdr_u_int(xdrs
, (uint_t
*)&objp
->lr_oplookup
))
308 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->lr_lookup_status
))
310 if (objp
->lr_lookup_status
== NFS4_OK
) {
311 return (xdr_b_getattr_res_common(xdrs
,
312 (getattrres_cmn_t
*)&objp
->lr_gcmn
));
318 xdr_lookupp4_args(XDR
*xdrs
, lookupp4arg_t
*objp
)
320 if (!xdr_b_compound_args(xdrs
, (b_compound_t
*)&objp
->la_arg
))
322 if (!xdr_u_int(xdrs
, (uint_t
*)&objp
->la_oplookupp
))
324 if (!xdr_u_int(xdrs
, (uint_t
*)&objp
->la_opgetattr
))
326 return (xdr_b_bitmap4(xdrs
, (b_bitmap4_t
*)&objp
->la_attr_req
));
330 xdr_read4_args(XDR
*xdrs
, read4arg_t
*objp
)
332 if (!xdr_b_compound_args(xdrs
, (b_compound_t
*)&objp
->r_arg
))
334 if (!xdr_u_int(xdrs
, (uint_t
*)&objp
->r_opread
))
336 if (!xdr_b_stateid4(xdrs
, (stateid4
*)&objp
->r_stateid
))
338 if (!xdr_u_longlong_t(xdrs
, (u_longlong_t
*)&objp
->r_offset
))
340 return (xdr_u_int(xdrs
, (uint_t
*)&objp
->r_count
));
344 xdr_read4_res(XDR
*xdrs
, read4res_t
*objp
)
346 if (!xdr_b_compound_res(xdrs
, (b_compound_t
*)&objp
->r_res
))
348 if (!xdr_u_int(xdrs
, (uint_t
*)&objp
->r_opread
))
350 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->r_status
))
352 if (objp
->r_status
== NFS4_OK
) {
353 if (!xdr_bool(xdrs
, (bool_t
*)&objp
->r_eof
))
355 return (xdr_bytes(xdrs
, (char **)&objp
->r_data_val
,
356 (uint_t
*)&objp
->r_data_len
, ~0));
362 xdr_readdir4_args(XDR
*xdrs
, readdir4arg_t
*objp
)
364 if (!xdr_b_compound_args(xdrs
, (b_compound_t
*)&objp
->rd_arg
))
366 if (!xdr_u_int(xdrs
, (uint_t
*)&objp
->rd_opreaddir
))
368 if (!xdr_u_longlong_t(xdrs
, (u_longlong_t
*)&objp
->rd_cookie
))
370 if (!xdr_opaque(xdrs
, objp
->rd_cookieverf
, NFS4_VERIFIER_SIZE
))
372 if (!xdr_u_int(xdrs
, (uint_t
*)&objp
->rd_dircount
))
374 if (!xdr_u_int(xdrs
, (uint_t
*)&objp
->rd_maxcount
))
376 return (xdr_b_bitmap4(xdrs
, (b_bitmap4_t
*)&objp
->rd_attr_req
));
380 xdr_b_entry4(XDR
*xdrs
, b_entry4_t
*objp
)
383 char attrvals
[sizeof (b_fattr4_t
)];
387 if (!xdr_u_longlong_t(xdrs
, (u_longlong_t
*)&objp
->b_cookie
))
389 if (!xdr_b_utf8string(xdrs
, &objp
->b_name
))
392 bzero(&attrvals
, sizeof (attrvals
));
393 if (!xdr_bytes(xdrs
, (char **)&ap
, (uint_t
*)&attrlen
,
394 sizeof (b_fattr4_t
)))
398 * We are *only* interested in the fileid, so just extract that.
400 if (attrlen
< sizeof (uint64_t))
403 xdrmem_create(&mxdrs
, ap
, attrlen
, XDR_DECODE
);
405 if (!xdr_u_longlong_t(&mxdrs
, (u_longlong_t
*)&objp
->b_fileid
))
407 return (xdr_pointer(xdrs
, (char **)&objp
->b_nextentry
,
408 sizeof (b_entry4_t
), (xdrproc_t
)xdr_b_entry4
));
412 xdr_readdir4_res(XDR
*xdrs
, readdir4res_t
*objp
)
414 if (!xdr_b_compound_res(xdrs
, (b_compound_t
*)&objp
->rd_res
))
416 if (!xdr_u_int(xdrs
, (uint_t
*)&objp
->rd_opreaddir
))
418 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->rd_status
))
420 if (objp
->rd_status
== NFS4_OK
) {
421 if (!xdr_opaque(xdrs
, objp
->rd_cookieverf
, NFS4_VERIFIER_SIZE
))
423 if (!xdr_pointer(xdrs
, (char **)&objp
->rd_entries
,
424 sizeof (b_entry4_t
), (xdrproc_t
)xdr_b_entry4
))
426 return (xdr_bool(xdrs
, &objp
->rd_eof
));
432 xdr_readlink4_args(XDR
*xdrs
, readlink4arg_t
*objp
)
434 if (!xdr_b_compound_args(xdrs
, (b_compound_t
*)&objp
->rl_arg
))
436 return (xdr_u_int(xdrs
, (uint_t
*)&objp
->rl_opreadlink
));
440 xdr_readlink4_res(XDR
*xdrs
, readlink4res_t
*objp
)
442 if (!xdr_b_compound_res(xdrs
, (b_compound_t
*)&objp
->rl_res
))
444 if (!xdr_u_int(xdrs
, (uint_t
*)&objp
->rl_opreadlink
))
446 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->rl_status
))
448 if (objp
->rl_status
== NFS4_OK
)
449 return (xdr_b_utf8string(xdrs
, (utf8string
*)&objp
->rl_link
));