Linux-NFS Archive on lore.kernel.org
 help / color / Atom feed
From: Su Yanjun <suyj.fnst@cn.fujitsu.com>
To: <trond.myklebust@hammerspace.com>
Cc: <linux-nfs@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<suyj.fnst@cn.fujitsu.com>
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> (raw)

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 <suyj.fnst@cn.fujitsu.com>
---
 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




             reply index

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-30  9:11 Su Yanjun [this message]
2019-09-30 18:02 ` [PATCH 0/2] Fix O_DIRECT error handling Trond Myklebust
2019-09-30 18:02   ` [PATCH 1/2] NFS: Fix O_DIRECT accounting of number of bytes read/written Trond Myklebust
2019-09-30 18:02     ` [PATCH 2/2] NFS: Remove redundant mirror tracking in O_DIRECT Trond Myklebust
2019-09-30 18:06 ` [PATCH] NFS: Fix O_DIRECT read problem when another write is going on Trond Myklebust
2019-10-07  2:17   ` Su Yanjun

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1569834678-16117-1-git-send-email-suyj.fnst@cn.fujitsu.com \
    --to=suyj.fnst@cn.fujitsu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=trond.myklebust@hammerspace.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-NFS Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-nfs/0 linux-nfs/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-nfs linux-nfs/ https://lore.kernel.org/linux-nfs \
		linux-nfs@vger.kernel.org
	public-inbox-index linux-nfs

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-nfs


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git