* [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.