All of lore.kernel.org
 help / color / mirror / Atom feed
From: Al Viro <viro@zeniv.linux.org.uk>
To: Christoph Hellwig <hch@lst.de>
Cc: Greg KH <gregkh@linuxfoundation.org>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Alexey Dobriyan <adobriyan@gmail.com>,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/6] seq_file: add seq_read_iter
Date: Tue, 10 Nov 2020 21:32:53 +0000	[thread overview]
Message-ID: <20201110213253.GV3576660@ZenIV.linux.org.uk> (raw)
In-Reply-To: <20201104082738.1054792-2-hch@lst.de>

On Wed, Nov 04, 2020 at 09:27:33AM +0100, Christoph Hellwig wrote:

>  ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
>  {
> -	struct seq_file *m = file->private_data;
> +	struct iovec iov = { .iov_base = buf, .iov_len = size};
> +	struct kiocb kiocb;
> +	struct iov_iter iter;
> +	ssize_t ret;
> +
> +	init_sync_kiocb(&kiocb, file);
> +	iov_iter_init(&iter, READ, &iov, 1, size);
> +
> +	kiocb.ki_pos = *ppos;
> +	ret = seq_read_iter(&kiocb, &iter);
> +	*ppos = kiocb.ki_pos;
> +	return ret;
> +}
> +EXPORT_SYMBOL(seq_read);

This is basically an open-coded copy of new_sync_read()...

>  	if (m->count) {
>  		n = min(m->count, size);
> -		err = copy_to_user(buf, m->buf + m->from, n);
> -		if (err)
> +		if (copy_to_iter(m->buf + m->from, n, iter) != n)
>  			goto Efault;
>  		m->count -= n;
>  		m->from += n;
>  		size -= n;
> -		buf += n;
>  		copied += n;
>  		if (!size)
>  			goto Done;

>  	n = min(m->count, size);
> -	err = copy_to_user(buf, m->buf, n);
> -	if (err)
> +	if (copy_to_iter(m->buf, n, iter) != n)
>  		goto Efault;

This is actually broken from generic_file_splice_read() POV; if you've
already emitted something, you will end up with more data spewed into
pipe than you report to caller.  You want something similar to
copy_to_iter_full() here, with iterator _not_ advanced in case of
failure.  The first call is not an issue (you have no data copied
yet, so you'll end up with -EFAULT, aka "discard everything you've
put there and return -EAGAIN"), but the second really is a problem.

BTW, other ->read_iter() instances might need to be careful with that
pattern as well; drivers/gpu/drm/drm_dp_aux_dev.c:auxdev_read_iter()
would appear to have the same problem.

<greps some more>
                if (unlikely(iov_iter_is_pipe(iter))) {
                        void *addr = kmap_atomic(page);

                        written = copy_to_iter(addr, copy, iter);
                        kunmap_atomic(addr);   
                } else
in fs/cifs/file.c looks... interesting, considering the fact that
copy_to_iter() for pipe destination might very well have to do
allocations.  With GFP_USER.  Under kmap_atomic()...

Note that we have this:
static inline int copy_linear_skb(struct sk_buff *skb, int len, int off,
                                  struct iov_iter *to)
{
        int n;

        n = copy_to_iter(skb->data + off, len, to);
        if (n == len)
                return 0;

        iov_iter_revert(to, n);
        return -EFAULT;
}
i.e. the same "do not advance on short copy" kind of thing.

AFAICS, not all callers want that semantics, but I think it's worth
a new primitive.  I'm not saying it should be a prereq for your
series, but either that or an explicit iov_iter_revert() is needed.

  reply	other threads:[~2020-11-10 21:33 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-04  8:27 support splice reads on seq_file based procfs files v2 Christoph Hellwig
2020-11-04  8:27 ` [PATCH 1/6] seq_file: add seq_read_iter Christoph Hellwig
2020-11-10 21:32   ` Al Viro [this message]
2020-11-10 21:35     ` Al Viro
2020-11-10 23:20       ` Al Viro
2020-11-11  7:55         ` Christoph Hellwig
2020-11-11 17:54         ` Linus Torvalds
2020-11-11 21:52           ` Al Viro
2020-11-11 22:21             ` Al Viro
2020-11-11 22:27               ` Linus Torvalds
2020-11-11 23:00                 ` Al Viro
2020-11-13 23:54               ` Nathan Chancellor
2020-11-14  1:17                 ` Al Viro
2020-11-14  3:01                   ` Nathan Chancellor
2020-11-14  3:54                     ` Al Viro
2020-11-14  4:14                       ` Nathan Chancellor
2020-11-14  5:50                         ` Al Viro
2020-11-14  6:19                           ` Nathan Chancellor
2020-11-14  7:00                             ` Al Viro
2020-11-14 20:50                               ` Al Viro
2020-11-15 15:53                                 ` Al Viro
2020-11-15 16:56                                   ` Linus Torvalds
2020-11-15 21:41                                   ` Nathan Chancellor
2020-11-15 23:38                                     ` Al Viro
2020-11-15 23:51                                       ` Nathan Chancellor
2020-11-16  0:25                                         ` Al Viro
2020-11-16  0:34                                           ` Nathan Chancellor
2020-11-16  3:29                                             ` Al Viro
2020-11-27 16:29                                               ` Christoph Hellwig
2020-12-08 16:35                                                 ` Christoph Hellwig
2020-12-08 18:34                                                   ` Linus Torvalds
2020-12-08 19:49                                                     ` Al Viro
2020-12-08 20:25                                                       ` Linus Torvalds
2020-12-08 20:53                                                         ` Al Viro
2020-12-08 21:01                                                           ` Linus Torvalds
2020-12-08 19:49                                                     ` Greg KH
2020-11-14 21:44                 ` Al Viro
2020-11-04  8:27 ` [PATCH 2/6] proc: wire up generic_file_splice_read for iter ops Christoph Hellwig
2020-11-04  8:27 ` [PATCH 3/6] proc/cpuinfo: switch to ->read_iter Christoph Hellwig
2020-11-04  8:27 ` [PATCH 4/6] proc/stat: " Christoph Hellwig
2020-11-04  8:27 ` [PATCH 5/6] proc "single files": " Christoph Hellwig
2020-11-04  8:27 ` [PATCH 6/6] proc "seq " Christoph Hellwig
2020-11-04 17:53 ` support splice reads on seq_file based procfs files v2 Linus Torvalds

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201110213253.GV3576660@ZenIV.linux.org.uk \
    --to=viro@zeniv.linux.org.uk \
    --cc=adobriyan@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=hch@lst.de \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.