hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/fs/nfs/nfs4state.c
....@@ -67,6 +67,8 @@
6767
6868 #define OPENOWNER_POOL_SIZE 8
6969
70
+static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp);
71
+
7072 const nfs4_stateid zero_stateid = {
7173 { .data = { 0 } },
7274 .type = NFS4_SPECIAL_STATEID_TYPE,
....@@ -330,6 +332,8 @@
330332 status = nfs4_proc_create_session(clp, cred);
331333 if (status != 0)
332334 goto out;
335
+ if (!(clp->cl_exchange_flags & EXCHGID4_FLAG_CONFIRMED_R))
336
+ nfs4_state_start_reclaim_reboot(clp);
333337 nfs41_finish_session_reset(clp);
334338 nfs_mark_client_ready(clp, NFS_CS_READY);
335339 out:
....@@ -1208,10 +1212,23 @@
12081212 {
12091213 struct task_struct *task;
12101214 char buf[INET6_ADDRSTRLEN + sizeof("-manager") + 1];
1215
+ struct rpc_clnt *clnt = clp->cl_rpcclient;
1216
+ bool swapon = false;
12111217
12121218 set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state);
1219
+
1220
+ if (atomic_read(&clnt->cl_swapper)) {
1221
+ swapon = !test_and_set_bit(NFS4CLNT_MANAGER_AVAILABLE,
1222
+ &clp->cl_state);
1223
+ if (!swapon) {
1224
+ wake_up_var(&clp->cl_state);
1225
+ return;
1226
+ }
1227
+ }
1228
+
12131229 if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
12141230 return;
1231
+
12151232 __module_get(THIS_MODULE);
12161233 refcount_inc(&clp->cl_count);
12171234
....@@ -1226,6 +1243,10 @@
12261243 if (IS_ERR(task)) {
12271244 printk(KERN_ERR "%s: kthread_run: %ld\n",
12281245 __func__, PTR_ERR(task));
1246
+ if (!nfs_client_init_is_complete(clp))
1247
+ nfs_mark_client_ready(clp, PTR_ERR(task));
1248
+ if (swapon)
1249
+ clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state);
12291250 nfs4_clear_state_manager_bit(clp);
12301251 nfs_put_client(clp);
12311252 module_put(THIS_MODULE);
....@@ -2669,6 +2690,13 @@
26692690 nfs4_end_drain_session(clp);
26702691 nfs4_clear_state_manager_bit(clp);
26712692
2693
+ if (test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state) &&
2694
+ !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING,
2695
+ &clp->cl_state)) {
2696
+ memflags = memalloc_nofs_save();
2697
+ continue;
2698
+ }
2699
+
26722700 if (!test_and_set_bit(NFS4CLNT_RECALL_RUNNING, &clp->cl_state)) {
26732701 if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) {
26742702 nfs_client_return_marked_delegations(clp);
....@@ -2678,12 +2706,8 @@
26782706 clear_bit(NFS4CLNT_RECALL_RUNNING, &clp->cl_state);
26792707 }
26802708
2681
- /* Did we race with an attempt to give us more work? */
2682
- if (!test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state))
2683
- return;
2684
- if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
2685
- return;
2686
- memflags = memalloc_nofs_save();
2709
+ return;
2710
+
26872711 } while (refcount_read(&clp->cl_count) > 1 && !signalled());
26882712 goto out_drain;
26892713
....@@ -2704,9 +2728,34 @@
27042728 static int nfs4_run_state_manager(void *ptr)
27052729 {
27062730 struct nfs_client *clp = ptr;
2731
+ struct rpc_clnt *cl = clp->cl_rpcclient;
2732
+
2733
+ while (cl != cl->cl_parent)
2734
+ cl = cl->cl_parent;
27072735
27082736 allow_signal(SIGKILL);
2737
+again:
27092738 nfs4_state_manager(clp);
2739
+
2740
+ if (test_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state) &&
2741
+ !test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state)) {
2742
+ wait_var_event_interruptible(&clp->cl_state,
2743
+ test_bit(NFS4CLNT_RUN_MANAGER,
2744
+ &clp->cl_state));
2745
+ if (!atomic_read(&cl->cl_swapper))
2746
+ clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state);
2747
+ if (refcount_read(&clp->cl_count) > 1 && !signalled() &&
2748
+ !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state))
2749
+ goto again;
2750
+ /* Either no longer a swapper, or were signalled */
2751
+ clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state);
2752
+ }
2753
+
2754
+ if (refcount_read(&clp->cl_count) > 1 && !signalled() &&
2755
+ test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state) &&
2756
+ !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state))
2757
+ goto again;
2758
+
27102759 nfs_put_client(clp);
27112760 module_put_and_exit(0);
27122761 return 0;