Commit 286d7d6a0cb38d3d4316a1dfea9b0c0fc5a6455b
1 parent
b4454fe1a7
Exists in
master
and in
7 other branches
NFSv4: Remove requirement for machine creds for the "setclientid" operation
Use a cred from the nfs4_client->cl_state_owners list. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Showing 4 changed files with 52 additions and 49 deletions Side-by-side Diff
fs/nfs/inode.c
... | ... | @@ -1822,22 +1822,8 @@ |
1822 | 1822 | clnt->cl_softrtry = 1; |
1823 | 1823 | clnt->cl_chatty = 1; |
1824 | 1824 | clp->cl_rpcclient = clnt; |
1825 | - clp->cl_cred = rpcauth_lookupcred(clnt->cl_auth, 0); | |
1826 | - if (IS_ERR(clp->cl_cred)) { | |
1827 | - up_write(&clp->cl_sem); | |
1828 | - err = PTR_ERR(clp->cl_cred); | |
1829 | - clp->cl_cred = NULL; | |
1830 | - goto out_fail; | |
1831 | - } | |
1832 | 1825 | memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr)); |
1833 | 1826 | nfs_idmap_new(clp); |
1834 | - } | |
1835 | - if (list_empty(&clp->cl_superblocks)) { | |
1836 | - err = nfs4_init_client(clp); | |
1837 | - if (err != 0) { | |
1838 | - up_write(&clp->cl_sem); | |
1839 | - goto out_fail; | |
1840 | - } | |
1841 | 1827 | } |
1842 | 1828 | list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks); |
1843 | 1829 | clnt = rpc_clone_client(clp->cl_rpcclient); |
fs/nfs/nfs4_fs.h
... | ... | @@ -68,7 +68,6 @@ |
68 | 68 | atomic_t cl_count; |
69 | 69 | |
70 | 70 | struct rpc_clnt * cl_rpcclient; |
71 | - struct rpc_cred * cl_cred; | |
72 | 71 | |
73 | 72 | struct list_head cl_superblocks; /* List of nfs_server structs */ |
74 | 73 | |
... | ... | @@ -211,8 +210,8 @@ |
211 | 210 | |
212 | 211 | /* nfs4proc.c */ |
213 | 212 | extern int nfs4_map_errors(int err); |
214 | -extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short); | |
215 | -extern int nfs4_proc_setclientid_confirm(struct nfs4_client *); | |
213 | +extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short, struct rpc_cred *); | |
214 | +extern int nfs4_proc_setclientid_confirm(struct nfs4_client *, struct rpc_cred *); | |
216 | 215 | extern int nfs4_proc_async_renew(struct nfs4_client *, struct rpc_cred *); |
217 | 216 | extern int nfs4_proc_renew(struct nfs4_client *, struct rpc_cred *); |
218 | 217 | extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state); |
... | ... | @@ -238,7 +237,6 @@ |
238 | 237 | extern void destroy_nfsv4_state(struct nfs_server *); |
239 | 238 | extern struct nfs4_client *nfs4_get_client(struct in_addr *); |
240 | 239 | extern void nfs4_put_client(struct nfs4_client *clp); |
241 | -extern int nfs4_init_client(struct nfs4_client *clp); | |
242 | 240 | extern struct nfs4_client *nfs4_find_client(struct in_addr *); |
243 | 241 | struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp); |
244 | 242 | extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *); |
fs/nfs/nfs4proc.c
... | ... | @@ -2846,7 +2846,7 @@ |
2846 | 2846 | return nfs4_map_errors(ret); |
2847 | 2847 | } |
2848 | 2848 | |
2849 | -int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short port) | |
2849 | +int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short port, struct rpc_cred *cred) | |
2850 | 2850 | { |
2851 | 2851 | nfs4_verifier sc_verifier; |
2852 | 2852 | struct nfs4_setclientid setclientid = { |
... | ... | @@ -2857,7 +2857,7 @@ |
2857 | 2857 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID], |
2858 | 2858 | .rpc_argp = &setclientid, |
2859 | 2859 | .rpc_resp = clp, |
2860 | - .rpc_cred = clp->cl_cred, | |
2860 | + .rpc_cred = cred, | |
2861 | 2861 | }; |
2862 | 2862 | u32 *p; |
2863 | 2863 | int loop = 0; |
... | ... | @@ -2871,7 +2871,7 @@ |
2871 | 2871 | setclientid.sc_name_len = scnprintf(setclientid.sc_name, |
2872 | 2872 | sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u %s %u", |
2873 | 2873 | clp->cl_ipaddr, NIPQUAD(clp->cl_addr.s_addr), |
2874 | - clp->cl_cred->cr_ops->cr_name, | |
2874 | + cred->cr_ops->cr_name, | |
2875 | 2875 | clp->cl_id_uniquifier); |
2876 | 2876 | setclientid.sc_netid_len = scnprintf(setclientid.sc_netid, |
2877 | 2877 | sizeof(setclientid.sc_netid), "tcp"); |
2878 | 2878 | |
... | ... | @@ -2894,14 +2894,14 @@ |
2894 | 2894 | } |
2895 | 2895 | |
2896 | 2896 | int |
2897 | -nfs4_proc_setclientid_confirm(struct nfs4_client *clp) | |
2897 | +nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cred *cred) | |
2898 | 2898 | { |
2899 | 2899 | struct nfs_fsinfo fsinfo; |
2900 | 2900 | struct rpc_message msg = { |
2901 | 2901 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM], |
2902 | 2902 | .rpc_argp = clp, |
2903 | 2903 | .rpc_resp = &fsinfo, |
2904 | - .rpc_cred = clp->cl_cred, | |
2904 | + .rpc_cred = cred, | |
2905 | 2905 | }; |
2906 | 2906 | unsigned long now; |
2907 | 2907 | int status; |
fs/nfs/nfs4state.c
... | ... | @@ -91,11 +91,10 @@ |
91 | 91 | |
92 | 92 | if (nfs_callback_up() < 0) |
93 | 93 | return NULL; |
94 | - if ((clp = kmalloc(sizeof(*clp), GFP_KERNEL)) == NULL) { | |
94 | + if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) { | |
95 | 95 | nfs_callback_down(); |
96 | 96 | return NULL; |
97 | 97 | } |
98 | - memset(clp, 0, sizeof(*clp)); | |
99 | 98 | memcpy(&clp->cl_addr, addr, sizeof(clp->cl_addr)); |
100 | 99 | init_rwsem(&clp->cl_sem); |
101 | 100 | INIT_LIST_HEAD(&clp->cl_delegations); |
... | ... | @@ -108,7 +107,7 @@ |
108 | 107 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client"); |
109 | 108 | clp->cl_rpcclient = ERR_PTR(-EINVAL); |
110 | 109 | clp->cl_boot_time = CURRENT_TIME; |
111 | - clp->cl_state = 0; | |
110 | + clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; | |
112 | 111 | return clp; |
113 | 112 | } |
114 | 113 | |
... | ... | @@ -125,8 +124,6 @@ |
125 | 124 | kfree(sp); |
126 | 125 | } |
127 | 126 | BUG_ON(!list_empty(&clp->cl_state_owners)); |
128 | - if (clp->cl_cred) | |
129 | - put_rpccred(clp->cl_cred); | |
130 | 127 | nfs_idmap_delete(clp); |
131 | 128 | if (!IS_ERR(clp->cl_rpcclient)) |
132 | 129 | rpc_shutdown_client(clp->cl_rpcclient); |
133 | 130 | |
134 | 131 | |
135 | 132 | |
... | ... | @@ -196,21 +193,17 @@ |
196 | 193 | nfs4_free_client(clp); |
197 | 194 | } |
198 | 195 | |
199 | -static int __nfs4_init_client(struct nfs4_client *clp) | |
196 | +static int nfs4_init_client(struct nfs4_client *clp, struct rpc_cred *cred) | |
200 | 197 | { |
201 | - int status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, nfs_callback_tcpport); | |
198 | + int status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, | |
199 | + nfs_callback_tcpport, cred); | |
202 | 200 | if (status == 0) |
203 | - status = nfs4_proc_setclientid_confirm(clp); | |
201 | + status = nfs4_proc_setclientid_confirm(clp, cred); | |
204 | 202 | if (status == 0) |
205 | 203 | nfs4_schedule_state_renewal(clp); |
206 | 204 | return status; |
207 | 205 | } |
208 | 206 | |
209 | -int nfs4_init_client(struct nfs4_client *clp) | |
210 | -{ | |
211 | - return nfs4_map_errors(__nfs4_init_client(clp)); | |
212 | -} | |
213 | - | |
214 | 207 | u32 |
215 | 208 | nfs4_alloc_lockowner_id(struct nfs4_client *clp) |
216 | 209 | { |
... | ... | @@ -246,6 +239,18 @@ |
246 | 239 | return cred; |
247 | 240 | } |
248 | 241 | |
242 | +struct rpc_cred *nfs4_get_setclientid_cred(struct nfs4_client *clp) | |
243 | +{ | |
244 | + struct nfs4_state_owner *sp; | |
245 | + | |
246 | + if (!list_empty(&clp->cl_state_owners)) { | |
247 | + sp = list_entry(clp->cl_state_owners.next, | |
248 | + struct nfs4_state_owner, so_list); | |
249 | + return get_rpccred(sp->so_cred); | |
250 | + } | |
251 | + return NULL; | |
252 | +} | |
253 | + | |
249 | 254 | static struct nfs4_state_owner * |
250 | 255 | nfs4_find_state_owner(struct nfs4_client *clp, struct rpc_cred *cred) |
251 | 256 | { |
... | ... | @@ -902,6 +907,7 @@ |
902 | 907 | struct nfs4_client *clp = ptr; |
903 | 908 | struct nfs4_state_owner *sp; |
904 | 909 | struct nfs4_state_recovery_ops *ops; |
910 | + struct rpc_cred *cred; | |
905 | 911 | int status = 0; |
906 | 912 | |
907 | 913 | allow_signal(SIGKILL); |
908 | 914 | |
... | ... | @@ -913,20 +919,33 @@ |
913 | 919 | if (list_empty(&clp->cl_superblocks)) |
914 | 920 | goto out; |
915 | 921 | restart_loop: |
916 | - status = nfs4_proc_renew(clp, clp->cl_cred); | |
917 | - switch (status) { | |
918 | - case 0: | |
919 | - case -NFS4ERR_CB_PATH_DOWN: | |
920 | - goto out; | |
921 | - case -NFS4ERR_STALE_CLIENTID: | |
922 | - case -NFS4ERR_LEASE_MOVED: | |
923 | - ops = &nfs4_reboot_recovery_ops; | |
924 | - break; | |
925 | - default: | |
926 | - ops = &nfs4_network_partition_recovery_ops; | |
927 | - }; | |
922 | + ops = &nfs4_network_partition_recovery_ops; | |
923 | + /* Are there any open files on this volume? */ | |
924 | + cred = nfs4_get_renew_cred(clp); | |
925 | + if (cred != NULL) { | |
926 | + /* Yes there are: try to renew the old lease */ | |
927 | + status = nfs4_proc_renew(clp, cred); | |
928 | + switch (status) { | |
929 | + case 0: | |
930 | + case -NFS4ERR_CB_PATH_DOWN: | |
931 | + put_rpccred(cred); | |
932 | + goto out; | |
933 | + case -NFS4ERR_STALE_CLIENTID: | |
934 | + case -NFS4ERR_LEASE_MOVED: | |
935 | + ops = &nfs4_reboot_recovery_ops; | |
936 | + } | |
937 | + } else { | |
938 | + /* "reboot" to ensure we clear all state on the server */ | |
939 | + clp->cl_boot_time = CURRENT_TIME; | |
940 | + cred = nfs4_get_setclientid_cred(clp); | |
941 | + } | |
942 | + /* We're going to have to re-establish a clientid */ | |
928 | 943 | nfs4_state_mark_reclaim(clp); |
929 | - status = __nfs4_init_client(clp); | |
944 | + status = -ENOENT; | |
945 | + if (cred != NULL) { | |
946 | + status = nfs4_init_client(clp, cred); | |
947 | + put_rpccred(cred); | |
948 | + } | |
930 | 949 | if (status) |
931 | 950 | goto out_error; |
932 | 951 | /* Mark all delegations for reclaim */ |