Commit a14ad05f authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
  firewire: Preserve response data alignment bug when it is harmless
parents 0016fe9d 8401d92b
...@@ -369,22 +369,33 @@ complete_transaction(struct fw_card *card, int rcode, ...@@ -369,22 +369,33 @@ complete_transaction(struct fw_card *card, int rcode,
struct response *response = data; struct response *response = data;
struct client *client = response->client; struct client *client = response->client;
unsigned long flags; unsigned long flags;
struct fw_cdev_event_response *r = &response->response;
if (length < response->response.length) if (length < r->length)
response->response.length = length; r->length = length;
if (rcode == RCODE_COMPLETE) if (rcode == RCODE_COMPLETE)
memcpy(response->response.data, payload, memcpy(r->data, payload, r->length);
response->response.length);
spin_lock_irqsave(&client->lock, flags); spin_lock_irqsave(&client->lock, flags);
list_del(&response->resource.link); list_del(&response->resource.link);
spin_unlock_irqrestore(&client->lock, flags); spin_unlock_irqrestore(&client->lock, flags);
response->response.type = FW_CDEV_EVENT_RESPONSE; r->type = FW_CDEV_EVENT_RESPONSE;
response->response.rcode = rcode; r->rcode = rcode;
queue_event(client, &response->event, &response->response,
sizeof(response->response) + response->response.length, /*
NULL, 0); * In the case that sizeof(*r) doesn't align with the position of the
* data, and the read is short, preserve an extra copy of the data
* to stay compatible with a pre-2.6.27 bug. Since the bug is harmless
* for short reads and some apps depended on it, this is both safe
* and prudent for compatibility.
*/
if (r->length <= sizeof(*r) - offsetof(typeof(*r), data))
queue_event(client, &response->event, r, sizeof(*r),
r->data, r->length);
else
queue_event(client, &response->event, r, sizeof(*r) + r->length,
NULL, 0);
} }
static int ioctl_send_request(struct client *client, void *buffer) static int ioctl_send_request(struct client *client, void *buffer)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment