Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 144474
b: refs/heads/master
c: 71f32e3
h: refs/heads/master
v: v3
  • Loading branch information
Boaz Harrosh authored and James Bottomley committed Apr 27, 2009
1 parent 2acb7a4 commit 94c1852
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 24 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bf5e84f69618f416e89a5a53434a8c865e70252e
refs/heads/master: 71f32e31e5638df37904697e2d04182935add85d
86 changes: 68 additions & 18 deletions trunk/drivers/scsi/osd/osd_initiator.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,69 @@ 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);

oa->val_ptr = attr->attr_val;
}
return inc;
}

static unsigned _osd_req_alist_size(struct osd_request *or, void *list_head)
{
return osd_req_is_ver1(or) ?
Expand Down Expand Up @@ -798,7 +861,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;
Expand All @@ -811,11 +873,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;
Expand Down Expand Up @@ -1070,26 +1128,18 @@ 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);
oa->val_ptr = NULL;
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;
}
Expand Down
20 changes: 15 additions & 5 deletions trunk/include/scsi/osd_protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,15 +300,25 @@ struct osd_attributes_list_attrid {
__be32 attr_id;
} __packed;

/*
* NOTE: v1: is not aligned.
*/
struct osdv1_attributes_list_element {
__be32 attr_page;
__be32 attr_id;
__be16 attr_bytes; /* valid bytes at attr_val without padding */
u8 attr_val[0];
} __packed;

/*
* osd2r03: 7.1.3.3 List entry format for retrieved attributes and
* for setting attributes
* NOTE: v2 is 8-bytes aligned, v1 is not aligned.
* NOTE: v2 is 8-bytes aligned
*/
struct osd_attributes_list_element {
struct osdv2_attributes_list_element {
__be32 attr_page;
__be32 attr_id;
__be16 attr_bytes;
__be16 attr_bytes; /* valid bytes at attr_val without padding */
u8 attr_val[0];
} __packed;

Expand All @@ -324,13 +334,13 @@ enum {

static inline unsigned osdv1_attr_list_elem_size(unsigned len)
{
return ALIGN(len + sizeof(struct osd_attributes_list_element),
return ALIGN(len + sizeof(struct osdv1_attributes_list_element),
OSDv1_ATTRIBUTES_ELEM_ALIGN);
}

static inline unsigned osdv2_attr_list_elem_size(unsigned len)
{
return ALIGN(len + sizeof(struct osd_attributes_list_element),
return ALIGN(len + sizeof(struct osdv2_attributes_list_element),
OSD_ATTRIBUTES_ELEM_ALIGN);
}

Expand Down

0 comments on commit 94c1852

Please sign in to comment.