From: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
To: axboe@suse.de, james.bottomley@steeleye.com
Cc: linux-scsi@vger.kernel.org
Subject: [PATCH 2/6] block layer: add partial mappings support to bio_map_user
Date: Fri, 10 Mar 2006 20:46:59 +0900 [thread overview]
Message-ID: <20060310204659N.tomof@acm.org> (raw)
This is the updated patch for partial mappings support.
- bio_map_user_iov always allows partial mappings.
- The two users (blk_rq_map_user and blk_rq_map_user_iov) will fails
if the bio is partially mapped.
- Added a length argument to blk_rq_map_user_iov in order to avoid
including sg.h in ll_rw_blk.c for struct sg_iovec.
This is a resend:
http://marc.theaimsgroup.com/?l=linux-scsi&m=114086655400806&w=2
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
---
block/ll_rw_blk.c | 29 ++++++++++++++++++-----------
block/scsi_ioctl.c | 3 ++-
fs/bio.c | 14 +-------------
include/linux/blkdev.h | 3 ++-
4 files changed, 23 insertions(+), 26 deletions(-)
bd5a6476b9a4fe5953527fd7c162a1e7754eea7c
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 03d9c82..6849859 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -2291,19 +2291,20 @@ int blk_rq_map_user(request_queue_t *q,
else
bio = bio_copy_user(q, uaddr, len, reading);
- if (!IS_ERR(bio)) {
- rq->bio = rq->biotail = bio;
- blk_rq_bio_prep(q, rq, bio);
+ if (IS_ERR(bio))
+ return PTR_ERR(bio);
- rq->buffer = rq->data = NULL;
- rq->data_len = len;
- return 0;
+ if (bio->bi_size != len) {
+ bio_endio(bio, bio->bi_size, 0);
+ bio_unmap_user(bio);
+ return -EINVAL;
}
- /*
- * bio is the err-ptr
- */
- return PTR_ERR(bio);
+ rq->bio = rq->biotail = bio;
+ blk_rq_bio_prep(q, rq, bio);
+ rq->buffer = rq->data = NULL;
+ rq->data_len = len;
+ return 0;
}
EXPORT_SYMBOL(blk_rq_map_user);
@@ -2329,7 +2330,7 @@ EXPORT_SYMBOL(blk_rq_map_user);
* unmapping.
*/
int blk_rq_map_user_iov(request_queue_t *q, struct request *rq,
- struct sg_iovec *iov, int iov_count)
+ struct sg_iovec *iov, int iov_count, unsigned int len)
{
struct bio *bio;
@@ -2343,6 +2344,12 @@ int blk_rq_map_user_iov(request_queue_t
if (IS_ERR(bio))
return PTR_ERR(bio);
+ if (bio->bi_size != len) {
+ bio_endio(bio, bio->bi_size, 0);
+ bio_unmap_user(bio);
+ return -EINVAL;
+ }
+
rq->bio = rq->biotail = bio;
blk_rq_bio_prep(q, rq, bio);
rq->buffer = rq->data = NULL;
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 24f7af9..ef9900d 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -274,7 +274,8 @@ static int sg_io(struct file *file, requ
goto out;
}
- ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count);
+ ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count,
+ hdr->dxfer_len);
kfree(iov);
} else if (hdr->dxfer_len)
ret = blk_rq_map_user(q, rq, hdr->dxferp, hdr->dxfer_len);
diff --git a/fs/bio.c b/fs/bio.c
index d8259d9..f51a873 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -749,7 +749,6 @@ struct bio *bio_map_user_iov(request_que
int write_to_vm)
{
struct bio *bio;
- int len = 0, i;
bio = __bio_map_user_iov(q, bdev, iov, iov_count, write_to_vm);
@@ -764,18 +763,7 @@ struct bio *bio_map_user_iov(request_que
*/
bio_get(bio);
- for (i = 0; i < iov_count; i++)
- len += iov[i].iov_len;
-
- if (bio->bi_size == len)
- return bio;
-
- /*
- * don't support partial mappings
- */
- bio_endio(bio, bio->bi_size, 0);
- bio_unmap_user(bio);
- return ERR_PTR(-EINVAL);
+ return bio;
}
static void __bio_unmap_user(struct bio *bio)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 860e7a4..619ef1d 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -611,7 +611,8 @@ extern void blk_queue_activity_fn(reques
extern int blk_rq_map_user(request_queue_t *, struct request *, void __user *, unsigned int);
extern int blk_rq_unmap_user(struct bio *, unsigned int);
extern int blk_rq_map_kern(request_queue_t *, struct request *, void *, unsigned int, gfp_t);
-extern int blk_rq_map_user_iov(request_queue_t *, struct request *, struct sg_iovec *, int);
+extern int blk_rq_map_user_iov(request_queue_t *, struct request *,
+ struct sg_iovec *, int, unsigned int);
extern int blk_execute_rq(request_queue_t *, struct gendisk *,
struct request *, int);
extern void blk_execute_rq_nowait(request_queue_t *, struct gendisk *,
--
1.1.5
reply other threads:[~2006-03-10 11:50 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060310204659N.tomof@acm.org \
--to=fujita.tomonori@lab.ntt.co.jp \
--cc=axboe@suse.de \
--cc=james.bottomley@steeleye.com \
--cc=linux-scsi@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.