mv sg.c features to the block layer
Subsystems (5)
PATCH 1/2 mv sg.c features to the block layer
This patch moves the reserve buffer, large segment allocations, and mmap to the block layer. This patches also converts bsg, tgt, cdrom, and scsi_ioctl.c to the change in the blk_rq_map_user api. A side affect of coverting tgt to the new api, is that I killed the scsi_cmnd->offset field which was supposed to be removed before merging but snuck in. It also kills the tgt bio layer violations.
The mmap code and reserve buffer code is very simple. It should behave and work like sg where we have one command using the reserve buffer at a time. If it does not and will affect users, let me know and I will fix. The bsg and scsi_ioctl code does not use the reserve buffer or mmap code, and that should behave like it did before, except for the copy path we allocated multiple pages at a time so we can get very large IOs.
The patches have been lightly tested. I ran sg utils over a block device. I did not test cdrom, tgt or bsg.
If you guys want me to try and break up the patches to make it easier to review I will. Then I can resend them in a git bisect friendly way.
block/bsg.c +3 -2
@@ -321,7 +321,7 @@ bsg_map_hdr(struct bsg_device *bd, struc dxfer_len =0 ;if (dxfer_len) { - ret =blk_rq_map_user (q, rq, dxferp, dxfer_len); + ret =blk_rq_init_transfer (q, rq, dxferp, dxfer_len);if (ret) {dprintk ("failed map at %d\n" , ret);blk_put_request (rq);
@@ -460,7 +460,8 @@ static int blk_complete_sgv4_hdr_rq(stru ret = -EFAULT ; } -blk_rq_unmap_user (bio); +blk_rq_complete_transfer (rq->q, bio, (void __user *)hdr->din_xferp, + hdr->din_xfer_len);blk_put_request (rq);return ret;
block/ll_rw_blk.c +420 -89
595 lines not on this page · raw message
block/scsi_ioctl.c +2 -2
@@ -244,7 +244,7 @@ EXPORT_SYMBOL_GPL(blk_fill_sghdr_rq);*/ int blk_unmap_sghdr_rq (struct request *rq,struct sg_io_hdr *hdr) { -blk_rq_unmap_user (rq->bio); +blk_rq_complete_transfer (rq->q, rq->bio, hdr->dxferp, hdr->dxfer_len);blk_put_request (rq);return 0 ; }
@@ -348,7 +348,7 @@ static int sg_io(struct file *file, requ hdr->dxfer_len);kfree (iov); }else if (hdr->dxfer_len) - ret =blk_rq_map_user (q, rq, hdr->dxferp, hdr->dxfer_len); + ret =blk_rq_init_transfer (q, rq, hdr->dxferp, hdr->dxfer_len);if (ret) goto out;
drivers/cdrom/cdrom.c +2 -2
@@ -2118,7 +2118,7 @@ static int cdrom_read_cdda_bpc(struct cd len = nr *CD_FRAMESIZE_RAW ; - ret =blk_rq_map_user (q, rq, ubuf, len); + ret =blk_rq_init_transfer (q, rq, ubuf, len);if (ret)break ;
@@ -2145,7 +2145,7 @@ static int cdrom_read_cdda_bpc(struct cd cdi->last_sense = s->sense_key; } -if (blk_rq_unmap_user (bio)) +if (blk_rq_complete_transfer (q, bio, ubuf, len)) ret = -EFAULT ;if (ret)
drivers/scsi/scsi_tgt_lib.c +21 -84
170 lines not on this page · raw message
fs/bio.c +207 -65
367 lines not on this page · raw message
include/linux/bio.h +8 -4
@@ -125,6 +125,7 @@ #define BIO_CLONED 4 /* doesn't own data#define BIO_BOUNCED 5/* bio is a bounce bio */ #define BIO_USER_MAPPED 6/* contains user pages */ #define BIO_EOPNOTSUPP 7/* not supported */ +#define BIO_USED_RESERVE 8/* using reserve buffer */ #define bio_flagged (bio, flag) ((bio)->bi_flags & (1 << (flag)))/*
@@ -298,8 +299,8 @@ extern int bio_add_page(struct bio *, stextern int bio_add_pc_page (struct request_queue *,struct bio *,struct page *,unsigned int ,unsigned int );extern int bio_get_nr_vecs (struct block_device *); -extern struct bio *bio_map_user (struct request_queue *,struct block_device *, -unsigned long ,unsigned int ,int ); +extern struct bio *bio_map_user (struct request_queue *,unsigned long , +unsigned int ,int ,int );struct sg_iovec ; extern struct bio *bio_map_user_iov(struct request_queue *, struct block_device *,
@@ -310,8 +311,11 @@ extern struct bio *bio_map_kern(struct rextern void bio_set_pages_dirty (struct bio *bio);extern void bio_check_pages_dirty (struct bio *bio);extern void bio_release_pages (struct bio *bio); -extern struct bio *bio_copy_user (struct request_queue *,unsigned long ,unsigned int ,int ); -extern int bio_uncopy_user (struct bio *); +extern struct bio *bio_copy_user (struct request_queue *,unsigned long ,unsigned int ,int ,int ); +extern int bio_uncopy_user (struct bio *,void __user *,unsigned long ,int *); +extern unsigned int bio_estimate_max_segment_size (struct request_queue *); +extern struct page *bio_alloc_pages (struct request_queue *,unsigned int , +int *);void zero_fill_bio (struct bio *bio);#ifdef CONFIG_HIGHMEM
include/linux/blkdev.h +26 -2
@@ -359,6 +359,13 @@ struct blk_queue_tag {atomic_t refcnt;/* map can be shared */ }; +struct blk_reserve_buf { +struct scatterlist *sg;/* sg to hold pages */ +unsigned buf_size;/* size of reserve buffer */ +int sg_count;/* number of sg entries in use */ +int sg_index;/* index pf sg in list */ +}; +struct request_queue {/*
@@ -454,6 +461,7 @@ struct request_queue/* * sg stuff */ +struct blk_reserve_buf *reserve_buf;unsigned int sg_timeout;unsigned int sg_reserved_size;int node;
@@ -481,6 +489,7 @@ #define QUEUE_FLAG_DEAD 5 /* queue bein#define QUEUE_FLAG_REENTER 6/* Re-entrancy avoidance */ #define QUEUE_FLAG_PLUGGED 7/* queue is plugged */ #define QUEUE_FLAG_ELVSWITCH 8/* don't use elevator, just do FIFO */ +#define QUEUE_FLAG_RESERVE_USED 9/* sg reserve buffer in use */ enum {/*
@@ -526,6 +535,7 @@ #define blk_queue_plugged(q) test_bit(QU#define blk_queue_tagged (q) test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)#define blk_queue_stopped (q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)#define blk_queue_flushing (q) ((q)->ordseq) +#define blk_queue_reserve_in_use (q) test_bit(QUEUE_FLAG_RESERVE_USED, &(q)->queue_flags)#define blk_fs_request (rq) ((rq)->cmd_type == REQ_TYPE_FS)#define blk_pc_request (rq) ((rq)->cmd_type == REQ_TYPE_BLOCK_PC)
@@ -678,8 +688,22 @@ extern void blk_sync_queue(struct requesextern void __blk_stop_queue (request_queue_t *q);extern void blk_run_queue (request_queue_t *);extern void blk_start_queueing (request_queue_t *); -extern int blk_rq_map_user (request_queue_t *,struct request *,void __user *,unsigned long ); -extern int blk_rq_unmap_user (struct bio *); +extern struct page *blk_rq_vma_nopage (struct request_queue *,struct request *, +struct vm_area_struct *,unsigned long , +int *); +extern int blk_rq_mmap (struct request_queue *,struct request *, +struct vm_area_struct *); +extern int blk_queue_free_reserve_buf (struct request_queue *); +extern int blk_queue_alloc_reserve_buf (struct request_queue *,unsigned long ); +extern struct page *blk_get_reserve_seg (struct request_queue *,unsigned int *); +extern void blk_put_reserve_seg (request_queue_t *); +extern int blk_rq_init_transfer (request_queue_t *,struct request *,void __user *,unsigned long ); +extern int blk_rq_map_user (request_queue_t *,struct request *, +void __user *,unsigned long ,int ); +extern int blk_rq_copy_user (request_queue_t *,struct request *, +void __user *,unsigned long ,int ); +extern int blk_rq_complete_transfer (struct request_queue *,struct bio *, +void __user *,unsigned long );extern int blk_rq_map_kern (request_queue_t *,struct request *,void *,unsigned int ,gfp_t );extern int blk_rq_map_user_iov (request_queue_t *,struct request *,struct sg_iovec *,int ,unsigned int );
include/scsi/scsi_cmnd.h +0 -3
@@ -73,9 +73,6 @@ #define MAX_COMMAND_SIZE 16unsigned short use_sg;/* Number of pieces of scatter-gather */ unsigned short sglist_len;/* size of malloc'd scatter-gather list */ -/* offset in cmd we are at (for multi-transfer tgt cmds) */ -unsigned offset; -unsigned underflow;/* Return error if less than this amount is transferred */
Signature · 1 line
1.4.1.1