diff options
author | David Howells <dhowells@redhat.com> | 2018-10-19 19:57:56 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2018-10-23 19:41:07 -0400 |
commit | aa563d7bca6e882ec2bdae24603c8f016401a144 (patch) | |
tree | 874b10fc11da3178e4630f7a430e1b299d3b3806 /lib/iov_iter.c | |
parent | 00e23707442a75b404392cef1405ab4fd498de6b (diff) |
iov_iter: Separate type from direction and use accessor functions
In the iov_iter struct, separate the iterator type from the iterator
direction and use accessor functions to access them in most places.
Convert a bunch of places to use switch-statements to access them rather
then chains of bitwise-AND statements. This makes it easier to add further
iterator types. Also, this can be more efficient as to implement a switch
of small contiguous integers, the compiler can use ~50% fewer compare
instructions than it has to use bitwise-and instructions.
Further, cease passing the iterator type into the iterator setup function.
The iterator function can set that itself. Only the direction is required.
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'lib/iov_iter.c')
-rw-r--r-- | lib/iov_iter.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 42d39116a556..c42b928b15ef 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c | |||
@@ -428,17 +428,19 @@ int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes) | |||
428 | } | 428 | } |
429 | EXPORT_SYMBOL(iov_iter_fault_in_readable); | 429 | EXPORT_SYMBOL(iov_iter_fault_in_readable); |
430 | 430 | ||
431 | void iov_iter_init(struct iov_iter *i, int direction, | 431 | void iov_iter_init(struct iov_iter *i, unsigned int direction, |
432 | const struct iovec *iov, unsigned long nr_segs, | 432 | const struct iovec *iov, unsigned long nr_segs, |
433 | size_t count) | 433 | size_t count) |
434 | { | 434 | { |
435 | WARN_ON(direction & ~(READ | WRITE)); | ||
436 | direction &= READ | WRITE; | ||
437 | |||
435 | /* It will get better. Eventually... */ | 438 | /* It will get better. Eventually... */ |
436 | if (uaccess_kernel()) { | 439 | if (uaccess_kernel()) { |
437 | direction |= ITER_KVEC; | 440 | i->type = ITER_KVEC | direction; |
438 | i->type = direction; | ||
439 | i->kvec = (struct kvec *)iov; | 441 | i->kvec = (struct kvec *)iov; |
440 | } else { | 442 | } else { |
441 | i->type = direction; | 443 | i->type = ITER_IOVEC | direction; |
442 | i->iov = iov; | 444 | i->iov = iov; |
443 | } | 445 | } |
444 | i->nr_segs = nr_segs; | 446 | i->nr_segs = nr_segs; |
@@ -1060,12 +1062,12 @@ size_t iov_iter_single_seg_count(const struct iov_iter *i) | |||
1060 | } | 1062 | } |
1061 | EXPORT_SYMBOL(iov_iter_single_seg_count); | 1063 | EXPORT_SYMBOL(iov_iter_single_seg_count); |
1062 | 1064 | ||
1063 | void iov_iter_kvec(struct iov_iter *i, int direction, | 1065 | void iov_iter_kvec(struct iov_iter *i, unsigned int direction, |
1064 | const struct kvec *kvec, unsigned long nr_segs, | 1066 | const struct kvec *kvec, unsigned long nr_segs, |
1065 | size_t count) | 1067 | size_t count) |
1066 | { | 1068 | { |
1067 | BUG_ON(!(direction & ITER_KVEC)); | 1069 | WARN_ON(direction & ~(READ | WRITE)); |
1068 | i->type = direction; | 1070 | i->type = ITER_KVEC | (direction & (READ | WRITE)); |
1069 | i->kvec = kvec; | 1071 | i->kvec = kvec; |
1070 | i->nr_segs = nr_segs; | 1072 | i->nr_segs = nr_segs; |
1071 | i->iov_offset = 0; | 1073 | i->iov_offset = 0; |
@@ -1073,12 +1075,12 @@ void iov_iter_kvec(struct iov_iter *i, int direction, | |||
1073 | } | 1075 | } |
1074 | EXPORT_SYMBOL(iov_iter_kvec); | 1076 | EXPORT_SYMBOL(iov_iter_kvec); |
1075 | 1077 | ||
1076 | void iov_iter_bvec(struct iov_iter *i, int direction, | 1078 | void iov_iter_bvec(struct iov_iter *i, unsigned int direction, |
1077 | const struct bio_vec *bvec, unsigned long nr_segs, | 1079 | const struct bio_vec *bvec, unsigned long nr_segs, |
1078 | size_t count) | 1080 | size_t count) |
1079 | { | 1081 | { |
1080 | BUG_ON(!(direction & ITER_BVEC)); | 1082 | WARN_ON(direction & ~(READ | WRITE)); |
1081 | i->type = direction; | 1083 | i->type = ITER_BVEC | (direction & (READ | WRITE)); |
1082 | i->bvec = bvec; | 1084 | i->bvec = bvec; |
1083 | i->nr_segs = nr_segs; | 1085 | i->nr_segs = nr_segs; |
1084 | i->iov_offset = 0; | 1086 | i->iov_offset = 0; |
@@ -1086,13 +1088,13 @@ void iov_iter_bvec(struct iov_iter *i, int direction, | |||
1086 | } | 1088 | } |
1087 | EXPORT_SYMBOL(iov_iter_bvec); | 1089 | EXPORT_SYMBOL(iov_iter_bvec); |
1088 | 1090 | ||
1089 | void iov_iter_pipe(struct iov_iter *i, int direction, | 1091 | void iov_iter_pipe(struct iov_iter *i, unsigned int direction, |
1090 | struct pipe_inode_info *pipe, | 1092 | struct pipe_inode_info *pipe, |
1091 | size_t count) | 1093 | size_t count) |
1092 | { | 1094 | { |
1093 | BUG_ON(direction != ITER_PIPE); | 1095 | BUG_ON(direction != READ); |
1094 | WARN_ON(pipe->nrbufs == pipe->buffers); | 1096 | WARN_ON(pipe->nrbufs == pipe->buffers); |
1095 | i->type = direction; | 1097 | i->type = ITER_PIPE | READ; |
1096 | i->pipe = pipe; | 1098 | i->pipe = pipe; |
1097 | i->idx = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1); | 1099 | i->idx = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1); |
1098 | i->iov_offset = 0; | 1100 | i->iov_offset = 0; |