iov_iter: Use accessor function
authorDavid Howells <dhowells@redhat.com>
Mon, 22 Oct 2018 12:07:28 +0000 (13:07 +0100)
committerDavid Howells <dhowells@redhat.com>
Tue, 23 Oct 2018 23:40:44 +0000 (00:40 +0100)
Use accessor functions to access an iterator's type and direction.  This
allows for the possibility of using some other method of determining the
type of iterator than if-chains with bitwise-AND conditions.

Signed-off-by: David Howells <dhowells@redhat.com>
14 files changed:
block/bio.c
fs/block_dev.c
fs/ceph/file.c
fs/cifs/file.c
fs/cifs/misc.c
fs/cifs/smbdirect.c
fs/direct-io.c
fs/fuse/file.c
fs/iomap.c
include/linux/uio.h
lib/iov_iter.c
mm/filemap.c
net/9p/trans_virtio.c
net/tls/tls_sw.c

index 0093bed81c0e85882066499dcd92c5e94bd8a35d..c55f36bbe12acb925bafbea596ce9b861ba02f63 100644 (file)
@@ -1255,7 +1255,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
        /*
         * success
         */
-       if (((iter->type & WRITE) && (!map_data || !map_data->null_mapped)) ||
+       if ((iov_iter_rw(iter) == WRITE && (!map_data || !map_data->null_mapped)) ||
            (map_data && map_data->from_user)) {
                ret = bio_copy_from_iter(bio, iter);
                if (ret)
index 38b8ce05cbc7e693d5d4b835eb586c586680ef0c..a80b4f0ee7c4f172d19b4df1c8c330e4c0738557 100644 (file)
@@ -349,7 +349,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
 
        dio->size = 0;
        dio->multi_bio = false;
-       dio->should_dirty = is_read && (iter->type == ITER_IOVEC);
+       dio->should_dirty = is_read && iter_is_iovec(iter);
 
        blk_start_plug(&plug);
        for (;;) {
index 92ab2043368291e68c5c4b67b2da7e6bfdd25fcf..524ecc95b04dee00279a59da29ac370a17812d33 100644 (file)
@@ -658,7 +658,7 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *to,
        if (ret < 0)
                return ret;
 
-       if (unlikely(to->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(to))) {
                size_t page_off;
                ret = iov_iter_get_pages_alloc(to, &pages, len,
                                               &page_off);
index 8d41ca7bfcf1fe8f0eb0e3e8c6272547e09cc16c..dcdbcb6f09f825c978545188c3f98309bb6e7202 100644 (file)
@@ -2990,7 +2990,7 @@ cifs_readdata_to_iov(struct cifs_readdata *rdata, struct iov_iter *iter)
                size_t copy = min_t(size_t, remaining, PAGE_SIZE);
                size_t written;
 
-               if (unlikely(iter->type & ITER_PIPE)) {
+               if (unlikely(iov_iter_is_pipe(iter))) {
                        void *addr = kmap_atomic(page);
 
                        written = copy_to_iter(addr, copy, iter);
@@ -3302,7 +3302,7 @@ ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to)
        if (!is_sync_kiocb(iocb))
                ctx->iocb = iocb;
 
-       if (to->type == ITER_IOVEC)
+       if (iter_is_iovec(to))
                ctx->should_dirty = true;
 
        rc = setup_aio_ctx_iter(ctx, to, READ);
index 6926685e513cf4a3691df7efba36eb3dcb578b83..7b5b960a04b8cea3604d5741bebc96d0503c2270 100644 (file)
@@ -786,7 +786,7 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw)
        struct page **pages = NULL;
        struct bio_vec *bv = NULL;
 
-       if (iter->type & ITER_KVEC) {
+       if (iov_iter_is_kvec(iter)) {
                memcpy(&ctx->iter, iter, sizeof(struct iov_iter));
                ctx->len = count;
                iov_iter_advance(iter, count);
index 5fdb9a509a97f13fddba3099dc9d9720a3b78d51..5b05bf2552682940752e9c41e57aa40e9adfa229 100644 (file)
@@ -2054,14 +2054,22 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
 
        info->smbd_recv_pending++;
 
-       switch (msg->msg_iter.type) {
-       case READ | ITER_KVEC:
+       if (iov_iter_rw(&msg->msg_iter) == WRITE) {
+               /* It's a bug in upper layer to get there */
+               cifs_dbg(VFS, "CIFS: invalid msg iter dir %u\n",
+                        iov_iter_rw(&msg->msg_iter));
+               rc = -EINVAL;
+               goto out;
+       }
+
+       switch (iov_iter_type(&msg->msg_iter)) {
+       case ITER_KVEC:
                buf = msg->msg_iter.kvec->iov_base;
                to_read = msg->msg_iter.kvec->iov_len;
                rc = smbd_recv_buf(info, buf, to_read);
                break;
 
-       case READ | ITER_BVEC:
+       case ITER_BVEC:
                page = msg->msg_iter.bvec->bv_page;
                page_offset = msg->msg_iter.bvec->bv_offset;
                to_read = msg->msg_iter.bvec->bv_len;
@@ -2071,10 +2079,11 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
        default:
                /* It's a bug in upper layer to get there */
                cifs_dbg(VFS, "CIFS: invalid msg type %d\n",
-                       msg->msg_iter.type);
+                        iov_iter_type(&msg->msg_iter));
                rc = -EINVAL;
        }
 
+out:
        info->smbd_recv_pending--;
        wake_up(&info->wait_smbd_recv_pending);
 
index 093fb54cd3163d96b03ebf3b0bea4a83a26bb02a..722d17c88edb9016ac910072f4f758605089ec83 100644 (file)
@@ -1313,7 +1313,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
        spin_lock_init(&dio->bio_lock);
        dio->refcount = 1;
 
-       dio->should_dirty = (iter->type == ITER_IOVEC);
+       dio->should_dirty = iter_is_iovec(iter) && iov_iter_rw(iter) == READ;
        sdio.iter = iter;
        sdio.final_block_in_request = end >> blkbits;
 
index 32d0b883e74f340d442754a5a87b82629b96658e..c9ccd45156dc907fc6abdaadb660b7984fbf6b5d 100644 (file)
@@ -1271,7 +1271,7 @@ static int fuse_get_user_pages(struct fuse_req *req, struct iov_iter *ii,
        ssize_t ret = 0;
 
        /* Special case for kernel I/O: can copy directly into the buffer */
-       if (ii->type & ITER_KVEC) {
+       if (iov_iter_is_kvec(ii)) {
                unsigned long user_addr = fuse_get_user_addr(ii);
                size_t frag_size = fuse_get_frag_size(ii, *nbytesp);
 
index ec15cf2ec696dae1f77a2c45fe4fd7129bbc2e29..2c53400aa802e198abc4c54e5e669665ce5f1d06 100644 (file)
@@ -1795,7 +1795,7 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
                if (pos >= dio->i_size)
                        goto out_free_dio;
 
-               if (iter->type == ITER_IOVEC)
+               if (iter_is_iovec(iter) && iov_iter_rw(iter) == READ)
                        dio->flags |= IOMAP_DIO_DIRTY;
        } else {
                flags |= IOMAP_WRITE;
index 422b1c01ee0de0d679d7f6cb4276bb7d45e82186..fcabc959c794d47be8732c54ff1f43f039e77ddd 100644 (file)
@@ -21,7 +21,7 @@ struct kvec {
        size_t iov_len;
 };
 
-enum {
+enum iter_type {
        ITER_IOVEC = 0,
        ITER_KVEC = 2,
        ITER_BVEC = 4,
@@ -47,6 +47,36 @@ struct iov_iter {
        };
 };
 
+static inline enum iter_type iov_iter_type(const struct iov_iter *i)
+{
+       return i->type & ~(READ | WRITE);
+}
+
+static inline bool iter_is_iovec(const struct iov_iter *i)
+{
+       return iov_iter_type(i) == ITER_IOVEC;
+}
+
+static inline bool iov_iter_is_kvec(const struct iov_iter *i)
+{
+       return iov_iter_type(i) == ITER_KVEC;
+}
+
+static inline bool iov_iter_is_bvec(const struct iov_iter *i)
+{
+       return iov_iter_type(i) == ITER_BVEC;
+}
+
+static inline bool iov_iter_is_pipe(const struct iov_iter *i)
+{
+       return iov_iter_type(i) == ITER_PIPE;
+}
+
+static inline unsigned char iov_iter_rw(const struct iov_iter *i)
+{
+       return i->type & (READ | WRITE);
+}
+
 /*
  * Total number of bytes covered by an iovec.
  *
@@ -74,7 +104,8 @@ static inline struct iovec iov_iter_iovec(const struct iov_iter *iter)
 }
 
 #define iov_for_each(iov, iter, start)                         \
-       if (!((start).type & (ITER_BVEC | ITER_PIPE)))          \
+       if (iov_iter_type(start) == ITER_IOVEC ||               \
+           iov_iter_type(start) == ITER_KVEC)                  \
        for (iter = (start);                                    \
             (iter).count &&                                    \
             ((iov = iov_iter_iovec(&(iter))), 1);              \
@@ -202,19 +233,6 @@ static inline size_t iov_iter_count(const struct iov_iter *i)
        return i->count;
 }
 
-static inline bool iter_is_iovec(const struct iov_iter *i)
-{
-       return !(i->type & (ITER_BVEC | ITER_KVEC | ITER_PIPE));
-}
-
-/*
- * Get one of READ or WRITE out of iter->type without any other flags OR'd in
- * with it.
- *
- * The ?: is just for type safety.
- */
-#define iov_iter_rw(i) ((0 ? (struct iov_iter *)0 : (i))->type & (READ | WRITE))
-
 /*
  * Cap the iov_iter by given limit; note that the second argument is
  * *not* the new size - it's upper limit for such.  Passing it a value
index 8be175df30753c95692007a5d41503838344d9a5..42d39116a5564daf057b6248eb95e433c4c101db 100644 (file)
@@ -558,7 +558,7 @@ static size_t copy_pipe_to_iter(const void *addr, size_t bytes,
 size_t _copy_to_iter(const void *addr, size_t bytes, struct iov_iter *i)
 {
        const char *from = addr;
-       if (unlikely(i->type & ITER_PIPE))
+       if (unlikely(iov_iter_is_pipe(i)))
                return copy_pipe_to_iter(addr, bytes, i);
        if (iter_is_iovec(i))
                might_fault();
@@ -658,7 +658,7 @@ size_t _copy_to_iter_mcsafe(const void *addr, size_t bytes, struct iov_iter *i)
        const char *from = addr;
        unsigned long rem, curr_addr, s_addr = (unsigned long) addr;
 
-       if (unlikely(i->type & ITER_PIPE))
+       if (unlikely(iov_iter_is_pipe(i)))
                return copy_pipe_to_iter_mcsafe(addr, bytes, i);
        if (iter_is_iovec(i))
                might_fault();
@@ -692,7 +692,7 @@ EXPORT_SYMBOL_GPL(_copy_to_iter_mcsafe);
 size_t _copy_from_iter(void *addr, size_t bytes, struct iov_iter *i)
 {
        char *to = addr;
-       if (unlikely(i->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(i))) {
                WARN_ON(1);
                return 0;
        }
@@ -712,7 +712,7 @@ EXPORT_SYMBOL(_copy_from_iter);
 bool _copy_from_iter_full(void *addr, size_t bytes, struct iov_iter *i)
 {
        char *to = addr;
-       if (unlikely(i->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(i))) {
                WARN_ON(1);
                return false;
        }
@@ -739,7 +739,7 @@ EXPORT_SYMBOL(_copy_from_iter_full);
 size_t _copy_from_iter_nocache(void *addr, size_t bytes, struct iov_iter *i)
 {
        char *to = addr;
-       if (unlikely(i->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(i))) {
                WARN_ON(1);
                return 0;
        }
@@ -773,7 +773,7 @@ EXPORT_SYMBOL(_copy_from_iter_nocache);
 size_t _copy_from_iter_flushcache(void *addr, size_t bytes, struct iov_iter *i)
 {
        char *to = addr;
-       if (unlikely(i->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(i))) {
                WARN_ON(1);
                return 0;
        }
@@ -794,7 +794,7 @@ EXPORT_SYMBOL_GPL(_copy_from_iter_flushcache);
 bool _copy_from_iter_full_nocache(void *addr, size_t bytes, struct iov_iter *i)
 {
        char *to = addr;
-       if (unlikely(i->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(i))) {
                WARN_ON(1);
                return false;
        }
@@ -836,7 +836,7 @@ size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes,
                size_t wanted = copy_to_iter(kaddr + offset, bytes, i);
                kunmap_atomic(kaddr);
                return wanted;
-       } else if (likely(!(i->type & ITER_PIPE)))
+       } else if (likely(!iov_iter_is_pipe(i)))
                return copy_page_to_iter_iovec(page, offset, bytes, i);
        else
                return copy_page_to_iter_pipe(page, offset, bytes, i);
@@ -848,7 +848,7 @@ size_t copy_page_from_iter(struct page *page, size_t offset, size_t bytes,
 {
        if (unlikely(!page_copy_sane(page, offset, bytes)))
                return 0;
-       if (unlikely(i->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(i))) {
                WARN_ON(1);
                return 0;
        }
@@ -888,7 +888,7 @@ static size_t pipe_zero(size_t bytes, struct iov_iter *i)
 
 size_t iov_iter_zero(size_t bytes, struct iov_iter *i)
 {
-       if (unlikely(i->type & ITER_PIPE))
+       if (unlikely(iov_iter_is_pipe(i)))
                return pipe_zero(bytes, i);
        iterate_and_advance(i, bytes, v,
                clear_user(v.iov_base, v.iov_len),
@@ -908,7 +908,7 @@ size_t iov_iter_copy_from_user_atomic(struct page *page,
                kunmap_atomic(kaddr);
                return 0;
        }
-       if (unlikely(i->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(i))) {
                kunmap_atomic(kaddr);
                WARN_ON(1);
                return 0;
@@ -972,7 +972,7 @@ static void pipe_advance(struct iov_iter *i, size_t size)
 
 void iov_iter_advance(struct iov_iter *i, size_t size)
 {
-       if (unlikely(i->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(i))) {
                pipe_advance(i, size);
                return;
        }
@@ -987,7 +987,7 @@ void iov_iter_revert(struct iov_iter *i, size_t unroll)
        if (WARN_ON(unroll > MAX_RW_COUNT))
                return;
        i->count += unroll;
-       if (unlikely(i->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(i))) {
                struct pipe_inode_info *pipe = i->pipe;
                int idx = i->idx;
                size_t off = i->iov_offset;
@@ -1016,7 +1016,7 @@ void iov_iter_revert(struct iov_iter *i, size_t unroll)
                return;
        }
        unroll -= i->iov_offset;
-       if (i->type & ITER_BVEC) {
+       if (iov_iter_is_bvec(i)) {
                const struct bio_vec *bvec = i->bvec;
                while (1) {
                        size_t n = (--bvec)->bv_len;
@@ -1049,11 +1049,11 @@ EXPORT_SYMBOL(iov_iter_revert);
  */
 size_t iov_iter_single_seg_count(const struct iov_iter *i)
 {
-       if (unlikely(i->type & ITER_PIPE))
+       if (unlikely(iov_iter_is_pipe(i)))
                return i->count;        // it is a silly place, anyway
        if (i->nr_segs == 1)
                return i->count;
-       else if (i->type & ITER_BVEC)
+       else if (iov_iter_is_bvec(i))
                return min(i->count, i->bvec->bv_len - i->iov_offset);
        else
                return min(i->count, i->iov->iov_len - i->iov_offset);
@@ -1106,7 +1106,7 @@ unsigned long iov_iter_alignment(const struct iov_iter *i)
        unsigned long res = 0;
        size_t size = i->count;
 
-       if (unlikely(i->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(i))) {
                if (size && i->iov_offset && allocated(&i->pipe->bufs[i->idx]))
                        return size | i->iov_offset;
                return size;
@@ -1125,7 +1125,7 @@ unsigned long iov_iter_gap_alignment(const struct iov_iter *i)
        unsigned long res = 0;
        size_t size = i->count;
 
-       if (unlikely(i->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(i))) {
                WARN_ON(1);
                return ~0U;
        }
@@ -1193,7 +1193,7 @@ ssize_t iov_iter_get_pages(struct iov_iter *i,
        if (maxsize > i->count)
                maxsize = i->count;
 
-       if (unlikely(i->type & ITER_PIPE))
+       if (unlikely(iov_iter_is_pipe(i)))
                return pipe_get_pages(i, pages, maxsize, maxpages, start);
        iterate_all_kinds(i, maxsize, v, ({
                unsigned long addr = (unsigned long)v.iov_base;
@@ -1205,7 +1205,7 @@ ssize_t iov_iter_get_pages(struct iov_iter *i,
                        len = maxpages * PAGE_SIZE;
                addr &= ~(PAGE_SIZE - 1);
                n = DIV_ROUND_UP(len, PAGE_SIZE);
-               res = get_user_pages_fast(addr, n, (i->type & WRITE) != WRITE, pages);
+               res = get_user_pages_fast(addr, n, iov_iter_rw(i) != WRITE, pages);
                if (unlikely(res < 0))
                        return res;
                return (res == n ? len : res * PAGE_SIZE) - *start;
@@ -1270,7 +1270,7 @@ ssize_t iov_iter_get_pages_alloc(struct iov_iter *i,
        if (maxsize > i->count)
                maxsize = i->count;
 
-       if (unlikely(i->type & ITER_PIPE))
+       if (unlikely(iov_iter_is_pipe(i)))
                return pipe_get_pages_alloc(i, pages, maxsize, start);
        iterate_all_kinds(i, maxsize, v, ({
                unsigned long addr = (unsigned long)v.iov_base;
@@ -1283,7 +1283,7 @@ ssize_t iov_iter_get_pages_alloc(struct iov_iter *i,
                p = get_pages_array(n);
                if (!p)
                        return -ENOMEM;
-               res = get_user_pages_fast(addr, n, (i->type & WRITE) != WRITE, p);
+               res = get_user_pages_fast(addr, n, iov_iter_rw(i) != WRITE, p);
                if (unlikely(res < 0)) {
                        kvfree(p);
                        return res;
@@ -1313,7 +1313,7 @@ size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum,
        __wsum sum, next;
        size_t off = 0;
        sum = *csum;
-       if (unlikely(i->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(i))) {
                WARN_ON(1);
                return 0;
        }
@@ -1355,7 +1355,7 @@ bool csum_and_copy_from_iter_full(void *addr, size_t bytes, __wsum *csum,
        __wsum sum, next;
        size_t off = 0;
        sum = *csum;
-       if (unlikely(i->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(i))) {
                WARN_ON(1);
                return false;
        }
@@ -1400,7 +1400,7 @@ size_t csum_and_copy_to_iter(const void *addr, size_t bytes, __wsum *csum,
        __wsum sum, next;
        size_t off = 0;
        sum = *csum;
-       if (unlikely(i->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(i))) {
                WARN_ON(1);     /* for now */
                return 0;
        }
@@ -1443,7 +1443,7 @@ int iov_iter_npages(const struct iov_iter *i, int maxpages)
        if (!size)
                return 0;
 
-       if (unlikely(i->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(i))) {
                struct pipe_inode_info *pipe = i->pipe;
                size_t off;
                int idx;
@@ -1481,11 +1481,11 @@ EXPORT_SYMBOL(iov_iter_npages);
 const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags)
 {
        *new = *old;
-       if (unlikely(new->type & ITER_PIPE)) {
+       if (unlikely(iov_iter_is_pipe(new))) {
                WARN_ON(1);
                return NULL;
        }
-       if (new->type & ITER_BVEC)
+       if (iov_iter_is_bvec(new))
                return new->bvec = kmemdup(new->bvec,
                                    new->nr_segs * sizeof(struct bio_vec),
                                    flags);
index 52517f28e6f4a69020cfc60867f5a57461c89fb8..bdeee0168ea75bca333755f54f7215a41c517150 100644 (file)
@@ -2122,7 +2122,7 @@ find_page:
                                        !mapping->a_ops->is_partially_uptodate)
                                goto page_not_up_to_date;
                        /* pipes can't handle partially uptodate pages */
-                       if (unlikely(iter->type & ITER_PIPE))
+                       if (unlikely(iov_iter_is_pipe(iter)))
                                goto page_not_up_to_date;
                        if (!trylock_page(page))
                                goto page_not_up_to_date;
index 7728b0acde09aa904f4cc564de23f264abd8d2b6..4d7d2070e9c85917d75a4a5654a52ea99a62f7c0 100644 (file)
@@ -322,7 +322,7 @@ static int p9_get_mapped_pages(struct virtio_chan *chan,
        if (!iov_iter_count(data))
                return 0;
 
-       if (!(data->type & ITER_KVEC)) {
+       if (iov_iter_is_kvec(data)) {
                int n;
                /*
                 * We allow only p9_max_pages pinned. We wait for the
index a525fc4c2a4b9a12496ff4ef86fdf82e5137ebc5..ad64b9c8b6006593815bb366589b780f65e92ab2 100644 (file)
@@ -799,7 +799,7 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
        struct crypto_tfm *tfm = crypto_aead_tfm(ctx->aead_send);
        bool async_capable = tfm->__crt_alg->cra_flags & CRYPTO_ALG_ASYNC;
        unsigned char record_type = TLS_RECORD_TYPE_DATA;
-       bool is_kvec = msg->msg_iter.type & ITER_KVEC;
+       bool is_kvec = iov_iter_is_kvec(&msg->msg_iter);
        bool eor = !(msg->msg_flags & MSG_MORE);
        size_t try_to_copy, copied = 0;
        struct sk_msg *msg_pl, *msg_en;
@@ -1457,7 +1457,7 @@ int tls_sw_recvmsg(struct sock *sk,
        bool cmsg = false;
        int target, err = 0;
        long timeo;
-       bool is_kvec = msg->msg_iter.type & ITER_KVEC;
+       bool is_kvec = iov_iter_is_kvec(&msg->msg_iter);
        int num_async = 0;
 
        flags |= nonblock;