From patchwork Tue Apr 18 22:40:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 13216208 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B93CDC6FD18 for ; Tue, 18 Apr 2023 22:41:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230153AbjDRWlR (ORCPT ); Tue, 18 Apr 2023 18:41:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60720 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232772AbjDRWlJ (ORCPT ); Tue, 18 Apr 2023 18:41:09 -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 B9B3D9745 for ; Tue, 18 Apr 2023 15:40:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1681857613; 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: content-transfer-encoding:content-transfer-encoding; bh=88WLzUQfui8MOyB5NEFokobl+41u8GpMubwgrVgH7UQ=; b=KFcsdEbaMDJvabIpradp/yHzVpp+HxP+Fx1Nb7wLkMo5W/WEeFxJ2Wf1WRm41QFjCzFgE7 lthJsVkKC1dSGaZCwJbHz5FW56TgmGCgXcW7gWLF2tYhsp3zzqSZc92WsZfOX2dCOydtub mE8sSFcMHUPACu8VOqR5sJhHnUbzoyM= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-463-ld5D_CZpP5eRYdorAN4ycA-1; Tue, 18 Apr 2023 18:40:09 -0400 X-MC-Unique: ld5D_CZpP5eRYdorAN4ycA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 290F3101A531; Tue, 18 Apr 2023 22:40:09 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.42.28.67]) by smtp.corp.redhat.com (Postfix) with ESMTP id EE26540BC798; Tue, 18 Apr 2023 22:40:07 +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: Steve French cc: dhowells@redhat.com, Paulo Alcantara , =?utf-8?b?SsOp?= =?utf-8?b?csO0bWU=?= Glisse , Long Li , Enzo Matsumiya , Shyam Prasad N , Rohith Surabattula , Jeff Layton , linux-cifs@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] cifs: Fix unbuffered read MIME-Version: 1.0 Date: Tue, 18 Apr 2023 23:40:07 +0100 Message-ID: <1692048.1681857607@warthog.procyon.org.uk> X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org If read() is done in an unbuffered manner, such that, say, cifs_strict_readv() goes through cifs_user_readv() and thence __cifs_readv(), it doesn't recognise the EOF and keeps indicating to userspace that it returning full buffers of data. This is due to ctx->iter being advanced in cifs_send_async_read() as the buffer is split up amongst a number of rdata objects. The iterator count is then used in collect_uncached_read_data() in the non-DIO case to set the total length read - and thus the return value of sys_read(). But since the iterator normally gets used up completely during splitting, ctx->total_len gets overridden to the full amount. However, prior to that in collect_uncached_read_data(), we've gone through the list of rdatas and added up the amount of data we actually received (which we then throw away). Fix this by removing the bit that overrides the amount read in the non-DIO case and just going with the total added up in the aforementioned loop. This was observed by mounting a cifs share with multiple channels, e.g.: mount //192.168.6.1/test /test/ -o user=shares,pass=...,max_channels=6 and then reading a 1MiB file on the share: strace cat /xfstest.test/1M >/dev/null Through strace, the same data can be seen being read again and again. Fixes: d08089f649a0 ("cifs: Change the I/O paths to use an iterator rather than a page list") Signed-off-by: David Howells cc: Steve French cc: Paulo Alcantara cc: Jérôme Glisse cc: Long Li cc: Enzo Matsumiya cc: Shyam Prasad N cc: Rohith Surabattula cc: Jeff Layton cc: linux-cifs@vger.kernel.org Acked-by: Paulo Alcantara (SUSE) --- fs/cifs/file.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 321f9b7c84c9..f8877dc91cc5 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -4010,7 +4010,6 @@ static void collect_uncached_read_data(struct cifs_aio_ctx *ctx) { struct cifs_readdata *rdata, *tmp; - struct iov_iter *to = &ctx->iter; struct cifs_sb_info *cifs_sb; int rc; @@ -4076,9 +4075,6 @@ collect_uncached_read_data(struct cifs_aio_ctx *ctx) kref_put(&rdata->refcount, cifs_readdata_release); } - if (!ctx->direct_io) - ctx->total_len = ctx->len - iov_iter_count(to); - /* mask nodata case */ if (rc == -ENODATA) rc = 0;