summaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4client.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2017-06-08 11:52:44 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2017-07-13 16:00:12 -0400
commit8dcbec6d20eb881ba368d0aebc3a8a678aebb1da (patch)
tree403e867311961dce6e0b680b34d6bf7e8526617c /fs/nfs/nfs4client.c
parent1f541895dae956df0be14a3190f507b601ac3fcc (diff)
NFSv4.1: Handle EXCHGID4_FLAG_CONFIRMED_R during NFSv4.1 migration
Transparent State Migration copies a client's lease state from the server where a filesystem used to reside to the server where it now resides. When an NFSv4.1 client first contacts that destination server, it uses EXCHANGE_ID to detect trunking relationships. The lease that was copied there is returned to that client, but the destination server sets EXCHGID4_FLAG_CONFIRMED_R when replying to the client. This is because the lease was confirmed on the source server (before it was copied). Normally, when CONFIRMED_R is set, a client purges the lease and creates a new one. However, that throws away the entire benefit of Transparent State Migration. Therefore, the client must not purge that lease when it is possible that Transparent State Migration has occurred. Reported-by: Xuan Qi <xuan.qi@oracle.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Tested-by: Xuan Qi <xuan.qi@oracle.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs/nfs4client.c')
-rw-r--r--fs/nfs/nfs4client.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 66776f022111..50566acb5469 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -414,6 +414,7 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,
414 if (clp != old) 414 if (clp != old)
415 clp->cl_preserve_clid = true; 415 clp->cl_preserve_clid = true;
416 nfs_put_client(clp); 416 nfs_put_client(clp);
417 clear_bit(NFS_CS_TSM_POSSIBLE, &clp->cl_flags);
417 return old; 418 return old;
418 419
419error: 420error:
@@ -852,6 +853,8 @@ static int nfs4_set_client(struct nfs_server *server,
852 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags); 853 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
853 if (server->options & NFS_OPTION_MIGRATION) 854 if (server->options & NFS_OPTION_MIGRATION)
854 set_bit(NFS_CS_MIGRATION, &cl_init.init_flags); 855 set_bit(NFS_CS_MIGRATION, &cl_init.init_flags);
856 if (test_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status))
857 set_bit(NFS_CS_TSM_POSSIBLE, &cl_init.init_flags);
855 858
856 /* Allocate or find a client reference we can use */ 859 /* Allocate or find a client reference we can use */
857 clp = nfs_get_client(&cl_init); 860 clp = nfs_get_client(&cl_init);
@@ -1212,9 +1215,11 @@ int nfs4_update_server(struct nfs_server *server, const char *hostname,
1212 return -EAFNOSUPPORT; 1215 return -EAFNOSUPPORT;
1213 1216
1214 nfs_server_remove_lists(server); 1217 nfs_server_remove_lists(server);
1218 set_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status);
1215 error = nfs4_set_client(server, hostname, sap, salen, buf, 1219 error = nfs4_set_client(server, hostname, sap, salen, buf,
1216 clp->cl_proto, clnt->cl_timeout, 1220 clp->cl_proto, clnt->cl_timeout,
1217 clp->cl_minorversion, net); 1221 clp->cl_minorversion, net);
1222 clear_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status);
1218 nfs_put_client(clp); 1223 nfs_put_client(clp);
1219 if (error != 0) { 1224 if (error != 0) {
1220 nfs_server_insert_lists(server); 1225 nfs_server_insert_lists(server);