diff options
Diffstat (limited to 'drivers/scsi/osd')
-rw-r--r-- | drivers/scsi/osd/osd_initiator.c | 125 | ||||
-rw-r--r-- | drivers/scsi/osd/osd_uld.c | 20 |
2 files changed, 109 insertions, 36 deletions
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 2a5f0777148d..1ce6b24abab2 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c | |||
@@ -205,6 +205,74 @@ static unsigned _osd_req_alist_elem_size(struct osd_request *or, unsigned len) | |||
205 | osdv2_attr_list_elem_size(len); | 205 | osdv2_attr_list_elem_size(len); |
206 | } | 206 | } |
207 | 207 | ||
208 | static void _osd_req_alist_elem_encode(struct osd_request *or, | ||
209 | void *attr_last, const struct osd_attr *oa) | ||
210 | { | ||
211 | if (osd_req_is_ver1(or)) { | ||
212 | struct osdv1_attributes_list_element *attr = attr_last; | ||
213 | |||
214 | attr->attr_page = cpu_to_be32(oa->attr_page); | ||
215 | attr->attr_id = cpu_to_be32(oa->attr_id); | ||
216 | attr->attr_bytes = cpu_to_be16(oa->len); | ||
217 | memcpy(attr->attr_val, oa->val_ptr, oa->len); | ||
218 | } else { | ||
219 | struct osdv2_attributes_list_element *attr = attr_last; | ||
220 | |||
221 | attr->attr_page = cpu_to_be32(oa->attr_page); | ||
222 | attr->attr_id = cpu_to_be32(oa->attr_id); | ||
223 | attr->attr_bytes = cpu_to_be16(oa->len); | ||
224 | memcpy(attr->attr_val, oa->val_ptr, oa->len); | ||
225 | } | ||
226 | } | ||
227 | |||
228 | static int _osd_req_alist_elem_decode(struct osd_request *or, | ||
229 | void *cur_p, struct osd_attr *oa, unsigned max_bytes) | ||
230 | { | ||
231 | unsigned inc; | ||
232 | if (osd_req_is_ver1(or)) { | ||
233 | struct osdv1_attributes_list_element *attr = cur_p; | ||
234 | |||
235 | if (max_bytes < sizeof(*attr)) | ||
236 | return -1; | ||
237 | |||
238 | oa->len = be16_to_cpu(attr->attr_bytes); | ||
239 | inc = _osd_req_alist_elem_size(or, oa->len); | ||
240 | if (inc > max_bytes) | ||
241 | return -1; | ||
242 | |||
243 | oa->attr_page = be32_to_cpu(attr->attr_page); | ||
244 | oa->attr_id = be32_to_cpu(attr->attr_id); | ||
245 | |||
246 | /* OSD1: On empty attributes we return a pointer to 2 bytes | ||
247 | * of zeros. This keeps similar behaviour with OSD2. | ||
248 | * (See below) | ||
249 | */ | ||
250 | oa->val_ptr = likely(oa->len) ? attr->attr_val : | ||
251 | (u8 *)&attr->attr_bytes; | ||
252 | } else { | ||
253 | struct osdv2_attributes_list_element *attr = cur_p; | ||
254 | |||
255 | if (max_bytes < sizeof(*attr)) | ||
256 | return -1; | ||
257 | |||
258 | oa->len = be16_to_cpu(attr->attr_bytes); | ||
259 | inc = _osd_req_alist_elem_size(or, oa->len); | ||
260 | if (inc > max_bytes) | ||
261 | return -1; | ||
262 | |||
263 | oa->attr_page = be32_to_cpu(attr->attr_page); | ||
264 | oa->attr_id = be32_to_cpu(attr->attr_id); | ||
265 | |||
266 | /* OSD2: For convenience, on empty attributes, we return 8 bytes | ||
267 | * of zeros here. This keeps the same behaviour with OSD2r04, | ||
268 | * and is nice with null terminating ASCII fields. | ||
269 | * oa->val_ptr == NULL marks the end-of-list, or error. | ||
270 | */ | ||
271 | oa->val_ptr = likely(oa->len) ? attr->attr_val : attr->reserved; | ||
272 | } | ||
273 | return inc; | ||
274 | } | ||
275 | |||
208 | static unsigned _osd_req_alist_size(struct osd_request *or, void *list_head) | 276 | static unsigned _osd_req_alist_size(struct osd_request *or, void *list_head) |
209 | { | 277 | { |
210 | return osd_req_is_ver1(or) ? | 278 | return osd_req_is_ver1(or) ? |
@@ -282,9 +350,9 @@ _osd_req_sec_params(struct osd_request *or) | |||
282 | struct osd_cdb *ocdb = &or->cdb; | 350 | struct osd_cdb *ocdb = &or->cdb; |
283 | 351 | ||
284 | if (osd_req_is_ver1(or)) | 352 | if (osd_req_is_ver1(or)) |
285 | return &ocdb->v1.sec_params; | 353 | return (struct osd_security_parameters *)&ocdb->v1.sec_params; |
286 | else | 354 | else |
287 | return &ocdb->v2.sec_params; | 355 | return (struct osd_security_parameters *)&ocdb->v2.sec_params; |
288 | } | 356 | } |
289 | 357 | ||
290 | void osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device) | 358 | void osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device) |
@@ -612,9 +680,9 @@ static int _osd_req_list_objects(struct osd_request *or, | |||
612 | 680 | ||
613 | WARN_ON(or->in.bio); | 681 | WARN_ON(or->in.bio); |
614 | bio = bio_map_kern(q, list, len, or->alloc_flags); | 682 | bio = bio_map_kern(q, list, len, or->alloc_flags); |
615 | if (!bio) { | 683 | if (IS_ERR(bio)) { |
616 | OSD_ERR("!!! Failed to allocate list_objects BIO\n"); | 684 | OSD_ERR("!!! Failed to allocate list_objects BIO\n"); |
617 | return -ENOMEM; | 685 | return PTR_ERR(bio); |
618 | } | 686 | } |
619 | 687 | ||
620 | bio->bi_rw &= ~(1 << BIO_RW); | 688 | bio->bi_rw &= ~(1 << BIO_RW); |
@@ -798,7 +866,6 @@ int osd_req_add_set_attr_list(struct osd_request *or, | |||
798 | attr_last = or->set_attr.buff + total_bytes; | 866 | attr_last = or->set_attr.buff + total_bytes; |
799 | 867 | ||
800 | for (; nelem; --nelem) { | 868 | for (; nelem; --nelem) { |
801 | struct osd_attributes_list_element *attr; | ||
802 | unsigned elem_size = _osd_req_alist_elem_size(or, oa->len); | 869 | unsigned elem_size = _osd_req_alist_elem_size(or, oa->len); |
803 | 870 | ||
804 | total_bytes += elem_size; | 871 | total_bytes += elem_size; |
@@ -811,11 +878,7 @@ int osd_req_add_set_attr_list(struct osd_request *or, | |||
811 | or->set_attr.buff + or->set_attr.total_bytes; | 878 | or->set_attr.buff + or->set_attr.total_bytes; |
812 | } | 879 | } |
813 | 880 | ||
814 | attr = attr_last; | 881 | _osd_req_alist_elem_encode(or, attr_last, oa); |
815 | attr->attr_page = cpu_to_be32(oa->attr_page); | ||
816 | attr->attr_id = cpu_to_be32(oa->attr_id); | ||
817 | attr->attr_bytes = cpu_to_be16(oa->len); | ||
818 | memcpy(attr->attr_val, oa->val_ptr, oa->len); | ||
819 | 882 | ||
820 | attr_last += elem_size; | 883 | attr_last += elem_size; |
821 | ++oa; | 884 | ++oa; |
@@ -1070,15 +1133,10 @@ int osd_req_decode_get_attr_list(struct osd_request *or, | |||
1070 | } | 1133 | } |
1071 | 1134 | ||
1072 | for (n = 0; (n < *nelem) && (cur_bytes < returned_bytes); ++n) { | 1135 | for (n = 0; (n < *nelem) && (cur_bytes < returned_bytes); ++n) { |
1073 | struct osd_attributes_list_element *attr = cur_p; | 1136 | int inc = _osd_req_alist_elem_decode(or, cur_p, oa, |
1074 | unsigned inc; | 1137 | returned_bytes - cur_bytes); |
1075 | 1138 | ||
1076 | oa->len = be16_to_cpu(attr->attr_bytes); | 1139 | if (inc < 0) { |
1077 | inc = _osd_req_alist_elem_size(or, oa->len); | ||
1078 | OSD_DEBUG("oa->len=%d inc=%d cur_bytes=%d\n", | ||
1079 | oa->len, inc, cur_bytes); | ||
1080 | cur_bytes += inc; | ||
1081 | if (cur_bytes > returned_bytes) { | ||
1082 | OSD_ERR("BAD FOOD from target. list not valid!" | 1140 | OSD_ERR("BAD FOOD from target. list not valid!" |
1083 | "c=%d r=%d n=%d\n", | 1141 | "c=%d r=%d n=%d\n", |
1084 | cur_bytes, returned_bytes, n); | 1142 | cur_bytes, returned_bytes, n); |
@@ -1086,10 +1144,7 @@ int osd_req_decode_get_attr_list(struct osd_request *or, | |||
1086 | break; | 1144 | break; |
1087 | } | 1145 | } |
1088 | 1146 | ||
1089 | oa->attr_page = be32_to_cpu(attr->attr_page); | 1147 | cur_bytes += inc; |
1090 | oa->attr_id = be32_to_cpu(attr->attr_id); | ||
1091 | oa->val_ptr = attr->attr_val; | ||
1092 | |||
1093 | cur_p += inc; | 1148 | cur_p += inc; |
1094 | ++oa; | 1149 | ++oa; |
1095 | } | 1150 | } |
@@ -1159,6 +1214,24 @@ static int _osd_req_finalize_attr_page(struct osd_request *or) | |||
1159 | return ret; | 1214 | return ret; |
1160 | } | 1215 | } |
1161 | 1216 | ||
1217 | static inline void osd_sec_parms_set_out_offset(bool is_v1, | ||
1218 | struct osd_security_parameters *sec_parms, osd_cdb_offset offset) | ||
1219 | { | ||
1220 | if (is_v1) | ||
1221 | sec_parms->v1.data_out_integrity_check_offset = offset; | ||
1222 | else | ||
1223 | sec_parms->v2.data_out_integrity_check_offset = offset; | ||
1224 | } | ||
1225 | |||
1226 | static inline void osd_sec_parms_set_in_offset(bool is_v1, | ||
1227 | struct osd_security_parameters *sec_parms, osd_cdb_offset offset) | ||
1228 | { | ||
1229 | if (is_v1) | ||
1230 | sec_parms->v1.data_in_integrity_check_offset = offset; | ||
1231 | else | ||
1232 | sec_parms->v2.data_in_integrity_check_offset = offset; | ||
1233 | } | ||
1234 | |||
1162 | static int _osd_req_finalize_data_integrity(struct osd_request *or, | 1235 | static int _osd_req_finalize_data_integrity(struct osd_request *or, |
1163 | bool has_in, bool has_out, const u8 *cap_key) | 1236 | bool has_in, bool has_out, const u8 *cap_key) |
1164 | { | 1237 | { |
@@ -1182,8 +1255,8 @@ static int _osd_req_finalize_data_integrity(struct osd_request *or, | |||
1182 | or->out_data_integ.get_attributes_bytes = cpu_to_be64( | 1255 | or->out_data_integ.get_attributes_bytes = cpu_to_be64( |
1183 | or->enc_get_attr.total_bytes); | 1256 | or->enc_get_attr.total_bytes); |
1184 | 1257 | ||
1185 | sec_parms->data_out_integrity_check_offset = | 1258 | osd_sec_parms_set_out_offset(osd_req_is_ver1(or), sec_parms, |
1186 | osd_req_encode_offset(or, or->out.total_bytes, &pad); | 1259 | osd_req_encode_offset(or, or->out.total_bytes, &pad)); |
1187 | 1260 | ||
1188 | ret = _req_append_segment(or, pad, &seg, or->out.last_seg, | 1261 | ret = _req_append_segment(or, pad, &seg, or->out.last_seg, |
1189 | &or->out); | 1262 | &or->out); |
@@ -1203,8 +1276,8 @@ static int _osd_req_finalize_data_integrity(struct osd_request *or, | |||
1203 | }; | 1276 | }; |
1204 | unsigned pad; | 1277 | unsigned pad; |
1205 | 1278 | ||
1206 | sec_parms->data_in_integrity_check_offset = | 1279 | osd_sec_parms_set_in_offset(osd_req_is_ver1(or), sec_parms, |
1207 | osd_req_encode_offset(or, or->in.total_bytes, &pad); | 1280 | osd_req_encode_offset(or, or->in.total_bytes, &pad)); |
1208 | 1281 | ||
1209 | ret = _req_append_segment(or, pad, &seg, or->in.last_seg, | 1282 | ret = _req_append_segment(or, pad, &seg, or->in.last_seg, |
1210 | &or->in); | 1283 | &or->in); |
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c index f644c9571eab..22b59e13ba83 100644 --- a/drivers/scsi/osd/osd_uld.c +++ b/drivers/scsi/osd/osd_uld.c | |||
@@ -173,26 +173,26 @@ static const struct file_operations osd_fops = { | |||
173 | .unlocked_ioctl = osd_uld_ioctl, | 173 | .unlocked_ioctl = osd_uld_ioctl, |
174 | }; | 174 | }; |
175 | 175 | ||
176 | struct osd_dev *osduld_path_lookup(const char *path) | 176 | struct osd_dev *osduld_path_lookup(const char *name) |
177 | { | 177 | { |
178 | struct nameidata nd; | 178 | struct path path; |
179 | struct inode *inode; | 179 | struct inode *inode; |
180 | struct cdev *cdev; | 180 | struct cdev *cdev; |
181 | struct osd_uld_device *uninitialized_var(oud); | 181 | struct osd_uld_device *uninitialized_var(oud); |
182 | int error; | 182 | int error; |
183 | 183 | ||
184 | if (!path || !*path) { | 184 | if (!name || !*name) { |
185 | OSD_ERR("Mount with !path || !*path\n"); | 185 | OSD_ERR("Mount with !path || !*path\n"); |
186 | return ERR_PTR(-EINVAL); | 186 | return ERR_PTR(-EINVAL); |
187 | } | 187 | } |
188 | 188 | ||
189 | error = path_lookup(path, LOOKUP_FOLLOW, &nd); | 189 | error = kern_path(name, LOOKUP_FOLLOW, &path); |
190 | if (error) { | 190 | if (error) { |
191 | OSD_ERR("path_lookup of %s faild=>%d\n", path, error); | 191 | OSD_ERR("path_lookup of %s failed=>%d\n", name, error); |
192 | return ERR_PTR(error); | 192 | return ERR_PTR(error); |
193 | } | 193 | } |
194 | 194 | ||
195 | inode = nd.path.dentry->d_inode; | 195 | inode = path.dentry->d_inode; |
196 | error = -EINVAL; /* Not the right device e.g osd_uld_device */ | 196 | error = -EINVAL; /* Not the right device e.g osd_uld_device */ |
197 | if (!S_ISCHR(inode->i_mode)) { | 197 | if (!S_ISCHR(inode->i_mode)) { |
198 | OSD_DEBUG("!S_ISCHR()\n"); | 198 | OSD_DEBUG("!S_ISCHR()\n"); |
@@ -202,15 +202,15 @@ struct osd_dev *osduld_path_lookup(const char *path) | |||
202 | cdev = inode->i_cdev; | 202 | cdev = inode->i_cdev; |
203 | if (!cdev) { | 203 | if (!cdev) { |
204 | OSD_ERR("Before mounting an OSD Based filesystem\n"); | 204 | OSD_ERR("Before mounting an OSD Based filesystem\n"); |
205 | OSD_ERR(" user-mode must open+close the %s device\n", path); | 205 | OSD_ERR(" user-mode must open+close the %s device\n", name); |
206 | OSD_ERR(" Example: bash: echo < %s\n", path); | 206 | OSD_ERR(" Example: bash: echo < %s\n", name); |
207 | goto out; | 207 | goto out; |
208 | } | 208 | } |
209 | 209 | ||
210 | /* The Magic wand. Is it our char-dev */ | 210 | /* The Magic wand. Is it our char-dev */ |
211 | /* TODO: Support sg devices */ | 211 | /* TODO: Support sg devices */ |
212 | if (cdev->owner != THIS_MODULE) { | 212 | if (cdev->owner != THIS_MODULE) { |
213 | OSD_ERR("Error mounting %s - is not an OSD device\n", path); | 213 | OSD_ERR("Error mounting %s - is not an OSD device\n", name); |
214 | goto out; | 214 | goto out; |
215 | } | 215 | } |
216 | 216 | ||
@@ -220,7 +220,7 @@ struct osd_dev *osduld_path_lookup(const char *path) | |||
220 | error = 0; | 220 | error = 0; |
221 | 221 | ||
222 | out: | 222 | out: |
223 | path_put(&nd.path); | 223 | path_put(&path); |
224 | return error ? ERR_PTR(error) : &oud->od; | 224 | return error ? ERR_PTR(error) : &oud->od; |
225 | } | 225 | } |
226 | EXPORT_SYMBOL(osduld_path_lookup); | 226 | EXPORT_SYMBOL(osduld_path_lookup); |