xref: /OK3568_Linux_fs/kernel/include/linux/pnfs_osd_xdr.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  *  pNFS-osd on-the-wire data structures
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  *  Copyright (C) 2007 Panasas Inc. [year of first publication]
5*4882a593Smuzhiyun  *  All rights reserved.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  *  Benny Halevy <bhalevy@panasas.com>
8*4882a593Smuzhiyun  *  Boaz Harrosh <ooo@electrozaur.com>
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  *  This program is free software; you can redistribute it and/or modify
11*4882a593Smuzhiyun  *  it under the terms of the GNU General Public License version 2
12*4882a593Smuzhiyun  *  See the file COPYING included with this distribution for more details.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  *  Redistribution and use in source and binary forms, with or without
15*4882a593Smuzhiyun  *  modification, are permitted provided that the following conditions
16*4882a593Smuzhiyun  *  are met:
17*4882a593Smuzhiyun  *
18*4882a593Smuzhiyun  *  1. Redistributions of source code must retain the above copyright
19*4882a593Smuzhiyun  *     notice, this list of conditions and the following disclaimer.
20*4882a593Smuzhiyun  *  2. Redistributions in binary form must reproduce the above copyright
21*4882a593Smuzhiyun  *     notice, this list of conditions and the following disclaimer in the
22*4882a593Smuzhiyun  *     documentation and/or other materials provided with the distribution.
23*4882a593Smuzhiyun  *  3. Neither the name of the Panasas company nor the names of its
24*4882a593Smuzhiyun  *     contributors may be used to endorse or promote products derived
25*4882a593Smuzhiyun  *     from this software without specific prior written permission.
26*4882a593Smuzhiyun  *
27*4882a593Smuzhiyun  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
28*4882a593Smuzhiyun  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
29*4882a593Smuzhiyun  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30*4882a593Smuzhiyun  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31*4882a593Smuzhiyun  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32*4882a593Smuzhiyun  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33*4882a593Smuzhiyun  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
34*4882a593Smuzhiyun  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35*4882a593Smuzhiyun  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36*4882a593Smuzhiyun  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37*4882a593Smuzhiyun  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38*4882a593Smuzhiyun  */
39*4882a593Smuzhiyun #ifndef __PNFS_OSD_XDR_H__
40*4882a593Smuzhiyun #define __PNFS_OSD_XDR_H__
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun #include <linux/nfs_fs.h>
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun /*
45*4882a593Smuzhiyun  * draft-ietf-nfsv4-minorversion-22
46*4882a593Smuzhiyun  * draft-ietf-nfsv4-pnfs-obj-12
47*4882a593Smuzhiyun  */
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun /* Layout Structure */
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun enum pnfs_osd_raid_algorithm4 {
52*4882a593Smuzhiyun 	PNFS_OSD_RAID_0		= 1,
53*4882a593Smuzhiyun 	PNFS_OSD_RAID_4		= 2,
54*4882a593Smuzhiyun 	PNFS_OSD_RAID_5		= 3,
55*4882a593Smuzhiyun 	PNFS_OSD_RAID_PQ	= 4     /* Reed-Solomon P+Q */
56*4882a593Smuzhiyun };
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun /*   struct pnfs_osd_data_map4 {
59*4882a593Smuzhiyun  *       uint32_t                    odm_num_comps;
60*4882a593Smuzhiyun  *       length4                     odm_stripe_unit;
61*4882a593Smuzhiyun  *       uint32_t                    odm_group_width;
62*4882a593Smuzhiyun  *       uint32_t                    odm_group_depth;
63*4882a593Smuzhiyun  *       uint32_t                    odm_mirror_cnt;
64*4882a593Smuzhiyun  *       pnfs_osd_raid_algorithm4    odm_raid_algorithm;
65*4882a593Smuzhiyun  *   };
66*4882a593Smuzhiyun  */
67*4882a593Smuzhiyun struct pnfs_osd_data_map {
68*4882a593Smuzhiyun 	u32	odm_num_comps;
69*4882a593Smuzhiyun 	u64	odm_stripe_unit;
70*4882a593Smuzhiyun 	u32	odm_group_width;
71*4882a593Smuzhiyun 	u32	odm_group_depth;
72*4882a593Smuzhiyun 	u32	odm_mirror_cnt;
73*4882a593Smuzhiyun 	u32	odm_raid_algorithm;
74*4882a593Smuzhiyun };
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun /*   struct pnfs_osd_objid4 {
77*4882a593Smuzhiyun  *       deviceid4       oid_device_id;
78*4882a593Smuzhiyun  *       uint64_t        oid_partition_id;
79*4882a593Smuzhiyun  *       uint64_t        oid_object_id;
80*4882a593Smuzhiyun  *   };
81*4882a593Smuzhiyun  */
82*4882a593Smuzhiyun struct pnfs_osd_objid {
83*4882a593Smuzhiyun 	struct nfs4_deviceid	oid_device_id;
84*4882a593Smuzhiyun 	u64			oid_partition_id;
85*4882a593Smuzhiyun 	u64			oid_object_id;
86*4882a593Smuzhiyun };
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun /* For printout. I use:
89*4882a593Smuzhiyun  * kprint("dev(%llx:%llx)", _DEVID_LO(pointer), _DEVID_HI(pointer));
90*4882a593Smuzhiyun  * BE style
91*4882a593Smuzhiyun  */
92*4882a593Smuzhiyun #define _DEVID_LO(oid_device_id) \
93*4882a593Smuzhiyun 	(unsigned long long)be64_to_cpup((__be64 *)(oid_device_id)->data)
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun #define _DEVID_HI(oid_device_id) \
96*4882a593Smuzhiyun 	(unsigned long long)be64_to_cpup(((__be64 *)(oid_device_id)->data) + 1)
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun enum pnfs_osd_version {
99*4882a593Smuzhiyun 	PNFS_OSD_MISSING              = 0,
100*4882a593Smuzhiyun 	PNFS_OSD_VERSION_1            = 1,
101*4882a593Smuzhiyun 	PNFS_OSD_VERSION_2            = 2
102*4882a593Smuzhiyun };
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun struct pnfs_osd_opaque_cred {
105*4882a593Smuzhiyun 	u32 cred_len;
106*4882a593Smuzhiyun 	void *cred;
107*4882a593Smuzhiyun };
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun enum pnfs_osd_cap_key_sec {
110*4882a593Smuzhiyun 	PNFS_OSD_CAP_KEY_SEC_NONE     = 0,
111*4882a593Smuzhiyun 	PNFS_OSD_CAP_KEY_SEC_SSV      = 1,
112*4882a593Smuzhiyun };
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun /*   struct pnfs_osd_object_cred4 {
115*4882a593Smuzhiyun  *       pnfs_osd_objid4         oc_object_id;
116*4882a593Smuzhiyun  *       pnfs_osd_version4       oc_osd_version;
117*4882a593Smuzhiyun  *       pnfs_osd_cap_key_sec4   oc_cap_key_sec;
118*4882a593Smuzhiyun  *       opaque                  oc_capability_key<>;
119*4882a593Smuzhiyun  *       opaque                  oc_capability<>;
120*4882a593Smuzhiyun  *   };
121*4882a593Smuzhiyun  */
122*4882a593Smuzhiyun struct pnfs_osd_object_cred {
123*4882a593Smuzhiyun 	struct pnfs_osd_objid		oc_object_id;
124*4882a593Smuzhiyun 	u32				oc_osd_version;
125*4882a593Smuzhiyun 	u32				oc_cap_key_sec;
126*4882a593Smuzhiyun 	struct pnfs_osd_opaque_cred	oc_cap_key;
127*4882a593Smuzhiyun 	struct pnfs_osd_opaque_cred	oc_cap;
128*4882a593Smuzhiyun };
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun /*   struct pnfs_osd_layout4 {
131*4882a593Smuzhiyun  *       pnfs_osd_data_map4      olo_map;
132*4882a593Smuzhiyun  *       uint32_t                olo_comps_index;
133*4882a593Smuzhiyun  *       pnfs_osd_object_cred4   olo_components<>;
134*4882a593Smuzhiyun  *   };
135*4882a593Smuzhiyun  */
136*4882a593Smuzhiyun struct pnfs_osd_layout {
137*4882a593Smuzhiyun 	struct pnfs_osd_data_map	olo_map;
138*4882a593Smuzhiyun 	u32				olo_comps_index;
139*4882a593Smuzhiyun 	u32				olo_num_comps;
140*4882a593Smuzhiyun 	struct pnfs_osd_object_cred	*olo_comps;
141*4882a593Smuzhiyun };
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun /* Device Address */
144*4882a593Smuzhiyun enum pnfs_osd_targetid_type {
145*4882a593Smuzhiyun 	OBJ_TARGET_ANON = 1,
146*4882a593Smuzhiyun 	OBJ_TARGET_SCSI_NAME = 2,
147*4882a593Smuzhiyun 	OBJ_TARGET_SCSI_DEVICE_ID = 3,
148*4882a593Smuzhiyun };
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun /*   union pnfs_osd_targetid4 switch (pnfs_osd_targetid_type4 oti_type) {
151*4882a593Smuzhiyun  *       case OBJ_TARGET_SCSI_NAME:
152*4882a593Smuzhiyun  *           string              oti_scsi_name<>;
153*4882a593Smuzhiyun  *
154*4882a593Smuzhiyun  *       case OBJ_TARGET_SCSI_DEVICE_ID:
155*4882a593Smuzhiyun  *           opaque              oti_scsi_device_id<>;
156*4882a593Smuzhiyun  *
157*4882a593Smuzhiyun  *       default:
158*4882a593Smuzhiyun  *           void;
159*4882a593Smuzhiyun  *   };
160*4882a593Smuzhiyun  *
161*4882a593Smuzhiyun  *   union pnfs_osd_targetaddr4 switch (bool ota_available) {
162*4882a593Smuzhiyun  *       case TRUE:
163*4882a593Smuzhiyun  *           netaddr4            ota_netaddr;
164*4882a593Smuzhiyun  *       case FALSE:
165*4882a593Smuzhiyun  *           void;
166*4882a593Smuzhiyun  *   };
167*4882a593Smuzhiyun  *
168*4882a593Smuzhiyun  *   struct pnfs_osd_deviceaddr4 {
169*4882a593Smuzhiyun  *       pnfs_osd_targetid4      oda_targetid;
170*4882a593Smuzhiyun  *       pnfs_osd_targetaddr4    oda_targetaddr;
171*4882a593Smuzhiyun  *       uint64_t                oda_lun;
172*4882a593Smuzhiyun  *       opaque                  oda_systemid<>;
173*4882a593Smuzhiyun  *       pnfs_osd_object_cred4   oda_root_obj_cred;
174*4882a593Smuzhiyun  *       opaque                  oda_osdname<>;
175*4882a593Smuzhiyun  *   };
176*4882a593Smuzhiyun  */
177*4882a593Smuzhiyun struct pnfs_osd_targetid {
178*4882a593Smuzhiyun 	u32				oti_type;
179*4882a593Smuzhiyun 	struct nfs4_string		oti_scsi_device_id;
180*4882a593Smuzhiyun };
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun /*   struct netaddr4 {
183*4882a593Smuzhiyun  *       // see struct rpcb in RFC1833
184*4882a593Smuzhiyun  *       string r_netid<>;    // network id
185*4882a593Smuzhiyun  *       string r_addr<>;     // universal address
186*4882a593Smuzhiyun  *   };
187*4882a593Smuzhiyun  */
188*4882a593Smuzhiyun struct pnfs_osd_net_addr {
189*4882a593Smuzhiyun 	struct nfs4_string	r_netid;
190*4882a593Smuzhiyun 	struct nfs4_string	r_addr;
191*4882a593Smuzhiyun };
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun struct pnfs_osd_targetaddr {
194*4882a593Smuzhiyun 	u32				ota_available;
195*4882a593Smuzhiyun 	struct pnfs_osd_net_addr	ota_netaddr;
196*4882a593Smuzhiyun };
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun struct pnfs_osd_deviceaddr {
199*4882a593Smuzhiyun 	struct pnfs_osd_targetid	oda_targetid;
200*4882a593Smuzhiyun 	struct pnfs_osd_targetaddr	oda_targetaddr;
201*4882a593Smuzhiyun 	u8				oda_lun[8];
202*4882a593Smuzhiyun 	struct nfs4_string		oda_systemid;
203*4882a593Smuzhiyun 	struct pnfs_osd_object_cred	oda_root_obj_cred;
204*4882a593Smuzhiyun 	struct nfs4_string		oda_osdname;
205*4882a593Smuzhiyun };
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun /* LAYOUTCOMMIT: layoutupdate */
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun /*   union pnfs_osd_deltaspaceused4 switch (bool dsu_valid) {
210*4882a593Smuzhiyun  *       case TRUE:
211*4882a593Smuzhiyun  *           int64_t     dsu_delta;
212*4882a593Smuzhiyun  *       case FALSE:
213*4882a593Smuzhiyun  *           void;
214*4882a593Smuzhiyun  *   };
215*4882a593Smuzhiyun  *
216*4882a593Smuzhiyun  *   struct pnfs_osd_layoutupdate4 {
217*4882a593Smuzhiyun  *       pnfs_osd_deltaspaceused4    olu_delta_space_used;
218*4882a593Smuzhiyun  *       bool                        olu_ioerr_flag;
219*4882a593Smuzhiyun  *   };
220*4882a593Smuzhiyun  */
221*4882a593Smuzhiyun struct pnfs_osd_layoutupdate {
222*4882a593Smuzhiyun 	u32	dsu_valid;
223*4882a593Smuzhiyun 	s64	dsu_delta;
224*4882a593Smuzhiyun 	u32	olu_ioerr_flag;
225*4882a593Smuzhiyun };
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun /* LAYOUTRETURN: I/O Rrror Report */
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun enum pnfs_osd_errno {
230*4882a593Smuzhiyun 	PNFS_OSD_ERR_EIO		= 1,
231*4882a593Smuzhiyun 	PNFS_OSD_ERR_NOT_FOUND		= 2,
232*4882a593Smuzhiyun 	PNFS_OSD_ERR_NO_SPACE		= 3,
233*4882a593Smuzhiyun 	PNFS_OSD_ERR_BAD_CRED		= 4,
234*4882a593Smuzhiyun 	PNFS_OSD_ERR_NO_ACCESS		= 5,
235*4882a593Smuzhiyun 	PNFS_OSD_ERR_UNREACHABLE	= 6,
236*4882a593Smuzhiyun 	PNFS_OSD_ERR_RESOURCE		= 7
237*4882a593Smuzhiyun };
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun /*   struct pnfs_osd_ioerr4 {
240*4882a593Smuzhiyun  *       pnfs_osd_objid4     oer_component;
241*4882a593Smuzhiyun  *       length4             oer_comp_offset;
242*4882a593Smuzhiyun  *       length4             oer_comp_length;
243*4882a593Smuzhiyun  *       bool                oer_iswrite;
244*4882a593Smuzhiyun  *       pnfs_osd_errno4     oer_errno;
245*4882a593Smuzhiyun  *   };
246*4882a593Smuzhiyun  */
247*4882a593Smuzhiyun struct pnfs_osd_ioerr {
248*4882a593Smuzhiyun 	struct pnfs_osd_objid	oer_component;
249*4882a593Smuzhiyun 	u64			oer_comp_offset;
250*4882a593Smuzhiyun 	u64			oer_comp_length;
251*4882a593Smuzhiyun 	u32			oer_iswrite;
252*4882a593Smuzhiyun 	u32			oer_errno;
253*4882a593Smuzhiyun };
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun /* OSD XDR Client API */
256*4882a593Smuzhiyun /* Layout helpers */
257*4882a593Smuzhiyun /* Layout decoding is done in two parts:
258*4882a593Smuzhiyun  * 1. First Call pnfs_osd_xdr_decode_layout_map to read in only the header part
259*4882a593Smuzhiyun  *    of the layout. @iter members need not be initialized.
260*4882a593Smuzhiyun  *    Returned:
261*4882a593Smuzhiyun  *             @layout members are set. (@layout->olo_comps set to NULL).
262*4882a593Smuzhiyun  *
263*4882a593Smuzhiyun  *             Zero on success, or negative error if passed xdr is broken.
264*4882a593Smuzhiyun  *
265*4882a593Smuzhiyun  * 2. 2nd Call pnfs_osd_xdr_decode_layout_comp() in a loop until it returns
266*4882a593Smuzhiyun  *    false, to decode the next component.
267*4882a593Smuzhiyun  *    Returned:
268*4882a593Smuzhiyun  *       true if there is more to decode or false if we are done or error.
269*4882a593Smuzhiyun  *
270*4882a593Smuzhiyun  * Example:
271*4882a593Smuzhiyun  *	struct pnfs_osd_xdr_decode_layout_iter iter;
272*4882a593Smuzhiyun  *	struct pnfs_osd_layout layout;
273*4882a593Smuzhiyun  *	struct pnfs_osd_object_cred comp;
274*4882a593Smuzhiyun  *	int status;
275*4882a593Smuzhiyun  *
276*4882a593Smuzhiyun  *	status = pnfs_osd_xdr_decode_layout_map(&layout, &iter, xdr);
277*4882a593Smuzhiyun  *	if (unlikely(status))
278*4882a593Smuzhiyun  *		goto err;
279*4882a593Smuzhiyun  *	while(pnfs_osd_xdr_decode_layout_comp(&comp, &iter, xdr, &status)) {
280*4882a593Smuzhiyun  *		// All of @comp strings point to inside the xdr_buffer
281*4882a593Smuzhiyun  *		// or scrach buffer. Copy them out to user memory eg.
282*4882a593Smuzhiyun  *		copy_single_comp(dest_comp++, &comp);
283*4882a593Smuzhiyun  *	}
284*4882a593Smuzhiyun  *	if (unlikely(status))
285*4882a593Smuzhiyun  *		goto err;
286*4882a593Smuzhiyun  */
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun struct pnfs_osd_xdr_decode_layout_iter {
289*4882a593Smuzhiyun 	unsigned total_comps;
290*4882a593Smuzhiyun 	unsigned decoded_comps;
291*4882a593Smuzhiyun };
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun extern int pnfs_osd_xdr_decode_layout_map(struct pnfs_osd_layout *layout,
294*4882a593Smuzhiyun 	struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr);
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun extern bool pnfs_osd_xdr_decode_layout_comp(struct pnfs_osd_object_cred *comp,
297*4882a593Smuzhiyun 	struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr,
298*4882a593Smuzhiyun 	int *err);
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun /* Device Info helpers */
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun /* Note: All strings inside @deviceaddr point to space inside @p.
303*4882a593Smuzhiyun  * @p should stay valid while @deviceaddr is in use.
304*4882a593Smuzhiyun  */
305*4882a593Smuzhiyun extern void pnfs_osd_xdr_decode_deviceaddr(
306*4882a593Smuzhiyun 	struct pnfs_osd_deviceaddr *deviceaddr, __be32 *p);
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun /* layoutupdate (layout_commit) xdr helpers */
309*4882a593Smuzhiyun extern int
310*4882a593Smuzhiyun pnfs_osd_xdr_encode_layoutupdate(struct xdr_stream *xdr,
311*4882a593Smuzhiyun 				 struct pnfs_osd_layoutupdate *lou);
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun /* osd_ioerror encoding (layout_return) */
314*4882a593Smuzhiyun extern __be32 *pnfs_osd_xdr_ioerr_reserve_space(struct xdr_stream *xdr);
315*4882a593Smuzhiyun extern void pnfs_osd_xdr_encode_ioerr(__be32 *p, struct pnfs_osd_ioerr *ioerr);
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun #endif /* __PNFS_OSD_XDR_H__ */
318