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 45 /* 46 * draft-ietf-nfsv4-minorversion-22 47 * draft-ietf-nfsv4-pnfs-obj-12 48 */ 49 50 /* Layout Structure */ 51 52 enum pnfs_osd_raid_algorithm4 { 53 PNFS_OSD_RAID_0 = 1, 54 PNFS_OSD_RAID_4 = 2, 55 PNFS_OSD_RAID_5 = 3, 56 PNFS_OSD_RAID_PQ = 4 /* Reed-Solomon P+Q */ 57 }; 58 59 /* struct pnfs_osd_data_map4 { 60 * uint32_t odm_num_comps; 61 * length4 odm_stripe_unit; 62 * uint32_t odm_group_width; 63 * uint32_t odm_group_depth; 64 * uint32_t odm_mirror_cnt; 65 * pnfs_osd_raid_algorithm4 odm_raid_algorithm; 66 * }; 67 */ 68 struct pnfs_osd_data_map { 69 u32 odm_num_comps; 70 u64 odm_stripe_unit; 71 u32 odm_group_width; 72 u32 odm_group_depth; 73 u32 odm_mirror_cnt; 74 u32 odm_raid_algorithm; 75 }; 76 77 /* struct pnfs_osd_objid4 { 78 * deviceid4 oid_device_id; 79 * uint64_t oid_partition_id; 80 * uint64_t oid_object_id; 81 * }; 82 */ 83 struct pnfs_osd_objid { 84 struct nfs4_deviceid oid_device_id; 85 u64 oid_partition_id; 86 u64 oid_object_id; 87 }; 88 89 /* For printout. I use: 90 * kprint("dev(%llx:%llx)", _DEVID_LO(pointer), _DEVID_HI(pointer)); 91 * BE style 92 */ 93 #define _DEVID_LO(oid_device_id) \ 94 (unsigned long long)be64_to_cpup((__be64 *)(oid_device_id)->data) 95 96 #define _DEVID_HI(oid_device_id) \ 97 (unsigned long long)be64_to_cpup(((__be64 *)(oid_device_id)->data) + 1) 98 99 enum pnfs_osd_version { 100 PNFS_OSD_MISSING = 0, 101 PNFS_OSD_VERSION_1 = 1, 102 PNFS_OSD_VERSION_2 = 2 103 }; 104 105 struct pnfs_osd_opaque_cred { 106 u32 cred_len; 107 void *cred; 108 }; 109 110 enum pnfs_osd_cap_key_sec { 111 PNFS_OSD_CAP_KEY_SEC_NONE = 0, 112 PNFS_OSD_CAP_KEY_SEC_SSV = 1, 113 }; 114 115 /* struct pnfs_osd_object_cred4 { 116 * pnfs_osd_objid4 oc_object_id; 117 * pnfs_osd_version4 oc_osd_version; 118 * pnfs_osd_cap_key_sec4 oc_cap_key_sec; 119 * opaque oc_capability_key<>; 120 * opaque oc_capability<>; 121 * }; 122 */ 123 struct pnfs_osd_object_cred { 124 struct pnfs_osd_objid oc_object_id; 125 u32 oc_osd_version; 126 u32 oc_cap_key_sec; 127 struct pnfs_osd_opaque_cred oc_cap_key; 128 struct pnfs_osd_opaque_cred oc_cap; 129 }; 130 131 /* struct pnfs_osd_layout4 { 132 * pnfs_osd_data_map4 olo_map; 133 * uint32_t olo_comps_index; 134 * pnfs_osd_object_cred4 olo_components<>; 135 * }; 136 */ 137 struct pnfs_osd_layout { 138 struct pnfs_osd_data_map olo_map; 139 u32 olo_comps_index; 140 u32 olo_num_comps; 141 struct pnfs_osd_object_cred *olo_comps; 142 }; 143 144 /* Device Address */ 145 enum pnfs_osd_targetid_type { 146 OBJ_TARGET_ANON = 1, 147 OBJ_TARGET_SCSI_NAME = 2, 148 OBJ_TARGET_SCSI_DEVICE_ID = 3, 149 }; 150 151 /* union pnfs_osd_targetid4 switch (pnfs_osd_targetid_type4 oti_type) { 152 * case OBJ_TARGET_SCSI_NAME: 153 * string oti_scsi_name<>; 154 * 155 * case OBJ_TARGET_SCSI_DEVICE_ID: 156 * opaque oti_scsi_device_id<>; 157 * 158 * default: 159 * void; 160 * }; 161 * 162 * union pnfs_osd_targetaddr4 switch (bool ota_available) { 163 * case TRUE: 164 * netaddr4 ota_netaddr; 165 * case FALSE: 166 * void; 167 * }; 168 * 169 * struct pnfs_osd_deviceaddr4 { 170 * pnfs_osd_targetid4 oda_targetid; 171 * pnfs_osd_targetaddr4 oda_targetaddr; 172 * uint64_t oda_lun; 173 * opaque oda_systemid<>; 174 * pnfs_osd_object_cred4 oda_root_obj_cred; 175 * opaque oda_osdname<>; 176 * }; 177 */ 178 struct pnfs_osd_targetid { 179 u32 oti_type; 180 struct nfs4_string oti_scsi_device_id; 181 }; 182 183 /* struct netaddr4 { 184 * // see struct rpcb in RFC1833 185 * string r_netid<>; // network id 186 * string r_addr<>; // universal address 187 * }; 188 */ 189 struct pnfs_osd_net_addr { 190 struct nfs4_string r_netid; 191 struct nfs4_string r_addr; 192 }; 193 194 struct pnfs_osd_targetaddr { 195 u32 ota_available; 196 struct pnfs_osd_net_addr ota_netaddr; 197 }; 198 199 struct pnfs_osd_deviceaddr { 200 struct pnfs_osd_targetid oda_targetid; 201 struct pnfs_osd_targetaddr oda_targetaddr; 202 u8 oda_lun[8]; 203 struct nfs4_string oda_systemid; 204 struct pnfs_osd_object_cred oda_root_obj_cred; 205 struct nfs4_string oda_osdname; 206 }; 207 208 /* LAYOUTCOMMIT: layoutupdate */ 209 210 /* union pnfs_osd_deltaspaceused4 switch (bool dsu_valid) { 211 * case TRUE: 212 * int64_t dsu_delta; 213 * case FALSE: 214 * void; 215 * }; 216 * 217 * struct pnfs_osd_layoutupdate4 { 218 * pnfs_osd_deltaspaceused4 olu_delta_space_used; 219 * bool olu_ioerr_flag; 220 * }; 221 */ 222 struct pnfs_osd_layoutupdate { 223 u32 dsu_valid; 224 s64 dsu_delta; 225 u32 olu_ioerr_flag; 226 }; 227 228 /* LAYOUTRETURN: I/O Rrror Report */ 229 230 enum pnfs_osd_errno { 231 PNFS_OSD_ERR_EIO = 1, 232 PNFS_OSD_ERR_NOT_FOUND = 2, 233 PNFS_OSD_ERR_NO_SPACE = 3, 234 PNFS_OSD_ERR_BAD_CRED = 4, 235 PNFS_OSD_ERR_NO_ACCESS = 5, 236 PNFS_OSD_ERR_UNREACHABLE = 6, 237 PNFS_OSD_ERR_RESOURCE = 7 238 }; 239 240 /* struct pnfs_osd_ioerr4 { 241 * pnfs_osd_objid4 oer_component; 242 * length4 oer_comp_offset; 243 * length4 oer_comp_length; 244 * bool oer_iswrite; 245 * pnfs_osd_errno4 oer_errno; 246 * }; 247 */ 248 struct pnfs_osd_ioerr { 249 struct pnfs_osd_objid oer_component; 250 u64 oer_comp_offset; 251 u64 oer_comp_length; 252 u32 oer_iswrite; 253 u32 oer_errno; 254 }; 255 256 /* OSD XDR Client API */ 257 /* Layout helpers */ 258 /* Layout decoding is done in two parts: 259 * 1. First Call pnfs_osd_xdr_decode_layout_map to read in only the header part 260 * of the layout. @iter members need not be initialized. 261 * Returned: 262 * @layout members are set. (@layout->olo_comps set to NULL). 263 * 264 * Zero on success, or negative error if passed xdr is broken. 265 * 266 * 2. 2nd Call pnfs_osd_xdr_decode_layout_comp() in a loop until it returns 267 * false, to decode the next component. 268 * Returned: 269 * true if there is more to decode or false if we are done or error. 270 * 271 * Example: 272 * struct pnfs_osd_xdr_decode_layout_iter iter; 273 * struct pnfs_osd_layout layout; 274 * struct pnfs_osd_object_cred comp; 275 * int status; 276 * 277 * status = pnfs_osd_xdr_decode_layout_map(&layout, &iter, xdr); 278 * if (unlikely(status)) 279 * goto err; 280 * while(pnfs_osd_xdr_decode_layout_comp(&comp, &iter, xdr, &status)) { 281 * // All of @comp strings point to inside the xdr_buffer 282 * // or scrach buffer. Copy them out to user memory eg. 283 * copy_single_comp(dest_comp++, &comp); 284 * } 285 * if (unlikely(status)) 286 * goto err; 287 */ 288 289 struct pnfs_osd_xdr_decode_layout_iter { 290 unsigned total_comps; 291 unsigned decoded_comps; 292 }; 293 294 extern int pnfs_osd_xdr_decode_layout_map(struct pnfs_osd_layout *layout, 295 struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr); 296 297 extern bool pnfs_osd_xdr_decode_layout_comp(struct pnfs_osd_object_cred *comp, 298 struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr, 299 int *err); 300 301 /* Device Info helpers */ 302 303 /* Note: All strings inside @deviceaddr point to space inside @p. 304 * @p should stay valid while @deviceaddr is in use. 305 */ 306 extern void pnfs_osd_xdr_decode_deviceaddr( 307 struct pnfs_osd_deviceaddr *deviceaddr, __be32 *p); 308 309 /* layoutupdate (layout_commit) xdr helpers */ 310 extern int 311 pnfs_osd_xdr_encode_layoutupdate(struct xdr_stream *xdr, 312 struct pnfs_osd_layoutupdate *lou); 313 314 /* osd_ioerror encoding (layout_return) */ 315 extern __be32 *pnfs_osd_xdr_ioerr_reserve_space(struct xdr_stream *xdr); 316 extern void pnfs_osd_xdr_encode_ioerr(__be32 *p, struct pnfs_osd_ioerr *ioerr); 317 318 #endif /* __PNFS_OSD_XDR_H__ */ 319