2 * pNFS Objects layout implementation over open-osd initiator library
4 * Copyright (C) 2009 Panasas Inc. [year of first publication]
7 * Benny Halevy <bhalevy@panasas.com>
8 * Boaz Harrosh <bharrosh@panasas.com>
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.
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
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.
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.
40 #include <linux/module.h>
41 #include <scsi/osd_initiator.h>
43 #include "objlayout.h"
45 #define NFSDBG_FACILITY NFSDBG_PNFS_LD
47 #define _LLU(x) ((unsigned long long)x)
50 u8 caps_key
[OSD_CRYPTO_KEYID_SIZE
];
51 u8 creds
[OSD_CAP_LEN
];
54 struct objio_segment
{
55 struct pnfs_layout_segment lseg
;
57 struct pnfs_osd_object_cred
*comps
;
61 unsigned group_width
; /* Data stripe_units without integrity comps */
68 struct objio_dev_ent
*ods
[];
71 static inline struct objio_segment
*
72 OBJIO_LSEG(struct pnfs_layout_segment
*lseg
)
74 return container_of(lseg
, struct objio_segment
, lseg
);
77 static int _verify_data_map(struct pnfs_osd_layout
*layout
)
79 struct pnfs_osd_data_map
*data_map
= &layout
->olo_map
;
83 /* FIXME: Only raid0 for now. if not go through MDS */
84 if (data_map
->odm_raid_algorithm
!= PNFS_OSD_RAID_0
) {
85 printk(KERN_ERR
"Only RAID_0 for now\n");
88 if (0 != (data_map
->odm_num_comps
% (data_map
->odm_mirror_cnt
+ 1))) {
89 printk(KERN_ERR
"Data Map wrong, num_comps=%u mirrors=%u\n",
90 data_map
->odm_num_comps
, data_map
->odm_mirror_cnt
);
94 if (data_map
->odm_group_width
)
95 group_width
= data_map
->odm_group_width
;
97 group_width
= data_map
->odm_num_comps
/
98 (data_map
->odm_mirror_cnt
+ 1);
100 stripe_length
= (u64
)data_map
->odm_stripe_unit
* group_width
;
101 if (stripe_length
>= (1ULL << 32)) {
102 printk(KERN_ERR
"Total Stripe length(0x%llx)"
103 " >= 32bit is not supported\n", _LLU(stripe_length
));
107 if (0 != (data_map
->odm_stripe_unit
& ~PAGE_MASK
)) {
108 printk(KERN_ERR
"Stripe Unit(0x%llx)"
109 " must be Multples of PAGE_SIZE(0x%lx)\n",
110 _LLU(data_map
->odm_stripe_unit
), PAGE_SIZE
);
117 static void copy_single_comp(struct pnfs_osd_object_cred
*cur_comp
,
118 struct pnfs_osd_object_cred
*src_comp
,
119 struct caps_buffers
*caps_p
)
121 WARN_ON(src_comp
->oc_cap_key
.cred_len
> sizeof(caps_p
->caps_key
));
122 WARN_ON(src_comp
->oc_cap
.cred_len
> sizeof(caps_p
->creds
));
124 *cur_comp
= *src_comp
;
126 memcpy(caps_p
->caps_key
, src_comp
->oc_cap_key
.cred
,
127 sizeof(caps_p
->caps_key
));
128 cur_comp
->oc_cap_key
.cred
= caps_p
->caps_key
;
130 memcpy(caps_p
->creds
, src_comp
->oc_cap
.cred
,
131 sizeof(caps_p
->creds
));
132 cur_comp
->oc_cap
.cred
= caps_p
->creds
;
135 int objio_alloc_lseg(struct pnfs_layout_segment
**outp
,
136 struct pnfs_layout_hdr
*pnfslay
,
137 struct pnfs_layout_range
*range
,
138 struct xdr_stream
*xdr
,
141 struct objio_segment
*objio_seg
;
142 struct pnfs_osd_xdr_decode_layout_iter iter
;
143 struct pnfs_osd_layout layout
;
144 struct pnfs_osd_object_cred
*cur_comp
, src_comp
;
145 struct caps_buffers
*caps_p
;
148 err
= pnfs_osd_xdr_decode_layout_map(&layout
, &iter
, xdr
);
152 err
= _verify_data_map(&layout
);
156 objio_seg
= kzalloc(sizeof(*objio_seg
) +
157 sizeof(objio_seg
->ods
[0]) * layout
.olo_num_comps
+
158 sizeof(*objio_seg
->comps
) * layout
.olo_num_comps
+
159 sizeof(struct caps_buffers
) * layout
.olo_num_comps
,
164 objio_seg
->comps
= (void *)(objio_seg
->ods
+ layout
.olo_num_comps
);
165 cur_comp
= objio_seg
->comps
;
166 caps_p
= (void *)(cur_comp
+ layout
.olo_num_comps
);
167 while (pnfs_osd_xdr_decode_layout_comp(&src_comp
, &iter
, xdr
, &err
))
168 copy_single_comp(cur_comp
++, &src_comp
, caps_p
++);
172 objio_seg
->num_comps
= layout
.olo_num_comps
;
173 objio_seg
->comps_index
= layout
.olo_comps_index
;
175 objio_seg
->mirrors_p1
= layout
.olo_map
.odm_mirror_cnt
+ 1;
176 objio_seg
->stripe_unit
= layout
.olo_map
.odm_stripe_unit
;
177 if (layout
.olo_map
.odm_group_width
) {
178 objio_seg
->group_width
= layout
.olo_map
.odm_group_width
;
179 objio_seg
->group_depth
= layout
.olo_map
.odm_group_depth
;
180 objio_seg
->group_count
= layout
.olo_map
.odm_num_comps
/
181 objio_seg
->mirrors_p1
/
182 objio_seg
->group_width
;
184 objio_seg
->group_width
= layout
.olo_map
.odm_num_comps
/
185 objio_seg
->mirrors_p1
;
186 objio_seg
->group_depth
= -1;
187 objio_seg
->group_count
= 1;
190 *outp
= &objio_seg
->lseg
;
195 dprintk("%s: Error: return %d\n", __func__
, err
);
200 void objio_free_lseg(struct pnfs_layout_segment
*lseg
)
202 struct objio_segment
*objio_seg
= OBJIO_LSEG(lseg
);
208 static struct pnfs_layoutdriver_type objlayout_type
= {
209 .id
= LAYOUT_OSD2_OBJECTS
,
210 .name
= "LAYOUT_OSD2_OBJECTS",
212 .alloc_lseg
= objlayout_alloc_lseg
,
213 .free_lseg
= objlayout_free_lseg
,
216 MODULE_DESCRIPTION("pNFS Layout Driver for OSD2 objects");
217 MODULE_AUTHOR("Benny Halevy <bhalevy@panasas.com>");
218 MODULE_LICENSE("GPL");
223 int ret
= pnfs_register_layoutdriver(&objlayout_type
);
227 "%s: Registering OSD pNFS Layout Driver failed: error=%d\n",
230 printk(KERN_INFO
"%s: Registered OSD pNFS Layout Driver\n",
238 pnfs_unregister_layoutdriver(&objlayout_type
);
239 printk(KERN_INFO
"%s: Unregistered OSD pNFS Layout Driver\n",
243 module_init(objlayout_init
);
244 module_exit(objlayout_exit
);