Home Home > GIT Browse > stable
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2019-08-16 22:01:45 +0200
committerJiri Slaby <jslaby@suse.cz>2019-08-16 22:25:11 +0200
commit86a725821d623d8aea2f961130d7095d289507c4 (patch)
tree35d2db89a8be6ab7d51160a6ba55b6fe65a8a6dd
parentad787d132c77481fc8fcb21d4a8c480b21774c20 (diff)
NFSv4: Fix delegation state recovery (bnc#1012628).
-rw-r--r--patches.kernel.org/5.2.9-134-NFSv4-Fix-delegation-state-recovery.patch122
-rw-r--r--series.conf1
2 files changed, 123 insertions, 0 deletions
diff --git a/patches.kernel.org/5.2.9-134-NFSv4-Fix-delegation-state-recovery.patch b/patches.kernel.org/5.2.9-134-NFSv4-Fix-delegation-state-recovery.patch
new file mode 100644
index 0000000000..c5a5f242f2
--- /dev/null
+++ b/patches.kernel.org/5.2.9-134-NFSv4-Fix-delegation-state-recovery.patch
@@ -0,0 +1,122 @@
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+Date: Fri, 19 Jul 2019 14:08:37 -0400
+Subject: [PATCH] NFSv4: Fix delegation state recovery
+References: bnc#1012628
+Patch-mainline: 5.2.9
+Git-commit: 5eb8d18ca0e001c6055da2b7f30d8f6dca23a44f
+
+commit 5eb8d18ca0e001c6055da2b7f30d8f6dca23a44f upstream.
+
+Once we clear the NFS_DELEGATED_STATE flag, we're telling
+nfs_delegation_claim_opens() that we're done recovering all open state
+for that stateid, so we really need to ensure that we test for all
+open modes that are currently cached and recover them before exiting
+nfs4_open_delegation_recall().
+
+Fixes: 24311f884189d ("NFSv4: Recovery of recalled read delegations...")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Cc: stable@vger.kernel.org # v4.3+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ fs/nfs/delegation.c | 2 +-
+ fs/nfs/delegation.h | 2 +-
+ fs/nfs/nfs4proc.c | 25 ++++++++++++-------------
+ 3 files changed, 14 insertions(+), 15 deletions(-)
+
+diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
+index 0ff3facf81da..0af854cce8ff 100644
+--- a/fs/nfs/delegation.c
++++ b/fs/nfs/delegation.c
+@@ -153,7 +153,7 @@ static int nfs_delegation_claim_opens(struct inode *inode,
+ /* Block nfs4_proc_unlck */
+ mutex_lock(&sp->so_delegreturn_mutex);
+ seq = raw_seqcount_begin(&sp->so_reclaim_seqcount);
+- err = nfs4_open_delegation_recall(ctx, state, stateid, type);
++ err = nfs4_open_delegation_recall(ctx, state, stateid);
+ if (!err)
+ err = nfs_delegation_claim_locks(state, stateid);
+ if (!err && read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
+diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
+index 5799777df5ec..9eb87ae4c982 100644
+--- a/fs/nfs/delegation.h
++++ b/fs/nfs/delegation.h
+@@ -63,7 +63,7 @@ void nfs_reap_expired_delegations(struct nfs_client *clp);
+
+ /* NFSv4 delegation-related procedures */
+ int nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, const nfs4_stateid *stateid, int issync);
+-int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid, fmode_t type);
++int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid);
+ int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state, const nfs4_stateid *stateid);
+ bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags, nfs4_stateid *dst, const struct cred **cred);
+ bool nfs4_refresh_delegation_stateid(nfs4_stateid *dst, struct inode *inode);
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 6418cb6c079b..61a01e1399ac 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -2148,12 +2148,10 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
+ case -NFS4ERR_BAD_HIGH_SLOT:
+ case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
+ case -NFS4ERR_DEADSESSION:
+- set_bit(NFS_DELEGATED_STATE, &state->flags);
+ nfs4_schedule_session_recovery(server->nfs_client->cl_session, err);
+ return -EAGAIN;
+ case -NFS4ERR_STALE_CLIENTID:
+ case -NFS4ERR_STALE_STATEID:
+- set_bit(NFS_DELEGATED_STATE, &state->flags);
+ /* Don't recall a delegation if it was lost */
+ nfs4_schedule_lease_recovery(server->nfs_client);
+ return -EAGAIN;
+@@ -2174,7 +2172,6 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
+ return -EAGAIN;
+ case -NFS4ERR_DELAY:
+ case -NFS4ERR_GRACE:
+- set_bit(NFS_DELEGATED_STATE, &state->flags);
+ ssleep(1);
+ return -EAGAIN;
+ case -ENOMEM:
+@@ -2190,8 +2187,7 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
+ }
+
+ int nfs4_open_delegation_recall(struct nfs_open_context *ctx,
+- struct nfs4_state *state, const nfs4_stateid *stateid,
+- fmode_t type)
++ struct nfs4_state *state, const nfs4_stateid *stateid)
+ {
+ struct nfs_server *server = NFS_SERVER(state->inode);
+ struct nfs4_opendata *opendata;
+@@ -2202,20 +2198,23 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx,
+ if (IS_ERR(opendata))
+ return PTR_ERR(opendata);
+ nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid);
+- nfs_state_clear_delegation(state);
+- switch (type & (FMODE_READ|FMODE_WRITE)) {
+- case FMODE_READ|FMODE_WRITE:
+- case FMODE_WRITE:
++ if (!test_bit(NFS_O_RDWR_STATE, &state->flags)) {
+ err = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE);
+ if (err)
+- break;
++ goto out;
++ }
++ if (!test_bit(NFS_O_WRONLY_STATE, &state->flags)) {
+ err = nfs4_open_recover_helper(opendata, FMODE_WRITE);
+ if (err)
+- break;
+- /* Fall through */
+- case FMODE_READ:
++ goto out;
++ }
++ if (!test_bit(NFS_O_RDONLY_STATE, &state->flags)) {
+ err = nfs4_open_recover_helper(opendata, FMODE_READ);
++ if (err)
++ goto out;
+ }
++ nfs_state_clear_delegation(state);
++out:
+ nfs4_opendata_put(opendata);
+ return nfs4_handle_delegation_recall_error(server, state, stateid, NULL, err);
+ }
+--
+2.22.0
+
diff --git a/series.conf b/series.conf
index 1fc457463f..396275ae96 100644
--- a/series.conf
+++ b/series.conf
@@ -1154,6 +1154,7 @@
patches.kernel.org/5.2.9-131-dax-dax_layout_busy_page-should-not-unmap-cow-p.patch
patches.kernel.org/5.2.9-132-SMB3-Fix-deadlock-in-validate-negotiate-hits-re.patch
patches.kernel.org/5.2.9-133-smb3-send-CAP_DFS-capability-during-session-set.patch
+ patches.kernel.org/5.2.9-134-NFSv4-Fix-delegation-state-recovery.patch
########################################################
# Build fixes that apply to the vanilla kernel too.