diff options
author | Miklos Szeredi <mszeredi@redhat.com> | 2016-09-27 04:45:12 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-10-05 18:23:58 -0400 |
commit | a779638cf622f069a484e8802134cca3c6c71415 (patch) | |
tree | a9eb77b635e86421465f6e06d1e29bc406cfdc8c | |
parent | 7bf2d1df80822ec056363627e2014990f068f7aa (diff) |
pipe: add pipe_buf_release() helper
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/fuse/dev.c | 7 | ||||
-rw-r--r-- | fs/pipe.c | 5 | ||||
-rw-r--r-- | fs/splice.c | 17 | ||||
-rw-r--r-- | include/linux/pipe_fs_i.h | 14 | ||||
-rw-r--r-- | lib/iov_iter.c | 4 |
5 files changed, 25 insertions, 22 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index b50220c75132..d82414a1f936 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -1985,10 +1985,9 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, | |||
1985 | 1985 | ||
1986 | ret = fuse_dev_do_write(fud, &cs, len); | 1986 | ret = fuse_dev_do_write(fud, &cs, len); |
1987 | 1987 | ||
1988 | for (idx = 0; idx < nbuf; idx++) { | 1988 | for (idx = 0; idx < nbuf; idx++) |
1989 | struct pipe_buffer *buf = &bufs[idx]; | 1989 | pipe_buf_release(pipe, &bufs[idx]); |
1990 | buf->ops->release(pipe, buf); | 1990 | |
1991 | } | ||
1992 | out: | 1991 | out: |
1993 | kfree(bufs); | 1992 | kfree(bufs); |
1994 | return ret; | 1993 | return ret; |
@@ -299,8 +299,7 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to) | |||
299 | } | 299 | } |
300 | 300 | ||
301 | if (!buf->len) { | 301 | if (!buf->len) { |
302 | buf->ops = NULL; | 302 | pipe_buf_release(pipe, buf); |
303 | ops->release(pipe, buf); | ||
304 | curbuf = (curbuf + 1) & (pipe->buffers - 1); | 303 | curbuf = (curbuf + 1) & (pipe->buffers - 1); |
305 | pipe->curbuf = curbuf; | 304 | pipe->curbuf = curbuf; |
306 | pipe->nrbufs = --bufs; | 305 | pipe->nrbufs = --bufs; |
@@ -664,7 +663,7 @@ void free_pipe_info(struct pipe_inode_info *pipe) | |||
664 | for (i = 0; i < pipe->buffers; i++) { | 663 | for (i = 0; i < pipe->buffers; i++) { |
665 | struct pipe_buffer *buf = pipe->bufs + i; | 664 | struct pipe_buffer *buf = pipe->bufs + i; |
666 | if (buf->ops) | 665 | if (buf->ops) |
667 | buf->ops->release(pipe, buf); | 666 | pipe_buf_release(pipe, buf); |
668 | } | 667 | } |
669 | if (pipe->tmp_page) | 668 | if (pipe->tmp_page) |
670 | __free_page(pipe->tmp_page); | 669 | __free_page(pipe->tmp_page); |
diff --git a/fs/splice.c b/fs/splice.c index 188a386bf379..ae90cd1d2999 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -238,8 +238,7 @@ ssize_t add_to_pipe(struct pipe_inode_info *pipe, struct pipe_buffer *buf) | |||
238 | pipe->nrbufs++; | 238 | pipe->nrbufs++; |
239 | return buf->len; | 239 | return buf->len; |
240 | } | 240 | } |
241 | buf->ops->release(pipe, buf); | 241 | pipe_buf_release(pipe, buf); |
242 | buf->ops = NULL; | ||
243 | return ret; | 242 | return ret; |
244 | } | 243 | } |
245 | EXPORT_SYMBOL(add_to_pipe); | 244 | EXPORT_SYMBOL(add_to_pipe); |
@@ -516,7 +515,6 @@ static int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_des | |||
516 | 515 | ||
517 | while (pipe->nrbufs) { | 516 | while (pipe->nrbufs) { |
518 | struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; | 517 | struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; |
519 | const struct pipe_buf_operations *ops = buf->ops; | ||
520 | 518 | ||
521 | sd->len = buf->len; | 519 | sd->len = buf->len; |
522 | if (sd->len > sd->total_len) | 520 | if (sd->len > sd->total_len) |
@@ -542,8 +540,7 @@ static int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_des | |||
542 | sd->total_len -= ret; | 540 | sd->total_len -= ret; |
543 | 541 | ||
544 | if (!buf->len) { | 542 | if (!buf->len) { |
545 | buf->ops = NULL; | 543 | pipe_buf_release(pipe, buf); |
546 | ops->release(pipe, buf); | ||
547 | pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1); | 544 | pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1); |
548 | pipe->nrbufs--; | 545 | pipe->nrbufs--; |
549 | if (pipe->files) | 546 | if (pipe->files) |
@@ -789,11 +786,9 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | |||
789 | while (ret) { | 786 | while (ret) { |
790 | struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; | 787 | struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; |
791 | if (ret >= buf->len) { | 788 | if (ret >= buf->len) { |
792 | const struct pipe_buf_operations *ops = buf->ops; | ||
793 | ret -= buf->len; | 789 | ret -= buf->len; |
794 | buf->len = 0; | 790 | buf->len = 0; |
795 | buf->ops = NULL; | 791 | pipe_buf_release(pipe, buf); |
796 | ops->release(pipe, buf); | ||
797 | pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1); | 792 | pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1); |
798 | pipe->nrbufs--; | 793 | pipe->nrbufs--; |
799 | if (pipe->files) | 794 | if (pipe->files) |
@@ -1032,10 +1027,8 @@ out_release: | |||
1032 | for (i = 0; i < pipe->buffers; i++) { | 1027 | for (i = 0; i < pipe->buffers; i++) { |
1033 | struct pipe_buffer *buf = pipe->bufs + i; | 1028 | struct pipe_buffer *buf = pipe->bufs + i; |
1034 | 1029 | ||
1035 | if (buf->ops) { | 1030 | if (buf->ops) |
1036 | buf->ops->release(pipe, buf); | 1031 | pipe_buf_release(pipe, buf); |
1037 | buf->ops = NULL; | ||
1038 | } | ||
1039 | } | 1032 | } |
1040 | 1033 | ||
1041 | if (!bytes) | 1034 | if (!bytes) |
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 10876f3cb3da..d24fa6da6ae3 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h | |||
@@ -126,6 +126,20 @@ static inline void pipe_buf_get(struct pipe_inode_info *pipe, | |||
126 | buf->ops->get(pipe, buf); | 126 | buf->ops->get(pipe, buf); |
127 | } | 127 | } |
128 | 128 | ||
129 | /** | ||
130 | * pipe_buf_release - put a reference to a pipe_buffer | ||
131 | * @pipe: the pipe that the buffer belongs to | ||
132 | * @buf: the buffer to put a reference to | ||
133 | */ | ||
134 | static inline void pipe_buf_release(struct pipe_inode_info *pipe, | ||
135 | struct pipe_buffer *buf) | ||
136 | { | ||
137 | const struct pipe_buf_operations *ops = buf->ops; | ||
138 | |||
139 | buf->ops = NULL; | ||
140 | ops->release(pipe, buf); | ||
141 | } | ||
142 | |||
129 | /* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual | 143 | /* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual |
130 | memory allocation, whereas PIPE_BUF makes atomicity guarantees. */ | 144 | memory allocation, whereas PIPE_BUF makes atomicity guarantees. */ |
131 | #define PIPE_SIZE PAGE_SIZE | 145 | #define PIPE_SIZE PAGE_SIZE |
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 659eaafcde65..48b8c27acabb 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c | |||
@@ -709,9 +709,7 @@ static void pipe_advance(struct iov_iter *i, size_t size) | |||
709 | int unused = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1); | 709 | int unused = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1); |
710 | /* [curbuf,unused) is in use. Free [idx,unused) */ | 710 | /* [curbuf,unused) is in use. Free [idx,unused) */ |
711 | while (idx != unused) { | 711 | while (idx != unused) { |
712 | buf = &pipe->bufs[idx]; | 712 | pipe_buf_release(pipe, &pipe->bufs[idx]); |
713 | buf->ops->release(pipe, buf); | ||
714 | buf->ops = NULL; | ||
715 | idx = next_idx(idx, pipe); | 713 | idx = next_idx(idx, pipe); |
716 | pipe->nrbufs--; | 714 | pipe->nrbufs--; |
717 | } | 715 | } |