Skip to content

Commit ce95858

Browse files
committed
Merge tag 'nfs-for-6.16-2' of git://git.linux-nfs.org/projects/anna/linux-nfs
Pull NFS client fixes from Anna Schumaker: - Fix loop in GSS sequence number cache - Clean up /proc/net/rpc/nfs if nfs_fs_proc_net_init() fails - Fix a race to wake on NFS_LAYOUT_DRAIN - Fix handling of NFS level errors in I/O * tag 'nfs-for-6.16-2' of git://git.linux-nfs.org/projects/anna/linux-nfs: NFSv4/flexfiles: Fix handling of NFS level errors in I/O NFSv4/pNFS: Fix a race to wake on NFS_LAYOUT_DRAIN nfs: Clean up /proc/net/rpc/nfs when nfs_fs_proc_net_init() fails. sunrpc: fix loop in gss seqno cache
2 parents 6670175 + 38074de commit ce95858

File tree

4 files changed

+102
-39
lines changed

4 files changed

+102
-39
lines changed

fs/nfs/flexfilelayout/flexfilelayout.c

Lines changed: 84 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,7 @@ static void ff_layout_reset_read(struct nfs_pgio_header *hdr)
11051105
}
11061106

11071107
static int ff_layout_async_handle_error_v4(struct rpc_task *task,
1108+
u32 op_status,
11081109
struct nfs4_state *state,
11091110
struct nfs_client *clp,
11101111
struct pnfs_layout_segment *lseg,
@@ -1115,34 +1116,42 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
11151116
struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx);
11161117
struct nfs4_slot_table *tbl = &clp->cl_session->fc_slot_table;
11171118

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:
11261135
dprintk("%s ERROR %d, Reset session. Exchangeid "
11271136
"flags 0x%x\n", __func__, task->tk_status,
11281137
clp->cl_exchange_flags);
11291138
nfs4_schedule_session_recovery(clp->cl_session, task->tk_status);
1130-
break;
1131-
case -NFS4ERR_DELAY:
1139+
goto out_retry;
1140+
case NFS4ERR_DELAY:
11321141
nfs_inc_stats(lseg->pls_layout->plh_inode, NFSIOS_DELAY);
11331142
fallthrough;
1134-
case -NFS4ERR_GRACE:
1143+
case NFS4ERR_GRACE:
11351144
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;
11391148
/* 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:
11461155
dprintk("%s Invalid layout error %d\n", __func__,
11471156
task->tk_status);
11481157
/*
@@ -1155,6 +1164,11 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
11551164
pnfs_destroy_layout(NFS_I(inode));
11561165
rpc_wake_up(&tbl->slot_tbl_waitq);
11571166
goto reset;
1167+
default:
1168+
break;
1169+
}
1170+
1171+
switch (task->tk_status) {
11581172
/* RPC connection errors */
11591173
case -ENETDOWN:
11601174
case -ENETUNREACH:
@@ -1174,27 +1188,56 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
11741188
nfs4_delete_deviceid(devid->ld, devid->nfs_client,
11751189
&devid->deviceid);
11761190
rpc_wake_up(&tbl->slot_tbl_waitq);
1177-
fallthrough;
1191+
break;
11781192
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;
11851194
}
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:
11861204
task->tk_status = 0;
11871205
return -EAGAIN;
11881206
}
11891207

11901208
/* Retry all errors through either pNFS or MDS except for -EJUKEBOX */
11911209
static int ff_layout_async_handle_error_v3(struct rpc_task *task,
1210+
u32 op_status,
11921211
struct nfs_client *clp,
11931212
struct pnfs_layout_segment *lseg,
11941213
u32 idx)
11951214
{
11961215
struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx);
11971216

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+
11981241
switch (task->tk_status) {
11991242
/* File access problems. Don't mark the device as unavailable */
12001243
case -EACCES:
@@ -1218,6 +1261,7 @@ static int ff_layout_async_handle_error_v3(struct rpc_task *task,
12181261
nfs4_delete_deviceid(devid->ld, devid->nfs_client,
12191262
&devid->deviceid);
12201263
}
1264+
out_reset_to_pnfs:
12211265
/* FIXME: Need to prevent infinite looping here. */
12221266
return -NFS4ERR_RESET_TO_PNFS;
12231267
out_retry:
@@ -1228,6 +1272,7 @@ static int ff_layout_async_handle_error_v3(struct rpc_task *task,
12281272
}
12291273

12301274
static int ff_layout_async_handle_error(struct rpc_task *task,
1275+
u32 op_status,
12311276
struct nfs4_state *state,
12321277
struct nfs_client *clp,
12331278
struct pnfs_layout_segment *lseg,
@@ -1246,10 +1291,11 @@ static int ff_layout_async_handle_error(struct rpc_task *task,
12461291

12471292
switch (vers) {
12481293
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,
12521295
lseg, idx);
1296+
case 4:
1297+
return ff_layout_async_handle_error_v4(task, op_status, state,
1298+
clp, lseg, idx);
12531299
default:
12541300
/* should never happen */
12551301
WARN_ON_ONCE(1);
@@ -1302,6 +1348,7 @@ static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg,
13021348
switch (status) {
13031349
case NFS4ERR_DELAY:
13041350
case NFS4ERR_GRACE:
1351+
case NFS4ERR_PERM:
13051352
break;
13061353
case NFS4ERR_NXIO:
13071354
ff_layout_mark_ds_unreachable(lseg, idx);
@@ -1334,7 +1381,8 @@ static int ff_layout_read_done_cb(struct rpc_task *task,
13341381
trace_ff_layout_read_error(hdr, task->tk_status);
13351382
}
13361383

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,
13381386
hdr->ds_clp, hdr->lseg,
13391387
hdr->pgio_mirror_idx);
13401388

@@ -1507,7 +1555,8 @@ static int ff_layout_write_done_cb(struct rpc_task *task,
15071555
trace_ff_layout_write_error(hdr, task->tk_status);
15081556
}
15091557

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,
15111560
hdr->ds_clp, hdr->lseg,
15121561
hdr->pgio_mirror_idx);
15131562

@@ -1556,8 +1605,9 @@ static int ff_layout_commit_done_cb(struct rpc_task *task,
15561605
trace_ff_layout_commit_error(data, task->tk_status);
15571606
}
15581607

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);
15611611

15621612
trace_nfs4_pnfs_commit_ds(data, err);
15631613
switch (err) {

fs/nfs/inode.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2589,15 +2589,26 @@ EXPORT_SYMBOL_GPL(nfs_net_id);
25892589
static int nfs_net_init(struct net *net)
25902590
{
25912591
struct nfs_net *nn = net_generic(net, nfs_net_id);
2592+
int err;
25922593

25932594
nfs_clients_init(net);
25942595

25952596
if (!rpc_proc_register(net, &nn->rpcstats)) {
2596-
nfs_clients_exit(net);
2597-
return -ENOMEM;
2597+
err = -ENOMEM;
2598+
goto err_proc_rpc;
25982599
}
25992600

2600-
return nfs_fs_proc_net_init(net);
2601+
err = nfs_fs_proc_net_init(net);
2602+
if (err)
2603+
goto err_proc_nfs;
2604+
2605+
return 0;
2606+
2607+
err_proc_nfs:
2608+
rpc_proc_unregister(net, "nfs");
2609+
err_proc_rpc:
2610+
nfs_clients_exit(net);
2611+
return err;
26012612
}
26022613

26032614
static void nfs_net_exit(struct net *net)

fs/nfs/pnfs.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2059,8 +2059,10 @@ static void nfs_layoutget_begin(struct pnfs_layout_hdr *lo)
20592059
static void nfs_layoutget_end(struct pnfs_layout_hdr *lo)
20602060
{
20612061
if (atomic_dec_and_test(&lo->plh_outstanding) &&
2062-
test_and_clear_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags))
2062+
test_and_clear_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags)) {
2063+
smp_mb__after_atomic();
20632064
wake_up_bit(&lo->plh_flags, NFS_LAYOUT_DRAIN);
2065+
}
20642066
}
20652067

20662068
static bool pnfs_is_first_layoutget(struct pnfs_layout_hdr *lo)

net/sunrpc/auth_gss/auth_gss.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1724,7 +1724,7 @@ gss_validate(struct rpc_task *task, struct xdr_stream *xdr)
17241724
maj_stat = gss_validate_seqno_mic(ctx, task->tk_rqstp->rq_seqnos[0], seq, p, len);
17251725
/* RFC 2203 5.3.3.1 - compute the checksum of each sequence number in the cache */
17261726
while (unlikely(maj_stat == GSS_S_BAD_SIG && i < task->tk_rqstp->rq_seqno_count))
1727-
maj_stat = gss_validate_seqno_mic(ctx, task->tk_rqstp->rq_seqnos[i], seq, p, len);
1727+
maj_stat = gss_validate_seqno_mic(ctx, task->tk_rqstp->rq_seqnos[i++], seq, p, len);
17281728
if (maj_stat == GSS_S_CONTEXT_EXPIRED)
17291729
clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
17301730
if (maj_stat)

0 commit comments

Comments
 (0)