diff options
author | Kent Overstreet <kmo@daterainc.com> | 2013-11-22 22:39:06 -0500 |
---|---|---|
committer | Kent Overstreet <kmo@daterainc.com> | 2013-11-24 01:33:55 -0500 |
commit | c8db444820a1e37ebdca38a0210bca85f832214f (patch) | |
tree | 88d5e301acb94b7cb43b74e10a5d9d2d484696fa /fs | |
parent | 1c3b13e64cf70d652fb04e32d13ae3e36810c2e4 (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.c | 54 |
1 files changed, 13 insertions, 41 deletions
@@ -967,60 +967,33 @@ void bio_copy_data(struct bio *dst, struct bio *src) | |||
967 | EXPORT_SYMBOL(bio_copy_data); | 967 | EXPORT_SYMBOL(bio_copy_data); |
968 | 968 | ||
969 | struct bio_map_data { | 969 | struct 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 | ||
976 | static void bio_set_map_data(struct bio_map_data *bmd, struct bio *bio, | 975 | static 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 | ||
987 | static void bio_free_map_data(struct bio_map_data *bmd) | ||
988 | { | ||
989 | kfree(bmd->iovecs); | ||
990 | kfree(bmd->sgvecs); | ||
991 | kfree(bmd); | ||
992 | } | ||
993 | |||
994 | static struct bio_map_data *bio_alloc_map_data(int nr_segs, | 985 | static 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 | ||
1022 | static int __bio_copy_iov(struct bio *bio, struct bio_vec *iovecs, | 996 | static 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); |
1227 | out_bmd: | 1200 | out_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 | ||