.. | .. |
---|
67 | 67 | |
---|
68 | 68 | #define OPENOWNER_POOL_SIZE 8 |
---|
69 | 69 | |
---|
| 70 | +static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp); |
---|
| 71 | + |
---|
70 | 72 | const nfs4_stateid zero_stateid = { |
---|
71 | 73 | { .data = { 0 } }, |
---|
72 | 74 | .type = NFS4_SPECIAL_STATEID_TYPE, |
---|
.. | .. |
---|
330 | 332 | status = nfs4_proc_create_session(clp, cred); |
---|
331 | 333 | if (status != 0) |
---|
332 | 334 | goto out; |
---|
| 335 | + if (!(clp->cl_exchange_flags & EXCHGID4_FLAG_CONFIRMED_R)) |
---|
| 336 | + nfs4_state_start_reclaim_reboot(clp); |
---|
333 | 337 | nfs41_finish_session_reset(clp); |
---|
334 | 338 | nfs_mark_client_ready(clp, NFS_CS_READY); |
---|
335 | 339 | out: |
---|
.. | .. |
---|
1208 | 1212 | { |
---|
1209 | 1213 | struct task_struct *task; |
---|
1210 | 1214 | char buf[INET6_ADDRSTRLEN + sizeof("-manager") + 1]; |
---|
| 1215 | + struct rpc_clnt *clnt = clp->cl_rpcclient; |
---|
| 1216 | + bool swapon = false; |
---|
1211 | 1217 | |
---|
1212 | 1218 | 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 | + |
---|
1213 | 1229 | if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) |
---|
1214 | 1230 | return; |
---|
| 1231 | + |
---|
1215 | 1232 | __module_get(THIS_MODULE); |
---|
1216 | 1233 | refcount_inc(&clp->cl_count); |
---|
1217 | 1234 | |
---|
.. | .. |
---|
1226 | 1243 | if (IS_ERR(task)) { |
---|
1227 | 1244 | printk(KERN_ERR "%s: kthread_run: %ld\n", |
---|
1228 | 1245 | __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); |
---|
1229 | 1250 | nfs4_clear_state_manager_bit(clp); |
---|
1230 | 1251 | nfs_put_client(clp); |
---|
1231 | 1252 | module_put(THIS_MODULE); |
---|
.. | .. |
---|
2669 | 2690 | nfs4_end_drain_session(clp); |
---|
2670 | 2691 | nfs4_clear_state_manager_bit(clp); |
---|
2671 | 2692 | |
---|
| 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 | + |
---|
2672 | 2700 | if (!test_and_set_bit(NFS4CLNT_RECALL_RUNNING, &clp->cl_state)) { |
---|
2673 | 2701 | if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) { |
---|
2674 | 2702 | nfs_client_return_marked_delegations(clp); |
---|
.. | .. |
---|
2678 | 2706 | clear_bit(NFS4CLNT_RECALL_RUNNING, &clp->cl_state); |
---|
2679 | 2707 | } |
---|
2680 | 2708 | |
---|
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 | + |
---|
2687 | 2711 | } while (refcount_read(&clp->cl_count) > 1 && !signalled()); |
---|
2688 | 2712 | goto out_drain; |
---|
2689 | 2713 | |
---|
.. | .. |
---|
2704 | 2728 | static int nfs4_run_state_manager(void *ptr) |
---|
2705 | 2729 | { |
---|
2706 | 2730 | 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; |
---|
2707 | 2735 | |
---|
2708 | 2736 | allow_signal(SIGKILL); |
---|
| 2737 | +again: |
---|
2709 | 2738 | 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 | + |
---|
2710 | 2759 | nfs_put_client(clp); |
---|
2711 | 2760 | module_put_and_exit(0); |
---|
2712 | 2761 | return 0; |
---|