Skip to content

Commit

Permalink
iov_iter: Use accessor function
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
dhowells committed Oct 23, 2018
1 parent 1fcb748 commit 00e2370
Show file tree
Hide file tree
Showing 14 changed files with 87 additions and 60 deletions.
2 changes: 1 addition & 1 deletion block/bio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion fs/block_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 (;;) {
Expand Down
2 changes: 1 addition & 1 deletion fs/ceph/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions fs/cifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion fs/cifs/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
17 changes: 13 additions & 4 deletions fs/cifs/smbdirect.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion fs/direct-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion fs/fuse/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion fs/iomap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
48 changes: 33 additions & 15 deletions include/linux/uio.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct kvec {
size_t iov_len;
};

enum {
enum iter_type {
ITER_IOVEC = 0,
ITER_KVEC = 2,
ITER_BVEC = 4,
Expand All @@ -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.
*
Expand Down Expand Up @@ -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); \
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit 00e2370

Please sign in to comment.