diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2009-05-22 14:25:34 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-05-22 14:25:34 -0400 |
commit | e4b636366c00738b9609cda307014d71b1225b7f (patch) | |
tree | 760b67b3624eda62e943e48ce93635c30a5b47bf /drivers/scsi/osd | |
parent | b9ed7252d219c1c663944bf03846eabb515dbe75 (diff) | |
parent | 279e677faa775ad16e75c32e1bf4a37f8158bc61 (diff) |
Merge branch 'master' into for-2.6.31
Conflicts:
drivers/block/hd.c
drivers/block/mg_disk.c
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
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 865ec0f4aa80..5776b2ab6b12 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; |
@@ -1050,15 +1113,10 @@ int osd_req_decode_get_attr_list(struct osd_request *or, | |||
1050 | } | 1113 | } |
1051 | 1114 | ||
1052 | for (n = 0; (n < *nelem) && (cur_bytes < returned_bytes); ++n) { | 1115 | for (n = 0; (n < *nelem) && (cur_bytes < returned_bytes); ++n) { |
1053 | struct osd_attributes_list_element *attr = cur_p; | 1116 | int inc = _osd_req_alist_elem_decode(or, cur_p, oa, |
1054 | unsigned inc; | 1117 | returned_bytes - cur_bytes); |
1055 | 1118 | ||
1056 | oa->len = be16_to_cpu(attr->attr_bytes); | 1119 | if (inc < 0) { |
1057 | inc = _osd_req_alist_elem_size(or, oa->len); | ||
1058 | OSD_DEBUG("oa->len=%d inc=%d cur_bytes=%d\n", | ||
1059 | oa->len, inc, cur_bytes); | ||
1060 | cur_bytes += inc; | ||
1061 | if (cur_bytes > returned_bytes) { | ||
1062 | OSD_ERR("BAD FOOD from target. list not valid!" | 1120 | OSD_ERR("BAD FOOD from target. list not valid!" |
1063 | "c=%d r=%d n=%d\n", | 1121 | "c=%d r=%d n=%d\n", |
1064 | cur_bytes, returned_bytes, n); | 1122 | cur_bytes, returned_bytes, n); |
@@ -1066,10 +1124,7 @@ int osd_req_decode_get_attr_list(struct osd_request *or, | |||
1066 | break; | 1124 | break; |
1067 | } | 1125 | } |
1068 | 1126 | ||
1069 | oa->attr_page = be32_to_cpu(attr->attr_page); | 1127 | cur_bytes += inc; |
1070 | oa->attr_id = be32_to_cpu(attr->attr_id); | ||
1071 | oa->val_ptr = attr->attr_val; | ||
1072 | |||
1073 | cur_p += inc; | 1128 | cur_p += inc; |
1074 | ++oa; | 1129 | ++oa; |
1075 | } | 1130 | } |
@@ -1139,6 +1194,24 @@ static int _osd_req_finalize_attr_page(struct osd_request *or) | |||
1139 | return ret; | 1194 | return ret; |
1140 | } | 1195 | } |
1141 | 1196 | ||
1197 | static inline void osd_sec_parms_set_out_offset(bool is_v1, | ||
1198 | struct osd_security_parameters *sec_parms, osd_cdb_offset offset) | ||
1199 | { | ||
1200 | if (is_v1) | ||
1201 | sec_parms->v1.data_out_integrity_check_offset = offset; | ||
1202 | else | ||
1203 | sec_parms->v2.data_out_integrity_check_offset = offset; | ||
1204 | } | ||
1205 | |||
1206 | static inline void osd_sec_parms_set_in_offset(bool is_v1, | ||
1207 | struct osd_security_parameters *sec_parms, osd_cdb_offset offset) | ||
1208 | { | ||
1209 | if (is_v1) | ||
1210 | sec_parms->v1.data_in_integrity_check_offset = offset; | ||
1211 | else | ||
1212 | sec_parms->v2.data_in_integrity_check_offset = offset; | ||
1213 | } | ||
1214 | |||
1142 | static int _osd_req_finalize_data_integrity(struct osd_request *or, | 1215 | static int _osd_req_finalize_data_integrity(struct osd_request *or, |
1143 | bool has_in, bool has_out, const u8 *cap_key) | 1216 | bool has_in, bool has_out, const u8 *cap_key) |
1144 | { | 1217 | { |
@@ -1162,8 +1235,8 @@ static int _osd_req_finalize_data_integrity(struct osd_request *or, | |||
1162 | or->out_data_integ.get_attributes_bytes = cpu_to_be64( | 1235 | or->out_data_integ.get_attributes_bytes = cpu_to_be64( |
1163 | or->enc_get_attr.total_bytes); | 1236 | or->enc_get_attr.total_bytes); |
1164 | 1237 | ||
1165 | sec_parms->data_out_integrity_check_offset = | 1238 | osd_sec_parms_set_out_offset(osd_req_is_ver1(or), sec_parms, |
1166 | osd_req_encode_offset(or, or->out.total_bytes, &pad); | 1239 | osd_req_encode_offset(or, or->out.total_bytes, &pad)); |
1167 | 1240 | ||
1168 | ret = _req_append_segment(or, pad, &seg, or->out.last_seg, | 1241 | ret = _req_append_segment(or, pad, &seg, or->out.last_seg, |
1169 | &or->out); | 1242 | &or->out); |
@@ -1183,8 +1256,8 @@ static int _osd_req_finalize_data_integrity(struct osd_request *or, | |||
1183 | }; | 1256 | }; |
1184 | unsigned pad; | 1257 | unsigned pad; |
1185 | 1258 | ||
1186 | sec_parms->data_in_integrity_check_offset = | 1259 | osd_sec_parms_set_in_offset(osd_req_is_ver1(or), sec_parms, |
1187 | osd_req_encode_offset(or, or->in.total_bytes, &pad); | 1260 | osd_req_encode_offset(or, or->in.total_bytes, &pad)); |
1188 | 1261 | ||
1189 | ret = _req_append_segment(or, pad, &seg, or->in.last_seg, | 1262 | ret = _req_append_segment(or, pad, &seg, or->in.last_seg, |
1190 | &or->in); | 1263 | &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); |