Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp13100807rwd; Fri, 23 Jun 2023 15:58:03 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ55yP99kGm5rBVFz+/za+AibUJFgvdnqxC4XLtl2P7dl0/JSlEWsDC6pA3rq7Vsiq0AxUee X-Received: by 2002:a9d:7ac7:0:b0:6af:7e7e:d7b with SMTP id m7-20020a9d7ac7000000b006af7e7e0d7bmr20452621otn.15.1687561083335; Fri, 23 Jun 2023 15:58:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1687561083; cv=none; d=google.com; s=arc-20160816; b=0b/B/9KIU6p1qjTR+arhw3TplKd0o4XdLUgLKEmQQN6QGtaZ8riv1w8KeJmSbpeoFq fz1ic9Zl7NWje8FfF0HU4QxMxDo3J1gLLmMhY2N4VBvqlvM4N5ihwsa2ZjRPcZHou/ah JeH/BIWygpbto9AxFkQEjK8zUQCP6m/Uhbny9pxz9RWCE9Cd50cwCrE5xgLGQ7AX4iNv wb2bAJmm8yhQXHh7TaGaoaVQno/6uOxLA8c10htjNURXuYZYBtmskNSV6ekPofTEF2aw T1easF/nH4yG4zROM6jJSyH9of9fFw9xCZO1zwfR2d1zb6BxUADFQL0Y/fUqFTPqBmrO QT2A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:message-id:date:content-id:mime-version:subject :cc:to:from:organization:dkim-signature; bh=OXHK801MHw6sMHY68DL31vt5Z/u/q42/rUnJs7PRou0=; fh=QAtWHkaW9gJ0moNccuuIfDXcdgxDsLcouCF/DkdZ48Y=; b=QpJzZDX1yP+PaitefoTk5Olj67JBtJWGzM+M66e7QSFg3m3vP5HyPlWylxJdQNMTrV SI2x6KglmldVY84Vp6p7SsnIFBRPJhihHl8BapvDYo8ltvD1VfQeyPLrcCR0dwbsd0cI RPYJATkbpKN/rbX1o50ln8XEiS9cRaRtEH4+9+1NeLoZHBu5N2K+dGg+Xtyz3B4MWDdz d2RgFvVSwtY1cuuQ3pbyPXzTBlKBVnVz8e0nrkYRQNu0Quxl0PkScO1ykkQPRbZjWWBI cjScXeWVQgGrXbIYAMniFWS9iKIJnPFMXX5b5lz0H1apzjdbKLqlZcbWRP699HhTGTaY FCKw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=grZNkrOg; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id x71-20020a63864a000000b00553859c59c1si352561pgd.695.2023.06.23.15.57.51; Fri, 23 Jun 2023 15:58:03 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=grZNkrOg; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231896AbjFWWfV (ORCPT + 99 others); Fri, 23 Jun 2023 18:35:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59760 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231667AbjFWWfT (ORCPT ); Fri, 23 Jun 2023 18:35:19 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2AB5C193 for ; Fri, 23 Jun 2023 15:34:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1687559671; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type; bh=OXHK801MHw6sMHY68DL31vt5Z/u/q42/rUnJs7PRou0=; b=grZNkrOg0sNQKjMjqGmdYlBXtp90aedIYYWw/zglNZA13O4uXIajxgcMvocGaGR6dsGNYA 5dkXAQPwZKiserJCXtBChInljRaqz98zByIN3D/ESWg5oTXmC8Xp4n3u/NAeAy8phh/Eym cYkoNqcKlqlemGq1edPCepFP8/sq0lE= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-399-qKtsGPptMGm18tLLs81clg-1; Fri, 23 Jun 2023 18:34:30 -0400 X-MC-Unique: qKtsGPptMGm18tLLs81clg-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A39BC1C03D8A; Fri, 23 Jun 2023 22:34:29 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.42.28.4]) by smtp.corp.redhat.com (Postfix) with ESMTP id AE10140C2063; Fri, 23 Jun 2023 22:34:28 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 From: David Howells To: Linus Torvalds cc: dhowells@redhat.com, Franck Grosjean , Phil Auld , Alexander Viro , Christian Brauner , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] pipe: Make a partially-satisfied blocking read wait for more MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <2730510.1687559668.1@warthog.procyon.org.uk> Date: Fri, 23 Jun 2023 23:34:28 +0100 Message-ID: <2730511.1687559668@warthog.procyon.org.uk> X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Linus, Can you consider merging something like the attached patch? Unfortunately, there are applications out there that depend on a read from pipe() waiting until the buffer is full under some circumstances. Patch a28c8b9db8a1 removed the conditionality on there being an attached writer. I'm not sure this is the best solution though as it goes over the other way and will now block reads for which there isn't an active writer - and I'm sure that, somewhere, there's an app that will break on tht. Thanks, David --- pipe: Make a partially-satisfied blocking read wait for more data A read on a pipe may return short after reading some data from a pipe, even though the pipe isn't non-blocking. This is stated in the read(2) manual page: ... It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal)... However, some applications depend on a blocking read on a pipe not returning until it fills the buffer unless it hits EOF or a signal occurs - at least as long as there's an active writer on the other end. Fix the pipe reader to restore this behaviour by only breaking out with a short read in the non-block (and signal) cases. Here's a reproducer for it: #include #include #include #include #include #define F_GETPIPE_SZ 1032 int main(int argc, char *argv[]) { int fildes[2]; if (pipe(fildes) == -1) { perror("in pipe"); return -1; } printf("%d %d\n", fcntl(fildes[0], F_GETPIPE_SZ), fcntl(fildes[1], F_GETPIPE_SZ)); if (fork() != 0) { void *tata = malloc(100000); int res = read(fildes[0], tata, 100000); printf("could read %d bytes\n", res); return -1; } void *toto = malloc(100000); struct iovec iov; iov.iov_base = toto; iov.iov_len = 100000; int d = writev(fildes[1], &iov, 1); if (d == -1) { perror("in writev"); return -1; } printf("could write %d bytes\n", d); sleep(1); return 0; } It should show the same amount read as written, but shows a short read because the pipe capacity isn't sufficient. Fixes: a28c8b9db8a1 ("pipe: remove 'waiting_writers' merging logic") Reported-by: Franck Grosjean Signed-off-by: David Howells Tested-by: Phil Auld cc: Linus Torvalds cc: Alexander Viro cc: Christian Brauner cc: linux-fsdevel@vger.kernel.org --- fs/pipe.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/pipe.c b/fs/pipe.c index 2d88f73f585a..c5c992f19d28 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -340,11 +340,10 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to) if (!pipe->writers) break; - if (ret) - break; if ((filp->f_flags & O_NONBLOCK) || (iocb->ki_flags & IOCB_NOWAIT)) { - ret = -EAGAIN; + if (!ret) + ret = -EAGAIN; break; } __pipe_unlock(pipe);