Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753394AbdDKX4o (ORCPT ); Tue, 11 Apr 2017 19:56:44 -0400 Received: from zeniv.linux.org.uk ([195.92.253.2]:36924 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752747AbdDKX4m (ORCPT ); Tue, 11 Apr 2017 19:56:42 -0400 Date: Wed, 12 Apr 2017 00:56:41 +0100 From: Al Viro To: Dave Jones , Linux Kernel Subject: Re: iov_iter_pipe warning. Message-ID: <20170411235641.GL29622@ZenIV.linux.org.uk> References: <20170410234830.tmqdhpjtfdveor3c@codemonkey.org.uk> <20170411002215.GE29622@ZenIV.linux.org.uk> <20170411030532.vcam25fz6224ny2h@codemonkey.org.uk> <20170411032839.GF29622@ZenIV.linux.org.uk> <20170411205336.uyz5vfw52twhh6ob@codemonkey.org.uk> <20170411211216.GH29622@ZenIV.linux.org.uk> <20170411222502.ldgahltwvrrxdbbw@codemonkey.org.uk> <20170411232842.GI29622@ZenIV.linux.org.uk> <20170411234558.zyzxznzaas3ge7qe@codemonkey.org.uk> <20170411235158.GK29622@ZenIV.linux.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20170411235158.GK29622@ZenIV.linux.org.uk> User-Agent: Mutt/1.7.1 (2016-10-04) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1871 Lines: 54 On Wed, Apr 12, 2017 at 12:51:58AM +0100, Al Viro wrote: > On Tue, Apr 11, 2017 at 07:45:58PM -0400, Dave Jones wrote: > > > if (file->f_op->splice_write == generic_splice_sendpage) { > > > struct socket *sock = file->private_data; > > > printk(KERN_ERR "socket [%d, %p]\n", sock->type, sock->ops); > > > } > > > printk(KERN_ERR "in->f_op = %p\n", in->f_op); > > > > Ugh, this explodes with a million errors when I try to compile it. > > It misses socket definition, and include causes another > > cascade of errors about linkage.h and nonsense. > > Ignore the socket part - you've already triggered it with NFS file as > destination, so this is not particularly interesting. I would still like > to see in->f_op and even more - the checks in default_file_splice_read(). ... and the latter had a braino - WARN_ON(size != ret), not len != ret. Diff follows: diff --git a/fs/splice.c b/fs/splice.c index 006ba50f4ece..43dd9b3140ee 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -448,6 +448,18 @@ static ssize_t default_file_splice_read(struct file *in, loff_t *ppos, put_page(pages[i]); kvfree(pages); iov_iter_advance(&to, copied); /* truncates and discards */ + if (res > 0 && pipe == current->splice_pipe) { + int idx = pipe->curbuf; + int n = pipe->nrbufs; + size_t size = 0; + while (n--) { + size += pipe->bufs[idx++].len; + if (idx == pipe->buffers) + idx = 0; + } + WARN_ON(size != res); + } + return res; } @@ -970,6 +982,11 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, while (len) { size_t read_len; loff_t pos = sd->pos, prev_pos = pos; + if (WARN_ON(pipe->buffers)) { + printk(KERN_ERR "in->f_op = %p, ->splice_write = %p\n", + in->f_op, + sd->u.file->f_op->splice_write); + } ret = do_splice_to(in, &pos, pipe, len, flags); if (unlikely(ret <= 0))