iov_iter: unify iterate_iovec and iterate_kvec
authorAl Viro <viro@zeniv.linux.org.uk>
Mon, 26 Apr 2021 03:57:42 +0000 (23:57 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 10 Jun 2021 15:45:16 +0000 (11:45 -0400)
The differences between iterate_iovec and iterate_kvec are minor:
* kvec callback is treated as if it returned 0
* initialization of __p is with i->iov and i->kvec resp.
which is trivially dealt with.

No code generation changes - compiler is quite capable of turning
left = ((void)(STEP), 0);
__v.iov_len -= left;
(with no accesses to left downstream) and
(void)(STEP);
into the same code.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
lib/iov_iter.c

index 2098059..fc071d7 100644 (file)
 
 #define PIPE_PARANOIA /* for now */
 
+/* covers iovec and kvec alike */
 #define iterate_iovec(i, n, __v, __p, skip, STEP) {            \
        size_t left;                                            \
        size_t wanted = n;                                      \
-       __p = i->iov;                                           \
        do {                                                    \
                __v.iov_len = min(n, __p->iov_len - skip);      \
                if (likely(__v.iov_len)) {                      \
        n = wanted - n;                                         \
 }
 
-#define iterate_kvec(i, n, __v, __p, skip, STEP) {             \
-       size_t wanted = n;                                      \
-       __p = i->kvec;                                          \
-       do {                                                    \
-               __v.iov_len = min(n, __p->iov_len - skip);      \
-               if (likely(__v.iov_len)) {                      \
-                       __v.iov_base = __p->iov_base + skip;    \
-                       (void)(STEP);                           \
-                       skip += __v.iov_len;                    \
-                       n -= __v.iov_len;                       \
-                       if (skip < __p->iov_len)                \
-                               break;                          \
-               }                                               \
-               __p++;                                          \
-               skip = 0;                                       \
-       } while (n);                                            \
-       n = wanted - n;                                         \
-}
-
 #define iterate_bvec(i, n, __v, __bi, skip, STEP) {    \
        struct bvec_iter __start;                       \
        __start.bi_size = n;                            \
        if (likely(n)) {                                        \
                size_t skip = i->iov_offset;                    \
                if (likely(iter_is_iovec(i))) {                 \
-                       const struct iovec *iov;                \
+                       const struct iovec *iov = i->iov;       \
                        struct iovec v;                         \
                        iterate_iovec(i, n, v, iov, skip, (I))  \
                        i->nr_segs -= iov - i->iov;             \
                        i->nr_segs -= i->bvec - bvec;           \
                        skip = __bi.bi_bvec_done;               \
                } else if (iov_iter_is_kvec(i)) {               \
-                       const struct kvec *kvec;                \
+                       const struct kvec *kvec = i->kvec;      \
                        struct kvec v;                          \
-                       iterate_kvec(i, n, v, kvec, skip, (K))  \
+                       iterate_iovec(i, n, v, kvec, skip,      \
+                                               ((void)(K),0))  \
                        i->nr_segs -= kvec - i->kvec;           \
                        i->kvec = kvec;                         \
                } else if (iov_iter_is_xarray(i)) {             \