lkml.org 
[lkml]   [2022]   [Aug]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 340/779] fs: check FMODE_LSEEK to control internal pipe splicing
    Date
    From: Jason A. Donenfeld <Jason@zx2c4.com>

    [ Upstream commit 97ef77c52b789ec1411d360ed99dca1efe4b2c81 ]

    The original direct splicing mechanism from Jens required the input to
    be a regular file because it was avoiding the special socket case. It
    also recognized blkdevs as being close enough to a regular file. But it
    forgot about chardevs, which behave the same way and work fine here.

    This is an okayish heuristic, but it doesn't totally work. For example,
    a few chardevs should be spliceable here. And a few regular files
    shouldn't. This patch fixes this by instead checking whether FMODE_LSEEK
    is set, which represents decently enough what we need rewinding for when
    splicing to internal pipes.

    Fixes: b92ce5589374 ("[PATCH] splice: add direct fd <-> fd splicing support")
    Cc: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/splice.c | 10 ++++------
    1 file changed, 4 insertions(+), 6 deletions(-)

    diff --git a/fs/splice.c b/fs/splice.c
    index 5dbce4dcc1a7..3abcd7fbc9f2 100644
    --- a/fs/splice.c
    +++ b/fs/splice.c
    @@ -814,17 +814,15 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
    {
    struct pipe_inode_info *pipe;
    long ret, bytes;
    - umode_t i_mode;
    size_t len;
    int i, flags, more;

    /*
    - * We require the input being a regular file, as we don't want to
    - * randomly drop data for eg socket -> socket splicing. Use the
    - * piped splicing for that!
    + * We require the input to be seekable, as we don't want to randomly
    + * drop data for eg socket -> socket splicing. Use the piped splicing
    + * for that!
    */
    - i_mode = file_inode(in)->i_mode;
    - if (unlikely(!S_ISREG(i_mode) && !S_ISBLK(i_mode)))
    + if (unlikely(!(in->f_mode & FMODE_LSEEK)))
    return -EINVAL;

    /*
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-08-15 21:00    [W:2.679 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site