From 76f3084be73eaea55b2ca9edcc6393e5591b7dcf Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 15 Apr 2009 22:10:24 +0900 Subject: [PATCH] --- yaml --- r: 143959 b: refs/heads/master c: 25636e282fe95508cae96bb27f86407aef935817 h: refs/heads/master i: 143957: d98a415112cab5ef5bf3e7955cffa45677e35470 143955: 0707c1913a23f65ee638d81719bd5bafeeb50f01 143951: e11fd5649e1f4bdfcfe8c748346554e94f07dd72 v: v3 --- [refs] | 2 +- trunk/block/scsi_ioctl.c | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 1c1e39694851..c92308a41fd3 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 23c560a99d78bddf5c251bfa97bce19e4da4b3f3 +refs/heads/master: 25636e282fe95508cae96bb27f86407aef935817 diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index 84b7f8709f41..82a0ca2f6729 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -290,6 +290,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, if (hdr->iovec_count) { const int size = sizeof(struct sg_iovec) * hdr->iovec_count; + size_t iov_data_len; struct sg_iovec *iov; iov = kmalloc(size, GFP_KERNEL); @@ -304,8 +305,18 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, goto out; } + /* SG_IO howto says that the shorter of the two wins */ + iov_data_len = iov_length((struct iovec *)iov, + hdr->iovec_count); + if (hdr->dxfer_len < iov_data_len) { + hdr->iovec_count = iov_shorten((struct iovec *)iov, + hdr->iovec_count, + hdr->dxfer_len); + iov_data_len = hdr->dxfer_len; + } + ret = blk_rq_map_user_iov(q, rq, NULL, iov, hdr->iovec_count, - hdr->dxfer_len, GFP_KERNEL); + iov_data_len, GFP_KERNEL); kfree(iov); } else if (hdr->dxfer_len) ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len,