diff options
Diffstat (limited to 'fs/nfs/flexfilelayout/flexfilelayout.c')
-rw-r--r-- | fs/nfs/flexfilelayout/flexfilelayout.c | 40 |
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 | ||
342 | static 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 | |||
342 | static struct pnfs_layout_segment * | 355 | static struct pnfs_layout_segment * |
343 | ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh, | 356 | ff_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 | ||
743 | static struct nfs4_pnfs_ds * | 757 | static struct nfs4_pnfs_ds * |
744 | ff_layout_choose_best_ds_for_read(struct nfs_pageio_descriptor *pgio, | 758 | ff_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; |
1040 | reset: | 1055 | reset: |
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 | |||
1157 | static int ff_layout_read_done_cb(struct rpc_task *task, | 1171 | static 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; |
1204 | out_eagain: | ||
1205 | rpc_restart_call_prepare(task); | ||
1206 | return -EAGAIN; | ||
1187 | } | 1207 | } |
1188 | 1208 | ||
1189 | static bool | 1209 | static bool |