aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c136
1 files changed, 56 insertions, 80 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 0422d77b73c7..5aa55c132aa2 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -77,7 +77,7 @@ struct nfs4_opendata;
77static int _nfs4_proc_open(struct nfs4_opendata *data); 77static int _nfs4_proc_open(struct nfs4_opendata *data);
78static int _nfs4_recover_proc_open(struct nfs4_opendata *data); 78static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
79static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 79static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
80static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); 80static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *, long *);
81static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr); 81static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
82static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label); 82static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label);
83static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label); 83static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label);
@@ -314,20 +314,30 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
314 kunmap_atomic(start); 314 kunmap_atomic(start);
315} 315}
316 316
317static long nfs4_update_delay(long *timeout)
318{
319 long ret;
320 if (!timeout)
321 return NFS4_POLL_RETRY_MAX;
322 if (*timeout <= 0)
323 *timeout = NFS4_POLL_RETRY_MIN;
324 if (*timeout > NFS4_POLL_RETRY_MAX)
325 *timeout = NFS4_POLL_RETRY_MAX;
326 ret = *timeout;
327 *timeout <<= 1;
328 return ret;
329}
330
317static int nfs4_delay(struct rpc_clnt *clnt, long *timeout) 331static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
318{ 332{
319 int res = 0; 333 int res = 0;
320 334
321 might_sleep(); 335 might_sleep();
322 336
323 if (*timeout <= 0) 337 freezable_schedule_timeout_killable_unsafe(
324 *timeout = NFS4_POLL_RETRY_MIN; 338 nfs4_update_delay(timeout));
325 if (*timeout > NFS4_POLL_RETRY_MAX)
326 *timeout = NFS4_POLL_RETRY_MAX;
327 freezable_schedule_timeout_killable_unsafe(*timeout);
328 if (fatal_signal_pending(current)) 339 if (fatal_signal_pending(current))
329 res = -ERESTARTSYS; 340 res = -ERESTARTSYS;
330 *timeout <<= 1;
331 return res; 341 return res;
332} 342}
333 343
@@ -1307,15 +1317,13 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
1307 int ret = -EAGAIN; 1317 int ret = -EAGAIN;
1308 1318
1309 for (;;) { 1319 for (;;) {
1320 spin_lock(&state->owner->so_lock);
1310 if (can_open_cached(state, fmode, open_mode)) { 1321 if (can_open_cached(state, fmode, open_mode)) {
1311 spin_lock(&state->owner->so_lock); 1322 update_open_stateflags(state, fmode);
1312 if (can_open_cached(state, fmode, open_mode)) {
1313 update_open_stateflags(state, fmode);
1314 spin_unlock(&state->owner->so_lock);
1315 goto out_return_state;
1316 }
1317 spin_unlock(&state->owner->so_lock); 1323 spin_unlock(&state->owner->so_lock);
1324 goto out_return_state;
1318 } 1325 }
1326 spin_unlock(&state->owner->so_lock);
1319 rcu_read_lock(); 1327 rcu_read_lock();
1320 delegation = rcu_dereference(nfsi->delegation); 1328 delegation = rcu_dereference(nfsi->delegation);
1321 if (!can_open_delegated(delegation, fmode)) { 1329 if (!can_open_delegated(delegation, fmode)) {
@@ -2589,7 +2597,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
2589 if (calldata->arg.fmode == 0) 2597 if (calldata->arg.fmode == 0)
2590 break; 2598 break;
2591 default: 2599 default:
2592 if (nfs4_async_handle_error(task, server, state) == -EAGAIN) { 2600 if (nfs4_async_handle_error(task, server, state, NULL) == -EAGAIN) {
2593 rpc_restart_call_prepare(task); 2601 rpc_restart_call_prepare(task);
2594 goto out_release; 2602 goto out_release;
2595 } 2603 }
@@ -3217,7 +3225,9 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
3217 struct nfs4_label *label = NULL; 3225 struct nfs4_label *label = NULL;
3218 int status; 3226 int status;
3219 3227
3220 if (pnfs_ld_layoutret_on_setattr(inode)) 3228 if (pnfs_ld_layoutret_on_setattr(inode) &&
3229 sattr->ia_valid & ATTR_SIZE &&
3230 sattr->ia_size < i_size_read(inode))
3221 pnfs_commit_and_return_layout(inode); 3231 pnfs_commit_and_return_layout(inode);
3222 3232
3223 nfs_fattr_init(fattr); 3233 nfs_fattr_init(fattr);
@@ -3576,7 +3586,8 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
3576 3586
3577 if (!nfs4_sequence_done(task, &res->seq_res)) 3587 if (!nfs4_sequence_done(task, &res->seq_res))
3578 return 0; 3588 return 0;
3579 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN) 3589 if (nfs4_async_handle_error(task, res->server, NULL,
3590 &data->timeout) == -EAGAIN)
3580 return 0; 3591 return 0;
3581 update_changeattr(dir, &res->cinfo); 3592 update_changeattr(dir, &res->cinfo);
3582 return 1; 3593 return 1;
@@ -3609,7 +3620,7 @@ static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
3609 3620
3610 if (!nfs4_sequence_done(task, &res->seq_res)) 3621 if (!nfs4_sequence_done(task, &res->seq_res))
3611 return 0; 3622 return 0;
3612 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN) 3623 if (nfs4_async_handle_error(task, res->server, NULL, &data->timeout) == -EAGAIN)
3613 return 0; 3624 return 0;
3614 3625
3615 update_changeattr(old_dir, &res->old_cinfo); 3626 update_changeattr(old_dir, &res->old_cinfo);
@@ -4113,7 +4124,8 @@ static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_pgio_header *hdr)
4113 4124
4114 trace_nfs4_read(hdr, task->tk_status); 4125 trace_nfs4_read(hdr, task->tk_status);
4115 if (nfs4_async_handle_error(task, server, 4126 if (nfs4_async_handle_error(task, server,
4116 hdr->args.context->state) == -EAGAIN) { 4127 hdr->args.context->state,
4128 NULL) == -EAGAIN) {
4117 rpc_restart_call_prepare(task); 4129 rpc_restart_call_prepare(task);
4118 return -EAGAIN; 4130 return -EAGAIN;
4119 } 4131 }
@@ -4181,10 +4193,11 @@ static int nfs4_write_done_cb(struct rpc_task *task,
4181 struct nfs_pgio_header *hdr) 4193 struct nfs_pgio_header *hdr)
4182{ 4194{
4183 struct inode *inode = hdr->inode; 4195 struct inode *inode = hdr->inode;
4184 4196
4185 trace_nfs4_write(hdr, task->tk_status); 4197 trace_nfs4_write(hdr, task->tk_status);
4186 if (nfs4_async_handle_error(task, NFS_SERVER(inode), 4198 if (nfs4_async_handle_error(task, NFS_SERVER(inode),
4187 hdr->args.context->state) == -EAGAIN) { 4199 hdr->args.context->state,
4200 NULL) == -EAGAIN) {
4188 rpc_restart_call_prepare(task); 4201 rpc_restart_call_prepare(task);
4189 return -EAGAIN; 4202 return -EAGAIN;
4190 } 4203 }
@@ -4264,7 +4277,8 @@ static int nfs4_commit_done_cb(struct rpc_task *task, struct nfs_commit_data *da
4264 struct inode *inode = data->inode; 4277 struct inode *inode = data->inode;
4265 4278
4266 trace_nfs4_commit(data, task->tk_status); 4279 trace_nfs4_commit(data, task->tk_status);
4267 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) { 4280 if (nfs4_async_handle_error(task, NFS_SERVER(inode),
4281 NULL, NULL) == -EAGAIN) {
4268 rpc_restart_call_prepare(task); 4282 rpc_restart_call_prepare(task);
4269 return -EAGAIN; 4283 return -EAGAIN;
4270 } 4284 }
@@ -4817,7 +4831,8 @@ out:
4817 4831
4818 4832
4819static int 4833static int
4820nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs4_state *state) 4834nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
4835 struct nfs4_state *state, long *timeout)
4821{ 4836{
4822 struct nfs_client *clp = server->nfs_client; 4837 struct nfs_client *clp = server->nfs_client;
4823 4838
@@ -4867,6 +4882,8 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
4867#endif /* CONFIG_NFS_V4_1 */ 4882#endif /* CONFIG_NFS_V4_1 */
4868 case -NFS4ERR_DELAY: 4883 case -NFS4ERR_DELAY:
4869 nfs_inc_server_stats(server, NFSIOS_DELAY); 4884 nfs_inc_server_stats(server, NFSIOS_DELAY);
4885 rpc_delay(task, nfs4_update_delay(timeout));
4886 goto restart_call;
4870 case -NFS4ERR_GRACE: 4887 case -NFS4ERR_GRACE:
4871 rpc_delay(task, NFS4_POLL_RETRY_MAX); 4888 rpc_delay(task, NFS4_POLL_RETRY_MAX);
4872 case -NFS4ERR_RETRY_UNCACHED_REP: 4889 case -NFS4ERR_RETRY_UNCACHED_REP:
@@ -5107,8 +5124,8 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
5107 pnfs_roc_set_barrier(data->inode, data->roc_barrier); 5124 pnfs_roc_set_barrier(data->inode, data->roc_barrier);
5108 break; 5125 break;
5109 default: 5126 default:
5110 if (nfs4_async_handle_error(task, data->res.server, NULL) == 5127 if (nfs4_async_handle_error(task, data->res.server,
5111 -EAGAIN) { 5128 NULL, NULL) == -EAGAIN) {
5112 rpc_restart_call_prepare(task); 5129 rpc_restart_call_prepare(task);
5113 return; 5130 return;
5114 } 5131 }
@@ -5372,7 +5389,8 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
5372 case -NFS4ERR_EXPIRED: 5389 case -NFS4ERR_EXPIRED:
5373 break; 5390 break;
5374 default: 5391 default:
5375 if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN) 5392 if (nfs4_async_handle_error(task, calldata->server,
5393 NULL, NULL) == -EAGAIN)
5376 rpc_restart_call_prepare(task); 5394 rpc_restart_call_prepare(task);
5377 } 5395 }
5378 nfs_release_seqid(calldata->arg.seqid); 5396 nfs_release_seqid(calldata->arg.seqid);
@@ -5978,7 +5996,8 @@ static void nfs4_release_lockowner_done(struct rpc_task *task, void *calldata)
5978 break; 5996 break;
5979 case -NFS4ERR_LEASE_MOVED: 5997 case -NFS4ERR_LEASE_MOVED:
5980 case -NFS4ERR_DELAY: 5998 case -NFS4ERR_DELAY:
5981 if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) 5999 if (nfs4_async_handle_error(task, server,
6000 NULL, NULL) == -EAGAIN)
5982 rpc_restart_call_prepare(task); 6001 rpc_restart_call_prepare(task);
5983 } 6002 }
5984} 6003}
@@ -7583,14 +7602,19 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
7583 } else { 7602 } else {
7584 LIST_HEAD(head); 7603 LIST_HEAD(head);
7585 7604
7605 /*
7606 * Mark the bad layout state as invalid, then retry
7607 * with the current stateid.
7608 */
7586 pnfs_mark_matching_lsegs_invalid(lo, &head, NULL); 7609 pnfs_mark_matching_lsegs_invalid(lo, &head, NULL);
7587 spin_unlock(&inode->i_lock); 7610 spin_unlock(&inode->i_lock);
7588 /* Mark the bad layout state as invalid, then
7589 * retry using the open stateid. */
7590 pnfs_free_lseg_list(&head); 7611 pnfs_free_lseg_list(&head);
7612
7613 task->tk_status = 0;
7614 rpc_restart_call_prepare(task);
7591 } 7615 }
7592 } 7616 }
7593 if (nfs4_async_handle_error(task, server, state) == -EAGAIN) 7617 if (nfs4_async_handle_error(task, server, state, NULL) == -EAGAIN)
7594 rpc_restart_call_prepare(task); 7618 rpc_restart_call_prepare(task);
7595out: 7619out:
7596 dprintk("<-- %s\n", __func__); 7620 dprintk("<-- %s\n", __func__);
@@ -7750,7 +7774,7 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
7750 case 0: 7774 case 0:
7751 break; 7775 break;
7752 case -NFS4ERR_DELAY: 7776 case -NFS4ERR_DELAY:
7753 if (nfs4_async_handle_error(task, server, NULL) != -EAGAIN) 7777 if (nfs4_async_handle_error(task, server, NULL, NULL) != -EAGAIN)
7754 break; 7778 break;
7755 rpc_restart_call_prepare(task); 7779 rpc_restart_call_prepare(task);
7756 return; 7780 return;
@@ -7809,54 +7833,6 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp)
7809 return status; 7833 return status;
7810} 7834}
7811 7835
7812/*
7813 * Retrieve the list of Data Server devices from the MDS.
7814 */
7815static int _nfs4_getdevicelist(struct nfs_server *server,
7816 const struct nfs_fh *fh,
7817 struct pnfs_devicelist *devlist)
7818{
7819 struct nfs4_getdevicelist_args args = {
7820 .fh = fh,
7821 .layoutclass = server->pnfs_curr_ld->id,
7822 };
7823 struct nfs4_getdevicelist_res res = {
7824 .devlist = devlist,
7825 };
7826 struct rpc_message msg = {
7827 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETDEVICELIST],
7828 .rpc_argp = &args,
7829 .rpc_resp = &res,
7830 };
7831 int status;
7832
7833 dprintk("--> %s\n", __func__);
7834 status = nfs4_call_sync(server->client, server, &msg, &args.seq_args,
7835 &res.seq_res, 0);
7836 dprintk("<-- %s status=%d\n", __func__, status);
7837 return status;
7838}
7839
7840int nfs4_proc_getdevicelist(struct nfs_server *server,
7841 const struct nfs_fh *fh,
7842 struct pnfs_devicelist *devlist)
7843{
7844 struct nfs4_exception exception = { };
7845 int err;
7846
7847 do {
7848 err = nfs4_handle_exception(server,
7849 _nfs4_getdevicelist(server, fh, devlist),
7850 &exception);
7851 } while (exception.retry);
7852
7853 dprintk("%s: err=%d, num_devs=%u\n", __func__,
7854 err, devlist->num_devs);
7855
7856 return err;
7857}
7858EXPORT_SYMBOL_GPL(nfs4_proc_getdevicelist);
7859
7860static int 7836static int
7861_nfs4_proc_getdeviceinfo(struct nfs_server *server, 7837_nfs4_proc_getdeviceinfo(struct nfs_server *server,
7862 struct pnfs_device *pdev, 7838 struct pnfs_device *pdev,
@@ -7929,7 +7905,7 @@ nfs4_layoutcommit_done(struct rpc_task *task, void *calldata)
7929 case 0: 7905 case 0:
7930 break; 7906 break;
7931 default: 7907 default:
7932 if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) { 7908 if (nfs4_async_handle_error(task, server, NULL, NULL) == -EAGAIN) {
7933 rpc_restart_call_prepare(task); 7909 rpc_restart_call_prepare(task);
7934 return; 7910 return;
7935 } 7911 }
@@ -8225,7 +8201,7 @@ static void nfs41_free_stateid_done(struct rpc_task *task, void *calldata)
8225 8201
8226 switch (task->tk_status) { 8202 switch (task->tk_status) {
8227 case -NFS4ERR_DELAY: 8203 case -NFS4ERR_DELAY:
8228 if (nfs4_async_handle_error(task, data->server, NULL) == -EAGAIN) 8204 if (nfs4_async_handle_error(task, data->server, NULL, NULL) == -EAGAIN)
8229 rpc_restart_call_prepare(task); 8205 rpc_restart_call_prepare(task);
8230 } 8206 }
8231} 8207}