aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4proc.c151
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;
63static int _nfs4_proc_open(struct nfs4_opendata *data); 63static int _nfs4_proc_open(struct nfs4_opendata *data);
64static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 64static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
65static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *); 65static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *);
66static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
67static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp);
68static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr); 66static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
69static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); 67static 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
196static int nfs4_wait_bit_killable(void *word)
197{
198 if (fatal_signal_pending(current))
199 return -ERESTARTSYS;
200 schedule();
201 return 0;
202}
203
204static 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
219static 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 */
239static 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
198static void renew_lease(const struct nfs_server *server, unsigned long timestamp) 270static 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
2802static int nfs4_wait_bit_killable(void *word)
2803{
2804 if (fatal_signal_pending(current))
2805 return -ERESTARTSYS;
2806 schedule();
2807 return 0;
2808}
2809
2810static 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
2825static 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 */
2845static 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
2875int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred) 2874int 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;