Re: [PATCH 34/44] fold __pipe_get_pages() into pipe_get_pages()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2022-06-22 at 05:15 +0100, Al Viro wrote:
> ... and don't mangle maxsize there - turn the loop into counting
> one instead.  Easier to see that we won't run out of array that
> way.  Note that special treatment of the partial buffer in that
> thing is an artifact of the non-advancing semantics of
> iov_iter_get_pages() - if not for that, it would be append_pipe(),
> same as the body of the loop that follows it.  IOW, once we make
> iov_iter_get_pages() advancing, the whole thing will turn into
> 	calculate how many pages do we want
> 	allocate an array (if needed)
> 	call append_pipe() that many times.
> 
> Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
> ---
>  lib/iov_iter.c | 75 +++++++++++++++++++++++++-------------------------
>  1 file changed, 38 insertions(+), 37 deletions(-)
> 
> diff --git a/lib/iov_iter.c b/lib/iov_iter.c
> index f455b8ee0d76..9280f865fd6a 100644
> --- a/lib/iov_iter.c
> +++ b/lib/iov_iter.c
> @@ -1192,60 +1192,61 @@ static struct page **get_pages_array(size_t n)
>  	return kvmalloc_array(n, sizeof(struct page *), GFP_KERNEL);
>  }
>  
> -static inline ssize_t __pipe_get_pages(struct iov_iter *i,
> -				size_t maxsize,
> -				struct page **pages,
> -				size_t off)
> -{
> -	struct pipe_inode_info *pipe = i->pipe;
> -	ssize_t left = maxsize;
> -
> -	if (off) {
> -		struct pipe_buffer *buf = pipe_buf(pipe, pipe->head - 1);
> -
> -		get_page(*pages++ = buf->page);
> -		left -= PAGE_SIZE - off;
> -		if (left <= 0) {
> -			buf->len += maxsize;
> -			return maxsize;
> -		}
> -		buf->len = PAGE_SIZE;
> -	}
> -	while (!pipe_full(pipe->head, pipe->tail, pipe->max_usage)) {
> -		struct page *page = push_anon(pipe,
> -					      min_t(ssize_t, left, PAGE_SIZE));
> -		if (!page)
> -			break;
> -		get_page(*pages++ = page);
> -		left -= PAGE_SIZE;
> -		if (left <= 0)
> -			return maxsize;
> -	}
> -	return maxsize - left ? : -EFAULT;
> -}
> -
>  static ssize_t pipe_get_pages(struct iov_iter *i,
>  		   struct page ***pages, size_t maxsize, unsigned maxpages,
>  		   size_t *start)
>  {
> +	struct pipe_inode_info *pipe = i->pipe;
>  	unsigned int npages, off;
>  	struct page **p;
> -	size_t capacity;
> +	ssize_t left;
> +	int count;
>  
>  	if (!sanity(i))
>  		return -EFAULT;
>  
>  	*start = off = pipe_npages(i, &npages);
> -	capacity = min(npages, maxpages) * PAGE_SIZE - off;
> -	maxsize = min(maxsize, capacity);
> +	count = DIV_ROUND_UP(maxsize + off, PAGE_SIZE);
> +	if (count > npages)
> +		count = npages;
> +	if (count > maxpages)
> +		count = maxpages;
>  	p = *pages;
>  	if (!p) {
> -		*pages = p = get_pages_array(DIV_ROUND_UP(maxsize + off, PAGE_SIZE));
> +		*pages = p = get_pages_array(count);
>  		if (!p)
>  			return -ENOMEM;
>  	}
>  
> -	return __pipe_get_pages(i, maxsize, p, off);
> +	left = maxsize;
> +	npages = 0;
> +	if (off) {
> +		struct pipe_buffer *buf = pipe_buf(pipe, pipe->head - 1);
> +
> +		get_page(*p++ = buf->page);
> +		left -= PAGE_SIZE - off;
> +		if (left <= 0) {
> +			buf->len += maxsize;
> +			return maxsize;
> +		}
> +		buf->len = PAGE_SIZE;
> +		npages = 1;
> +	}
> +	for ( ; npages < count; npages++) {
> +		struct page *page;
> +		unsigned int size = min_t(ssize_t, left, PAGE_SIZE);
> +
> +		if (pipe_full(pipe->head, pipe->tail, pipe->max_usage))
> +			break;
> +		page = push_anon(pipe, size);
> +		if (!page)
> +			break;
> +		get_page(*p++ = page);
> +		left -= size;
> +	}
> +	if (!npages)
> +		return -EFAULT;
> +	return maxsize - left;
>  }
>  
>  static ssize_t iter_xarray_populate_pages(struct page **pages, struct xarray *xa,

Reviewed-by: Jeff Layton <jlayton@xxxxxxxxxx>




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux