aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorKent Overstreet <kmo@daterainc.com>2013-11-22 22:39:06 -0500
committerKent Overstreet <kmo@daterainc.com>2013-11-24 01:33:55 -0500
commitc8db444820a1e37ebdca38a0210bca85f832214f (patch)
tree88d5e301acb94b7cb43b74e10a5d9d2d484696fa /fs
parent1c3b13e64cf70d652fb04e32d13ae3e36810c2e4 (diff)
block: Don't save/copy bvec array anymore
Now that drivers have been converted to the bvec_iter primitives, they shouldn't be modifying the biovec anymore and thus saving it is unnecessary - code that was previously making a backup of the bvec array can now just save bio->bi_iter. Signed-off-by: Kent Overstreet <kmo@daterainc.com> Cc: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs')
-rw-r--r--fs/bio.c54
1 files changed, 13 insertions, 41 deletions
diff --git a/fs/bio.c b/fs/bio.c
index 6e42b68ab0ac..9cff939b1bc6 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -967,60 +967,33 @@ void bio_copy_data(struct bio *dst, struct bio *src)
967EXPORT_SYMBOL(bio_copy_data); 967EXPORT_SYMBOL(bio_copy_data);
968 968
969struct bio_map_data { 969struct bio_map_data {
970 struct bio_vec *iovecs;
971 struct sg_iovec *sgvecs;
972 int nr_sgvecs; 970 int nr_sgvecs;
973 int is_our_pages; 971 int is_our_pages;
972 struct sg_iovec sgvecs[];
974}; 973};
975 974
976static void bio_set_map_data(struct bio_map_data *bmd, struct bio *bio, 975static void bio_set_map_data(struct bio_map_data *bmd, struct bio *bio,
977 struct sg_iovec *iov, int iov_count, 976 struct sg_iovec *iov, int iov_count,
978 int is_our_pages) 977 int is_our_pages)
979{ 978{
980 memcpy(bmd->iovecs, bio->bi_io_vec, sizeof(struct bio_vec) * bio->bi_vcnt);
981 memcpy(bmd->sgvecs, iov, sizeof(struct sg_iovec) * iov_count); 979 memcpy(bmd->sgvecs, iov, sizeof(struct sg_iovec) * iov_count);
982 bmd->nr_sgvecs = iov_count; 980 bmd->nr_sgvecs = iov_count;
983 bmd->is_our_pages = is_our_pages; 981 bmd->is_our_pages = is_our_pages;
984 bio->bi_private = bmd; 982 bio->bi_private = bmd;
985} 983}
986 984
987static void bio_free_map_data(struct bio_map_data *bmd)
988{
989 kfree(bmd->iovecs);
990 kfree(bmd->sgvecs);
991 kfree(bmd);
992}
993
994static struct bio_map_data *bio_alloc_map_data(int nr_segs, 985static struct bio_map_data *bio_alloc_map_data(int nr_segs,
995 unsigned int iov_count, 986 unsigned int iov_count,
996 gfp_t gfp_mask) 987 gfp_t gfp_mask)
997{ 988{
998 struct bio_map_data *bmd;
999
1000 if (iov_count > UIO_MAXIOV) 989 if (iov_count > UIO_MAXIOV)
1001 return NULL; 990 return NULL;
1002 991
1003 bmd = kmalloc(sizeof(*bmd), gfp_mask); 992 return kmalloc(sizeof(struct bio_map_data) +
1004 if (!bmd) 993 sizeof(struct sg_iovec) * iov_count, gfp_mask);
1005 return NULL;
1006
1007 bmd->iovecs = kmalloc(sizeof(struct bio_vec) * nr_segs, gfp_mask);
1008 if (!bmd->iovecs) {
1009 kfree(bmd);
1010 return NULL;
1011 }
1012
1013 bmd->sgvecs = kmalloc(sizeof(struct sg_iovec) * iov_count, gfp_mask);
1014 if (bmd->sgvecs)
1015 return bmd;
1016
1017 kfree(bmd->iovecs);
1018 kfree(bmd);
1019 return NULL;
1020} 994}
1021 995
1022static int __bio_copy_iov(struct bio *bio, struct bio_vec *iovecs, 996static int __bio_copy_iov(struct bio *bio, struct sg_iovec *iov, int iov_count,
1023 struct sg_iovec *iov, int iov_count,
1024 int to_user, int from_user, int do_free_page) 997 int to_user, int from_user, int do_free_page)
1025{ 998{
1026 int ret = 0, i; 999 int ret = 0, i;
@@ -1030,7 +1003,7 @@ static int __bio_copy_iov(struct bio *bio, struct bio_vec *iovecs,
1030 1003
1031 bio_for_each_segment_all(bvec, bio, i) { 1004 bio_for_each_segment_all(bvec, bio, i) {
1032 char *bv_addr = page_address(bvec->bv_page); 1005 char *bv_addr = page_address(bvec->bv_page);
1033 unsigned int bv_len = iovecs[i].bv_len; 1006 unsigned int bv_len = bvec->bv_len;
1034 1007
1035 while (bv_len && iov_idx < iov_count) { 1008 while (bv_len && iov_idx < iov_count) {
1036 unsigned int bytes; 1009 unsigned int bytes;
@@ -1090,14 +1063,14 @@ int bio_uncopy_user(struct bio *bio)
1090 * don't copy into a random user address space, just free. 1063 * don't copy into a random user address space, just free.
1091 */ 1064 */
1092 if (current->mm) 1065 if (current->mm)
1093 ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs, 1066 ret = __bio_copy_iov(bio, bmd->sgvecs, bmd->nr_sgvecs,
1094 bmd->nr_sgvecs, bio_data_dir(bio) == READ, 1067 bio_data_dir(bio) == READ,
1095 0, bmd->is_our_pages); 1068 0, bmd->is_our_pages);
1096 else if (bmd->is_our_pages) 1069 else if (bmd->is_our_pages)
1097 bio_for_each_segment_all(bvec, bio, i) 1070 bio_for_each_segment_all(bvec, bio, i)
1098 __free_page(bvec->bv_page); 1071 __free_page(bvec->bv_page);
1099 } 1072 }
1100 bio_free_map_data(bmd); 1073 kfree(bmd);
1101 bio_put(bio); 1074 bio_put(bio);
1102 return ret; 1075 return ret;
1103} 1076}
@@ -1211,7 +1184,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
1211 */ 1184 */
1212 if ((!write_to_vm && (!map_data || !map_data->null_mapped)) || 1185 if ((!write_to_vm && (!map_data || !map_data->null_mapped)) ||
1213 (map_data && map_data->from_user)) { 1186 (map_data && map_data->from_user)) {
1214 ret = __bio_copy_iov(bio, bio->bi_io_vec, iov, iov_count, 0, 1, 0); 1187 ret = __bio_copy_iov(bio, iov, iov_count, 0, 1, 0);
1215 if (ret) 1188 if (ret)
1216 goto cleanup; 1189 goto cleanup;
1217 } 1190 }
@@ -1225,7 +1198,7 @@ cleanup:
1225 1198
1226 bio_put(bio); 1199 bio_put(bio);
1227out_bmd: 1200out_bmd:
1228 bio_free_map_data(bmd); 1201 kfree(bmd);
1229 return ERR_PTR(ret); 1202 return ERR_PTR(ret);
1230} 1203}
1231 1204
@@ -1542,16 +1515,15 @@ static void bio_copy_kern_endio(struct bio *bio, int err)
1542 1515
1543 bio_for_each_segment_all(bvec, bio, i) { 1516 bio_for_each_segment_all(bvec, bio, i) {
1544 char *addr = page_address(bvec->bv_page); 1517 char *addr = page_address(bvec->bv_page);
1545 int len = bmd->iovecs[i].bv_len;
1546 1518
1547 if (read) 1519 if (read)
1548 memcpy(p, addr, len); 1520 memcpy(p, addr, bvec->bv_len);
1549 1521
1550 __free_page(bvec->bv_page); 1522 __free_page(bvec->bv_page);
1551 p += len; 1523 p += bvec->bv_len;
1552 } 1524 }
1553 1525
1554 bio_free_map_data(bmd); 1526 kfree(bmd);
1555 bio_put(bio); 1527 bio_put(bio);
1556} 1528}
1557 1529