From f290f1970f01287eaaffc798a677594a57ebd65e Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 8 Feb 2009 21:59:48 -0600 Subject: [SCSI] Make scsi.h independent of the rest of the scsi includes This allows it to compile and be used on the ps3 platform that wants to use the #define values in scsi.h without actually having CONFIG_SCSI set. Signed-off-by: James Bottomley --- block/cmd-filter.c | 1 + 1 file changed, 1 insertion(+) (limited to 'block') diff --git a/block/cmd-filter.c b/block/cmd-filter.c index 504b275e1b9..572bbc2f900 100644 --- a/block/cmd-filter.c +++ b/block/cmd-filter.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3 From f3b144aa7f2861e1024682af3bf3dbf1c29184b9 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 6 Mar 2009 08:48:33 +0100 Subject: block: remove various blk_queue_*() setting functions in blk_init_queue_node() It calls blk_queue_make_request(), which sets the identical set of limits. Signed-off-by: Jens Axboe --- block/blk-core.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'block') diff --git a/block/blk-core.c b/block/blk-core.c index 29bcfac6c68..5e14b3f4510 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -603,13 +603,10 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id) q->queue_flags = QUEUE_FLAG_DEFAULT; q->queue_lock = lock; - blk_queue_segment_boundary(q, BLK_SEG_BOUNDARY_MASK); - + /* + * This also sets hw/phys segments, boundary and size + */ blk_queue_make_request(q, __make_request); - blk_queue_max_segment_size(q, MAX_SEGMENT_SIZE); - - blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS); - blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS); q->sg_reserved_size = INT_MAX; -- cgit v1.2.3 From 50e174931051bf4849cd7931667bb0a4d681ff60 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 6 Mar 2009 11:12:17 +0100 Subject: block: get rid of unused blkdev_free_rq() define Signed-off-by: Jens Axboe --- block/blk-core.c | 1 - 1 file changed, 1 deletion(-) (limited to 'block') diff --git a/block/blk-core.c b/block/blk-core.c index 5e14b3f4510..7b63c9b6333 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -732,7 +732,6 @@ static void freed_request(struct request_queue *q, int rw, int priv) __freed_request(q, rw ^ 1); } -#define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist) /* * Get a free request, queue_lock must be held. * Returns NULL on failure, with queue_lock held. -- cgit v1.2.3 From 05378940caf979a8655c18b18a17213dcfa52412 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Tue, 24 Mar 2009 12:23:40 +0100 Subject: bsg: add support for tail queuing Currently inherited from sg.c bsg will submit asynchronous request at the head-of-the-queue, (using "at_head" set in the call to blk_execute_rq_nowait()). This is bad in situation where the queues are full, requests will execute out of order, and can cause starvation of the first submitted requests. The sg_io_v4->flags member is used and a bit is allocated to denote the Q_AT_TAIL. Zero is to queue at_head as before, to be compatible with old code at the write/read path. SG_IO code path behavior was changed so to be the same as write/read behavior. SG_IO was very rarely used and breaking compatibility with it is OK at this stage. sg_io_hdr at sg.h also has a flags member and uses 3 bits from the first nibble and one bit from the last nibble. Even though none of these bits are supported by bsg, The second nibble is allocated for use by bsg. Just in case. Signed-off-by: Boaz Harrosh CC: Douglas Gilbert Signed-off-by: Jens Axboe --- block/bsg.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'block') diff --git a/block/bsg.c b/block/bsg.c index 0ce8806dd0c..0f63b91d0af 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -353,6 +353,8 @@ static void bsg_rq_end_io(struct request *rq, int uptodate) static void bsg_add_command(struct bsg_device *bd, struct request_queue *q, struct bsg_command *bc, struct request *rq) { + int at_head = (0 == (bc->hdr.flags & BSG_FLAG_Q_AT_TAIL)); + /* * add bc command to busy queue and submit rq for io */ @@ -368,7 +370,7 @@ static void bsg_add_command(struct bsg_device *bd, struct request_queue *q, dprintk("%s: queueing rq %p, bc %p\n", bd->name, rq, bc); rq->end_io_data = bc; - blk_execute_rq_nowait(q, NULL, rq, 1, bsg_rq_end_io); + blk_execute_rq_nowait(q, NULL, rq, at_head, bsg_rq_end_io); } static struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd) @@ -924,6 +926,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) struct request *rq; struct bio *bio, *bidi_bio = NULL; struct sg_io_v4 hdr; + int at_head; u8 sense[SCSI_SENSE_BUFFERSIZE]; if (copy_from_user(&hdr, uarg, sizeof(hdr))) @@ -936,7 +939,9 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) bio = rq->bio; if (rq->next_rq) bidi_bio = rq->next_rq->bio; - blk_execute_rq(bd->queue, NULL, rq, 0); + + at_head = (0 == (hdr.flags & BSG_FLAG_Q_AT_TAIL)); + blk_execute_rq(bd->queue, NULL, rq, at_head); ret = blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio); if (copy_to_user(uarg, &hdr, sizeof(hdr))) -- cgit v1.2.3 From 1cd96c242a829d52f7a5ae98f554ca9775429685 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Tue, 24 Mar 2009 12:35:07 +0100 Subject: block: WARN in __blk_put_request() for potential bio leak Put a WARN_ON in __blk_put_request if it is about to leak bio(s). This is a serious bug that can happen in error handling code paths. For this to work I have fixed a couple of places in block/ where request->bio != NULL ownership was not honored. And a small cleanup at sg_io() while at it. Signed-off-by: Boaz Harrosh Signed-off-by: Jens Axboe --- block/blk-core.c | 3 +++ block/blk-merge.c | 2 ++ block/scsi_ioctl.c | 21 ++++----------------- 3 files changed, 9 insertions(+), 17 deletions(-) (limited to 'block') diff --git a/block/blk-core.c b/block/blk-core.c index 7b63c9b6333..996ed906d8c 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1062,6 +1062,9 @@ void __blk_put_request(struct request_queue *q, struct request *req) elv_completed_request(q, req); + /* this is a bio leak */ + WARN_ON(req->bio != NULL); + /* * Request may not have originated from ll_rw_blk. if not, * it didn't come out of our reserved rq pools diff --git a/block/blk-merge.c b/block/blk-merge.c index 5a244f05360..e39cb24b767 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -403,6 +403,8 @@ static int attempt_merge(struct request_queue *q, struct request *req, if (blk_rq_cpu_valid(next)) req->cpu = next->cpu; + /* owner-ship of bio passed from next to req */ + next->bio = NULL; __blk_put_request(q, next); return 1; } diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index ee9c67d7e1b..626ee274c5c 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -214,21 +214,10 @@ static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, return 0; } -/* - * unmap a request that was previously mapped to this sg_io_hdr. handles - * both sg and non-sg sg_io_hdr. - */ -static int blk_unmap_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr) -{ - blk_rq_unmap_user(rq->bio); - blk_put_request(rq); - return 0; -} - static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, struct bio *bio) { - int r, ret = 0; + int ret = 0; /* * fill in all the output members @@ -253,12 +242,10 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, ret = -EFAULT; } - rq->bio = bio; - r = blk_unmap_sghdr_rq(rq, hdr); - if (ret) - r = ret; + blk_rq_unmap_user(bio); + blk_put_request(rq); - return r; + return ret; } static int sg_io(struct request_queue *q, struct gendisk *bd_disk, -- cgit v1.2.3 From e7cbbf1bf17e3c706f874e867f7b744e1c86fed9 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Tue, 24 Mar 2009 12:37:50 +0100 Subject: bsg: Remove bogus check against request_queue->max_sectors bsg submits REQ_TYPE_BLOCK_PC so the right check is max_hw_sectors. But I've removed this check because right after, bsg proceeds with calling blk_rq_map_user() which does all the right checks. Signed-off-by: Boaz Harrosh Signed-off-by: Jens Axboe --- block/bsg.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'block') diff --git a/block/bsg.c b/block/bsg.c index 0f63b91d0af..206060e795d 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -218,9 +218,6 @@ bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw) if (hdr->guard != 'Q') return -EINVAL; - if (hdr->dout_xfer_len > (q->max_sectors << 9) || - hdr->din_xfer_len > (q->max_sectors << 9)) - return -EIO; switch (hdr->protocol) { case BSG_PROTOCOL_SCSI: -- cgit v1.2.3