lkml.org 
[lkml]   [2023]   [Feb]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 2/5] splice: Provide pipe_head_buf() helper
    Date
    Provide a helper, pipe_head_buf(), to get the current head buffer from a
    pipe. Implement this as a wrapper around a more general function,
    pipe_buf(), that gets a specified buffer.

    Requested-by: Christoph Hellwig <hch@lst.de>
    Signed-off-by: David Howells <dhowells@redhat.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    cc: Jens Axboe <axboe@kernel.dk>
    cc: Al Viro <viro@zeniv.linux.org.uk>
    cc: John Hubbard <jhubbard@nvidia.com>
    cc: David Hildenbrand <david@redhat.com>
    cc: Matthew Wilcox <willy@infradead.org>
    cc: linux-block@vger.kernel.org
    cc: linux-fsdevel@vger.kernel.org
    cc: linux-mm@kvack.org
    ---
    fs/splice.c | 9 +++------
    include/linux/pipe_fs_i.h | 20 ++++++++++++++++++++
    2 files changed, 23 insertions(+), 6 deletions(-)

    diff --git a/fs/splice.c b/fs/splice.c
    index 91b9e2cb9e03..7c0ff187f87a 100644
    --- a/fs/splice.c
    +++ b/fs/splice.c
    @@ -295,7 +295,6 @@ static ssize_t direct_splice_read(struct file *in, loff_t *ppos,
    struct bio_vec *bv;
    struct kiocb kiocb;
    struct page **pages;
    - unsigned int head;
    ssize_t ret;
    size_t used, npages, chunk, remain, reclaim;
    int i;
    @@ -358,9 +357,8 @@ static ssize_t direct_splice_read(struct file *in, loff_t *ppos,
    }

    /* Push the remaining pages into the pipe. */
    - head = pipe->head;
    for (i = 0; i < npages; i++) {
    - struct pipe_buffer *buf = &pipe->bufs[head & (pipe->ring_size - 1)];
    + struct pipe_buffer *buf = pipe_head_buf(pipe);

    chunk = min_t(size_t, remain, PAGE_SIZE);
    *buf = (struct pipe_buffer) {
    @@ -369,10 +367,9 @@ static ssize_t direct_splice_read(struct file *in, loff_t *ppos,
    .offset = 0,
    .len = chunk,
    };
    - head++;
    + pipe->head++;
    remain -= chunk;
    }
    - pipe->head = head;

    kfree(bv);
    return ret;
    @@ -394,7 +391,7 @@ static size_t splice_folio_into_pipe(struct pipe_inode_info *pipe,

    while (spliced < size &&
    !pipe_full(pipe->head, pipe->tail, pipe->max_usage)) {
    - struct pipe_buffer *buf = &pipe->bufs[pipe->head & (pipe->ring_size - 1)];
    + struct pipe_buffer *buf = pipe_head_buf(pipe);
    size_t part = min_t(size_t, PAGE_SIZE - offset, size - spliced);

    *buf = (struct pipe_buffer) {
    diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
    index 6cb65df3e3ba..d2c3f16cf6b1 100644
    --- a/include/linux/pipe_fs_i.h
    +++ b/include/linux/pipe_fs_i.h
    @@ -156,6 +156,26 @@ static inline bool pipe_full(unsigned int head, unsigned int tail,
    return pipe_occupancy(head, tail) >= limit;
    }

    +/**
    + * pipe_buf - Return the pipe buffer for the specified slot in the pipe ring
    + * @pipe: The pipe to access
    + * @slot: The slot of interest
    + */
    +static inline struct pipe_buffer *pipe_buf(const struct pipe_inode_info *pipe,
    + unsigned int slot)
    +{
    + return &pipe->bufs[slot & (pipe->ring_size - 1)];
    +}
    +
    +/**
    + * pipe_head_buf - Return the pipe buffer at the head of the pipe ring
    + * @pipe: The pipe to access
    + */
    +static inline struct pipe_buffer *pipe_head_buf(const struct pipe_inode_info *pipe)
    +{
    + return pipe_buf(pipe, pipe->head);
    +}
    +
    /**
    * pipe_buf_get - get a reference to a pipe_buffer
    * @pipe: the pipe that the buffer belongs to
    \
     
     \ /
      Last update: 2023-03-27 00:21    [W:3.383 / U:0.356 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site