aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r--fs/nfs/nfs4state.c49
1 files changed, 43 insertions, 6 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index b962397004c1..46eb624e4f16 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -71,6 +71,29 @@ static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred)
71 return status; 71 return status;
72} 72}
73 73
74static struct rpc_cred *nfs4_get_machine_cred(struct nfs_client *clp)
75{
76 struct rpc_cred *cred = NULL;
77
78 spin_lock(&clp->cl_lock);
79 if (clp->cl_machine_cred != NULL)
80 cred = get_rpccred(clp->cl_machine_cred);
81 spin_unlock(&clp->cl_lock);
82 return cred;
83}
84
85static void nfs4_clear_machine_cred(struct nfs_client *clp)
86{
87 struct rpc_cred *cred;
88
89 spin_lock(&clp->cl_lock);
90 cred = clp->cl_machine_cred;
91 clp->cl_machine_cred = NULL;
92 spin_unlock(&clp->cl_lock);
93 if (cred != NULL)
94 put_rpccred(cred);
95}
96
74struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp) 97struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp)
75{ 98{
76 struct nfs4_state_owner *sp; 99 struct nfs4_state_owner *sp;
@@ -91,13 +114,18 @@ static struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp)
91{ 114{
92 struct nfs4_state_owner *sp; 115 struct nfs4_state_owner *sp;
93 struct rb_node *pos; 116 struct rb_node *pos;
117 struct rpc_cred *cred;
94 118
119 cred = nfs4_get_machine_cred(clp);
120 if (cred != NULL)
121 goto out;
95 pos = rb_first(&clp->cl_state_owners); 122 pos = rb_first(&clp->cl_state_owners);
96 if (pos != NULL) { 123 if (pos != NULL) {
97 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); 124 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
98 return get_rpccred(sp->so_cred); 125 cred = get_rpccred(sp->so_cred);
99 } 126 }
100 return NULL; 127out:
128 return cred;
101} 129}
102 130
103static void nfs_alloc_unique_id(struct rb_root *root, struct nfs_unique_id *new, 131static void nfs_alloc_unique_id(struct rb_root *root, struct nfs_unique_id *new,
@@ -292,8 +320,10 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct
292 spin_unlock(&clp->cl_lock); 320 spin_unlock(&clp->cl_lock);
293 if (sp == new) 321 if (sp == new)
294 get_rpccred(cred); 322 get_rpccred(cred);
295 else 323 else {
324 rpc_destroy_wait_queue(&new->so_sequence.wait);
296 kfree(new); 325 kfree(new);
326 }
297 return sp; 327 return sp;
298} 328}
299 329
@@ -310,6 +340,7 @@ void nfs4_put_state_owner(struct nfs4_state_owner *sp)
310 return; 340 return;
311 nfs4_remove_state_owner(clp, sp); 341 nfs4_remove_state_owner(clp, sp);
312 spin_unlock(&clp->cl_lock); 342 spin_unlock(&clp->cl_lock);
343 rpc_destroy_wait_queue(&sp->so_sequence.wait);
313 put_rpccred(cred); 344 put_rpccred(cred);
314 kfree(sp); 345 kfree(sp);
315} 346}
@@ -529,6 +560,7 @@ static void nfs4_free_lock_state(struct nfs4_lock_state *lsp)
529 spin_lock(&clp->cl_lock); 560 spin_lock(&clp->cl_lock);
530 nfs_free_unique_id(&clp->cl_lockowner_id, &lsp->ls_id); 561 nfs_free_unique_id(&clp->cl_lockowner_id, &lsp->ls_id);
531 spin_unlock(&clp->cl_lock); 562 spin_unlock(&clp->cl_lock);
563 rpc_destroy_wait_queue(&lsp->ls_sequence.wait);
532 kfree(lsp); 564 kfree(lsp);
533} 565}
534 566
@@ -731,7 +763,7 @@ int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
731 list_add_tail(&seqid->list, &sequence->list); 763 list_add_tail(&seqid->list, &sequence->list);
732 if (list_first_entry(&sequence->list, struct nfs_seqid, list) == seqid) 764 if (list_first_entry(&sequence->list, struct nfs_seqid, list) == seqid)
733 goto unlock; 765 goto unlock;
734 rpc_sleep_on(&sequence->wait, task, NULL, NULL); 766 rpc_sleep_on(&sequence->wait, task, NULL);
735 status = -EAGAIN; 767 status = -EAGAIN;
736unlock: 768unlock:
737 spin_unlock(&sequence->lock); 769 spin_unlock(&sequence->lock);
@@ -920,10 +952,10 @@ restart_loop:
920 if (cred != NULL) { 952 if (cred != NULL) {
921 /* Yes there are: try to renew the old lease */ 953 /* Yes there are: try to renew the old lease */
922 status = nfs4_proc_renew(clp, cred); 954 status = nfs4_proc_renew(clp, cred);
955 put_rpccred(cred);
923 switch (status) { 956 switch (status) {
924 case 0: 957 case 0:
925 case -NFS4ERR_CB_PATH_DOWN: 958 case -NFS4ERR_CB_PATH_DOWN:
926 put_rpccred(cred);
927 goto out; 959 goto out;
928 case -NFS4ERR_STALE_CLIENTID: 960 case -NFS4ERR_STALE_CLIENTID:
929 case -NFS4ERR_LEASE_MOVED: 961 case -NFS4ERR_LEASE_MOVED:
@@ -932,14 +964,19 @@ restart_loop:
932 } else { 964 } else {
933 /* "reboot" to ensure we clear all state on the server */ 965 /* "reboot" to ensure we clear all state on the server */
934 clp->cl_boot_time = CURRENT_TIME; 966 clp->cl_boot_time = CURRENT_TIME;
935 cred = nfs4_get_setclientid_cred(clp);
936 } 967 }
937 /* We're going to have to re-establish a clientid */ 968 /* We're going to have to re-establish a clientid */
938 nfs4_state_mark_reclaim(clp); 969 nfs4_state_mark_reclaim(clp);
939 status = -ENOENT; 970 status = -ENOENT;
971 cred = nfs4_get_setclientid_cred(clp);
940 if (cred != NULL) { 972 if (cred != NULL) {
941 status = nfs4_init_client(clp, cred); 973 status = nfs4_init_client(clp, cred);
942 put_rpccred(cred); 974 put_rpccred(cred);
975 /* Handle case where the user hasn't set up machine creds */
976 if (status == -EACCES && cred == clp->cl_machine_cred) {
977 nfs4_clear_machine_cred(clp);
978 goto restart_loop;
979 }
943 } 980 }
944 if (status) 981 if (status)
945 goto out_error; 982 goto out_error;