diff options
-rw-r--r-- | fs/nfs/nfs4proc.c | 151 |
1 files changed, 75 insertions, 76 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 019c8d67e145..660c5dcfb0a5 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -63,8 +63,6 @@ struct nfs4_opendata; | |||
63 | static int _nfs4_proc_open(struct nfs4_opendata *data); | 63 | static int _nfs4_proc_open(struct nfs4_opendata *data); |
64 | static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); | 64 | static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); |
65 | static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *); | 65 | static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *); |
66 | static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception); | ||
67 | static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp); | ||
68 | static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr); | 66 | static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr); |
69 | static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); | 67 | static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); |
70 | 68 | ||
@@ -195,6 +193,80 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent | |||
195 | kunmap_atomic(start, KM_USER0); | 193 | kunmap_atomic(start, KM_USER0); |
196 | } | 194 | } |
197 | 195 | ||
196 | static int nfs4_wait_bit_killable(void *word) | ||
197 | { | ||
198 | if (fatal_signal_pending(current)) | ||
199 | return -ERESTARTSYS; | ||
200 | schedule(); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int nfs4_wait_clnt_recover(struct nfs_client *clp) | ||
205 | { | ||
206 | int res; | ||
207 | |||
208 | might_sleep(); | ||
209 | |||
210 | rwsem_acquire(&clp->cl_sem.dep_map, 0, 0, _RET_IP_); | ||
211 | |||
212 | res = wait_on_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER, | ||
213 | nfs4_wait_bit_killable, TASK_KILLABLE); | ||
214 | |||
215 | rwsem_release(&clp->cl_sem.dep_map, 1, _RET_IP_); | ||
216 | return res; | ||
217 | } | ||
218 | |||
219 | static int nfs4_delay(struct rpc_clnt *clnt, long *timeout) | ||
220 | { | ||
221 | int res = 0; | ||
222 | |||
223 | might_sleep(); | ||
224 | |||
225 | if (*timeout <= 0) | ||
226 | *timeout = NFS4_POLL_RETRY_MIN; | ||
227 | if (*timeout > NFS4_POLL_RETRY_MAX) | ||
228 | *timeout = NFS4_POLL_RETRY_MAX; | ||
229 | schedule_timeout_killable(*timeout); | ||
230 | if (fatal_signal_pending(current)) | ||
231 | res = -ERESTARTSYS; | ||
232 | *timeout <<= 1; | ||
233 | return res; | ||
234 | } | ||
235 | |||
236 | /* This is the error handling routine for processes that are allowed | ||
237 | * to sleep. | ||
238 | */ | ||
239 | static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception) | ||
240 | { | ||
241 | struct nfs_client *clp = server->nfs_client; | ||
242 | int ret = errorcode; | ||
243 | |||
244 | exception->retry = 0; | ||
245 | switch(errorcode) { | ||
246 | case 0: | ||
247 | return 0; | ||
248 | case -NFS4ERR_STALE_CLIENTID: | ||
249 | case -NFS4ERR_STALE_STATEID: | ||
250 | case -NFS4ERR_EXPIRED: | ||
251 | nfs4_schedule_state_recovery(clp); | ||
252 | ret = nfs4_wait_clnt_recover(clp); | ||
253 | if (ret == 0) | ||
254 | exception->retry = 1; | ||
255 | break; | ||
256 | case -NFS4ERR_FILE_OPEN: | ||
257 | case -NFS4ERR_GRACE: | ||
258 | case -NFS4ERR_DELAY: | ||
259 | ret = nfs4_delay(server->client, &exception->timeout); | ||
260 | if (ret != 0) | ||
261 | break; | ||
262 | case -NFS4ERR_OLD_STATEID: | ||
263 | exception->retry = 1; | ||
264 | } | ||
265 | /* We failed to handle the error */ | ||
266 | return nfs4_map_errors(ret); | ||
267 | } | ||
268 | |||
269 | |||
198 | static void renew_lease(const struct nfs_server *server, unsigned long timestamp) | 270 | static void renew_lease(const struct nfs_server *server, unsigned long timestamp) |
199 | { | 271 | { |
200 | struct nfs_client *clp = server->nfs_client; | 272 | struct nfs_client *clp = server->nfs_client; |
@@ -981,7 +1053,7 @@ static int nfs4_recover_expired_lease(struct nfs_server *server) | |||
981 | int ret; | 1053 | int ret; |
982 | 1054 | ||
983 | for (;;) { | 1055 | for (;;) { |
984 | ret = nfs4_wait_clnt_recover(server->client, clp); | 1056 | ret = nfs4_wait_clnt_recover(clp); |
985 | if (ret != 0) | 1057 | if (ret != 0) |
986 | return ret; | 1058 | return ret; |
987 | if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) && | 1059 | if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) && |
@@ -2799,79 +2871,6 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server) | |||
2799 | return 0; | 2871 | return 0; |
2800 | } | 2872 | } |
2801 | 2873 | ||
2802 | static int nfs4_wait_bit_killable(void *word) | ||
2803 | { | ||
2804 | if (fatal_signal_pending(current)) | ||
2805 | return -ERESTARTSYS; | ||
2806 | schedule(); | ||
2807 | return 0; | ||
2808 | } | ||
2809 | |||
2810 | static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp) | ||
2811 | { | ||
2812 | int res; | ||
2813 | |||
2814 | might_sleep(); | ||
2815 | |||
2816 | rwsem_acquire(&clp->cl_sem.dep_map, 0, 0, _RET_IP_); | ||
2817 | |||
2818 | res = wait_on_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER, | ||
2819 | nfs4_wait_bit_killable, TASK_KILLABLE); | ||
2820 | |||
2821 | rwsem_release(&clp->cl_sem.dep_map, 1, _RET_IP_); | ||
2822 | return res; | ||
2823 | } | ||
2824 | |||
2825 | static int nfs4_delay(struct rpc_clnt *clnt, long *timeout) | ||
2826 | { | ||
2827 | int res = 0; | ||
2828 | |||
2829 | might_sleep(); | ||
2830 | |||
2831 | if (*timeout <= 0) | ||
2832 | *timeout = NFS4_POLL_RETRY_MIN; | ||
2833 | if (*timeout > NFS4_POLL_RETRY_MAX) | ||
2834 | *timeout = NFS4_POLL_RETRY_MAX; | ||
2835 | schedule_timeout_killable(*timeout); | ||
2836 | if (fatal_signal_pending(current)) | ||
2837 | res = -ERESTARTSYS; | ||
2838 | *timeout <<= 1; | ||
2839 | return res; | ||
2840 | } | ||
2841 | |||
2842 | /* This is the error handling routine for processes that are allowed | ||
2843 | * to sleep. | ||
2844 | */ | ||
2845 | static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception) | ||
2846 | { | ||
2847 | struct nfs_client *clp = server->nfs_client; | ||
2848 | int ret = errorcode; | ||
2849 | |||
2850 | exception->retry = 0; | ||
2851 | switch(errorcode) { | ||
2852 | case 0: | ||
2853 | return 0; | ||
2854 | case -NFS4ERR_STALE_CLIENTID: | ||
2855 | case -NFS4ERR_STALE_STATEID: | ||
2856 | case -NFS4ERR_EXPIRED: | ||
2857 | nfs4_schedule_state_recovery(clp); | ||
2858 | ret = nfs4_wait_clnt_recover(server->client, clp); | ||
2859 | if (ret == 0) | ||
2860 | exception->retry = 1; | ||
2861 | break; | ||
2862 | case -NFS4ERR_FILE_OPEN: | ||
2863 | case -NFS4ERR_GRACE: | ||
2864 | case -NFS4ERR_DELAY: | ||
2865 | ret = nfs4_delay(server->client, &exception->timeout); | ||
2866 | if (ret != 0) | ||
2867 | break; | ||
2868 | case -NFS4ERR_OLD_STATEID: | ||
2869 | exception->retry = 1; | ||
2870 | } | ||
2871 | /* We failed to handle the error */ | ||
2872 | return nfs4_map_errors(ret); | ||
2873 | } | ||
2874 | |||
2875 | int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred) | 2874 | int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred) |
2876 | { | 2875 | { |
2877 | nfs4_verifier sc_verifier; | 2876 | nfs4_verifier sc_verifier; |