aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r--fs/nfs/nfs4state.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 8406cacd3240..9164758c1ace 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1249,6 +1249,12 @@ static int nfs4_reclaim_lease(struct nfs_client *clp)
1249} 1249}
1250 1250
1251#ifdef CONFIG_NFS_V4_1 1251#ifdef CONFIG_NFS_V4_1
1252void nfs41_handle_recall_slot(struct nfs_client *clp)
1253{
1254 set_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state);
1255 nfs4_schedule_state_recovery(clp);
1256}
1257
1252void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags) 1258void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags)
1253{ 1259{
1254 if (!flags) 1260 if (!flags)
@@ -1299,9 +1305,38 @@ out:
1299 return status; 1305 return status;
1300} 1306}
1301 1307
1308static int nfs4_recall_slot(struct nfs_client *clp)
1309{
1310 struct nfs4_slot_table *fc_tbl = &clp->cl_session->fc_slot_table;
1311 struct nfs4_channel_attrs *fc_attrs = &clp->cl_session->fc_attrs;
1312 struct nfs4_slot *new, *old;
1313 int i;
1314
1315 nfs4_begin_drain_session(clp);
1316 new = kmalloc(fc_tbl->target_max_slots * sizeof(struct nfs4_slot),
1317 GFP_KERNEL);
1318 if (!new)
1319 return -ENOMEM;
1320
1321 spin_lock(&fc_tbl->slot_tbl_lock);
1322 for (i = 0; i < fc_tbl->target_max_slots; i++)
1323 new[i].seq_nr = fc_tbl->slots[i].seq_nr;
1324 old = fc_tbl->slots;
1325 fc_tbl->slots = new;
1326 fc_tbl->max_slots = fc_tbl->target_max_slots;
1327 fc_tbl->target_max_slots = 0;
1328 fc_attrs->max_reqs = fc_tbl->max_slots;
1329 spin_unlock(&fc_tbl->slot_tbl_lock);
1330
1331 kfree(old);
1332 nfs4_end_drain_session(clp);
1333 return 0;
1334}
1335
1302#else /* CONFIG_NFS_V4_1 */ 1336#else /* CONFIG_NFS_V4_1 */
1303static int nfs4_reset_session(struct nfs_client *clp) { return 0; } 1337static int nfs4_reset_session(struct nfs_client *clp) { return 0; }
1304static int nfs4_end_drain_session(struct nfs_client *clp) { return 0; } 1338static int nfs4_end_drain_session(struct nfs_client *clp) { return 0; }
1339static int nfs4_recall_slot(struct nfs_client *clp) { return 0; }
1305#endif /* CONFIG_NFS_V4_1 */ 1340#endif /* CONFIG_NFS_V4_1 */
1306 1341
1307/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors 1342/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors
@@ -1398,6 +1433,15 @@ static void nfs4_state_manager(struct nfs_client *clp)
1398 nfs_client_return_marked_delegations(clp); 1433 nfs_client_return_marked_delegations(clp);
1399 continue; 1434 continue;
1400 } 1435 }
1436 /* Recall session slots */
1437 if (test_and_clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state)
1438 && nfs4_has_session(clp)) {
1439 status = nfs4_recall_slot(clp);
1440 if (status < 0)
1441 goto out_error;
1442 continue;
1443 }
1444
1401 1445
1402 nfs4_clear_state_manager_bit(clp); 1446 nfs4_clear_state_manager_bit(clp);
1403 /* Did we race with an attempt to give us more work? */ 1447 /* Did we race with an attempt to give us more work? */