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