aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-01-08 19:27:31 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-08 19:27:31 -0500
commitcd764695b67386a81964f68e9c66efd9f13f4d29 (patch)
tree504e961ab6bad164c41f4b9c1ff00c0ce7f645ee /block
parent97d61b8e3aef163a75f80f4762794c154572293d (diff)
parentffda8c7dc492e2170bb263f7c56f286992ceb54b (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (45 commits) [SCSI] qla2xxx: Update version number to 8.03.00-k1. [SCSI] qla2xxx: Add ISP81XX support. [SCSI] qla2xxx: Use proper request/response queues with MQ instantiations. [SCSI] qla2xxx: Correct MQ-chain information retrieval during a firmware dump. [SCSI] qla2xxx: Collapse EFT/FCE copy procedures during a firmware dump. [SCSI] qla2xxx: Don't pollute kernel logs with ZIO/RIO status messages. [SCSI] qla2xxx: Don't fallback to interrupt-polling during re-initialization with MSI-X enabled. [SCSI] qla2xxx: Remove support for reading/writing HW-event-log. [SCSI] cxgb3i: add missing include [SCSI] scsi_lib: fix DID_RESET status problems [SCSI] fc transport: restore missing dev_loss_tmo callback to LLDD [SCSI] aha152x_cs: Fix regression that keeps driver from using shared interrupts [SCSI] sd: Correctly handle 6-byte commands with DIX [SCSI] sd: DIF: Fix tagging on platforms with signed char [SCSI] sd: DIF: Show app tag on error [SCSI] Fix error handling for DIF/DIX [SCSI] scsi_lib: don't decrement busy counters when inserting commands [SCSI] libsas: fix test for negative unsigned and typos [SCSI] a2091, gvp11: kill warn_unused_result warnings [SCSI] fusion: Move a dereference below a NULL test ... Fixed up trivial conflict due to moving the async part of sd_probe around in the async probes vs using dev_set_name() in naming.
Diffstat (limited to 'block')
-rw-r--r--block/blk-map.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/block/blk-map.c b/block/blk-map.c
index 2990447f45e9..f103729b462f 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -42,7 +42,7 @@ static int __blk_rq_unmap_user(struct bio *bio)
42 42
43static int __blk_rq_map_user(struct request_queue *q, struct request *rq, 43static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
44 struct rq_map_data *map_data, void __user *ubuf, 44 struct rq_map_data *map_data, void __user *ubuf,
45 unsigned int len, int null_mapped, gfp_t gfp_mask) 45 unsigned int len, gfp_t gfp_mask)
46{ 46{
47 unsigned long uaddr; 47 unsigned long uaddr;
48 struct bio *bio, *orig_bio; 48 struct bio *bio, *orig_bio;
@@ -63,7 +63,7 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
63 if (IS_ERR(bio)) 63 if (IS_ERR(bio))
64 return PTR_ERR(bio); 64 return PTR_ERR(bio);
65 65
66 if (null_mapped) 66 if (map_data && map_data->null_mapped)
67 bio->bi_flags |= (1 << BIO_NULL_MAPPED); 67 bio->bi_flags |= (1 << BIO_NULL_MAPPED);
68 68
69 orig_bio = bio; 69 orig_bio = bio;
@@ -114,17 +114,15 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
114{ 114{
115 unsigned long bytes_read = 0; 115 unsigned long bytes_read = 0;
116 struct bio *bio = NULL; 116 struct bio *bio = NULL;
117 int ret, null_mapped = 0; 117 int ret;
118 118
119 if (len > (q->max_hw_sectors << 9)) 119 if (len > (q->max_hw_sectors << 9))
120 return -EINVAL; 120 return -EINVAL;
121 if (!len) 121 if (!len)
122 return -EINVAL; 122 return -EINVAL;
123 if (!ubuf) { 123
124 if (!map_data || rq_data_dir(rq) != READ) 124 if (!ubuf && (!map_data || !map_data->null_mapped))
125 return -EINVAL; 125 return -EINVAL;
126 null_mapped = 1;
127 }
128 126
129 while (bytes_read != len) { 127 while (bytes_read != len) {
130 unsigned long map_len, end, start; 128 unsigned long map_len, end, start;
@@ -143,13 +141,16 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
143 map_len -= PAGE_SIZE; 141 map_len -= PAGE_SIZE;
144 142
145 ret = __blk_rq_map_user(q, rq, map_data, ubuf, map_len, 143 ret = __blk_rq_map_user(q, rq, map_data, ubuf, map_len,
146 null_mapped, gfp_mask); 144 gfp_mask);
147 if (ret < 0) 145 if (ret < 0)
148 goto unmap_rq; 146 goto unmap_rq;
149 if (!bio) 147 if (!bio)
150 bio = rq->bio; 148 bio = rq->bio;
151 bytes_read += ret; 149 bytes_read += ret;
152 ubuf += ret; 150 ubuf += ret;
151
152 if (map_data)
153 map_data->offset += ret;
153 } 154 }
154 155
155 if (!bio_flagged(bio, BIO_USER_MAPPED)) 156 if (!bio_flagged(bio, BIO_USER_MAPPED))