aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/flexfilelayout/flexfilelayout.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/flexfilelayout/flexfilelayout.c')
-rw-r--r--fs/nfs/flexfilelayout/flexfilelayout.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index fbc5a56de875..03516c80855a 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -339,6 +339,19 @@ static void ff_layout_sort_mirrors(struct nfs4_ff_layout_segment *fls)
339 } 339 }
340} 340}
341 341
342static void ff_layout_mark_devices_valid(struct nfs4_ff_layout_segment *fls)
343{
344 struct nfs4_deviceid_node *node;
345 int i;
346
347 if (!(fls->flags & FF_FLAGS_NO_IO_THRU_MDS))
348 return;
349 for (i = 0; i < fls->mirror_array_cnt; i++) {
350 node = &fls->mirror_array[i]->mirror_ds->id_node;
351 clear_bit(NFS_DEVICEID_UNAVAILABLE, &node->flags);
352 }
353}
354
342static struct pnfs_layout_segment * 355static struct pnfs_layout_segment *
343ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh, 356ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
344 struct nfs4_layoutget_res *lgr, 357 struct nfs4_layoutget_res *lgr,
@@ -499,6 +512,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
499 rc = ff_layout_check_layout(lgr); 512 rc = ff_layout_check_layout(lgr);
500 if (rc) 513 if (rc)
501 goto out_err_free; 514 goto out_err_free;
515 ff_layout_mark_devices_valid(fls);
502 516
503 ret = &fls->generic_hdr; 517 ret = &fls->generic_hdr;
504 dprintk("<-- %s (success)\n", __func__); 518 dprintk("<-- %s (success)\n", __func__);
@@ -741,17 +755,17 @@ ff_layout_alloc_commit_info(struct pnfs_layout_segment *lseg,
741} 755}
742 756
743static struct nfs4_pnfs_ds * 757static struct nfs4_pnfs_ds *
744ff_layout_choose_best_ds_for_read(struct nfs_pageio_descriptor *pgio, 758ff_layout_choose_best_ds_for_read(struct pnfs_layout_segment *lseg,
759 int start_idx,
745 int *best_idx) 760 int *best_idx)
746{ 761{
747 struct nfs4_ff_layout_segment *fls; 762 struct nfs4_ff_layout_segment *fls = FF_LAYOUT_LSEG(lseg);
748 struct nfs4_pnfs_ds *ds; 763 struct nfs4_pnfs_ds *ds;
749 int idx; 764 int idx;
750 765
751 fls = FF_LAYOUT_LSEG(pgio->pg_lseg);
752 /* mirrors are sorted by efficiency */ 766 /* mirrors are sorted by efficiency */
753 for (idx = 0; idx < fls->mirror_array_cnt; idx++) { 767 for (idx = start_idx; idx < fls->mirror_array_cnt; idx++) {
754 ds = nfs4_ff_layout_prepare_ds(pgio->pg_lseg, idx, false); 768 ds = nfs4_ff_layout_prepare_ds(lseg, idx, false);
755 if (ds) { 769 if (ds) {
756 *best_idx = idx; 770 *best_idx = idx;
757 return ds; 771 return ds;
@@ -782,7 +796,7 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
782 if (pgio->pg_lseg == NULL) 796 if (pgio->pg_lseg == NULL)
783 goto out_mds; 797 goto out_mds;
784 798
785 ds = ff_layout_choose_best_ds_for_read(pgio, &ds_idx); 799 ds = ff_layout_choose_best_ds_for_read(pgio->pg_lseg, 0, &ds_idx);
786 if (!ds) 800 if (!ds)
787 goto out_mds; 801 goto out_mds;
788 mirror = FF_LAYOUT_COMP(pgio->pg_lseg, ds_idx); 802 mirror = FF_LAYOUT_COMP(pgio->pg_lseg, ds_idx);
@@ -1035,7 +1049,8 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
1035 rpc_wake_up(&tbl->slot_tbl_waitq); 1049 rpc_wake_up(&tbl->slot_tbl_waitq);
1036 /* fall through */ 1050 /* fall through */
1037 default: 1051 default:
1038 if (ff_layout_has_available_ds(lseg)) 1052 if (ff_layout_no_fallback_to_mds(lseg) ||
1053 ff_layout_has_available_ds(lseg))
1039 return -NFS4ERR_RESET_TO_PNFS; 1054 return -NFS4ERR_RESET_TO_PNFS;
1040reset: 1055reset:
1041 dprintk("%s Retry through MDS. Error %d\n", __func__, 1056 dprintk("%s Retry through MDS. Error %d\n", __func__,
@@ -1153,7 +1168,6 @@ static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg,
1153} 1168}
1154 1169
1155/* NFS_PROTO call done callback routines */ 1170/* NFS_PROTO call done callback routines */
1156
1157static int ff_layout_read_done_cb(struct rpc_task *task, 1171static int ff_layout_read_done_cb(struct rpc_task *task,
1158 struct nfs_pgio_header *hdr) 1172 struct nfs_pgio_header *hdr)
1159{ 1173{
@@ -1171,6 +1185,10 @@ static int ff_layout_read_done_cb(struct rpc_task *task,
1171 1185
1172 switch (err) { 1186 switch (err) {
1173 case -NFS4ERR_RESET_TO_PNFS: 1187 case -NFS4ERR_RESET_TO_PNFS:
1188 if (ff_layout_choose_best_ds_for_read(hdr->lseg,
1189 hdr->pgio_mirror_idx + 1,
1190 &hdr->pgio_mirror_idx))
1191 goto out_eagain;
1174 set_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE, 1192 set_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE,
1175 &hdr->lseg->pls_layout->plh_flags); 1193 &hdr->lseg->pls_layout->plh_flags);
1176 pnfs_read_resend_pnfs(hdr); 1194 pnfs_read_resend_pnfs(hdr);
@@ -1179,11 +1197,13 @@ static int ff_layout_read_done_cb(struct rpc_task *task,
1179 ff_layout_reset_read(hdr); 1197 ff_layout_reset_read(hdr);
1180 return task->tk_status; 1198 return task->tk_status;
1181 case -EAGAIN: 1199 case -EAGAIN:
1182 rpc_restart_call_prepare(task); 1200 goto out_eagain;
1183 return -EAGAIN;
1184 } 1201 }
1185 1202
1186 return 0; 1203 return 0;
1204out_eagain:
1205 rpc_restart_call_prepare(task);
1206 return -EAGAIN;
1187} 1207}
1188 1208
1189static bool 1209static bool