* [PATCH 0/2] older SG interface fixes (for the block layer conversion) @ 2008-09-02 7:20 FUJITA Tomonori 2008-09-02 7:20 ` [PATCH 1/2] block: make blk_rq_map_user take a NULL user-space buffer FUJITA Tomonori 2008-09-02 7:31 ` [PATCH 0/2] older SG interface fixes (for the block layer conversion) Jens Axboe 0 siblings, 2 replies; 4+ messages in thread From: FUJITA Tomonori @ 2008-09-02 7:20 UTC (permalink / raw) To: jens.axboe; +Cc: linux-scsi, dougg, michaelc, James.Bottomley, fujita.tomonori I messed up the older SG interface's READ commands. With READ commands via the older SG interface, we don't know a user-space address to transfer the result data when executing a SCSI command. So we can't pass a user-space address to blk_rq_map_user. This changes blk_rq_map_user to takes a NULL user-space address. That is, sg uses blk_rq_map_user to just set up a request and bios with page frames without data transfer (similar to what scsi_req_map_sg does for sg now). blk_rq_map_user doesn't map a user space address so the name, blk_rq_map_user, might be odd but I leave it alone. ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] block: make blk_rq_map_user take a NULL user-space buffer 2008-09-02 7:20 [PATCH 0/2] older SG interface fixes (for the block layer conversion) FUJITA Tomonori @ 2008-09-02 7:20 ` FUJITA Tomonori 2008-09-02 7:20 ` [PATCH 2/2] sg: set dxferp to NULL for READ with the older SG interface FUJITA Tomonori 2008-09-02 7:31 ` [PATCH 0/2] older SG interface fixes (for the block layer conversion) Jens Axboe 1 sibling, 1 reply; 4+ messages in thread From: FUJITA Tomonori @ 2008-09-02 7:20 UTC (permalink / raw) To: jens.axboe; +Cc: linux-scsi, dougg, michaelc, James.Bottomley, fujita.tomonori This patch changes blk_rq_map_user to accept a NULL user-space buffer with a READ command if rq_map_data is not NULL. Thus a caller can pass page frames to lk_rq_map_user to just set up a request and bios with page frames propely. bio_uncopy_user (called via blk_rq_unmap_user) doesn't copy data to user space with such request. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> --- block/blk-map.c | 16 ++++++++++++---- fs/bio.c | 8 ++++---- include/linux/bio.h | 1 + 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/block/blk-map.c b/block/blk-map.c index 572140c..4849fa3 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, gfp_t gfp_mask) + unsigned int len, int null_mapped, gfp_t gfp_mask) { unsigned long uaddr; struct bio *bio, *orig_bio; @@ -63,6 +63,9 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq, if (IS_ERR(bio)) return PTR_ERR(bio); + if (null_mapped) + bio->bi_flags |= (1 << BIO_NULL_MAPPED); + orig_bio = bio; blk_queue_bounce(q, &bio); @@ -111,12 +114,17 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq, { unsigned long bytes_read = 0; struct bio *bio = NULL; - int ret; + int ret, null_mapped = 0; if (len > (q->max_hw_sectors << 9)) return -EINVAL; - if (!len || !ubuf) + if (!len) return -EINVAL; + if (!ubuf) { + if (!map_data || rq_data_dir(rq) != READ) + return -EINVAL; + null_mapped = 1; + } while (bytes_read != len) { unsigned long map_len, end, start; @@ -135,7 +143,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, - gfp_mask); + null_mapped, gfp_mask); if (ret < 0) goto unmap_rq; if (!bio) diff --git a/fs/bio.c b/fs/bio.c index 9d68ddb..3553029 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -547,11 +547,11 @@ static int __bio_copy_iov(struct bio *bio, struct bio_vec *iovecs, int bio_uncopy_user(struct bio *bio) { struct bio_map_data *bmd = bio->bi_private; - int ret; - - ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs, bmd->nr_sgvecs, 1, - bmd->is_our_pages); + int ret = 0; + if (!bio_flagged(bio, BIO_NULL_MAPPED)) + ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs, + bmd->nr_sgvecs, 1, bmd->is_our_pages); bio_free_map_data(bmd); bio_put(bio); return ret; diff --git a/include/linux/bio.h b/include/linux/bio.h index bc386cd..7af373f 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -108,6 +108,7 @@ struct bio { #define BIO_USER_MAPPED 6 /* contains user pages */ #define BIO_EOPNOTSUPP 7 /* not supported */ #define BIO_CPU_AFFINE 8 /* complete bio on same CPU as submitted */ +#define BIO_NULL_MAPPED 9 /* contains invalid user pages */ #define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag))) /* -- 1.5.4.2 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] sg: set dxferp to NULL for READ with the older SG interface 2008-09-02 7:20 ` [PATCH 1/2] block: make blk_rq_map_user take a NULL user-space buffer FUJITA Tomonori @ 2008-09-02 7:20 ` FUJITA Tomonori 0 siblings, 0 replies; 4+ messages in thread From: FUJITA Tomonori @ 2008-09-02 7:20 UTC (permalink / raw) To: jens.axboe; +Cc: linux-scsi, dougg, michaelc, James.Bottomley, fujita.tomonori With the older SG interface, we don't know a user-space address to trasfer data when executing a SCSI command. So we can't pass a user-space address to blk_rq_map_user. This patch fixes sg to pass a NULL user-space address to blk_rq_map_user so that it just sets up a request and bios with page frames propely without data transfer. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> --- drivers/scsi/sg.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index ed69292..50c07bc 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -615,7 +615,10 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) else hp->dxfer_direction = (mxsize > 0) ? SG_DXFER_FROM_DEV : SG_DXFER_NONE; hp->dxfer_len = mxsize; - hp->dxferp = (char __user *)buf + cmd_size; + if (hp->dxfer_direction == SG_DXFER_TO_DEV) + hp->dxferp = (char __user *)buf + cmd_size; + else + hp->dxferp = NULL; hp->sbp = NULL; hp->timeout = old_hdr.reply_len; /* structure abuse ... */ hp->flags = input_size; /* structure abuse ... */ -- 1.5.4.2 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 0/2] older SG interface fixes (for the block layer conversion) 2008-09-02 7:20 [PATCH 0/2] older SG interface fixes (for the block layer conversion) FUJITA Tomonori 2008-09-02 7:20 ` [PATCH 1/2] block: make blk_rq_map_user take a NULL user-space buffer FUJITA Tomonori @ 2008-09-02 7:31 ` Jens Axboe 1 sibling, 0 replies; 4+ messages in thread From: Jens Axboe @ 2008-09-02 7:31 UTC (permalink / raw) Cc: linux-scsi, dougg, michaelc, James.Bottomley, fujita.tomonori On Tue, Sep 02 2008, FUJITA Tomonori wrote: > I messed up the older SG interface's READ commands. > > With READ commands via the older SG interface, we don't know a > user-space address to transfer the result data when executing a SCSI > command. So we can't pass a user-space address to blk_rq_map_user. > > This changes blk_rq_map_user to takes a NULL user-space address. That > is, sg uses blk_rq_map_user to just set up a request and bios with > page frames without data transfer (similar to what scsi_req_map_sg > does for sg now). > > blk_rq_map_user doesn't map a user space address so the name, > blk_rq_map_user, might be odd but I leave it alone. Applied -- Jens Axboe ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-09-02 7:31 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-09-02 7:20 [PATCH 0/2] older SG interface fixes (for the block layer conversion) FUJITA Tomonori 2008-09-02 7:20 ` [PATCH 1/2] block: make blk_rq_map_user take a NULL user-space buffer FUJITA Tomonori 2008-09-02 7:20 ` [PATCH 2/2] sg: set dxferp to NULL for READ with the older SG interface FUJITA Tomonori 2008-09-02 7:31 ` [PATCH 0/2] older SG interface fixes (for the block layer conversion) 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.