diff options
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r-- | fs/nfs/nfs4state.c | 49 |
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 | ||
74 | static 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 | |||
85 | static 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 | |||
74 | struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp) | 97 | struct 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; | 127 | out: |
128 | return cred; | ||
101 | } | 129 | } |
102 | 130 | ||
103 | static void nfs_alloc_unique_id(struct rb_root *root, struct nfs_unique_id *new, | 131 | static 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; |
736 | unlock: | 768 | unlock: |
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; |