Commit 286d7d6a0cb38d3d4316a1dfea9b0c0fc5a6455b

Authored by Trond Myklebust
1 parent b4454fe1a7

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

... ... @@ -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);
... ... @@ -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 *);
... ... @@ -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;
... ... @@ -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 */