Skip to content

Commit 241699c

Browse files
author
Al Viro
committed
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 <[email protected]>
1 parent d82718e commit 241699c

File tree

4 files changed

+408
-6
lines changed

4 files changed

+408
-6
lines changed

fs/splice.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
524524
}
525525
EXPORT_SYMBOL(generic_file_splice_read);
526526

527-
static const struct pipe_buf_operations default_pipe_buf_ops = {
527+
const struct pipe_buf_operations default_pipe_buf_ops = {
528528
.can_merge = 0,
529529
.confirm = generic_pipe_buf_confirm,
530530
.release = generic_pipe_buf_release,

include/linux/splice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,5 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
8585
extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
8686

8787
extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
88+
extern const struct pipe_buf_operations default_pipe_buf_ops;
8889
#endif

include/linux/uio.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <uapi/linux/uio.h>
1414

1515
struct page;
16+
struct pipe_inode_info;
1617

1718
struct kvec {
1819
void *iov_base; /* and that should *never* hold a userland pointer */
@@ -23,6 +24,7 @@ enum {
2324
ITER_IOVEC = 0,
2425
ITER_KVEC = 2,
2526
ITER_BVEC = 4,
27+
ITER_PIPE = 8,
2628
};
2729

2830
struct iov_iter {
@@ -33,8 +35,12 @@ struct iov_iter {
3335
const struct iovec *iov;
3436
const struct kvec *kvec;
3537
const struct bio_vec *bvec;
38+
struct pipe_inode_info *pipe;
39+
};
40+
union {
41+
unsigned long nr_segs;
42+
int idx;
3643
};
37-
unsigned long nr_segs;
3844
};
3945

4046
/*
@@ -64,7 +70,7 @@ static inline struct iovec iov_iter_iovec(const struct iov_iter *iter)
6470
}
6571

6672
#define iov_for_each(iov, iter, start) \
67-
if (!((start).type & ITER_BVEC)) \
73+
if (!((start).type & (ITER_BVEC | ITER_PIPE))) \
6874
for (iter = (start); \
6975
(iter).count && \
7076
((iov = iov_iter_iovec(&(iter))), 1); \
@@ -94,6 +100,8 @@ void iov_iter_kvec(struct iov_iter *i, int direction, const struct kvec *kvec,
94100
unsigned long nr_segs, size_t count);
95101
void iov_iter_bvec(struct iov_iter *i, int direction, const struct bio_vec *bvec,
96102
unsigned long nr_segs, size_t count);
103+
void iov_iter_pipe(struct iov_iter *i, int direction, struct pipe_inode_info *pipe,
104+
size_t count);
97105
ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages,
98106
size_t maxsize, unsigned maxpages, size_t *start);
99107
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)
109117

110118
static inline bool iter_is_iovec(struct iov_iter *i)
111119
{
112-
return !(i->type & (ITER_BVEC | ITER_KVEC));
120+
return !(i->type & (ITER_BVEC | ITER_KVEC | ITER_PIPE));
113121
}
114122

115123
/*

0 commit comments

Comments
 (0)