Received: by 2002:a25:824b:0:0:0:0:0 with SMTP id d11csp6698005ybn; Mon, 30 Sep 2019 02:14:24 -0700 (PDT) X-Google-Smtp-Source: APXvYqxh0VuEHaSOhwIxeh+ATFfkZh/hvMVSU2CxTmSIfCTothfi/4eIaeEEohVccWhUAT60Es5K X-Received: by 2002:a17:907:388:: with SMTP id ss8mr18275363ejb.26.1569834864288; Mon, 30 Sep 2019 02:14:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1569834864; cv=none; d=google.com; s=arc-20160816; b=rCNGNw+6lYrhX+QKrzYt2qMMdqgo2nNUhWndiCZ9dWJ77TX0nLyTJjvYcMH2ZR71ap eOCRkvl5mCD/dcEPQ2c2fN8TDJ/PDQ7Nct1qB6zpT5CjK83qCeBtIfAiRd/ZCp9gKB9H 6SyRXCCAF6ZkT0q9nKH4OKUftyAIWzt/760C/+U1CZ+lJSiUig+l7jQdeHCJrBpI0v/o +7+In2auJ6pXeeN8wmrCul9GxqL5bcujXdq1GTu2ZtfPKoy8xnoRXMTX/2zWe8vPXbnd F3iZHl8z1iU0RrgP0sBFzsqvpOkjJPf5L2/jwLMVIh4SRo5jz1cCnQJPAv/3GGVV/ilx F8Xg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:message-id:date:subject:cc :to:from; bh=DqkN2ufGU21pyr3qS6qfkpWcC532c8OiiDjAEpopjGM=; b=teuVeVVb5Ewe6E4YTyff3Sw3VocUsuLFdqIAcqDH4A2mw1/HlnxftM9NLMS8K2wkcI HiHYOy8i+sT4CXQLC7whXUhJEYA7uhle0VNsvgqu2eah9IdXhsXNg9Gzipmlf+WEgBvZ Ls6TLE4FEUBbBBeDNbqFHMudGTfdYlz3WpKZuEI74ond3ZdWCjYKExaUsWFQB88H0HUD Eh8wjjatoiH1U593TZEsGnNdTEbWyiWYJqAqRNn9iYGiNvtXUinmak5t4vF/Diay2I7c Fs8R8rwM+X6ljQkJwAdvPlKcyEHOgR2fT0giABHKyctnUvWWCyxuxp9LOAqWM0QJ82N0 iJTg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r1si2899010ejp.287.2019.09.30.02.13.59; Mon, 30 Sep 2019 02:14:24 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729836AbfI3JN4 (ORCPT + 99 others); Mon, 30 Sep 2019 05:13:56 -0400 Received: from mail.cn.fujitsu.com ([183.91.158.132]:49177 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726121AbfI3JNz (ORCPT ); Mon, 30 Sep 2019 05:13:55 -0400 X-IronPort-AV: E=Sophos;i="5.64,565,1559491200"; d="scan'208";a="76258074" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 30 Sep 2019 17:13:53 +0800 Received: from G08CNEXCHPEKD03.g08.fujitsu.local (unknown [10.167.33.85]) by cn.fujitsu.com (Postfix) with ESMTP id 73F414CE14F9; Mon, 30 Sep 2019 17:13:57 +0800 (CST) Received: from localhost.localdomain (10.167.226.33) by G08CNEXCHPEKD03.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.439.0; Mon, 30 Sep 2019 17:13:57 +0800 From: Su Yanjun To: CC: , , Subject: [PATCH] NFS: Fix O_DIRECT read problem when another write is going on Date: Mon, 30 Sep 2019 17:11:18 +0800 Message-ID: <1569834678-16117-1-git-send-email-suyj.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.167.226.33] X-yoursite-MailScanner-ID: 73F414CE14F9.AFB38 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: suyj.fnst@cn.fujitsu.com X-Spam-Status: No Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In xfstests generic/465 tests failed. Because O_DIRECT r/w use async rpc calls, when r/w rpc calls are running concurrently we may read partial data which is wrong. For example as follows. user buffer /--------\ | |XXXX| rpc0 rpc1 When rpc0 runs it encounters eof so return 0, then another writes something. When rpc1 runs it returns some data. The total data buffer contains wrong data. In this patch we check eof mark for each direct request. If encounters eof then set eof mark in the request, when we meet it again report -EAGAIN error. In nfs_direct_complete we convert -EAGAIN as if read nothing. When the reader issue another read it will read ok. Signed-off-by: Su Yanjun --- fs/nfs/direct.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 222d711..7f737a3 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -93,6 +93,7 @@ struct nfs_direct_req { bytes_left, /* bytes left to be sent */ error; /* any reported error */ struct completion completion; /* wait for i/o completion */ + int eof; /* eof mark in the req */ /* commit state */ struct nfs_mds_commit_info mds_cinfo; /* Storage for cinfo */ @@ -380,6 +381,12 @@ static void nfs_direct_complete(struct nfs_direct_req *dreq) { struct inode *inode = dreq->inode; + /* read partial data just as read nothing */ + if (dreq->error == -EAGAIN) { + dreq->count = 0; + dreq->error = 0; + } + inode_dio_end(inode); if (dreq->iocb) { @@ -413,8 +420,13 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr) if (hdr->good_bytes != 0) nfs_direct_good_bytes(dreq, hdr); - if (test_bit(NFS_IOHDR_EOF, &hdr->flags)) + if (dreq->eof) + dreq->error = -EAGAIN; + + if (test_bit(NFS_IOHDR_EOF, &hdr->flags)) { dreq->error = 0; + dreq->eof = 1; + } spin_unlock(&dreq->lock); -- 2.7.4