linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).