linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Trond Myklebust <trond.myklebust@primarydata.com>
To: Benjamin Coddington <bcodding@redhat.com>,
	Anna Schumaker <anna.schumaker@netapp.com>
Cc: linux-nfs@vger.kernel.org
Subject: [PATCH v8 06/11] NFSv4: Don't try to CLOSE if the stateid 'other' field has changed
Date: Mon,  6 Nov 2017 15:28:06 -0500	[thread overview]
Message-ID: <20171106202811.70202-7-trond.myklebust@primarydata.com> (raw)
In-Reply-To: <20171106202811.70202-6-trond.myklebust@primarydata.com>

If the stateid is no longer recognised on the server, either due to a
restart, or due to a competing CLOSE call, then we do not have to
retry. Any open contexts that triggered a reopen of the file, will
also act as triggers for any CLOSE for the updated stateids.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
---
 fs/nfs/nfs4_fs.h   |  2 ++
 fs/nfs/nfs4proc.c  | 14 ++++----------
 fs/nfs/nfs4state.c |  9 +++++++--
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 84c3adc6bf96..cdab6e8dbacc 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -463,6 +463,8 @@ extern int nfs4_select_rw_stateid(struct nfs4_state *, fmode_t,
 		struct rpc_cred **);
 extern bool nfs4_refresh_open_stateid(nfs4_stateid *dst,
 		struct nfs4_state *state);
+extern bool nfs4_copy_open_stateid(nfs4_stateid *dst,
+		struct nfs4_state *state);
 
 extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask);
 extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 8abf24907102..25d310e33f55 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3215,14 +3215,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
 					task->tk_msg.rpc_cred);
 			/* Fallthrough */
 		case -NFS4ERR_BAD_STATEID:
-			if (!nfs4_stateid_match(&calldata->arg.stateid,
-						&state->open_stateid)) {
-				rpc_restart_call_prepare(task);
-				goto out_release;
-			}
-			if (calldata->arg.fmode == 0)
-				break;
-			/* Fallthrough */
+			break;
 		default:
 			if (nfs4_async_handle_error(task, server, state, NULL) == -EAGAIN) {
 				rpc_restart_call_prepare(task);
@@ -3254,7 +3247,6 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
 	is_rdwr = test_bit(NFS_O_RDWR_STATE, &state->flags);
 	is_rdonly = test_bit(NFS_O_RDONLY_STATE, &state->flags);
 	is_wronly = test_bit(NFS_O_WRONLY_STATE, &state->flags);
-	nfs4_stateid_copy(&calldata->arg.stateid, &state->open_stateid);
 	/* Calculate the change in open mode */
 	calldata->arg.fmode = 0;
 	if (state->n_rdwr == 0) {
@@ -3272,7 +3264,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
 		calldata->arg.fmode |= FMODE_READ|FMODE_WRITE;
 
 	if (!nfs4_valid_open_stateid(state) ||
-	    test_bit(NFS_OPEN_STATE, &state->flags) == 0)
+	    !nfs4_refresh_open_stateid(&calldata->arg.stateid, state))
 		call_close = 0;
 	spin_unlock(&state->owner->so_lock);
 
@@ -3366,6 +3358,8 @@ int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait)
 	calldata->inode = state->inode;
 	calldata->state = state;
 	calldata->arg.fh = NFS_FH(state->inode);
+	if (!nfs4_copy_open_stateid(&calldata->arg.stateid, state))
+		goto out_free_calldata;
 	/* Serialization for the sequence id */
 	alloc_seqid = server->nfs_client->cl_mvops->alloc_seqid;
 	calldata->arg.seqid = alloc_seqid(&state->owner->so_seqid, gfp_mask);
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index ccf3b4e03997..4a6f77880992 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1002,18 +1002,23 @@ bool nfs4_refresh_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
 	return ret;
 }
 
-static void nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
+bool nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
 {
+	bool ret;
 	const nfs4_stateid *src;
 	int seq;
 
 	do {
+		ret = false;
 		src = &zero_stateid;
 		seq = read_seqbegin(&state->seqlock);
-		if (test_bit(NFS_OPEN_STATE, &state->flags))
+		if (test_bit(NFS_OPEN_STATE, &state->flags)) {
 			src = &state->open_stateid;
+			ret = true;
+		}
 		nfs4_stateid_copy(dst, src);
 	} while (read_seqretry(&state->seqlock, seq));
+	return ret;
 }
 
 /*
-- 
2.13.6

  reply	other threads:[~2017-11-06 20:28 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-06 20:28 [PATCH v8 00/11] Fix OPEN/CLOSE races Trond Myklebust
2017-11-06 20:28 ` [PATCH v8 01/11] NFSv4: Fix OPEN / CLOSE race Trond Myklebust
2017-11-06 20:28   ` [PATCH v8 02/11] NFSv4: Add a tracepoint to document open stateid updates Trond Myklebust
2017-11-06 20:28     ` [PATCH v8 03/11] NFSv4: Fix open create exclusive when the server reboots Trond Myklebust
2017-11-06 20:28       ` [PATCH v8 04/11] NFS: Fix a typo in nfs_rename() Trond Myklebust
2017-11-06 20:28         ` [PATCH v8 05/11] NFSv4: Retry CLOSE and DELEGRETURN on NFS4ERR_OLD_STATEID Trond Myklebust
2017-11-06 20:28           ` Trond Myklebust [this message]
2017-11-06 20:28             ` [PATCH v8 07/11] pNFS: Retry NFS4ERR_OLD_STATEID errors in layoutreturn-on-close Trond Myklebust
2017-11-06 20:28               ` [PATCH v8 08/11] NFSv4: Retry NFS4ERR_OLD_STATEID errors in layoutreturn Trond Myklebust
2017-11-06 20:28                 ` [PATCH v8 09/11] NFSv4: cleanup nfs4_close_done Trond Myklebust
2017-11-06 20:28                   ` [PATCH v8 10/11] NFSv4: Clean up nfs4_delegreturn_done Trond Myklebust
2017-11-06 20:28                     ` [PATCH v8 11/11] NFSv4: Check the open stateid when searching for expired state Trond Myklebust
2017-11-06 22:46 ` [PATCH v8 00/11] Fix OPEN/CLOSE races Andrew W Elble
2017-11-06 22:50   ` Trond Myklebust
2017-11-06 23:13     ` Andrew W Elble
2017-11-07 16:59     ` Andrew W Elble
2017-11-07 18:35       ` Trond Myklebust
2017-11-07 19:00         ` Trond Myklebust
2017-11-07 23:03           ` Andrew W Elble
2017-11-07 23:44             ` Trond Myklebust

Reply instructions:

You may reply publicly 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=20171106202811.70202-7-trond.myklebust@primarydata.com \
    --to=trond.myklebust@primarydata.com \
    --cc=anna.schumaker@netapp.com \
    --cc=bcodding@redhat.com \
    --cc=linux-nfs@vger.kernel.org \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).