diff options
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/inode.c | 14 | ||||
-rw-r--r-- | fs/nfs/nfs4_fs.h | 6 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 10 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 71 |
4 files changed, 52 insertions, 49 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 432f41cd75e6..740d3cd40246 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -1822,23 +1822,9 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, | |||
1822 | clnt->cl_softrtry = 1; | 1822 | clnt->cl_softrtry = 1; |
1823 | clnt->cl_chatty = 1; | 1823 | clnt->cl_chatty = 1; |
1824 | clp->cl_rpcclient = clnt; | 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 | memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr)); | 1825 | memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr)); |
1833 | nfs_idmap_new(clp); | 1826 | nfs_idmap_new(clp); |
1834 | } | 1827 | } |
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 | } | ||
1842 | list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks); | 1828 | list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks); |
1843 | clnt = rpc_clone_client(clp->cl_rpcclient); | 1829 | clnt = rpc_clone_client(clp->cl_rpcclient); |
1844 | if (!IS_ERR(clnt)) | 1830 | if (!IS_ERR(clnt)) |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 4a9c53e0793c..0f5e4e7cddec 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -68,7 +68,6 @@ struct nfs4_client { | |||
68 | atomic_t cl_count; | 68 | atomic_t cl_count; |
69 | 69 | ||
70 | struct rpc_clnt * cl_rpcclient; | 70 | struct rpc_clnt * cl_rpcclient; |
71 | struct rpc_cred * cl_cred; | ||
72 | 71 | ||
73 | struct list_head cl_superblocks; /* List of nfs_server structs */ | 72 | struct list_head cl_superblocks; /* List of nfs_server structs */ |
74 | 73 | ||
@@ -211,8 +210,8 @@ extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t); | |||
211 | 210 | ||
212 | /* nfs4proc.c */ | 211 | /* nfs4proc.c */ |
213 | extern int nfs4_map_errors(int err); | 212 | extern int nfs4_map_errors(int err); |
214 | extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short); | 213 | extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short, struct rpc_cred *); |
215 | extern int nfs4_proc_setclientid_confirm(struct nfs4_client *); | 214 | extern int nfs4_proc_setclientid_confirm(struct nfs4_client *, struct rpc_cred *); |
216 | extern int nfs4_proc_async_renew(struct nfs4_client *, struct rpc_cred *); | 215 | extern int nfs4_proc_async_renew(struct nfs4_client *, struct rpc_cred *); |
217 | extern int nfs4_proc_renew(struct nfs4_client *, struct rpc_cred *); | 216 | extern int nfs4_proc_renew(struct nfs4_client *, struct rpc_cred *); |
218 | extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state); | 217 | extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state); |
@@ -238,7 +237,6 @@ extern void init_nfsv4_state(struct nfs_server *); | |||
238 | extern void destroy_nfsv4_state(struct nfs_server *); | 237 | extern void destroy_nfsv4_state(struct nfs_server *); |
239 | extern struct nfs4_client *nfs4_get_client(struct in_addr *); | 238 | extern struct nfs4_client *nfs4_get_client(struct in_addr *); |
240 | extern void nfs4_put_client(struct nfs4_client *clp); | 239 | extern void nfs4_put_client(struct nfs4_client *clp); |
241 | extern int nfs4_init_client(struct nfs4_client *clp); | ||
242 | extern struct nfs4_client *nfs4_find_client(struct in_addr *); | 240 | extern struct nfs4_client *nfs4_find_client(struct in_addr *); |
243 | struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp); | 241 | struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp); |
244 | extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *); | 242 | extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *); |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index e38401931291..b3349154994b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2846,7 +2846,7 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct | |||
2846 | return nfs4_map_errors(ret); | 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 | nfs4_verifier sc_verifier; | 2851 | nfs4_verifier sc_verifier; |
2852 | struct nfs4_setclientid setclientid = { | 2852 | struct nfs4_setclientid setclientid = { |
@@ -2857,7 +2857,7 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p | |||
2857 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID], | 2857 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID], |
2858 | .rpc_argp = &setclientid, | 2858 | .rpc_argp = &setclientid, |
2859 | .rpc_resp = clp, | 2859 | .rpc_resp = clp, |
2860 | .rpc_cred = clp->cl_cred, | 2860 | .rpc_cred = cred, |
2861 | }; | 2861 | }; |
2862 | u32 *p; | 2862 | u32 *p; |
2863 | int loop = 0; | 2863 | int loop = 0; |
@@ -2871,7 +2871,7 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p | |||
2871 | setclientid.sc_name_len = scnprintf(setclientid.sc_name, | 2871 | setclientid.sc_name_len = scnprintf(setclientid.sc_name, |
2872 | sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u %s %u", | 2872 | sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u %s %u", |
2873 | clp->cl_ipaddr, NIPQUAD(clp->cl_addr.s_addr), | 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 | clp->cl_id_uniquifier); | 2875 | clp->cl_id_uniquifier); |
2876 | setclientid.sc_netid_len = scnprintf(setclientid.sc_netid, | 2876 | setclientid.sc_netid_len = scnprintf(setclientid.sc_netid, |
2877 | sizeof(setclientid.sc_netid), "tcp"); | 2877 | sizeof(setclientid.sc_netid), "tcp"); |
@@ -2894,14 +2894,14 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p | |||
2894 | } | 2894 | } |
2895 | 2895 | ||
2896 | int | 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 | struct nfs_fsinfo fsinfo; | 2899 | struct nfs_fsinfo fsinfo; |
2900 | struct rpc_message msg = { | 2900 | struct rpc_message msg = { |
2901 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM], | 2901 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM], |
2902 | .rpc_argp = clp, | 2902 | .rpc_argp = clp, |
2903 | .rpc_resp = &fsinfo, | 2903 | .rpc_resp = &fsinfo, |
2904 | .rpc_cred = clp->cl_cred, | 2904 | .rpc_cred = cred, |
2905 | }; | 2905 | }; |
2906 | unsigned long now; | 2906 | unsigned long now; |
2907 | int status; | 2907 | int status; |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 18f6ed1a0b54..afad0255e7db 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -91,11 +91,10 @@ nfs4_alloc_client(struct in_addr *addr) | |||
91 | 91 | ||
92 | if (nfs_callback_up() < 0) | 92 | if (nfs_callback_up() < 0) |
93 | return NULL; | 93 | return NULL; |
94 | if ((clp = kmalloc(sizeof(*clp), GFP_KERNEL)) == NULL) { | 94 | if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) { |
95 | nfs_callback_down(); | 95 | nfs_callback_down(); |
96 | return NULL; | 96 | return NULL; |
97 | } | 97 | } |
98 | memset(clp, 0, sizeof(*clp)); | ||
99 | memcpy(&clp->cl_addr, addr, sizeof(clp->cl_addr)); | 98 | memcpy(&clp->cl_addr, addr, sizeof(clp->cl_addr)); |
100 | init_rwsem(&clp->cl_sem); | 99 | init_rwsem(&clp->cl_sem); |
101 | INIT_LIST_HEAD(&clp->cl_delegations); | 100 | INIT_LIST_HEAD(&clp->cl_delegations); |
@@ -108,7 +107,7 @@ nfs4_alloc_client(struct in_addr *addr) | |||
108 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client"); | 107 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client"); |
109 | clp->cl_rpcclient = ERR_PTR(-EINVAL); | 108 | clp->cl_rpcclient = ERR_PTR(-EINVAL); |
110 | clp->cl_boot_time = CURRENT_TIME; | 109 | clp->cl_boot_time = CURRENT_TIME; |
111 | clp->cl_state = 0; | 110 | clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; |
112 | return clp; | 111 | return clp; |
113 | } | 112 | } |
114 | 113 | ||
@@ -125,8 +124,6 @@ nfs4_free_client(struct nfs4_client *clp) | |||
125 | kfree(sp); | 124 | kfree(sp); |
126 | } | 125 | } |
127 | BUG_ON(!list_empty(&clp->cl_state_owners)); | 126 | BUG_ON(!list_empty(&clp->cl_state_owners)); |
128 | if (clp->cl_cred) | ||
129 | put_rpccred(clp->cl_cred); | ||
130 | nfs_idmap_delete(clp); | 127 | nfs_idmap_delete(clp); |
131 | if (!IS_ERR(clp->cl_rpcclient)) | 128 | if (!IS_ERR(clp->cl_rpcclient)) |
132 | rpc_shutdown_client(clp->cl_rpcclient); | 129 | rpc_shutdown_client(clp->cl_rpcclient); |
@@ -196,21 +193,17 @@ nfs4_put_client(struct nfs4_client *clp) | |||
196 | nfs4_free_client(clp); | 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 | if (status == 0) | 200 | if (status == 0) |
203 | status = nfs4_proc_setclientid_confirm(clp); | 201 | status = nfs4_proc_setclientid_confirm(clp, cred); |
204 | if (status == 0) | 202 | if (status == 0) |
205 | nfs4_schedule_state_renewal(clp); | 203 | nfs4_schedule_state_renewal(clp); |
206 | return status; | 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 | u32 | 207 | u32 |
215 | nfs4_alloc_lockowner_id(struct nfs4_client *clp) | 208 | nfs4_alloc_lockowner_id(struct nfs4_client *clp) |
216 | { | 209 | { |
@@ -246,6 +239,18 @@ struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp) | |||
246 | return cred; | 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 | static struct nfs4_state_owner * | 254 | static struct nfs4_state_owner * |
250 | nfs4_find_state_owner(struct nfs4_client *clp, struct rpc_cred *cred) | 255 | nfs4_find_state_owner(struct nfs4_client *clp, struct rpc_cred *cred) |
251 | { | 256 | { |
@@ -902,6 +907,7 @@ static int reclaimer(void *ptr) | |||
902 | struct nfs4_client *clp = ptr; | 907 | struct nfs4_client *clp = ptr; |
903 | struct nfs4_state_owner *sp; | 908 | struct nfs4_state_owner *sp; |
904 | struct nfs4_state_recovery_ops *ops; | 909 | struct nfs4_state_recovery_ops *ops; |
910 | struct rpc_cred *cred; | ||
905 | int status = 0; | 911 | int status = 0; |
906 | 912 | ||
907 | allow_signal(SIGKILL); | 913 | allow_signal(SIGKILL); |
@@ -913,20 +919,33 @@ static int reclaimer(void *ptr) | |||
913 | if (list_empty(&clp->cl_superblocks)) | 919 | if (list_empty(&clp->cl_superblocks)) |
914 | goto out; | 920 | goto out; |
915 | restart_loop: | 921 | restart_loop: |
916 | status = nfs4_proc_renew(clp, clp->cl_cred); | 922 | ops = &nfs4_network_partition_recovery_ops; |
917 | switch (status) { | 923 | /* Are there any open files on this volume? */ |
918 | case 0: | 924 | cred = nfs4_get_renew_cred(clp); |
919 | case -NFS4ERR_CB_PATH_DOWN: | 925 | if (cred != NULL) { |
920 | goto out; | 926 | /* Yes there are: try to renew the old lease */ |
921 | case -NFS4ERR_STALE_CLIENTID: | 927 | status = nfs4_proc_renew(clp, cred); |
922 | case -NFS4ERR_LEASE_MOVED: | 928 | switch (status) { |
923 | ops = &nfs4_reboot_recovery_ops; | 929 | case 0: |
924 | break; | 930 | case -NFS4ERR_CB_PATH_DOWN: |
925 | default: | 931 | put_rpccred(cred); |
926 | ops = &nfs4_network_partition_recovery_ops; | 932 | goto out; |
927 | }; | 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 | nfs4_state_mark_reclaim(clp); | 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 | if (status) | 949 | if (status) |
931 | goto out_error; | 950 | goto out_error; |
932 | /* Mark all delegations for reclaim */ | 951 | /* Mark all delegations for reclaim */ |