aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2005-06-20 08:04:44 -0400
committerJens Axboe <axboe@suse.de>2005-06-20 08:04:44 -0400
commitdf46b9a44ceb5af2ea2351ce8e28ae7bd840b00f (patch)
tree30ab71759486f94d60af2283fc55bfffcc22155a /drivers/block
parent8b22c249e7de453961e4d253b19fc2a0bdd65d53 (diff)
[PATCH] Add blk_rq_map_kern()
Add blk_rq_map_kern which takes a kernel buffer and maps it into a request and bio. This can be used by the dm hw_handlers, old sg_scsi_ioctl, and one day scsi special requests so all requests comming into scsi will have bios. All requests having bios should allow scsi to use scatter lists for all IO and allow it to use block layer functions. Signed-off-by: Jens Axboe <axboe@suse.de>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/ll_rw_blk.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index f20eba22b14b..e30a3c93b70c 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -281,6 +281,7 @@ static inline void rq_init(request_queue_t *q, struct request *rq)
281 rq->special = NULL; 281 rq->special = NULL;
282 rq->data_len = 0; 282 rq->data_len = 0;
283 rq->data = NULL; 283 rq->data = NULL;
284 rq->nr_phys_segments = 0;
284 rq->sense = NULL; 285 rq->sense = NULL;
285 rq->end_io = NULL; 286 rq->end_io = NULL;
286 rq->end_io_data = NULL; 287 rq->end_io_data = NULL;
@@ -2176,6 +2177,61 @@ int blk_rq_unmap_user(struct request *rq, struct bio *bio, unsigned int ulen)
2176 2177
2177EXPORT_SYMBOL(blk_rq_unmap_user); 2178EXPORT_SYMBOL(blk_rq_unmap_user);
2178 2179
2180static int blk_rq_map_kern_endio(struct bio *bio, unsigned int bytes_done,
2181 int error)
2182{
2183 if (bio->bi_size)
2184 return 1;
2185
2186 bio_put(bio);
2187 return 0;
2188}
2189
2190/**
2191 * blk_rq_map_kern - map kernel data to a request, for REQ_BLOCK_PC usage
2192 * @q: request queue where request should be inserted
2193 * @rw: READ or WRITE data
2194 * @kbuf: the kernel buffer
2195 * @len: length of user data
2196 */
2197struct request *blk_rq_map_kern(request_queue_t *q, int rw, void *kbuf,
2198 unsigned int len, unsigned int gfp_mask)
2199{
2200 struct request *rq;
2201 struct bio *bio;
2202
2203 if (len > (q->max_sectors << 9))
2204 return ERR_PTR(-EINVAL);
2205 if ((!len && kbuf) || (len && !kbuf))
2206 return ERR_PTR(-EINVAL);
2207
2208 rq = blk_get_request(q, rw, gfp_mask);
2209 if (!rq)
2210 return ERR_PTR(-ENOMEM);
2211
2212 bio = bio_map_kern(q, kbuf, len, gfp_mask);
2213 if (!IS_ERR(bio)) {
2214 if (rw)
2215 bio->bi_rw |= (1 << BIO_RW);
2216 bio->bi_end_io = blk_rq_map_kern_endio;
2217
2218 rq->bio = rq->biotail = bio;
2219 blk_rq_bio_prep(q, rq, bio);
2220
2221 rq->buffer = rq->data = NULL;
2222 rq->data_len = len;
2223 return rq;
2224 }
2225
2226 /*
2227 * bio is the err-ptr
2228 */
2229 blk_put_request(rq);
2230 return (struct request *) bio;
2231}
2232
2233EXPORT_SYMBOL(blk_rq_map_kern);
2234
2179/** 2235/**
2180 * blk_execute_rq - insert a request into queue for execution 2236 * blk_execute_rq - insert a request into queue for execution
2181 * @q: queue to insert the request in 2237 * @q: queue to insert the request in