mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
new iov_iter flavour: pipe-backed
iov_iter variant for passing data into pipe. copy_to_iter() copies data into page(s) it has allocated and stuffs them into the pipe; copy_page_to_iter() stuffs there a reference to the page given to it. Both will try to coalesce if possible. iov_iter_zero() is similar to copy_to_iter(); iov_iter_get_pages() and friends will do as copy_to_iter() would have and return the pages where the data would've been copied. iov_iter_advance() will truncate everything past the spot it has advanced to. New primitive: iov_iter_pipe(), used for initializing those. pipe should be locked all along. Running out of space acts as fault would for iovec-backed ones; in other words, giving it to ->read_iter() may result in short read if the pipe overflows, or -EFAULT if it happens with nothing copied there. In other words, ->read_iter() on those acts pretty much like ->splice_read(). Moreover, all generic_file_splice_read() users, as well as many other ->splice_read() instances can be switched to that scheme - that'll happen in the next commit. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
d82718e348
commit
241699cd72
4 changed files with 408 additions and 6 deletions
|
@ -13,6 +13,7 @@
|
|||
#include <uapi/linux/uio.h>
|
||||
|
||||
struct page;
|
||||
struct pipe_inode_info;
|
||||
|
||||
struct kvec {
|
||||
void *iov_base; /* and that should *never* hold a userland pointer */
|
||||
|
@ -23,6 +24,7 @@ enum {
|
|||
ITER_IOVEC = 0,
|
||||
ITER_KVEC = 2,
|
||||
ITER_BVEC = 4,
|
||||
ITER_PIPE = 8,
|
||||
};
|
||||
|
||||
struct iov_iter {
|
||||
|
@ -33,8 +35,12 @@ struct iov_iter {
|
|||
const struct iovec *iov;
|
||||
const struct kvec *kvec;
|
||||
const struct bio_vec *bvec;
|
||||
struct pipe_inode_info *pipe;
|
||||
};
|
||||
union {
|
||||
unsigned long nr_segs;
|
||||
int idx;
|
||||
};
|
||||
unsigned long nr_segs;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -64,7 +70,7 @@ static inline struct iovec iov_iter_iovec(const struct iov_iter *iter)
|
|||
}
|
||||
|
||||
#define iov_for_each(iov, iter, start) \
|
||||
if (!((start).type & ITER_BVEC)) \
|
||||
if (!((start).type & (ITER_BVEC | ITER_PIPE))) \
|
||||
for (iter = (start); \
|
||||
(iter).count && \
|
||||
((iov = iov_iter_iovec(&(iter))), 1); \
|
||||
|
@ -94,6 +100,8 @@ void iov_iter_kvec(struct iov_iter *i, int direction, const struct kvec *kvec,
|
|||
unsigned long nr_segs, size_t count);
|
||||
void iov_iter_bvec(struct iov_iter *i, int direction, const struct bio_vec *bvec,
|
||||
unsigned long nr_segs, size_t count);
|
||||
void iov_iter_pipe(struct iov_iter *i, int direction, struct pipe_inode_info *pipe,
|
||||
size_t count);
|
||||
ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages,
|
||||
size_t maxsize, unsigned maxpages, size_t *start);
|
||||
ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, struct page ***pages,
|
||||
|
@ -109,7 +117,7 @@ static inline size_t iov_iter_count(struct iov_iter *i)
|
|||
|
||||
static inline bool iter_is_iovec(struct iov_iter *i)
|
||||
{
|
||||
return !(i->type & (ITER_BVEC | ITER_KVEC));
|
||||
return !(i->type & (ITER_BVEC | ITER_KVEC | ITER_PIPE));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue