aboutsummaryrefslogtreecommitdiffstats
path: root/fs/bio.c
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2008-08-28 02:05:57 -0400
committerJens Axboe <jens.axboe@oracle.com>2008-10-09 02:56:10 -0400
commit4d8ab62e087d9300883b82c2662e73e6eef803a3 (patch)
tree379f6c1a3dfb165ce1c604d34ddb42ac1447d832 /fs/bio.c
parent10db10d144c0248f285242f79daf6b9de6b00a62 (diff)
bio: convert bio_copy_kern to use bio_copy_user
bio_copy_kern and bio_copy_user are very similar. This converts bio_copy_kern to use bio_copy_user. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: Jens Axboe <jens.axboe@oracle.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'fs/bio.c')
-rw-r--r--fs/bio.c54
1 files changed, 4 insertions, 50 deletions
diff --git a/fs/bio.c b/fs/bio.c
index a2f072647cdf..9d68ddb89b71 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -995,48 +995,13 @@ static void bio_copy_kern_endio(struct bio *bio, int err)
995struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len, 995struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len,
996 gfp_t gfp_mask, int reading) 996 gfp_t gfp_mask, int reading)
997{ 997{
998 unsigned long kaddr = (unsigned long)data;
999 unsigned long end = (kaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
1000 unsigned long start = kaddr >> PAGE_SHIFT;
1001 const int nr_pages = end - start;
1002 struct bio *bio; 998 struct bio *bio;
1003 struct bio_vec *bvec; 999 struct bio_vec *bvec;
1004 struct bio_map_data *bmd; 1000 int i;
1005 int i, ret;
1006 struct sg_iovec iov;
1007
1008 iov.iov_base = data;
1009 iov.iov_len = len;
1010
1011 bmd = bio_alloc_map_data(nr_pages, 1, gfp_mask);
1012 if (!bmd)
1013 return ERR_PTR(-ENOMEM);
1014
1015 ret = -ENOMEM;
1016 bio = bio_alloc(gfp_mask, nr_pages);
1017 if (!bio)
1018 goto out_bmd;
1019
1020 while (len) {
1021 struct page *page;
1022 unsigned int bytes = PAGE_SIZE;
1023
1024 if (bytes > len)
1025 bytes = len;
1026
1027 page = alloc_page(q->bounce_gfp | gfp_mask);
1028 if (!page) {
1029 ret = -ENOMEM;
1030 goto cleanup;
1031 }
1032
1033 if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes) {
1034 ret = -EINVAL;
1035 goto cleanup;
1036 }
1037 1001
1038 len -= bytes; 1002 bio = bio_copy_user(q, NULL, (unsigned long)data, len, 1, gfp_mask);
1039 } 1003 if (IS_ERR(bio))
1004 return bio;
1040 1005
1041 if (!reading) { 1006 if (!reading) {
1042 void *p = data; 1007 void *p = data;
@@ -1049,20 +1014,9 @@ struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len,
1049 } 1014 }
1050 } 1015 }
1051 1016
1052 bio->bi_private = bmd;
1053 bio->bi_end_io = bio_copy_kern_endio; 1017 bio->bi_end_io = bio_copy_kern_endio;
1054 1018
1055 bio_set_map_data(bmd, bio, &iov, 1, 1);
1056 return bio; 1019 return bio;
1057cleanup:
1058 bio_for_each_segment(bvec, bio, i)
1059 __free_page(bvec->bv_page);
1060
1061 bio_put(bio);
1062out_bmd:
1063 bio_free_map_data(bmd);
1064
1065 return ERR_PTR(ret);
1066} 1020}
1067 1021
1068/* 1022/*