@@ -1096,6 +1096,7 @@ static void ff_layout_reset_read(struct nfs_pgio_header *hdr)
1096
1096
}
1097
1097
1098
1098
static int ff_layout_async_handle_error_v4 (struct rpc_task * task ,
1099
+ u32 op_status ,
1099
1100
struct nfs4_state * state ,
1100
1101
struct nfs_client * clp ,
1101
1102
struct pnfs_layout_segment * lseg ,
@@ -1106,32 +1107,42 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
1106
1107
struct nfs4_deviceid_node * devid = FF_LAYOUT_DEVID_NODE (lseg , idx );
1107
1108
struct nfs4_slot_table * tbl = & clp -> cl_session -> fc_slot_table ;
1108
1109
1109
- switch (task -> tk_status ) {
1110
- case - NFS4ERR_BADSESSION :
1111
- case - NFS4ERR_BADSLOT :
1112
- case - NFS4ERR_BAD_HIGH_SLOT :
1113
- case - NFS4ERR_DEADSESSION :
1114
- case - NFS4ERR_CONN_NOT_BOUND_TO_SESSION :
1115
- case - NFS4ERR_SEQ_FALSE_RETRY :
1116
- case - NFS4ERR_SEQ_MISORDERED :
1110
+ switch (op_status ) {
1111
+ case NFS4_OK :
1112
+ case NFS4ERR_NXIO :
1113
+ break ;
1114
+ case NFSERR_PERM :
1115
+ if (!task -> tk_xprt )
1116
+ break ;
1117
+ xprt_force_disconnect (task -> tk_xprt );
1118
+ goto out_retry ;
1119
+ case NFS4ERR_BADSESSION :
1120
+ case NFS4ERR_BADSLOT :
1121
+ case NFS4ERR_BAD_HIGH_SLOT :
1122
+ case NFS4ERR_DEADSESSION :
1123
+ case NFS4ERR_CONN_NOT_BOUND_TO_SESSION :
1124
+ case NFS4ERR_SEQ_FALSE_RETRY :
1125
+ case NFS4ERR_SEQ_MISORDERED :
1117
1126
dprintk ("%s ERROR %d, Reset session. Exchangeid "
1118
1127
"flags 0x%x\n" , __func__ , task -> tk_status ,
1119
1128
clp -> cl_exchange_flags );
1120
1129
nfs4_schedule_session_recovery (clp -> cl_session , task -> tk_status );
1121
- break ;
1122
- case - NFS4ERR_DELAY :
1123
- case - NFS4ERR_GRACE :
1130
+ goto out_retry ;
1131
+ case NFS4ERR_DELAY :
1132
+ nfs_inc_stats (lseg -> pls_layout -> plh_inode , NFSIOS_DELAY );
1133
+ fallthrough ;
1134
+ case NFS4ERR_GRACE :
1124
1135
rpc_delay (task , FF_LAYOUT_POLL_RETRY_MAX );
1125
- break ;
1126
- case - NFS4ERR_RETRY_UNCACHED_REP :
1127
- break ;
1136
+ goto out_retry ;
1137
+ case NFS4ERR_RETRY_UNCACHED_REP :
1138
+ goto out_retry ;
1128
1139
/* Invalidate Layout errors */
1129
- case - NFS4ERR_PNFS_NO_LAYOUT :
1130
- case - ESTALE : /* mapped NFS4ERR_STALE */
1131
- case - EBADHANDLE : /* mapped NFS4ERR_BADHANDLE */
1132
- case - EISDIR : /* mapped NFS4ERR_ISDIR */
1133
- case - NFS4ERR_FHEXPIRED :
1134
- case - NFS4ERR_WRONG_TYPE :
1140
+ case NFS4ERR_PNFS_NO_LAYOUT :
1141
+ case NFS4ERR_STALE :
1142
+ case NFS4ERR_BADHANDLE :
1143
+ case NFS4ERR_ISDIR :
1144
+ case NFS4ERR_FHEXPIRED :
1145
+ case NFS4ERR_WRONG_TYPE :
1135
1146
dprintk ("%s Invalid layout error %d\n" , __func__ ,
1136
1147
task -> tk_status );
1137
1148
/*
@@ -1144,6 +1155,11 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
1144
1155
pnfs_destroy_layout (NFS_I (inode ));
1145
1156
rpc_wake_up (& tbl -> slot_tbl_waitq );
1146
1157
goto reset ;
1158
+ default :
1159
+ break ;
1160
+ }
1161
+
1162
+ switch (task -> tk_status ) {
1147
1163
/* RPC connection errors */
1148
1164
case - ECONNREFUSED :
1149
1165
case - EHOSTDOWN :
@@ -1159,26 +1175,56 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
1159
1175
nfs4_delete_deviceid (devid -> ld , devid -> nfs_client ,
1160
1176
& devid -> deviceid );
1161
1177
rpc_wake_up (& tbl -> slot_tbl_waitq );
1162
- fallthrough ;
1178
+ break ;
1163
1179
default :
1164
- if (ff_layout_avoid_mds_available_ds (lseg ))
1165
- return - NFS4ERR_RESET_TO_PNFS ;
1166
- reset :
1167
- dprintk ("%s Retry through MDS. Error %d\n" , __func__ ,
1168
- task -> tk_status );
1169
- return - NFS4ERR_RESET_TO_MDS ;
1180
+ break ;
1170
1181
}
1182
+
1183
+ if (ff_layout_avoid_mds_available_ds (lseg ))
1184
+ return - NFS4ERR_RESET_TO_PNFS ;
1185
+ reset :
1186
+ dprintk ("%s Retry through MDS. Error %d\n" , __func__ ,
1187
+ task -> tk_status );
1188
+ return - NFS4ERR_RESET_TO_MDS ;
1189
+
1190
+ out_retry :
1171
1191
task -> tk_status = 0 ;
1172
1192
return - EAGAIN ;
1173
1193
}
1174
1194
1175
1195
/* Retry all errors through either pNFS or MDS except for -EJUKEBOX */
1176
1196
static int ff_layout_async_handle_error_v3 (struct rpc_task * task ,
1197
+ u32 op_status ,
1198
+ struct nfs_client * clp ,
1177
1199
struct pnfs_layout_segment * lseg ,
1178
1200
u32 idx )
1179
1201
{
1180
1202
struct nfs4_deviceid_node * devid = FF_LAYOUT_DEVID_NODE (lseg , idx );
1181
1203
1204
+ switch (op_status ) {
1205
+ case NFS_OK :
1206
+ case NFSERR_NXIO :
1207
+ break ;
1208
+ case NFSERR_PERM :
1209
+ if (!task -> tk_xprt )
1210
+ break ;
1211
+ xprt_force_disconnect (task -> tk_xprt );
1212
+ goto out_retry ;
1213
+ case NFSERR_ACCES :
1214
+ case NFSERR_BADHANDLE :
1215
+ case NFSERR_FBIG :
1216
+ case NFSERR_IO :
1217
+ case NFSERR_NOSPC :
1218
+ case NFSERR_ROFS :
1219
+ case NFSERR_STALE :
1220
+ goto out_reset_to_pnfs ;
1221
+ case NFSERR_JUKEBOX :
1222
+ nfs_inc_stats (lseg -> pls_layout -> plh_inode , NFSIOS_DELAY );
1223
+ goto out_retry ;
1224
+ default :
1225
+ break ;
1226
+ }
1227
+
1182
1228
switch (task -> tk_status ) {
1183
1229
/* File access problems. Don't mark the device as unavailable */
1184
1230
case - EACCES :
@@ -1197,6 +1243,7 @@ static int ff_layout_async_handle_error_v3(struct rpc_task *task,
1197
1243
nfs4_delete_deviceid (devid -> ld , devid -> nfs_client ,
1198
1244
& devid -> deviceid );
1199
1245
}
1246
+ out_reset_to_pnfs :
1200
1247
/* FIXME: Need to prevent infinite looping here. */
1201
1248
return - NFS4ERR_RESET_TO_PNFS ;
1202
1249
out_retry :
@@ -1207,6 +1254,7 @@ static int ff_layout_async_handle_error_v3(struct rpc_task *task,
1207
1254
}
1208
1255
1209
1256
static int ff_layout_async_handle_error (struct rpc_task * task ,
1257
+ u32 op_status ,
1210
1258
struct nfs4_state * state ,
1211
1259
struct nfs_client * clp ,
1212
1260
struct pnfs_layout_segment * lseg ,
@@ -1225,10 +1273,11 @@ static int ff_layout_async_handle_error(struct rpc_task *task,
1225
1273
1226
1274
switch (vers ) {
1227
1275
case 3 :
1228
- return ff_layout_async_handle_error_v3 (task , lseg , idx );
1229
- case 4 :
1230
- return ff_layout_async_handle_error_v4 (task , state , clp ,
1276
+ return ff_layout_async_handle_error_v3 (task , op_status , clp ,
1231
1277
lseg , idx );
1278
+ case 4 :
1279
+ return ff_layout_async_handle_error_v4 (task , op_status , state ,
1280
+ clp , lseg , idx );
1232
1281
default :
1233
1282
/* should never happen */
1234
1283
WARN_ON_ONCE (1 );
@@ -1281,6 +1330,7 @@ static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg,
1281
1330
switch (status ) {
1282
1331
case NFS4ERR_DELAY :
1283
1332
case NFS4ERR_GRACE :
1333
+ case NFS4ERR_PERM :
1284
1334
break ;
1285
1335
case NFS4ERR_NXIO :
1286
1336
ff_layout_mark_ds_unreachable (lseg , idx );
@@ -1313,7 +1363,8 @@ static int ff_layout_read_done_cb(struct rpc_task *task,
1313
1363
trace_ff_layout_read_error (hdr );
1314
1364
}
1315
1365
1316
- err = ff_layout_async_handle_error (task , hdr -> args .context -> state ,
1366
+ err = ff_layout_async_handle_error (task , hdr -> res .op_status ,
1367
+ hdr -> args .context -> state ,
1317
1368
hdr -> ds_clp , hdr -> lseg ,
1318
1369
hdr -> pgio_mirror_idx );
1319
1370
@@ -1483,7 +1534,8 @@ static int ff_layout_write_done_cb(struct rpc_task *task,
1483
1534
trace_ff_layout_write_error (hdr );
1484
1535
}
1485
1536
1486
- err = ff_layout_async_handle_error (task , hdr -> args .context -> state ,
1537
+ err = ff_layout_async_handle_error (task , hdr -> res .op_status ,
1538
+ hdr -> args .context -> state ,
1487
1539
hdr -> ds_clp , hdr -> lseg ,
1488
1540
hdr -> pgio_mirror_idx );
1489
1541
@@ -1529,8 +1581,9 @@ static int ff_layout_commit_done_cb(struct rpc_task *task,
1529
1581
trace_ff_layout_commit_error (data );
1530
1582
}
1531
1583
1532
- err = ff_layout_async_handle_error (task , NULL , data -> ds_clp ,
1533
- data -> lseg , data -> ds_commit_index );
1584
+ err = ff_layout_async_handle_error (task , data -> res .op_status ,
1585
+ NULL , data -> ds_clp , data -> lseg ,
1586
+ data -> ds_commit_index );
1534
1587
1535
1588
trace_nfs4_pnfs_commit_ds (data , err );
1536
1589
switch (err ) {
0 commit comments