aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/osd
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2009-05-22 14:25:34 -0400
committerJens Axboe <jens.axboe@oracle.com>2009-05-22 14:25:34 -0400
commite4b636366c00738b9609cda307014d71b1225b7f (patch)
tree760b67b3624eda62e943e48ce93635c30a5b47bf /drivers/scsi/osd
parentb9ed7252d219c1c663944bf03846eabb515dbe75 (diff)
parent279e677faa775ad16e75c32e1bf4a37f8158bc61 (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.c125
-rw-r--r--drivers/scsi/osd/osd_uld.c20
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
208static 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
228static 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
208static unsigned _osd_req_alist_size(struct osd_request *or, void *list_head) 276static 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
290void osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device) 358void 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
1197static 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
1206static 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
1142static int _osd_req_finalize_data_integrity(struct osd_request *or, 1215static 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
176struct osd_dev *osduld_path_lookup(const char *path) 176struct 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
222out: 222out:
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}
226EXPORT_SYMBOL(osduld_path_lookup); 226EXPORT_SYMBOL(osduld_path_lookup);