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