add blk_rq_map_kern function
Subsystems (4)
RFC PATCH 1/4 add blk_rq_map_kern function
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.
This patch was made against 2.6.12-rc5 but also works against scsi-misc.
drivers/block/ll_rw_blk.c +55 -0
@@ -281,6 +281,7 @@ static inline void rq_init(request_queue rq->special =NULL ; rq->data_len =0 ; rq->data =NULL ; + rq->nr_phys_segments =0 ; rq->sense =NULL ; rq->end_io =NULL ; rq->end_io_data =NULL ;
@@ -2184,6 +2185,60 @@ int blk_rq_unmap_user(struct request *rqEXPORT_SYMBOL (blk_rq_unmap_user); +static int blk_rq_map_kern_endio (struct bio *bio,unsigned int bytes_done, +int error) +{ +if (bio->bi_size) +return 1 ; +bio_put (bio); +return 0 ; +} + +/** +* blk_rq_map_kern - map kernel data to a request, for REQ_BLOCK_PC usage +* @q: request queue where request should be inserted +* @rw: READ or WRITE data +* @kbuf: the kernel buffer +* @len: length of user data +*/ +struct request *blk_rq_map_kern (request_queue_t *q,int rw,void *kbuf, +unsigned int len,unsigned int gfp_mask) +{ +struct request *rq; +struct bio *bio; + +if (len > (q->max_sectors <<9 )) +return ERR_PTR (-EINVAL ); +if ((!len && kbuf) || (len && !kbuf)) +return ERR_PTR (-EINVAL ); + + rq =blk_get_request (q, rw, gfp_mask); +if (!rq) +return ERR_PTR (-ENOMEM ); + + bio =bio_map_kern (q, kbuf, len, gfp_mask); +if (!IS_ERR (bio)) { +if (rw) + bio->bi_rw |= (1 <<BIO_RW ); + bio->bi_end_io = blk_rq_map_kern_endio; + + rq->bio = rq->biotail = bio; +blk_rq_bio_prep (q, rq, bio); + + rq->buffer = rq->data =NULL ; + rq->data_len = len; +return rq; + } + +/* +* bio is the err-ptr +*/ +blk_put_request (rq); +return (struct request *) bio; +} + +EXPORT_SYMBOL (blk_rq_map_kern); +/** * blk_execute_rq - insert a request into queue for execution * @q: queue to insert the request in
fs/bio.c +66 -0
78 lines not on this page · raw message
include/linux/bio.h +2 -0
@@ -282,6 +282,8 @@ extern int bio_get_nr_vecs(struct block_extern struct bio *bio_map_user (struct request_queue *,struct block_device *,unsigned long ,unsigned int ,int );extern void bio_unmap_user (struct bio *); +extern struct bio *bio_map_kern (struct request_queue *,void *,unsigned int , +unsigned int );extern void bio_set_pages_dirty (struct bio *bio);extern void bio_check_pages_dirty (struct bio *bio);extern struct bio *bio_copy_user (struct request_queue *,unsigned long ,unsigned int ,int );
include/linux/blkdev.h +2 -0
@@ -560,6 +560,8 @@ extern void blk_run_queue(request_queue_extern void blk_queue_activity_fn (request_queue_t *,activity_fn *,void *);extern struct request *blk_rq_map_user (request_queue_t *,int ,void __user *,unsigned int );extern int blk_rq_unmap_user (struct request *,struct bio *,unsigned int ); +extern struct request *blk_rq_map_kern (request_queue_t *,int ,void *, +unsigned int ,unsigned int );extern int blk_execute_rq (request_queue_t *,struct gendisk *,struct request *);static inline request_queue_t *bdev_get_queue (struct block_device *bdev)