Re: [PATCH] sys_vmsplice

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

 



Jens Axboe <[email protected]> wrote:
>
> ...
>
> sys_splice() moves data to/from pipes with a file input/output. sys_vmsplice()
> moves data to a pipe, with the input being a user address range instead.
> 
> ...
>
> +static void *user_page_pipe_buf_map(struct file *file,
> +				    struct pipe_inode_info *pipe,
> +				    struct pipe_buffer *buf)
> +{
> +	return kmap(buf->page);
> +}
> +
> +static void user_page_pipe_buf_unmap(struct pipe_inode_info *pipe,
> +				     struct pipe_buffer *buf)
> +{
> +	kunmap(buf->page);
> +}

All these new kmaps and kunmaps hurt.  It's supposed to be
kinda-deprecated and scales poorly.  Oh well.

> -	while (i < nr_pages)
> -		page_cache_release(pages[i++]);
> +	while (i < spd->nr_pages)
> +		page_cache_release(spd->pages[i++]);

grumble.  I'm going to march over there and take away your `i' key.  Or
make it emit "page_nr".

> +static long do_vmsplice(struct file *file, void __user *buffer, size_t len,
> +			unsigned int flags)
> +{
> +	unsigned long uaddr = (unsigned long) buffer;
> +	struct pipe_inode_info *pipe;
> +	struct page *pages[PIPE_BUFFERS];
> +	unsigned int nr_pages;
> +	struct splice_pipe_desc spd = {
> +		.pages = pages,
> +		.len = len,
> +		.flags = flags,
> +		.ops = &user_page_pipe_buf_ops,
> +	};
> +
> +	pipe = file->f_dentry->d_inode->i_pipe;
> +	if (unlikely(!pipe))
> +		return -EBADF;
> +
> +	spd.offset = uaddr & ~PAGE_CACHE_MASK;
> +	nr_pages = (len + spd.offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;

Can I feed this 16TB of memory?   If so, we just overflowed `nr_pages'.

> --- a/include/asm-powerpc/unistd.h
> +++ b/include/asm-powerpc/unistd.h
> @@ -303,8 +303,9 @@ #define __NR_ppoll		281
>  #define __NR_unshare		282
>  #define __NR_splice		283
>  #define __NR_tee		284
> +#define __NR_vmsplice		285
>  
> -#define __NR_syscalls		285
> +#define __NR_syscalls		286
>  

Every time we do this the spufs build breaks:

long spu_sys_callback(struct spu_syscall_block *s)
{
	long (*syscall)(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6);

	BUILD_BUG_ON(ARRAY_SIZE(spu_syscall_table) != __NR_syscalls);


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux