@@ -1105,6 +1105,7 @@ static void ff_layout_reset_read(struct nfs_pgio_header *hdr)
1105
1105
}
1106
1106
1107
1107
static int ff_layout_async_handle_error_v4 (struct rpc_task * task ,
1108
+ u32 op_status ,
1108
1109
struct nfs4_state * state ,
1109
1110
struct nfs_client * clp ,
1110
1111
struct pnfs_layout_segment * lseg ,
@@ -1115,34 +1116,42 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
1115
1116
struct nfs4_deviceid_node * devid = FF_LAYOUT_DEVID_NODE (lseg , idx );
1116
1117
struct nfs4_slot_table * tbl = & clp -> cl_session -> fc_slot_table ;
1117
1118
1118
- switch (task -> tk_status ) {
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 :
1119
+ switch (op_status ) {
1120
+ case NFS4_OK :
1121
+ case NFS4ERR_NXIO :
1122
+ break ;
1123
+ case NFSERR_PERM :
1124
+ if (!task -> tk_xprt )
1125
+ break ;
1126
+ xprt_force_disconnect (task -> tk_xprt );
1127
+ goto out_retry ;
1128
+ case NFS4ERR_BADSESSION :
1129
+ case NFS4ERR_BADSLOT :
1130
+ case NFS4ERR_BAD_HIGH_SLOT :
1131
+ case NFS4ERR_DEADSESSION :
1132
+ case NFS4ERR_CONN_NOT_BOUND_TO_SESSION :
1133
+ case NFS4ERR_SEQ_FALSE_RETRY :
1134
+ case NFS4ERR_SEQ_MISORDERED :
1126
1135
dprintk ("%s ERROR %d, Reset session. Exchangeid "
1127
1136
"flags 0x%x\n" , __func__ , task -> tk_status ,
1128
1137
clp -> cl_exchange_flags );
1129
1138
nfs4_schedule_session_recovery (clp -> cl_session , task -> tk_status );
1130
- break ;
1131
- case - NFS4ERR_DELAY :
1139
+ goto out_retry ;
1140
+ case NFS4ERR_DELAY :
1132
1141
nfs_inc_stats (lseg -> pls_layout -> plh_inode , NFSIOS_DELAY );
1133
1142
fallthrough ;
1134
- case - NFS4ERR_GRACE :
1143
+ case NFS4ERR_GRACE :
1135
1144
rpc_delay (task , FF_LAYOUT_POLL_RETRY_MAX );
1136
- break ;
1137
- case - NFS4ERR_RETRY_UNCACHED_REP :
1138
- break ;
1145
+ goto out_retry ;
1146
+ case NFS4ERR_RETRY_UNCACHED_REP :
1147
+ goto out_retry ;
1139
1148
/* Invalidate Layout errors */
1140
- case - NFS4ERR_PNFS_NO_LAYOUT :
1141
- case - ESTALE : /* mapped NFS4ERR_STALE */
1142
- case - EBADHANDLE : /* mapped NFS4ERR_BADHANDLE */
1143
- case - EISDIR : /* mapped NFS4ERR_ISDIR */
1144
- case - NFS4ERR_FHEXPIRED :
1145
- case - NFS4ERR_WRONG_TYPE :
1149
+ case NFS4ERR_PNFS_NO_LAYOUT :
1150
+ case NFS4ERR_STALE :
1151
+ case NFS4ERR_BADHANDLE :
1152
+ case NFS4ERR_ISDIR :
1153
+ case NFS4ERR_FHEXPIRED :
1154
+ case NFS4ERR_WRONG_TYPE :
1146
1155
dprintk ("%s Invalid layout error %d\n" , __func__ ,
1147
1156
task -> tk_status );
1148
1157
/*
@@ -1155,6 +1164,11 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
1155
1164
pnfs_destroy_layout (NFS_I (inode ));
1156
1165
rpc_wake_up (& tbl -> slot_tbl_waitq );
1157
1166
goto reset ;
1167
+ default :
1168
+ break ;
1169
+ }
1170
+
1171
+ switch (task -> tk_status ) {
1158
1172
/* RPC connection errors */
1159
1173
case - ENETDOWN :
1160
1174
case - ENETUNREACH :
@@ -1174,27 +1188,56 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
1174
1188
nfs4_delete_deviceid (devid -> ld , devid -> nfs_client ,
1175
1189
& devid -> deviceid );
1176
1190
rpc_wake_up (& tbl -> slot_tbl_waitq );
1177
- fallthrough ;
1191
+ break ;
1178
1192
default :
1179
- if (ff_layout_avoid_mds_available_ds (lseg ))
1180
- return - NFS4ERR_RESET_TO_PNFS ;
1181
- reset :
1182
- dprintk ("%s Retry through MDS. Error %d\n" , __func__ ,
1183
- task -> tk_status );
1184
- return - NFS4ERR_RESET_TO_MDS ;
1193
+ break ;
1185
1194
}
1195
+
1196
+ if (ff_layout_avoid_mds_available_ds (lseg ))
1197
+ return - NFS4ERR_RESET_TO_PNFS ;
1198
+ reset :
1199
+ dprintk ("%s Retry through MDS. Error %d\n" , __func__ ,
1200
+ task -> tk_status );
1201
+ return - NFS4ERR_RESET_TO_MDS ;
1202
+
1203
+ out_retry :
1186
1204
task -> tk_status = 0 ;
1187
1205
return - EAGAIN ;
1188
1206
}
1189
1207
1190
1208
/* Retry all errors through either pNFS or MDS except for -EJUKEBOX */
1191
1209
static int ff_layout_async_handle_error_v3 (struct rpc_task * task ,
1210
+ u32 op_status ,
1192
1211
struct nfs_client * clp ,
1193
1212
struct pnfs_layout_segment * lseg ,
1194
1213
u32 idx )
1195
1214
{
1196
1215
struct nfs4_deviceid_node * devid = FF_LAYOUT_DEVID_NODE (lseg , idx );
1197
1216
1217
+ switch (op_status ) {
1218
+ case NFS_OK :
1219
+ case NFSERR_NXIO :
1220
+ break ;
1221
+ case NFSERR_PERM :
1222
+ if (!task -> tk_xprt )
1223
+ break ;
1224
+ xprt_force_disconnect (task -> tk_xprt );
1225
+ goto out_retry ;
1226
+ case NFSERR_ACCES :
1227
+ case NFSERR_BADHANDLE :
1228
+ case NFSERR_FBIG :
1229
+ case NFSERR_IO :
1230
+ case NFSERR_NOSPC :
1231
+ case NFSERR_ROFS :
1232
+ case NFSERR_STALE :
1233
+ goto out_reset_to_pnfs ;
1234
+ case NFSERR_JUKEBOX :
1235
+ nfs_inc_stats (lseg -> pls_layout -> plh_inode , NFSIOS_DELAY );
1236
+ goto out_retry ;
1237
+ default :
1238
+ break ;
1239
+ }
1240
+
1198
1241
switch (task -> tk_status ) {
1199
1242
/* File access problems. Don't mark the device as unavailable */
1200
1243
case - EACCES :
@@ -1218,6 +1261,7 @@ static int ff_layout_async_handle_error_v3(struct rpc_task *task,
1218
1261
nfs4_delete_deviceid (devid -> ld , devid -> nfs_client ,
1219
1262
& devid -> deviceid );
1220
1263
}
1264
+ out_reset_to_pnfs :
1221
1265
/* FIXME: Need to prevent infinite looping here. */
1222
1266
return - NFS4ERR_RESET_TO_PNFS ;
1223
1267
out_retry :
@@ -1228,6 +1272,7 @@ static int ff_layout_async_handle_error_v3(struct rpc_task *task,
1228
1272
}
1229
1273
1230
1274
static int ff_layout_async_handle_error (struct rpc_task * task ,
1275
+ u32 op_status ,
1231
1276
struct nfs4_state * state ,
1232
1277
struct nfs_client * clp ,
1233
1278
struct pnfs_layout_segment * lseg ,
@@ -1246,10 +1291,11 @@ static int ff_layout_async_handle_error(struct rpc_task *task,
1246
1291
1247
1292
switch (vers ) {
1248
1293
case 3 :
1249
- return ff_layout_async_handle_error_v3 (task , clp , lseg , idx );
1250
- case 4 :
1251
- return ff_layout_async_handle_error_v4 (task , state , clp ,
1294
+ return ff_layout_async_handle_error_v3 (task , op_status , clp ,
1252
1295
lseg , idx );
1296
+ case 4 :
1297
+ return ff_layout_async_handle_error_v4 (task , op_status , state ,
1298
+ clp , lseg , idx );
1253
1299
default :
1254
1300
/* should never happen */
1255
1301
WARN_ON_ONCE (1 );
@@ -1302,6 +1348,7 @@ static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg,
1302
1348
switch (status ) {
1303
1349
case NFS4ERR_DELAY :
1304
1350
case NFS4ERR_GRACE :
1351
+ case NFS4ERR_PERM :
1305
1352
break ;
1306
1353
case NFS4ERR_NXIO :
1307
1354
ff_layout_mark_ds_unreachable (lseg , idx );
@@ -1334,7 +1381,8 @@ static int ff_layout_read_done_cb(struct rpc_task *task,
1334
1381
trace_ff_layout_read_error (hdr , task -> tk_status );
1335
1382
}
1336
1383
1337
- err = ff_layout_async_handle_error (task , hdr -> args .context -> state ,
1384
+ err = ff_layout_async_handle_error (task , hdr -> res .op_status ,
1385
+ hdr -> args .context -> state ,
1338
1386
hdr -> ds_clp , hdr -> lseg ,
1339
1387
hdr -> pgio_mirror_idx );
1340
1388
@@ -1507,7 +1555,8 @@ static int ff_layout_write_done_cb(struct rpc_task *task,
1507
1555
trace_ff_layout_write_error (hdr , task -> tk_status );
1508
1556
}
1509
1557
1510
- err = ff_layout_async_handle_error (task , hdr -> args .context -> state ,
1558
+ err = ff_layout_async_handle_error (task , hdr -> res .op_status ,
1559
+ hdr -> args .context -> state ,
1511
1560
hdr -> ds_clp , hdr -> lseg ,
1512
1561
hdr -> pgio_mirror_idx );
1513
1562
@@ -1556,8 +1605,9 @@ static int ff_layout_commit_done_cb(struct rpc_task *task,
1556
1605
trace_ff_layout_commit_error (data , task -> tk_status );
1557
1606
}
1558
1607
1559
- err = ff_layout_async_handle_error (task , NULL , data -> ds_clp ,
1560
- data -> lseg , data -> ds_commit_index );
1608
+ err = ff_layout_async_handle_error (task , data -> res .op_status ,
1609
+ NULL , data -> ds_clp , data -> lseg ,
1610
+ data -> ds_commit_index );
1561
1611
1562
1612
trace_nfs4_pnfs_commit_ds (data , err );
1563
1613
switch (err ) {
0 commit comments