* [PATCH v2 00/16] st: remove scsi_execute_async usage (the second half) @ 2008-12-18 5:49 FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 01/16] block: fix bio_add_page misuse with rq_map_data FUJITA Tomonori 2008-12-25 14:51 ` [PATCH v2 00/16] st: remove scsi_execute_async usage (the second half) FUJITA Tomonori 0 siblings, 2 replies; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara; +Cc: James.Bottomley, fujita.tomonori, linux-scsi, jens.axboe This patchset is the second version of the second half patchset to remove scsi_execute_async in st driver (IOW, this converts st driver to use the block layer functions). http://marc.info/?l=linux-scsi&m=122900494917385&w=2 I've not changed the st patches much since the first version. No change to the #4-14 st patches except for cleanups to silence checkpatch.sh. The new #15-16 patches for st came from Kai, who greatly helped me out with this patchset. The #1-3 patches are for the block layer. The first patch is a slightly modified version of the following fix (I modified it for the later changes): http://marc.info/?l=linux-scsi&m=122927795113939&w=2 The second patch is a patch to fix the partial mappings with rq_map_data struct. Kai found this problem (which leads to data corruption). The first and second patches fix the bugs which affect sg. The third patch is the first patch in the previous patchset. It's a necessary change to the block layer to support st/osst. I slightly modified it due to the first and second patches. This is against scsi-misc. ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 01/16] block: fix bio_add_page misuse with rq_map_data 2008-12-18 5:49 [PATCH v2 00/16] st: remove scsi_execute_async usage (the second half) FUJITA Tomonori @ 2008-12-18 5:49 ` FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 02/16] block: fix the partial mappings with struct rq_map_data FUJITA Tomonori 2008-12-25 14:51 ` [PATCH v2 00/16] st: remove scsi_execute_async usage (the second half) FUJITA Tomonori 1 sibling, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara Cc: James.Bottomley, fujita.tomonori, linux-scsi, FUJITA Tomonori, Jens Axboe This fixes bio_add_page misuse in bio_copy_user_iov with rq_map_data, which only sg uses now. rq_map_data carries page frames for bio_add_pc_page. bio_copy_user_iov uses bio_add_pc_page with a larger size than PAGE_SIZE. It's clearly wrong. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: Jens Axboe <jens.axboe@oracle.com> --- fs/bio.c | 26 ++++++++++++++------------ 1 files changed, 14 insertions(+), 12 deletions(-) diff --git a/fs/bio.c b/fs/bio.c index 77a55bc..5fd6e98 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -662,28 +662,30 @@ struct bio *bio_copy_user_iov(struct request_queue *q, ret = 0; i = 0; + if (map_data) + nr_pages = 1 << map_data->page_order; while (len) { - unsigned int bytes; - - if (map_data) - bytes = 1U << (PAGE_SHIFT + map_data->page_order); - else - bytes = PAGE_SIZE; + unsigned int bytes = PAGE_SIZE; if (bytes > len) bytes = len; if (map_data) { - if (i == map_data->nr_entries) { + if (i == map_data->nr_entries * nr_pages) { ret = -ENOMEM; break; } - page = map_data->pages[i++]; - } else + + page = map_data->pages[i / nr_pages]; + page += (i % nr_pages); + + i++; + } else { page = alloc_page(q->bounce_gfp | gfp_mask); - if (!page) { - ret = -ENOMEM; - break; + if (!page) { + ret = -ENOMEM; + break; + } } if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes) -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 02/16] block: fix the partial mappings with struct rq_map_data 2008-12-18 5:49 ` [PATCH 01/16] block: fix bio_add_page misuse with rq_map_data FUJITA Tomonori @ 2008-12-18 5:49 ` FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 03/16] block: make blk_rq_map_user take a NULL user-space buffer for WRITE FUJITA Tomonori 0 siblings, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara Cc: James.Bottomley, fujita.tomonori, linux-scsi, FUJITA Tomonori, Jens Axboe This fixes bio_copy_user_iov to properly handle the partial mappings with struct rq_map_data (which only sg uses for now but st and osst will shortly). It adds the offset member to struct rq_map_data and changes blk_rq_map_user to update it so that bio_copy_user_iov can add an appropriate page frame via bio_add_pc_page(). Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: Jens Axboe <jens.axboe@oracle.com> --- block/blk-map.c | 3 +++ drivers/scsi/sg.c | 1 + fs/bio.c | 12 +++++++++--- include/linux/blkdev.h | 1 + 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/block/blk-map.c b/block/blk-map.c index 0f4b4b8..bc0ca0d 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -150,6 +150,9 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq, bio = rq->bio; bytes_read += ret; ubuf += ret; + + if (map_data) + map_data->offset += ret; } if (!bio_flagged(bio, BIO_USER_MAPPED)) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 5103855..7d0b3d9 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1669,6 +1669,7 @@ static int sg_start_req(Sg_request *srp, unsigned char *cmd) md->pages = req_schp->pages; md->page_order = req_schp->page_order; md->nr_entries = req_schp->k_use_sg; + md->offset = 0; } if (iov_count) diff --git a/fs/bio.c b/fs/bio.c index 5fd6e98..879d4ef 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -635,6 +635,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q, int i, ret; int nr_pages = 0; unsigned int len = 0; + unsigned int offset = map_data ? map_data->offset & ~PAGE_MASK : 0; for (i = 0; i < iov_count; i++) { unsigned long uaddr; @@ -661,12 +662,16 @@ struct bio *bio_copy_user_iov(struct request_queue *q, bio->bi_rw |= (!write_to_vm << BIO_RW); ret = 0; - i = 0; - if (map_data) + + if (map_data) { nr_pages = 1 << map_data->page_order; + i = map_data->offset / PAGE_SIZE; + } while (len) { unsigned int bytes = PAGE_SIZE; + bytes -= offset; + if (bytes > len) bytes = len; @@ -688,10 +693,11 @@ struct bio *bio_copy_user_iov(struct request_queue *q, } } - if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes) + if (bio_add_pc_page(q, bio, page, bytes, offset) < bytes) break; len -= bytes; + offset = 0; } if (ret) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index a135256..3cef38f 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -680,6 +680,7 @@ struct rq_map_data { struct page **pages; int page_order; int nr_entries; + unsigned long offset; }; struct req_iterator { -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 03/16] block: make blk_rq_map_user take a NULL user-space buffer for WRITE 2008-12-18 5:49 ` [PATCH 02/16] block: fix the partial mappings with struct rq_map_data FUJITA Tomonori @ 2008-12-18 5:49 ` FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 04/16] st: make all the fragment buffers the same size FUJITA Tomonori 0 siblings, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara Cc: James.Bottomley, fujita.tomonori, linux-scsi, FUJITA Tomonori, Jens Axboe The commit 818827669d85b84241696ffef2de485db46b0b5e (block: make blk_rq_map_user take a NULL user-space buffer) extended blk_rq_map_user to accept a NULL user-space buffer with a READ command. It was necessary to convert sg to use the block layer mapping API. This patch extends blk_rq_map_user again for a WRITE command. It is necessary to convert st and osst drivers to use the block layer apping API. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: Jens Axboe <jens.axboe@oracle.com> --- block/blk-map.c | 16 +++++++--------- drivers/scsi/sg.c | 1 + fs/bio.c | 2 +- include/linux/blkdev.h | 1 + 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/block/blk-map.c b/block/blk-map.c index bc0ca0d..01bd7ca 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -42,7 +42,7 @@ static int __blk_rq_unmap_user(struct bio *bio) static int __blk_rq_map_user(struct request_queue *q, struct request *rq, struct rq_map_data *map_data, void __user *ubuf, - unsigned int len, int null_mapped, gfp_t gfp_mask) + unsigned int len, gfp_t gfp_mask) { unsigned long uaddr; struct bio *bio, *orig_bio; @@ -63,7 +63,7 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq, if (IS_ERR(bio)) return PTR_ERR(bio); - if (null_mapped) + if (map_data && map_data->null_mapped) bio->bi_flags |= (1 << BIO_NULL_MAPPED); orig_bio = bio; @@ -114,17 +114,15 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq, { unsigned long bytes_read = 0; struct bio *bio = NULL; - int ret, null_mapped = 0; + int ret; if (len > (q->max_hw_sectors << 9)) return -EINVAL; if (!len) return -EINVAL; - if (!ubuf) { - if (!map_data || rq_data_dir(rq) != READ) - return -EINVAL; - null_mapped = 1; - } + + if (!ubuf && (!map_data || !map_data->null_mapped)) + return -EINVAL; while (bytes_read != len) { unsigned long map_len, end, start; @@ -143,7 +141,7 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq, map_len -= PAGE_SIZE; ret = __blk_rq_map_user(q, rq, map_data, ubuf, map_len, - null_mapped, gfp_mask); + gfp_mask); if (ret < 0) goto unmap_rq; if (!bio) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 7d0b3d9..8f0bd3f 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1670,6 +1670,7 @@ static int sg_start_req(Sg_request *srp, unsigned char *cmd) md->page_order = req_schp->page_order; md->nr_entries = req_schp->k_use_sg; md->offset = 0; + md->null_mapped = hp->dxferp ? 0 : 1; } if (iov_count) diff --git a/fs/bio.c b/fs/bio.c index 879d4ef..a5fb24d 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -706,7 +706,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q, /* * success */ - if (!write_to_vm) { + if (!write_to_vm && (!map_data || !map_data->null_mapped)) { ret = __bio_copy_iov(bio, bio->bi_io_vec, iov, iov_count, 0, 0); if (ret) goto cleanup; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 3cef38f..f11c3d0 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -681,6 +681,7 @@ struct rq_map_data { int page_order; int nr_entries; unsigned long offset; + int null_mapped; }; struct req_iterator { -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 04/16] st: make all the fragment buffers the same size 2008-12-18 5:49 ` [PATCH 03/16] block: make blk_rq_map_user take a NULL user-space buffer for WRITE FUJITA Tomonori @ 2008-12-18 5:49 ` FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 05/16] st: add struct rq_map_data support FUJITA Tomonori 0 siblings, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara Cc: James.Bottomley, fujita.tomonori, linux-scsi, FUJITA Tomonori This patch simiplifies the fragment buffer management a bit, all the buffers in the fragment list become the same size. This is necessary to use the block layer API (sg driver was modified in the same way) since the block layer API takes the same size page frames instead of scatter gatter. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> --- drivers/scsi/st.c | 18 +++++++++--------- 1 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 7f3f317..3984cd8 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3747,20 +3747,20 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm priority = GFP_KERNEL | __GFP_NOWARN; if (need_dma) priority |= GFP_DMA; - for (b_size = PAGE_SIZE, order=0; order <= 6 && - b_size < new_size - STbuffer->buffer_size; - order++, b_size *= 2) - ; /* empty */ + + if (STbuffer->frp_segs) { + b_size = STbuffer->frp[0].length; + order = get_order(b_size); + } else { + for (b_size = PAGE_SIZE, order = 0; + order <= 6 && b_size < new_size; order++, b_size *= 2) + ; /* empty */ + } for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size; segs < max_segs && got < new_size;) { STbuffer->frp[segs].page = alloc_pages(priority, order); if (STbuffer->frp[segs].page == NULL) { - if (new_size - got <= (max_segs - segs) * b_size / 2) { - b_size /= 2; /* Large enough for the rest of the buffers */ - order--; - continue; - } DEB(STbuffer->buffer_size = got); normalize_buffer(STbuffer); return 0; -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 05/16] st: add struct rq_map_data support 2008-12-18 5:49 ` [PATCH 04/16] st: make all the fragment buffers the same size FUJITA Tomonori @ 2008-12-18 5:49 ` FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 06/16] st: add st_scsi_execute helper function FUJITA Tomonori 0 siblings, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara Cc: James.Bottomley, fujita.tomonori, linux-scsi, FUJITA Tomonori This adds struct rq_map_data and the array of pointers to store fragment buffers to struct st_buffer. This patch doesn't remove st_buf_fragment but the latter patch does. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> --- drivers/scsi/st.c | 11 +++++++++++ drivers/scsi/st.h | 2 ++ 2 files changed, 13 insertions(+), 0 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 3984cd8..9d9e4b9 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3723,6 +3723,12 @@ static struct st_buffer * tb->buffer_size = got; sg_init_table(tb->sg, max_sg); + tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *), priority); + if (!tb->reserved_pages) { + kfree(tb); + return NULL; + } + return tb; } @@ -3771,9 +3777,11 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm STbuffer->buffer_size = got; if (STbuffer->cleared) memset(page_address(STbuffer->frp[segs].page), 0, b_size); + STbuffer->reserved_pages[segs] = STbuffer->frp[segs].page; segs++; } STbuffer->b_data = page_address(STbuffer->frp[0].page); + STbuffer->map_data.page_order = order; return 1; } @@ -3803,6 +3811,8 @@ static void normalize_buffer(struct st_buffer * STbuffer) STbuffer->frp_segs = STbuffer->orig_frp_segs; STbuffer->frp_sg_current = 0; STbuffer->sg_segs = 0; + STbuffer->map_data.page_order = 0; + STbuffer->map_data.offset = 0; } @@ -4282,6 +4292,7 @@ static void scsi_tape_release(struct kref *kref) if (tpnt->buffer) { tpnt->buffer->orig_frp_segs = 0; normalize_buffer(tpnt->buffer); + kfree(tpnt->buffer->reserved_pages); kfree(tpnt->buffer); } diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index b92712f..74748ab 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -44,6 +44,8 @@ struct st_buffer { int syscall_result; struct st_request *last_SRpnt; struct st_cmdstatus cmdstat; + struct page **reserved_pages; + struct rq_map_data map_data; unsigned char *b_data; unsigned short use_sg; /* zero or max number of s/g segments for this adapter */ unsigned short sg_segs; /* number of segments in s/g list */ -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 06/16] st: add st_scsi_execute helper function 2008-12-18 5:49 ` [PATCH 05/16] st: add struct rq_map_data support FUJITA Tomonori @ 2008-12-18 5:49 ` FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 07/16] st: convert non-dio path to use st_scsi_execute FUJITA Tomonori 0 siblings, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara Cc: James.Bottomley, fujita.tomonori, linux-scsi, FUJITA Tomonori st_scsi_execute is a helper function to perform SCSI commands involving data transfer between user and kernel space (st_read and st_write). It's the future plan to combine this with st_scsi_kern_execute helper function. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> --- drivers/scsi/st.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/scsi/st.h | 1 + 2 files changed, 55 insertions(+), 0 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 9d9e4b9..084a967 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -475,6 +475,60 @@ static void st_release_request(struct st_request *streq) kfree(streq); } +static void st_scsi_execute_end(struct request *req, int uptodate) +{ + struct st_request *SRpnt = req->end_io_data; + struct scsi_tape *STp = SRpnt->stp; + + STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors; + STp->buffer->cmdstat.residual = req->data_len; + + if (SRpnt->waiting) + complete(SRpnt->waiting); + + blk_rq_unmap_user(SRpnt->bio); + __blk_put_request(req->q, req); +} + +static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd, + int data_direction, void *buffer, unsigned bufflen, + int timeout, int retries) +{ + struct request *req; + struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data; + int err = 0; + int write = (data_direction == DMA_TO_DEVICE); + + req = blk_get_request(SRpnt->stp->device->request_queue, write, + GFP_KERNEL); + if (!req) + return DRIVER_ERROR << 24; + + req->cmd_type = REQ_TYPE_BLOCK_PC; + req->cmd_flags |= REQ_QUIET; + + mdata->null_mapped = 1; + + err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL); + if (err) { + blk_put_request(req); + return DRIVER_ERROR << 24; + } + + SRpnt->bio = req->bio; + req->cmd_len = COMMAND_SIZE(cmd[0]); + memset(req->cmd, 0, BLK_MAX_CDB); + memcpy(req->cmd, cmd, req->cmd_len); + req->sense = SRpnt->sense; + req->sense_len = 0; + req->timeout = timeout; + req->retries = retries; + req->end_io_data = SRpnt; + + blk_execute_rq_nowait(req->q, NULL, req, 1, st_scsi_execute_end); + return 0; +} + /* Do the scsi command. Waits until command performed if do_wait is true. Otherwise write_behind_check() is used to check that the command has finished. */ diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 74748ab..77302fa 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -29,6 +29,7 @@ struct st_request { int result; struct scsi_tape *stp; struct completion *waiting; + struct bio *bio; }; /* The tape buffer descriptor. */ -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 07/16] st: convert non-dio path to use st_scsi_execute 2008-12-18 5:49 ` [PATCH 06/16] st: add st_scsi_execute helper function FUJITA Tomonori @ 2008-12-18 5:49 ` FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 08/16] st: convert dio " FUJITA Tomonori 0 siblings, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara Cc: James.Bottomley, fujita.tomonori, linux-scsi, FUJITA Tomonori This patch converts the non-dio path (fragment buffer path) to use st_scsi_execute. IOW, it removes scsi_execute_async in the non-dio path. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> --- drivers/scsi/st.c | 27 +++++++++++++++++++++------ 1 files changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 084a967..390689d 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -537,6 +537,8 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd int bytes, int direction, int timeout, int retries, int do_wait) { struct completion *waiting; + struct rq_map_data *mdata = &STp->buffer->map_data; + int ret; /* if async, make sure there's no command outstanding */ if (!do_wait && ((STp->buffer)->last_SRpnt)) { @@ -564,21 +566,34 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd init_completion(waiting); SRpnt->waiting = waiting; - if (!STp->buffer->do_dio) + if (!STp->buffer->do_dio) { buf_to_sg(STp->buffer, bytes); + mdata->nr_entries = + DIV_ROUND_UP(bytes, PAGE_SIZE << mdata->page_order); + STp->buffer->map_data.pages = STp->buffer->reserved_pages; + STp->buffer->map_data.offset = 0; + } + memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd)); STp->buffer->cmdstat.have_sense = 0; STp->buffer->syscall_result = 0; - if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction, - &((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs, - timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) { + if (STp->buffer->do_dio) + ret = scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), + direction, &((STp->buffer)->sg[0]), + bytes, (STp->buffer)->sg_segs, timeout, + retries, SRpnt, st_sleep_done, + GFP_KERNEL); + else + ret = st_scsi_execute(SRpnt, cmd, direction, NULL, bytes, + timeout, retries); + + if (ret) { /* could not allocate the buffer or request was too large */ (STp->buffer)->syscall_result = (-EBUSY); (STp->buffer)->last_SRpnt = NULL; - } - else if (do_wait) { + } else if (do_wait) { wait_for_completion(waiting); SRpnt->waiting = NULL; (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt); -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 08/16] st: convert dio path to use st_scsi_execute 2008-12-18 5:49 ` [PATCH 07/16] st: convert non-dio path to use st_scsi_execute FUJITA Tomonori @ 2008-12-18 5:49 ` FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 09/16] st: remove buf_to_sg FUJITA Tomonori 0 siblings, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara Cc: James.Bottomley, fujita.tomonori, linux-scsi, FUJITA Tomonori This patch converts the dio path (mmap) to use st_scsi_execute. IOW, it removes scsi_execute_async in the non dio path. scsi_execute_async has gone! This also remove unused st_sleep_done. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> --- drivers/scsi/st.c | 76 ++++++++++++++++------------------------------------- drivers/scsi/st.h | 1 + 2 files changed, 24 insertions(+), 53 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 390689d..fec5568 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -191,9 +191,9 @@ static int from_buffer(struct st_buffer *, char __user *, int); static void move_buffer_data(struct st_buffer *, int); static void buf_to_sg(struct st_buffer *, unsigned int); -static int sgl_map_user_pages(struct scatterlist *, const unsigned int, +static int sgl_map_user_pages(struct st_buffer *, const unsigned int, unsigned long, size_t, int); -static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int); +static int sgl_unmap_user_pages(struct st_buffer *, const unsigned int, int); static int st_probe(struct device *); static int st_remove(struct device *); @@ -435,22 +435,6 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt) return (-EIO); } - -/* Wakeup from interrupt */ -static void st_sleep_done(void *data, char *sense, int result, int resid) -{ - struct st_request *SRpnt = data; - struct scsi_tape *STp = SRpnt->stp; - - memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE); - (STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result; - (STp->buffer)->cmdstat.residual = resid; - DEB( STp->write_pending = 0; ) - - if (SRpnt->waiting) - complete(SRpnt->waiting); -} - static struct st_request *st_allocate_request(struct scsi_tape *stp) { struct st_request *streq; @@ -566,7 +550,10 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd init_completion(waiting); SRpnt->waiting = waiting; - if (!STp->buffer->do_dio) { + if (STp->buffer->do_dio) { + mdata->nr_entries = STp->buffer->sg_segs; + mdata->pages = STp->buffer->mapped_pages; + } else { buf_to_sg(STp->buffer, bytes); mdata->nr_entries = @@ -579,16 +566,8 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd STp->buffer->cmdstat.have_sense = 0; STp->buffer->syscall_result = 0; - if (STp->buffer->do_dio) - ret = scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), - direction, &((STp->buffer)->sg[0]), - bytes, (STp->buffer)->sg_segs, timeout, - retries, SRpnt, st_sleep_done, - GFP_KERNEL); - else - ret = st_scsi_execute(SRpnt, cmd, direction, NULL, bytes, - timeout, retries); - + ret = st_scsi_execute(SRpnt, cmd, direction, NULL, bytes, timeout, + retries); if (ret) { /* could not allocate the buffer or request was too large */ (STp->buffer)->syscall_result = (-EBUSY); @@ -1540,8 +1519,8 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf, if (i && ((unsigned long)buf & queue_dma_alignment( STp->device->request_queue)) == 0) { - i = sgl_map_user_pages(&(STbp->sg[0]), STbp->use_sg, - (unsigned long)buf, count, (is_read ? READ : WRITE)); + i = sgl_map_user_pages(STbp, STbp->use_sg, (unsigned long)buf, + count, (is_read ? READ : WRITE)); if (i > 0) { STbp->do_dio = i; STbp->buffer_bytes = 0; /* can be used as transfer counter */ @@ -1595,7 +1574,7 @@ static void release_buffering(struct scsi_tape *STp, int is_read) STbp = STp->buffer; if (STbp->do_dio) { - sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, is_read); + sgl_unmap_user_pages(STbp, STbp->do_dio, is_read); STbp->do_dio = 0; STbp->sg_segs = 0; } @@ -4647,14 +4626,16 @@ out: } /* The following functions may be useful for a larger audience. */ -static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, - unsigned long uaddr, size_t count, int rw) +static int sgl_map_user_pages(struct st_buffer *STbp, + const unsigned int max_pages, unsigned long uaddr, + size_t count, int rw) { unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT; unsigned long start = uaddr >> PAGE_SHIFT; const int nr_pages = end - start; int res, i, j; struct page **pages; + struct rq_map_data *mdata = &STbp->map_data; /* User attempted Overflow! */ if ((uaddr + count) < uaddr) @@ -4696,24 +4677,11 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa flush_dcache_page(pages[i]); } - /* Populate the scatter/gather list */ - sg_set_page(&sgl[0], pages[0], 0, uaddr & ~PAGE_MASK); - if (nr_pages > 1) { - sgl[0].length = PAGE_SIZE - sgl[0].offset; - count -= sgl[0].length; - for (i=1; i < nr_pages ; i++) { - sg_set_page(&sgl[i], pages[i], - count < PAGE_SIZE ? count : PAGE_SIZE, 0);; - count -= PAGE_SIZE; - } - } - else { - sgl[0].length = count; - } + mdata->offset = uaddr & ~PAGE_MASK; + mdata->page_order = 0; + STbp->mapped_pages = pages; - kfree(pages); return nr_pages; - out_unmap: if (res > 0) { for (j=0; j < res; j++) @@ -4726,13 +4694,13 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa /* And unmap them... */ -static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages, - int dirtied) +static int sgl_unmap_user_pages(struct st_buffer *STbp, + const unsigned int nr_pages, int dirtied) { int i; for (i=0; i < nr_pages; i++) { - struct page *page = sg_page(&sgl[i]); + struct page *page = STbp->mapped_pages[i]; if (dirtied) SetPageDirty(page); @@ -4741,6 +4709,8 @@ static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_p */ page_cache_release(page); } + kfree(STbp->mapped_pages); + STbp->mapped_pages = NULL; return 0; } diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 77302fa..d80926f 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -46,6 +46,7 @@ struct st_buffer { struct st_request *last_SRpnt; struct st_cmdstatus cmdstat; struct page **reserved_pages; + struct page **mapped_pages; struct rq_map_data map_data; unsigned char *b_data; unsigned short use_sg; /* zero or max number of s/g segments for this adapter */ -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 09/16] st: remove buf_to_sg 2008-12-18 5:49 ` [PATCH 08/16] st: convert dio " FUJITA Tomonori @ 2008-12-18 5:49 ` FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 10/16] st: kill struct st_buff_fragment FUJITA Tomonori 0 siblings, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara Cc: James.Bottomley, fujita.tomonori, linux-scsi, FUJITA Tomonori This removes unused buf_to_sg() that the non-dio path used. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> --- drivers/scsi/st.c | 29 ----------------------------- 1 files changed, 0 insertions(+), 29 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index fec5568..ce1fd3a 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -189,7 +189,6 @@ static void normalize_buffer(struct st_buffer *); static int append_to_buffer(const char __user *, struct st_buffer *, int); static int from_buffer(struct st_buffer *, char __user *, int); static void move_buffer_data(struct st_buffer *, int); -static void buf_to_sg(struct st_buffer *, unsigned int); static int sgl_map_user_pages(struct st_buffer *, const unsigned int, unsigned long, size_t, int); @@ -554,8 +553,6 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd mdata->nr_entries = STp->buffer->sg_segs; mdata->pages = STp->buffer->mapped_pages; } else { - buf_to_sg(STp->buffer, bytes); - mdata->nr_entries = DIV_ROUND_UP(bytes, PAGE_SIZE << mdata->page_order); STp->buffer->map_data.pages = STp->buffer->reserved_pages; @@ -3964,32 +3961,6 @@ static void move_buffer_data(struct st_buffer * st_bp, int offset) } } - -/* Fill the s/g list up to the length required for this transfer */ -static void buf_to_sg(struct st_buffer *STbp, unsigned int length) -{ - int i; - unsigned int count; - struct scatterlist *sg; - struct st_buf_fragment *frp; - - if (length == STbp->frp_sg_current) - return; /* work already done */ - - sg = &(STbp->sg[0]); - frp = STbp->frp; - for (i=count=0; count < length; i++) { - if (length - count > frp[i].length) - sg_set_page(&sg[i], frp[i].page, frp[i].length, 0); - else - sg_set_page(&sg[i], frp[i].page, length - count, 0); - count += sg[i].length; - } - STbp->sg_segs = i; - STbp->frp_sg_current = length; -} - - /* Validate the options from command line or module parameters */ static void validate_options(void) { -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 10/16] st: kill struct st_buff_fragment 2008-12-18 5:49 ` [PATCH 09/16] st: remove buf_to_sg FUJITA Tomonori @ 2008-12-18 5:49 ` FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 11/16] st: remove struct scatterlist FUJITA Tomonori 0 siblings, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara Cc: James.Bottomley, fujita.tomonori, linux-scsi, FUJITA Tomonori This removes struct st_buff_fragment and use reserved_pages array to store fragment buffer. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> --- drivers/scsi/st.c | 78 +++++++++++++++++++++++++++++----------------------- drivers/scsi/st.h | 7 ----- 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index ce1fd3a..1cfd217 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3753,8 +3753,9 @@ static struct st_buffer * else priority = GFP_KERNEL; - i = sizeof(struct st_buffer) + (max_sg - 1) * sizeof(struct scatterlist) + - max_sg * sizeof(struct st_buf_fragment); + i = sizeof(struct st_buffer) + + (max_sg - 1) * sizeof(struct scatterlist); + tb = kzalloc(i, priority); if (!tb) { printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n"); @@ -3762,7 +3763,6 @@ static struct st_buffer * } tb->frp_segs = tb->orig_frp_segs = 0; tb->use_sg = max_sg; - tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg); tb->dma = need_dma; tb->buffer_size = got; @@ -3799,9 +3799,12 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm if (need_dma) priority |= GFP_DMA; + if (STbuffer->cleared) + priority |= __GFP_ZERO; + if (STbuffer->frp_segs) { - b_size = STbuffer->frp[0].length; - order = get_order(b_size); + order = STbuffer->map_data.page_order; + b_size = PAGE_SIZE << order; } else { for (b_size = PAGE_SIZE, order = 0; order <= 6 && b_size < new_size; order++, b_size *= 2) @@ -3810,22 +3813,22 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size; segs < max_segs && got < new_size;) { - STbuffer->frp[segs].page = alloc_pages(priority, order); - if (STbuffer->frp[segs].page == NULL) { + struct page *page; + + page = alloc_pages(priority, order); + if (!page) { DEB(STbuffer->buffer_size = got); normalize_buffer(STbuffer); return 0; } - STbuffer->frp[segs].length = b_size; + STbuffer->frp_segs += 1; got += b_size; STbuffer->buffer_size = got; - if (STbuffer->cleared) - memset(page_address(STbuffer->frp[segs].page), 0, b_size); - STbuffer->reserved_pages[segs] = STbuffer->frp[segs].page; + STbuffer->reserved_pages[segs] = page; segs++; } - STbuffer->b_data = page_address(STbuffer->frp[0].page); + STbuffer->b_data = page_address(STbuffer->reserved_pages[0]); STbuffer->map_data.page_order = order; return 1; @@ -3838,7 +3841,8 @@ static void clear_buffer(struct st_buffer * st_bp) int i; for (i=0; i < st_bp->frp_segs; i++) - memset(page_address(st_bp->frp[i].page), 0, st_bp->frp[i].length); + memset(page_address(st_bp->reserved_pages[i]), 0, + PAGE_SIZE << st_bp->map_data.page_order); st_bp->cleared = 1; } @@ -3846,12 +3850,11 @@ static void clear_buffer(struct st_buffer * st_bp) /* Release the extra buffer */ static void normalize_buffer(struct st_buffer * STbuffer) { - int i, order; + int i, order = STbuffer->map_data.page_order; for (i = STbuffer->orig_frp_segs; i < STbuffer->frp_segs; i++) { - order = get_order(STbuffer->frp[i].length); - __free_pages(STbuffer->frp[i].page, order); - STbuffer->buffer_size -= STbuffer->frp[i].length; + __free_pages(STbuffer->reserved_pages[i], order); + STbuffer->buffer_size -= (PAGE_SIZE << order); } STbuffer->frp_segs = STbuffer->orig_frp_segs; STbuffer->frp_sg_current = 0; @@ -3866,18 +3869,19 @@ static void normalize_buffer(struct st_buffer * STbuffer) static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count) { int i, cnt, res, offset; + int length = PAGE_SIZE << st_bp->map_data.page_order; for (i = 0, offset = st_bp->buffer_bytes; - i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++) - offset -= st_bp->frp[i].length; + i < st_bp->frp_segs && offset >= length; i++) + offset -= length; if (i == st_bp->frp_segs) { /* Should never happen */ printk(KERN_WARNING "st: append_to_buffer offset overflow.\n"); return (-EIO); } for (; i < st_bp->frp_segs && do_count > 0; i++) { - cnt = st_bp->frp[i].length - offset < do_count ? - st_bp->frp[i].length - offset : do_count; - res = copy_from_user(page_address(st_bp->frp[i].page) + offset, ubp, cnt); + struct page *page = st_bp->reserved_pages[i]; + cnt = length - offset < do_count ? length - offset : do_count; + res = copy_from_user(page_address(page) + offset, ubp, cnt); if (res) return (-EFAULT); do_count -= cnt; @@ -3897,18 +3901,19 @@ static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, in static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count) { int i, cnt, res, offset; + int length = PAGE_SIZE << st_bp->map_data.page_order; for (i = 0, offset = st_bp->read_pointer; - i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++) - offset -= st_bp->frp[i].length; + i < st_bp->frp_segs && offset >= length; i++) + offset -= length; if (i == st_bp->frp_segs) { /* Should never happen */ printk(KERN_WARNING "st: from_buffer offset overflow.\n"); return (-EIO); } for (; i < st_bp->frp_segs && do_count > 0; i++) { - cnt = st_bp->frp[i].length - offset < do_count ? - st_bp->frp[i].length - offset : do_count; - res = copy_to_user(ubp, page_address(st_bp->frp[i].page) + offset, cnt); + struct page *page = st_bp->reserved_pages[i]; + cnt = length - offset < do_count ? length - offset : do_count; + res = copy_to_user(ubp, page_address(page) + offset, cnt); if (res) return (-EFAULT); do_count -= cnt; @@ -3929,6 +3934,7 @@ static void move_buffer_data(struct st_buffer * st_bp, int offset) { int src_seg, dst_seg, src_offset = 0, dst_offset; int count, total; + int length = PAGE_SIZE << st_bp->map_data.page_order; if (offset == 0) return; @@ -3936,24 +3942,26 @@ static void move_buffer_data(struct st_buffer * st_bp, int offset) total=st_bp->buffer_bytes - offset; for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) { src_offset = offset; - if (src_offset < st_bp->frp[src_seg].length) + if (src_offset < length) break; - offset -= st_bp->frp[src_seg].length; + offset -= length; } st_bp->buffer_bytes = st_bp->read_pointer = total; for (dst_seg=dst_offset=0; total > 0; ) { - count = min(st_bp->frp[dst_seg].length - dst_offset, - st_bp->frp[src_seg].length - src_offset); - memmove(page_address(st_bp->frp[dst_seg].page) + dst_offset, - page_address(st_bp->frp[src_seg].page) + src_offset, count); + struct page *dpage = st_bp->reserved_pages[dst_seg]; + struct page *spage = st_bp->reserved_pages[src_seg]; + + count = min(length - dst_offset, length - src_offset); + memmove(page_address(dpage) + dst_offset, + page_address(spage) + src_offset, count); src_offset += count; - if (src_offset >= st_bp->frp[src_seg].length) { + if (src_offset >= length) { src_seg++; src_offset = 0; } dst_offset += count; - if (dst_offset >= st_bp->frp[dst_seg].length) { + if (dst_offset >= length) { dst_seg++; dst_offset = 0; } diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index d80926f..cc46f18 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -54,16 +54,9 @@ struct st_buffer { unsigned short orig_frp_segs; /* number of segments allocated at first try */ unsigned short frp_segs; /* number of buffer segments */ unsigned int frp_sg_current; /* driver buffer length currently in s/g list */ - struct st_buf_fragment *frp; /* the allocated buffer fragment list */ struct scatterlist sg[1]; /* MUST BE last item */ }; -/* The tape buffer fragment descriptor */ -struct st_buf_fragment { - struct page *page; - unsigned int length; -}; - /* The tape mode definition */ struct st_modedef { unsigned char defined; -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 11/16] st: remove struct scatterlist 2008-12-18 5:49 ` [PATCH 10/16] st: kill struct st_buff_fragment FUJITA Tomonori @ 2008-12-18 5:49 ` FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 12/16] st: simplify new_tape_buffer FUJITA Tomonori 0 siblings, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara Cc: James.Bottomley, fujita.tomonori, linux-scsi, FUJITA Tomonori This removes the usage of struct scatterlist completely. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> --- drivers/scsi/st.c | 8 ++------ drivers/scsi/st.h | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 1cfd217..f934016 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3744,7 +3744,7 @@ static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a static struct st_buffer * new_tape_buffer(int from_initialization, int need_dma, int max_sg) { - int i, got = 0; + int got = 0; gfp_t priority; struct st_buffer *tb; @@ -3753,10 +3753,7 @@ static struct st_buffer * else priority = GFP_KERNEL; - i = sizeof(struct st_buffer) + - (max_sg - 1) * sizeof(struct scatterlist); - - tb = kzalloc(i, priority); + tb = kzalloc(sizeof(struct st_buffer), priority); if (!tb) { printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n"); return NULL; @@ -3766,7 +3763,6 @@ static struct st_buffer * tb->dma = need_dma; tb->buffer_size = got; - sg_init_table(tb->sg, max_sg); tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *), priority); if (!tb->reserved_pages) { diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index cc46f18..d297607 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -54,7 +54,6 @@ struct st_buffer { unsigned short orig_frp_segs; /* number of segments allocated at first try */ unsigned short frp_segs; /* number of buffer segments */ unsigned int frp_sg_current; /* driver buffer length currently in s/g list */ - struct scatterlist sg[1]; /* MUST BE last item */ }; /* The tape mode definition */ -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 12/16] st: simplify new_tape_buffer 2008-12-18 5:49 ` [PATCH 11/16] st: remove struct scatterlist FUJITA Tomonori @ 2008-12-18 5:49 ` FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 13/16] st: remove unused orig_frp_segs FUJITA Tomonori 0 siblings, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara Cc: James.Bottomley, fujita.tomonori, linux-scsi, FUJITA Tomonori - remove the from_initialization argument, which is always 1. We always need to use GFP_ATOMIC. - 'got' valuable is initialized to zero and doesn't change. We don't need it. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> --- drivers/scsi/st.c | 21 ++++++--------------- 1 files changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index f934016..22ddca8 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -182,7 +182,6 @@ static struct scsi_tape **scsi_tapes = NULL; static int modes_defined; -static struct st_buffer *new_tape_buffer(int, int, int); static int enlarge_buffer(struct st_buffer *, int, int); static void clear_buffer(struct st_buffer *); static void normalize_buffer(struct st_buffer *); @@ -3741,30 +3740,22 @@ static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a /* Try to allocate a new tape buffer. Calling function must not hold dev_arr_lock. */ -static struct st_buffer * - new_tape_buffer(int from_initialization, int need_dma, int max_sg) +static struct st_buffer *new_tape_buffer(int need_dma, int max_sg) { - int got = 0; - gfp_t priority; struct st_buffer *tb; - if (from_initialization) - priority = GFP_ATOMIC; - else - priority = GFP_KERNEL; - - tb = kzalloc(sizeof(struct st_buffer), priority); + tb = kzalloc(sizeof(struct st_buffer), GFP_ATOMIC); if (!tb) { printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n"); return NULL; } tb->frp_segs = tb->orig_frp_segs = 0; tb->use_sg = max_sg; - tb->dma = need_dma; - tb->buffer_size = got; + tb->buffer_size = 0; - tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *), priority); + tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *), + GFP_ATOMIC); if (!tb->reserved_pages) { kfree(tb); return NULL; @@ -4059,7 +4050,7 @@ static int st_probe(struct device *dev) SDp->request_queue->max_phys_segments); if (st_max_sg_segs < i) i = st_max_sg_segs; - buffer = new_tape_buffer(1, (SDp->host)->unchecked_isa_dma, i); + buffer = new_tape_buffer((SDp->host)->unchecked_isa_dma, i); if (buffer == NULL) { printk(KERN_ERR "st: Can't allocate new tape buffer. Device not attached.\n"); -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 13/16] st: remove unused orig_frp_segs 2008-12-18 5:49 ` [PATCH 12/16] st: simplify new_tape_buffer FUJITA Tomonori @ 2008-12-18 5:49 ` FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 14/16] st: remove unused frp_sg_current FUJITA Tomonori 0 siblings, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara Cc: James.Bottomley, fujita.tomonori, linux-scsi, FUJITA Tomonori orig_frp_segs in struct st_buffer is always zero. We don't need it. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> --- drivers/scsi/st.c | 7 +++---- drivers/scsi/st.h | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 22ddca8..50dbe14 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3749,7 +3749,7 @@ static struct st_buffer *new_tape_buffer(int need_dma, int max_sg) printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n"); return NULL; } - tb->frp_segs = tb->orig_frp_segs = 0; + tb->frp_segs = 0; tb->use_sg = max_sg; tb->dma = need_dma; tb->buffer_size = 0; @@ -3839,11 +3839,11 @@ static void normalize_buffer(struct st_buffer * STbuffer) { int i, order = STbuffer->map_data.page_order; - for (i = STbuffer->orig_frp_segs; i < STbuffer->frp_segs; i++) { + for (i = 0; i < STbuffer->frp_segs; i++) { __free_pages(STbuffer->reserved_pages[i], order); STbuffer->buffer_size -= (PAGE_SIZE << order); } - STbuffer->frp_segs = STbuffer->orig_frp_segs; + STbuffer->frp_segs = 0; STbuffer->frp_sg_current = 0; STbuffer->sg_segs = 0; STbuffer->map_data.page_order = 0; @@ -4304,7 +4304,6 @@ static void scsi_tape_release(struct kref *kref) tpnt->device = NULL; if (tpnt->buffer) { - tpnt->buffer->orig_frp_segs = 0; normalize_buffer(tpnt->buffer); kfree(tpnt->buffer->reserved_pages); kfree(tpnt->buffer); diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index d297607..e682f80 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -51,7 +51,6 @@ struct st_buffer { unsigned char *b_data; unsigned short use_sg; /* zero or max number of s/g segments for this adapter */ unsigned short sg_segs; /* number of segments in s/g list */ - unsigned short orig_frp_segs; /* number of segments allocated at first try */ unsigned short frp_segs; /* number of buffer segments */ unsigned int frp_sg_current; /* driver buffer length currently in s/g list */ }; -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 14/16] st: remove unused frp_sg_current 2008-12-18 5:49 ` [PATCH 13/16] st: remove unused orig_frp_segs FUJITA Tomonori @ 2008-12-18 5:49 ` FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 15/16] st: integrate st_scsi_kern_execute and st_do_scsi FUJITA Tomonori 0 siblings, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara Cc: James.Bottomley, fujita.tomonori, linux-scsi, FUJITA Tomonori frp_sg_current in struct st_buffer is always zero. We don't need it. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> --- drivers/scsi/st.c | 2 -- drivers/scsi/st.h | 1 - 2 files changed, 0 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 50dbe14..fe4c202 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -1524,7 +1524,6 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf, else STbp->do_dio = 0; /* fall back to buffering with any error */ STbp->sg_segs = STbp->do_dio; - STbp->frp_sg_current = 0; DEB( if (STbp->do_dio) { STp->nbr_dio++; @@ -3844,7 +3843,6 @@ static void normalize_buffer(struct st_buffer * STbuffer) STbuffer->buffer_size -= (PAGE_SIZE << order); } STbuffer->frp_segs = 0; - STbuffer->frp_sg_current = 0; STbuffer->sg_segs = 0; STbuffer->map_data.page_order = 0; STbuffer->map_data.offset = 0; diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index e682f80..544dc6b 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -52,7 +52,6 @@ struct st_buffer { unsigned short use_sg; /* zero or max number of s/g segments for this adapter */ unsigned short sg_segs; /* number of segments in s/g list */ unsigned short frp_segs; /* number of buffer segments */ - unsigned int frp_sg_current; /* driver buffer length currently in s/g list */ }; /* The tape mode definition */ -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 15/16] st: integrate st_scsi_kern_execute and st_do_scsi 2008-12-18 5:49 ` [PATCH 14/16] st: remove unused frp_sg_current FUJITA Tomonori @ 2008-12-18 5:49 ` FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 16/16] st: retry enlarge_buffer allocation FUJITA Tomonori 0 siblings, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara; +Cc: James.Bottomley, fujita.tomonori, linux-scsi From: Kai Makisara <Kai.Makisara@kolumbus.fi> This integrates st_scsi_kern_execute and st_do_scsi. IOW, it removes st_scsi_kern_execute. Then st has a single function, st_do_scsi, to perform SCSI commands. Signed-off-by: Kai Makisara <Kai.Makisara@kolumbus.fi> --- drivers/scsi/st.c | 202 +++++++++++++++++----------------------------------- 1 files changed, 66 insertions(+), 136 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index fe4c202..ddf2630 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -17,7 +17,7 @@ Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support */ -static const char *verstr = "20080504"; +static const char *verstr = "20081215"; #include <linux/module.h> @@ -491,10 +491,13 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd, mdata->null_mapped = 1; - err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL); - if (err) { - blk_put_request(req); - return DRIVER_ERROR << 24; + if (bufflen) { + err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, + GFP_KERNEL); + if (err) { + blk_put_request(req); + return DRIVER_ERROR << 24; + } } SRpnt->bio = req->bio; @@ -577,28 +580,6 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd return SRpnt; } -static int st_scsi_kern_execute(struct st_request *streq, - const unsigned char *cmd, int data_direction, - void *buffer, unsigned bufflen, int timeout, - int retries) -{ - struct scsi_tape *stp = streq->stp; - int ret, resid; - - stp->buffer->cmdstat.have_sense = 0; - memcpy(streq->cmd, cmd, sizeof(streq->cmd)); - - ret = scsi_execute(stp->device, cmd, data_direction, buffer, bufflen, - streq->sense, timeout, retries, 0, &resid); - if (driver_byte(ret) & DRIVER_ERROR) - return -EBUSY; - - stp->buffer->cmdstat.midlevel_result = streq->result = ret; - stp->buffer->cmdstat.residual = resid; - stp->buffer->syscall_result = st_chk_result(stp, streq); - - return 0; -} /* Handle the write-behind checking (waits for completion). Returns -ENOSPC if write has been correct but EOM early warning reached, -EIO if write ended in @@ -671,7 +652,6 @@ static int cross_eof(struct scsi_tape * STp, int forward) { struct st_request *SRpnt; unsigned char cmd[MAX_COMMAND_SIZE]; - int ret; cmd[0] = SPACE; cmd[1] = 0x01; /* Space FileMarks */ @@ -685,26 +665,20 @@ static int cross_eof(struct scsi_tape * STp, int forward) DEBC(printk(ST_DEB_MSG "%s: Stepping over filemark %s.\n", tape_name(STp), forward ? "forward" : "backward")); - SRpnt = st_allocate_request(STp); + SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE, + STp->device->request_queue->rq_timeout, + MAX_RETRIES, 1); if (!SRpnt) - return STp->buffer->syscall_result; - - ret = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0, - STp->device->request_queue->rq_timeout, - MAX_RETRIES); - if (ret) - goto out; + return (STp->buffer)->syscall_result; - ret = STp->buffer->syscall_result; + st_release_request(SRpnt); + SRpnt = NULL; if ((STp->buffer)->cmdstat.midlevel_result != 0) printk(KERN_ERR "%s: Stepping over filemark %s failed.\n", tape_name(STp), forward ? "forward" : "backward"); -out: - st_release_request(SRpnt); - - return ret; + return (STp->buffer)->syscall_result; } @@ -925,24 +899,21 @@ static int test_ready(struct scsi_tape *STp, int do_wait) int attentions, waits, max_wait, scode; int retval = CHKRES_READY, new_session = 0; unsigned char cmd[MAX_COMMAND_SIZE]; - struct st_request *SRpnt; + struct st_request *SRpnt = NULL; struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat; - SRpnt = st_allocate_request(STp); - if (!SRpnt) - return STp->buffer->syscall_result; - max_wait = do_wait ? ST_BLOCK_SECONDS : 0; for (attentions=waits=0; ; ) { memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; + SRpnt = st_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, + STp->long_timeout, MAX_READY_RETRIES, 1); - retval = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0, - STp->long_timeout, - MAX_READY_RETRIES); - if (retval) + if (!SRpnt) { + retval = (STp->buffer)->syscall_result; break; + } if (cmdstatp->have_sense) { @@ -986,8 +957,8 @@ static int test_ready(struct scsi_tape *STp, int do_wait) break; } - st_release_request(SRpnt); - + if (SRpnt != NULL) + st_release_request(SRpnt); return retval; } @@ -1064,24 +1035,17 @@ static int check_tape(struct scsi_tape *STp, struct file *filp) } } - SRpnt = st_allocate_request(STp); - if (!SRpnt) { - retval = STp->buffer->syscall_result; - goto err_out; - } - if (STp->omit_blklims) STp->min_block = STp->max_block = (-1); else { memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE); cmd[0] = READ_BLOCK_LIMITS; - retval = st_scsi_kern_execute(SRpnt, cmd, DMA_FROM_DEVICE, - STp->buffer->b_data, 6, - STp->device->request_queue->rq_timeout, - MAX_READY_RETRIES); - if (retval) { - st_release_request(SRpnt); + SRpnt = st_do_scsi(SRpnt, STp, cmd, 6, DMA_FROM_DEVICE, + STp->device->request_queue->rq_timeout, + MAX_READY_RETRIES, 1); + if (!SRpnt) { + retval = (STp->buffer)->syscall_result; goto err_out; } @@ -1105,12 +1069,11 @@ static int check_tape(struct scsi_tape *STp, struct file *filp) cmd[0] = MODE_SENSE; cmd[4] = 12; - retval = st_scsi_kern_execute(SRpnt, cmd, DMA_FROM_DEVICE, - STp->buffer->b_data, 12, - STp->device->request_queue->rq_timeout, - MAX_READY_RETRIES); - if (retval) { - st_release_request(SRpnt); + SRpnt = st_do_scsi(SRpnt, STp, cmd, 12, DMA_FROM_DEVICE, + STp->device->request_queue->rq_timeout, + MAX_READY_RETRIES, 1); + if (!SRpnt) { + retval = (STp->buffer)->syscall_result; goto err_out; } @@ -1340,17 +1303,11 @@ static int st_flush(struct file *filp, fl_owner_t id) cmd[0] = WRITE_FILEMARKS; cmd[4] = 1 + STp->two_fm; - SRpnt = st_allocate_request(STp); + SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE, + STp->device->request_queue->rq_timeout, + MAX_WRITE_RETRIES, 1); if (!SRpnt) { - result = STp->buffer->syscall_result; - goto out; - } - - result = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0, - STp->device->request_queue->rq_timeout, - MAX_WRITE_RETRIES); - if (result) { - st_release_request(SRpnt); + result = (STp->buffer)->syscall_result; goto out; } @@ -2415,7 +2372,6 @@ static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs) { unsigned char cmd[MAX_COMMAND_SIZE]; struct st_request *SRpnt; - int ret; memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = MODE_SENSE; @@ -2424,17 +2380,14 @@ static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs) cmd[2] = page; cmd[4] = 255; - SRpnt = st_allocate_request(STp); - if (!SRpnt) - return STp->buffer->syscall_result; + SRpnt = st_do_scsi(NULL, STp, cmd, cmd[4], DMA_FROM_DEVICE, + STp->device->request_queue->rq_timeout, 0, 1); + if (SRpnt == NULL) + return (STp->buffer)->syscall_result; - ret = st_scsi_kern_execute(SRpnt, cmd, DMA_FROM_DEVICE, - STp->buffer->b_data, cmd[4], - STp->device->request_queue->rq_timeout, - MAX_RETRIES); st_release_request(SRpnt); - return ret ? : STp->buffer->syscall_result; + return STp->buffer->syscall_result; } @@ -2442,9 +2395,10 @@ static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs) in the buffer is correctly formatted. The long timeout is used if slow is non-zero. */ static int write_mode_page(struct scsi_tape *STp, int page, int slow) { - int pgo, timeout, ret = 0; + int pgo; unsigned char cmd[MAX_COMMAND_SIZE]; struct st_request *SRpnt; + int timeout; memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = MODE_SELECT; @@ -2458,21 +2412,16 @@ static int write_mode_page(struct scsi_tape *STp, int page, int slow) (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP; (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR; - SRpnt = st_allocate_request(STp); - if (!SRpnt) - return ret; - - timeout = slow ? STp->long_timeout : - STp->device->request_queue->rq_timeout; - - ret = st_scsi_kern_execute(SRpnt, cmd, DMA_TO_DEVICE, - STp->buffer->b_data, cmd[4], timeout, 0); - if (!ret) - ret = STp->buffer->syscall_result; + timeout = slow ? + STp->long_timeout : STp->device->request_queue->rq_timeout; + SRpnt = st_do_scsi(NULL, STp, cmd, cmd[4], DMA_TO_DEVICE, + timeout, 0, 1); + if (SRpnt == NULL) + return (STp->buffer)->syscall_result; st_release_request(SRpnt); - return ret; + return STp->buffer->syscall_result; } @@ -2590,16 +2539,13 @@ static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_cod printk(ST_DEB_MSG "%s: Loading tape.\n", name); ); - SRpnt = st_allocate_request(STp); + SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE, + timeout, MAX_RETRIES, 1); if (!SRpnt) - return STp->buffer->syscall_result; - - retval = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0, timeout, - MAX_RETRIES); - if (retval) - goto out; + return (STp->buffer)->syscall_result; retval = (STp->buffer)->syscall_result; + st_release_request(SRpnt); if (!retval) { /* SCSI command successful */ @@ -2618,8 +2564,6 @@ static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_cod STps = &(STp->ps[STp->partition]); STps->drv_file = STps->drv_block = (-1); } -out: - st_release_request(SRpnt); return retval; } @@ -2895,15 +2839,12 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon return (-ENOSYS); } - SRpnt = st_allocate_request(STp); + SRpnt = st_do_scsi(NULL, STp, cmd, datalen, direction, + timeout, MAX_RETRIES, 1); if (!SRpnt) return (STp->buffer)->syscall_result; - ioctl_result = st_scsi_kern_execute(SRpnt, cmd, direction, - STp->buffer->b_data, datalen, - timeout, MAX_RETRIES); - if (!ioctl_result) - ioctl_result = (STp->buffer)->syscall_result; + ioctl_result = (STp->buffer)->syscall_result; if (!ioctl_result) { /* SCSI command successful */ st_release_request(SRpnt); @@ -3065,17 +3006,11 @@ static int get_location(struct scsi_tape *STp, unsigned int *block, int *partiti if (!logical && !STp->scsi2_logical) scmd[1] = 1; } - - SRpnt = st_allocate_request(STp); + SRpnt = st_do_scsi(NULL, STp, scmd, 20, DMA_FROM_DEVICE, + STp->device->request_queue->rq_timeout, + MAX_READY_RETRIES, 1); if (!SRpnt) - return STp->buffer->syscall_result; - - result = st_scsi_kern_execute(SRpnt, scmd, DMA_FROM_DEVICE, - STp->buffer->b_data, 20, - STp->device->request_queue->rq_timeout, - MAX_READY_RETRIES); - if (result) - goto out; + return (STp->buffer)->syscall_result; if ((STp->buffer)->syscall_result != 0 || (STp->device->scsi_level >= SCSI_2 && @@ -3103,7 +3038,6 @@ static int get_location(struct scsi_tape *STp, unsigned int *block, int *partiti DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name, *block, *partition)); } -out: st_release_request(SRpnt); SRpnt = NULL; @@ -3178,14 +3112,10 @@ static int set_location(struct scsi_tape *STp, unsigned int block, int partition timeout = STp->device->request_queue->rq_timeout; } - SRpnt = st_allocate_request(STp); + SRpnt = st_do_scsi(NULL, STp, scmd, 0, DMA_NONE, + timeout, MAX_READY_RETRIES, 1); if (!SRpnt) - return STp->buffer->syscall_result; - - result = st_scsi_kern_execute(SRpnt, scmd, DMA_NONE, NULL, 0, - timeout, MAX_READY_RETRIES); - if (result) - goto out; + return (STp->buffer)->syscall_result; STps->drv_block = STps->drv_file = (-1); STps->eof = ST_NOEOF; @@ -3210,7 +3140,7 @@ static int set_location(struct scsi_tape *STp, unsigned int block, int partition STps->drv_block = STps->drv_file = 0; result = 0; } -out: + st_release_request(SRpnt); SRpnt = NULL; -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 16/16] st: retry enlarge_buffer allocation 2008-12-18 5:49 ` [PATCH 15/16] st: integrate st_scsi_kern_execute and st_do_scsi FUJITA Tomonori @ 2008-12-18 5:49 ` FUJITA Tomonori 0 siblings, 0 replies; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-18 5:49 UTC (permalink / raw) To: Kai.Makisara; +Cc: James.Bottomley, fujita.tomonori, linux-scsi From: Kai Makisara <Kai.Makisara@kolumbus.fi> Make enlarge_buffer() retry allocation if the previously chosen page order was too small. Really limit the page order to 6. Return error if the maximum order is not large enough for the request. Signed-off-by: Kai Makisara <Kai.Makisara@kolumbus.fi> --- drivers/scsi/st.c | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index ddf2630..c6f19ee 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3695,6 +3695,8 @@ static struct st_buffer *new_tape_buffer(int need_dma, int max_sg) /* Try to allocate enough space in the tape buffer */ +#define ST_MAX_ORDER 6 + static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma) { int segs, nbr, max_segs, b_size, order, got; @@ -3723,9 +3725,16 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm b_size = PAGE_SIZE << order; } else { for (b_size = PAGE_SIZE, order = 0; - order <= 6 && b_size < new_size; order++, b_size *= 2) + order < ST_MAX_ORDER && b_size < new_size; + order++, b_size *= 2) ; /* empty */ } + if (max_segs * (PAGE_SIZE << order) < new_size) { + if (order == ST_MAX_ORDER) + return 0; + normalize_buffer(STbuffer); + return enlarge_buffer(STbuffer, new_size, need_dma); + } for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size; segs < max_segs && got < new_size;) { -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v2 00/16] st: remove scsi_execute_async usage (the second half) 2008-12-18 5:49 [PATCH v2 00/16] st: remove scsi_execute_async usage (the second half) FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 01/16] block: fix bio_add_page misuse with rq_map_data FUJITA Tomonori @ 2008-12-25 14:51 ` FUJITA Tomonori 2008-12-25 21:17 ` Kai Makisara 1 sibling, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-25 14:51 UTC (permalink / raw) To: Kai.Makisara; +Cc: James.Bottomley, fujita.tomonori, linux-scsi, jens.axboe On Thu, 18 Dec 2008 14:49:35 +0900 FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote: > This patchset is the second version of the second half patchset to > remove scsi_execute_async in st driver (IOW, this converts st driver > to use the block layer functions). > > http://marc.info/?l=linux-scsi&m=122900494917385&w=2 > > I've not changed the st patches much since the first version. No > change to the #4-14 st patches except for cleanups to silence > checkpatch.sh. The new #15-16 patches for st came from Kai, who > greatly helped me out with this patchset. Kai, can I get your ACK on these patches? ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 00/16] st: remove scsi_execute_async usage (the second half) 2008-12-25 14:51 ` [PATCH v2 00/16] st: remove scsi_execute_async usage (the second half) FUJITA Tomonori @ 2008-12-25 21:17 ` Kai Makisara 2008-12-26 2:36 ` FUJITA Tomonori 0 siblings, 1 reply; 21+ messages in thread From: Kai Makisara @ 2008-12-25 21:17 UTC (permalink / raw) To: FUJITA Tomonori; +Cc: James Bottomley, linux-scsi, jens.axboe On Thu, 25 Dec 2008, FUJITA Tomonori wrote: > On Thu, 18 Dec 2008 14:49:35 +0900 > FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote: > > > This patchset is the second version of the second half patchset to > > remove scsi_execute_async in st driver (IOW, this converts st driver > > to use the block layer functions). > > > > http://marc.info/?l=linux-scsi&m=122900494917385&w=2 > > > > I've not changed the st patches much since the first version. No > > change to the #4-14 st patches except for cleanups to silence > > checkpatch.sh. The new #15-16 patches for st came from Kai, who > > greatly helped me out with this patchset. > > Kai, can I get your ACK on these patches? > Yes. I tested the patches and did not see any problems. Thanks, Kai ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 00/16] st: remove scsi_execute_async usage (the second half) 2008-12-25 21:17 ` Kai Makisara @ 2008-12-26 2:36 ` FUJITA Tomonori 2008-12-26 19:04 ` Jens Axboe 0 siblings, 1 reply; 21+ messages in thread From: FUJITA Tomonori @ 2008-12-26 2:36 UTC (permalink / raw) To: Kai.Makisara, jens.axboe; +Cc: fujita.tomonori, James.Bottomley, linux-scsi On Thu, 25 Dec 2008 23:17:51 +0200 (EET) Kai Makisara <Kai.Makisara@kolumbus.fi> wrote: > On Thu, 25 Dec 2008, FUJITA Tomonori wrote: > > > On Thu, 18 Dec 2008 14:49:35 +0900 > > FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote: > > > > > This patchset is the second version of the second half patchset to > > > remove scsi_execute_async in st driver (IOW, this converts st driver > > > to use the block layer functions). > > > > > > http://marc.info/?l=linux-scsi&m=122900494917385&w=2 > > > > > > I've not changed the st patches much since the first version. No > > > change to the #4-14 st patches except for cleanups to silence > > > checkpatch.sh. The new #15-16 patches for st came from Kai, who > > > greatly helped me out with this patchset. > > > > Kai, can I get your ACK on these patches? > > > Yes. I tested the patches and did not see any problems. Thanks a lot! Jens, merging the following patches for block via James' tree is ok? > The #1-3 patches are for the block layer. > > The first patch is a slightly modified version of the following fix (I > modified it for the later changes): > > http://marc.info/?l=linux-scsi&m=122927795113939&w=2 > > The second patch is a patch to fix the partial mappings with > rq_map_data struct. Kai found this problem (which leads to data > corruption). > > The first and second patches fix the bugs which affect sg. > > The third patch is the first patch in the previous patchset. It's a > necessary change to the block layer to support st/osst. I slightly > modified it due to the first and second patches. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 00/16] st: remove scsi_execute_async usage (the second half) 2008-12-26 2:36 ` FUJITA Tomonori @ 2008-12-26 19:04 ` Jens Axboe 0 siblings, 0 replies; 21+ messages in thread From: Jens Axboe @ 2008-12-26 19:04 UTC (permalink / raw) To: FUJITA Tomonori; +Cc: Kai.Makisara, James.Bottomley, linux-scsi On Fri, Dec 26 2008, FUJITA Tomonori wrote: > On Thu, 25 Dec 2008 23:17:51 +0200 (EET) > Kai Makisara <Kai.Makisara@kolumbus.fi> wrote: > > > On Thu, 25 Dec 2008, FUJITA Tomonori wrote: > > > > > On Thu, 18 Dec 2008 14:49:35 +0900 > > > FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote: > > > > > > > This patchset is the second version of the second half patchset to > > > > remove scsi_execute_async in st driver (IOW, this converts st driver > > > > to use the block layer functions). > > > > > > > > http://marc.info/?l=linux-scsi&m=122900494917385&w=2 > > > > > > > > I've not changed the st patches much since the first version. No > > > > change to the #4-14 st patches except for cleanups to silence > > > > checkpatch.sh. The new #15-16 patches for st came from Kai, who > > > > greatly helped me out with this patchset. > > > > > > Kai, can I get your ACK on these patches? > > > > > Yes. I tested the patches and did not see any problems. > > Thanks a lot! > > > Jens, merging the following patches for block via James' tree is ok? Yes, you can add my acked-by to them as well. -- Jens Axboe ^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2008-12-26 19:05 UTC | newest] Thread overview: 21+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-12-18 5:49 [PATCH v2 00/16] st: remove scsi_execute_async usage (the second half) FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 01/16] block: fix bio_add_page misuse with rq_map_data FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 02/16] block: fix the partial mappings with struct rq_map_data FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 03/16] block: make blk_rq_map_user take a NULL user-space buffer for WRITE FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 04/16] st: make all the fragment buffers the same size FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 05/16] st: add struct rq_map_data support FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 06/16] st: add st_scsi_execute helper function FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 07/16] st: convert non-dio path to use st_scsi_execute FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 08/16] st: convert dio " FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 09/16] st: remove buf_to_sg FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 10/16] st: kill struct st_buff_fragment FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 11/16] st: remove struct scatterlist FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 12/16] st: simplify new_tape_buffer FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 13/16] st: remove unused orig_frp_segs FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 14/16] st: remove unused frp_sg_current FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 15/16] st: integrate st_scsi_kern_execute and st_do_scsi FUJITA Tomonori 2008-12-18 5:49 ` [PATCH 16/16] st: retry enlarge_buffer allocation FUJITA Tomonori 2008-12-25 14:51 ` [PATCH v2 00/16] st: remove scsi_execute_async usage (the second half) FUJITA Tomonori 2008-12-25 21:17 ` Kai Makisara 2008-12-26 2:36 ` FUJITA Tomonori 2008-12-26 19:04 ` Jens Axboe
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.