aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJens Axboe <axboe@suse.de>2004-08-02 09:29:20 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-02 09:29:20 -0700
commit1737ddec952b0b386276516573baff59f58cc6f9 (patch)
treeb8218ab9ae3e9c3b2de3043cac0fabee70bdb207 /include
parent8e7e3e3ea30c8b242901e13ebc44253f22a99c82 (diff)
downloadhistory-1737ddec952b0b386276516573baff59f58cc6f9.tar.gz
[PATCH] bio_copy_user() cleanups and fixes
blk_rq_map_user() is a bit of a hack currently, since it drops back to kmalloc() if bio_map_user() fails. This is unfortunate since it means we do no real segment or size checking (and the request segment counts contain crap, already found one bug in a scsi lld). It's also pretty nasty for > PAGE_SIZE requests, as we attempt to do higher order page allocations. Even worse still, ide-cd will drop back to PIO for non-sg/bio requests. All in all, very suboptimal. This patch adds bio_copy_user() which simply sets up a bio with kernel pages and copies data as needed for reads and writes. It also changes bio_map_user() to return an error pointer like bio_copy_user(), so we can return something sane to the user instead of always -ENOMEM. Signed-off-by: Jens Axboe <axboe@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/bio.h5
-rw-r--r--include/linux/blkdev.h2
2 files changed, 5 insertions, 2 deletions
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 601531cf4976f1..b90e06c1764483 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -120,6 +120,7 @@ struct bio {
#define BIO_SEG_VALID 3 /* nr_hw_seg valid */
#define BIO_CLONED 4 /* doesn't own data */
#define BIO_BOUNCED 5 /* bio is a bounce bio */
+#define BIO_USER_MAPPED 6 /* contains user pages */
#define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag)))
/*
@@ -264,9 +265,11 @@ extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
extern int bio_get_nr_vecs(struct block_device *);
extern struct bio *bio_map_user(struct request_queue *, struct block_device *,
unsigned long, unsigned int, int);
-extern void bio_unmap_user(struct bio *, int);
+extern void bio_unmap_user(struct bio *);
extern void bio_set_pages_dirty(struct bio *bio);
extern void bio_check_pages_dirty(struct bio *bio);
+extern struct bio *bio_copy_user(struct request_queue *, unsigned long, unsigned int, int);
+extern int bio_uncopy_user(struct bio *);
#ifdef CONFIG_HIGHMEM
/*
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 0ac26dad8931d9..7df0f31bfe7d84 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -524,7 +524,7 @@ extern void __blk_stop_queue(request_queue_t *q);
extern void blk_run_queue(request_queue_t *);
extern void blk_queue_activity_fn(request_queue_t *, activity_fn *, void *);
extern struct request *blk_rq_map_user(request_queue_t *, int, void __user *, unsigned int);
-extern int blk_rq_unmap_user(struct request *, void __user *, struct bio *, unsigned int);
+extern int blk_rq_unmap_user(struct request *, struct bio *, unsigned int);
extern int blk_execute_rq(request_queue_t *, struct gendisk *, struct request *);
static inline request_queue_t *bdev_get_queue(struct block_device *bdev)