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>
This commit is contained in:
@@ -205,6 +205,74 @@ static unsigned _osd_req_alist_elem_size(struct osd_request *or, unsigned len)
|
||||
osdv2_attr_list_elem_size(len);
|
||||
}
|
||||
|
||||
static void _osd_req_alist_elem_encode(struct osd_request *or,
|
||||
void *attr_last, const struct osd_attr *oa)
|
||||
{
|
||||
if (osd_req_is_ver1(or)) {
|
||||
struct osdv1_attributes_list_element *attr = attr_last;
|
||||
|
||||
attr->attr_page = cpu_to_be32(oa->attr_page);
|
||||
attr->attr_id = cpu_to_be32(oa->attr_id);
|
||||
attr->attr_bytes = cpu_to_be16(oa->len);
|
||||
memcpy(attr->attr_val, oa->val_ptr, oa->len);
|
||||
} else {
|
||||
struct osdv2_attributes_list_element *attr = attr_last;
|
||||
|
||||
attr->attr_page = cpu_to_be32(oa->attr_page);
|
||||
attr->attr_id = cpu_to_be32(oa->attr_id);
|
||||
attr->attr_bytes = cpu_to_be16(oa->len);
|
||||
memcpy(attr->attr_val, oa->val_ptr, oa->len);
|
||||
}
|
||||
}
|
||||
|
||||
static int _osd_req_alist_elem_decode(struct osd_request *or,
|
||||
void *cur_p, struct osd_attr *oa, unsigned max_bytes)
|
||||
{
|
||||
unsigned inc;
|
||||
if (osd_req_is_ver1(or)) {
|
||||
struct osdv1_attributes_list_element *attr = cur_p;
|
||||
|
||||
if (max_bytes < sizeof(*attr))
|
||||
return -1;
|
||||
|
||||
oa->len = be16_to_cpu(attr->attr_bytes);
|
||||
inc = _osd_req_alist_elem_size(or, oa->len);
|
||||
if (inc > max_bytes)
|
||||
return -1;
|
||||
|
||||
oa->attr_page = be32_to_cpu(attr->attr_page);
|
||||
oa->attr_id = be32_to_cpu(attr->attr_id);
|
||||
|
||||
/* OSD1: On empty attributes we return a pointer to 2 bytes
|
||||
* of zeros. This keeps similar behaviour with OSD2.
|
||||
* (See below)
|
||||
*/
|
||||
oa->val_ptr = likely(oa->len) ? attr->attr_val :
|
||||
(u8 *)&attr->attr_bytes;
|
||||
} else {
|
||||
struct osdv2_attributes_list_element *attr = cur_p;
|
||||
|
||||
if (max_bytes < sizeof(*attr))
|
||||
return -1;
|
||||
|
||||
oa->len = be16_to_cpu(attr->attr_bytes);
|
||||
inc = _osd_req_alist_elem_size(or, oa->len);
|
||||
if (inc > max_bytes)
|
||||
return -1;
|
||||
|
||||
oa->attr_page = be32_to_cpu(attr->attr_page);
|
||||
oa->attr_id = be32_to_cpu(attr->attr_id);
|
||||
|
||||
/* OSD2: For convenience, on empty attributes, we return 8 bytes
|
||||
* of zeros here. This keeps the same behaviour with OSD2r04,
|
||||
* and is nice with null terminating ASCII fields.
|
||||
* oa->val_ptr == NULL marks the end-of-list, or error.
|
||||
*/
|
||||
oa->val_ptr = likely(oa->len) ? attr->attr_val : attr->reserved;
|
||||
}
|
||||
return inc;
|
||||
}
|
||||
|
||||
static unsigned _osd_req_alist_size(struct osd_request *or, void *list_head)
|
||||
{
|
||||
return osd_req_is_ver1(or) ?
|
||||
@@ -282,9 +350,9 @@ _osd_req_sec_params(struct osd_request *or)
|
||||
struct osd_cdb *ocdb = &or->cdb;
|
||||
|
||||
if (osd_req_is_ver1(or))
|
||||
return &ocdb->v1.sec_params;
|
||||
return (struct osd_security_parameters *)&ocdb->v1.sec_params;
|
||||
else
|
||||
return &ocdb->v2.sec_params;
|
||||
return (struct osd_security_parameters *)&ocdb->v2.sec_params;
|
||||
}
|
||||
|
||||
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,
|
||||
|
||||
WARN_ON(or->in.bio);
|
||||
bio = bio_map_kern(q, list, len, or->alloc_flags);
|
||||
if (!bio) {
|
||||
if (IS_ERR(bio)) {
|
||||
OSD_ERR("!!! Failed to allocate list_objects BIO\n");
|
||||
return -ENOMEM;
|
||||
return PTR_ERR(bio);
|
||||
}
|
||||
|
||||
bio->bi_rw &= ~(1 << BIO_RW);
|
||||
@@ -798,7 +866,6 @@ int osd_req_add_set_attr_list(struct osd_request *or,
|
||||
attr_last = or->set_attr.buff + total_bytes;
|
||||
|
||||
for (; nelem; --nelem) {
|
||||
struct osd_attributes_list_element *attr;
|
||||
unsigned elem_size = _osd_req_alist_elem_size(or, oa->len);
|
||||
|
||||
total_bytes += elem_size;
|
||||
@@ -811,11 +878,7 @@ int osd_req_add_set_attr_list(struct osd_request *or,
|
||||
or->set_attr.buff + or->set_attr.total_bytes;
|
||||
}
|
||||
|
||||
attr = attr_last;
|
||||
attr->attr_page = cpu_to_be32(oa->attr_page);
|
||||
attr->attr_id = cpu_to_be32(oa->attr_id);
|
||||
attr->attr_bytes = cpu_to_be16(oa->len);
|
||||
memcpy(attr->attr_val, oa->val_ptr, oa->len);
|
||||
_osd_req_alist_elem_encode(or, attr_last, oa);
|
||||
|
||||
attr_last += elem_size;
|
||||
++oa;
|
||||
@@ -1050,15 +1113,10 @@ int osd_req_decode_get_attr_list(struct osd_request *or,
|
||||
}
|
||||
|
||||
for (n = 0; (n < *nelem) && (cur_bytes < returned_bytes); ++n) {
|
||||
struct osd_attributes_list_element *attr = cur_p;
|
||||
unsigned inc;
|
||||
int inc = _osd_req_alist_elem_decode(or, cur_p, oa,
|
||||
returned_bytes - cur_bytes);
|
||||
|
||||
oa->len = be16_to_cpu(attr->attr_bytes);
|
||||
inc = _osd_req_alist_elem_size(or, oa->len);
|
||||
OSD_DEBUG("oa->len=%d inc=%d cur_bytes=%d\n",
|
||||
oa->len, inc, cur_bytes);
|
||||
cur_bytes += inc;
|
||||
if (cur_bytes > returned_bytes) {
|
||||
if (inc < 0) {
|
||||
OSD_ERR("BAD FOOD from target. list not valid!"
|
||||
"c=%d r=%d n=%d\n",
|
||||
cur_bytes, returned_bytes, n);
|
||||
@@ -1066,10 +1124,7 @@ int osd_req_decode_get_attr_list(struct osd_request *or,
|
||||
break;
|
||||
}
|
||||
|
||||
oa->attr_page = be32_to_cpu(attr->attr_page);
|
||||
oa->attr_id = be32_to_cpu(attr->attr_id);
|
||||
oa->val_ptr = attr->attr_val;
|
||||
|
||||
cur_bytes += inc;
|
||||
cur_p += inc;
|
||||
++oa;
|
||||
}
|
||||
@@ -1139,6 +1194,24 @@ static int _osd_req_finalize_attr_page(struct osd_request *or)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void osd_sec_parms_set_out_offset(bool is_v1,
|
||||
struct osd_security_parameters *sec_parms, osd_cdb_offset offset)
|
||||
{
|
||||
if (is_v1)
|
||||
sec_parms->v1.data_out_integrity_check_offset = offset;
|
||||
else
|
||||
sec_parms->v2.data_out_integrity_check_offset = offset;
|
||||
}
|
||||
|
||||
static inline void osd_sec_parms_set_in_offset(bool is_v1,
|
||||
struct osd_security_parameters *sec_parms, osd_cdb_offset offset)
|
||||
{
|
||||
if (is_v1)
|
||||
sec_parms->v1.data_in_integrity_check_offset = offset;
|
||||
else
|
||||
sec_parms->v2.data_in_integrity_check_offset = offset;
|
||||
}
|
||||
|
||||
static int _osd_req_finalize_data_integrity(struct osd_request *or,
|
||||
bool has_in, bool has_out, const u8 *cap_key)
|
||||
{
|
||||
@@ -1162,8 +1235,8 @@ static int _osd_req_finalize_data_integrity(struct osd_request *or,
|
||||
or->out_data_integ.get_attributes_bytes = cpu_to_be64(
|
||||
or->enc_get_attr.total_bytes);
|
||||
|
||||
sec_parms->data_out_integrity_check_offset =
|
||||
osd_req_encode_offset(or, or->out.total_bytes, &pad);
|
||||
osd_sec_parms_set_out_offset(osd_req_is_ver1(or), sec_parms,
|
||||
osd_req_encode_offset(or, or->out.total_bytes, &pad));
|
||||
|
||||
ret = _req_append_segment(or, pad, &seg, or->out.last_seg,
|
||||
&or->out);
|
||||
@@ -1183,8 +1256,8 @@ static int _osd_req_finalize_data_integrity(struct osd_request *or,
|
||||
};
|
||||
unsigned pad;
|
||||
|
||||
sec_parms->data_in_integrity_check_offset =
|
||||
osd_req_encode_offset(or, or->in.total_bytes, &pad);
|
||||
osd_sec_parms_set_in_offset(osd_req_is_ver1(or), sec_parms,
|
||||
osd_req_encode_offset(or, or->in.total_bytes, &pad));
|
||||
|
||||
ret = _req_append_segment(or, pad, &seg, or->in.last_seg,
|
||||
&or->in);
|
||||
|
مرجع در شماره جدید
Block a user