From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751947AbbEFOjZ (ORCPT ); Wed, 6 May 2015 10:39:25 -0400 Received: from pegase1.c-s.fr ([93.17.236.30]:24344 "EHLO mailhub1.si.c-s.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750816AbbEFOjW (ORCPT ); Wed, 6 May 2015 10:39:22 -0400 Message-ID: <554A276D.2080209@c-s.fr> Date: Wed, 06 May 2015 16:38:37 +0200 From: leroy christophe User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: Jens Axboe , Linus Torvalds , Herbert Xu CC: Al Viro , Linux Kernel Mailing List , linux-fsdevel , Linux Crypto Mailing List Subject: Re: [PATCH v2] splice: sendfile() at once fails for big files References: <20150423150308.8782B1A2439@localhost.localdomain> <20150427070131.GA21190@gondor.apana.org.au> <554A23F4.7010004@kernel.dk> In-Reply-To: <554A23F4.7010004@kernel.dk> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Le 06/05/2015 16:23, Jens Axboe a écrit : > On 05/05/2015 09:41 PM, Linus Torvalds wrote: >> Jens, ping? >> >> The test results should make this a no-brainer, but I hate how random >> these flag ops. > > Missed the original, apparently. I too am confused how this is a > correctness fix and not just an optimization. > > + if (read_len < len) > + sd->flags |= SPLICE_F_MORE; > + else if (!more) > + sd->flags &= ~SPLICE_F_MORE; > > Should that check be for 'more', not '!more'? > > @@ -1204,6 +1204,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, * Don't block on output, we have to drain the direct pipe. */ sd->flags &= ~SPLICE_F_NONBLOCK; + more = sd->flags & SPLICE_F_MORE; while (len) { size_t read_len; @@ -1216,6 +1217,10 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, read_len = ret; sd->total_len = read_len; + if (read_len < len) + sd->flags |= SPLICE_F_MORE; + else if (!more) + sd->flags &= ~SPLICE_F_MORE; 'more' contains whether sendfile() has been called with SPLICE_F_MORE or not. Until all bytes are processed, we have to force SPLICE_F_MORE regardless of how sendfile() was called. Once all bytes have been read, we have to reset the flags according to how sendfile() was called, so if 'more' is NOT set, we have to clear SPLICE_F_MORE from sd->flags (which was unconditionaly set for processing the first bytes) Christophe